-
Notifications
You must be signed in to change notification settings - Fork 333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add FreeRedis Diagnostics #547
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
using System; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All code files need to add the SkyAPM copyright header. Please refer to https://github.com/SkyAPM/SkyAPM-dotnet/blob/main/src/SkyApm.Abstractions/ITracingDiagnosticProcessor.cs#L1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ok |
||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace SkyApm.Diagnostics.FreeRedis | ||
{ | ||
internal static class FreeRedisPluginConfig | ||
{ | ||
internal static HashSet<String> OPERATION_MAPPING_WRITE = new HashSet<string>() { | ||
"GETSET", | ||
"SET", | ||
"SETBIT", | ||
"SETEX ", | ||
"SETNX ", | ||
"SETRANGE", | ||
"STRLEN ", | ||
"MSET", | ||
"MSETNX ", | ||
"PSETEX", | ||
"INCR ", | ||
"INCRBY ", | ||
"INCRBYFLOAT", | ||
"DECR ", | ||
"DECRBY ", | ||
"APPEND ", | ||
"HMSET", | ||
"HSET", | ||
"HSETNX ", | ||
"HINCRBY", | ||
"HINCRBYFLOAT", | ||
"HDEL", | ||
"RPOPLPUSH", | ||
"RPUSH", | ||
"RPUSHX", | ||
"LPUSH", | ||
"LPUSHX", | ||
"LREM", | ||
"LTRIM", | ||
"LSET", | ||
"BRPOPLPUSH", | ||
"LINSERT", | ||
"SADD", | ||
"SDIFF", | ||
"SDIFFSTORE", | ||
"SINTERSTORE", | ||
"SISMEMBER", | ||
"SREM", | ||
"SUNION", | ||
"SUNIONSTORE", | ||
"SINTER", | ||
"ZADD", | ||
"ZINCRBY", | ||
"ZINTERSTORE", | ||
"ZRANGE", | ||
"ZRANGEBYLEX", | ||
"ZRANGEBYSCORE", | ||
"ZRANK", | ||
"ZREM", | ||
"ZREMRANGEBYLEX", | ||
"ZREMRANGEBYRANK", | ||
"ZREMRANGEBYSCORE", | ||
"ZREVRANGE", | ||
"ZREVRANGEBYSCORE", | ||
"ZREVRANK", | ||
"ZUNIONSTORE", | ||
"XADD", | ||
"XDEL", | ||
"DEL", | ||
"XTRIM" | ||
}; | ||
internal static HashSet<String> OPERATION_MAPPING_READ = new HashSet<string>(){ | ||
"GET", | ||
"GETRANGE", | ||
"GETBIT ", | ||
"MGET", | ||
"HVALS", | ||
"HKEYS", | ||
"HLEN", | ||
"HEXISTS", | ||
"HGET", | ||
"HGETALL", | ||
"HMGET", | ||
"BLPOP", | ||
"BRPOP", | ||
"LINDEX", | ||
"LLEN", | ||
"LPOP", | ||
"LRANGE", | ||
"RPOP", | ||
"SCARD", | ||
"SRANDMEMBER", | ||
"SPOP", | ||
"SSCAN", | ||
"SMOVE", | ||
"ZLEXCOUNT", | ||
"ZSCORE", | ||
"ZSCAN", | ||
"ZCARD", | ||
"ZCOUNT", | ||
"XGET", | ||
"GET", | ||
"XREAD", | ||
"XLEN", | ||
"XRANGE", | ||
"XREVRANGE" | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
using FreeRedis; | ||
using SkyApm; | ||
using SkyApm.Common; | ||
using SkyApm.Config; | ||
using SkyApm.Diagnostics; | ||
using SkyApm.Tracing; | ||
using SkyApm.Tracing.Segments; | ||
using System; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace SkyApm.Diagnostics.FreeRedis | ||
{ | ||
|
||
|
||
/// <summary> | ||
/// FreeRedisTracingDiagnosticProcessor | ||
/// </summary> | ||
public class FreeRedisTracingDiagnosticProcessor : ITracingDiagnosticProcessor | ||
{ | ||
|
||
#region Const | ||
|
||
public const string ComponentName = "FreeRedis"; | ||
|
||
public const string FreeRedis_Notice = "FreeRedis.Notice"; | ||
|
||
#endregion | ||
|
||
public string ListenerName => "FreeRedisDiagnosticListener"; | ||
|
||
private readonly ITracingContext _tracingContext; | ||
private readonly ILocalSegmentContextAccessor _localSegmentContextAccessor; | ||
private readonly TracingConfig _tracingConfig; | ||
public FreeRedisTracingDiagnosticProcessor(ITracingContext tracingContext, | ||
ILocalSegmentContextAccessor localSegmentContextAccessor, IConfigAccessor configAccessor) | ||
{ | ||
_tracingContext = tracingContext; | ||
_localSegmentContextAccessor = localSegmentContextAccessor; | ||
_tracingConfig = configAccessor.Get<TracingConfig>(); | ||
} | ||
|
||
|
||
#region Notice | ||
[DiagnosticName(FreeRedis_Notice)] | ||
public void Notice([Object] NoticeEventArgs eventData) | ||
{ | ||
var ans = Analysis(eventData.Log); | ||
if (ans == null) return; | ||
var context = _tracingContext.CreateExitSegmentContext(ans[2], ans[0]); | ||
context.Span.SpanLayer = SpanLayer.CACHE; | ||
context.Span.Component = Components.Free_Redis; | ||
context.Span.AddTag(Tags.CACHE_TYPE, "FreeRedis"); | ||
context.Span.AddTag(Tags.CACHE_OP, parseOperation(ans[2])); | ||
context.Span.AddTag(Tags.CACHE_CMD, ans[1]); | ||
context.Span.AddTag("result", ans[3]); | ||
context.Span.AddTag("exec_time", ans[4]); | ||
if (eventData?.Exception != null) | ||
context.Span.ErrorOccurred(eventData.Exception, _tracingConfig); | ||
_tracingContext.Release(context); | ||
} | ||
#endregion | ||
private static String parseOperation(String cmd) | ||
{ | ||
if (FreeRedisPluginConfig.OPERATION_MAPPING_READ.Contains(cmd)) | ||
{ | ||
return "read"; | ||
} | ||
if (FreeRedisPluginConfig.OPERATION_MAPPING_WRITE.Contains(cmd)) | ||
{ | ||
return "write"; | ||
} | ||
return string.Empty; | ||
} | ||
private static Regex anRex = new Regex("(.+)\\s>\\s(([A-Z]+)\\s*.*?)\\r\\n(.*?)\\r\\n\\((\\d+)ms\\)\\r\\n"); | ||
/// <summary> | ||
/// Analysis | ||
/// </summary> | ||
/// <param name="cmd"></param> | ||
/// <returns>[address,cmd,op,result,exectime]</returns> | ||
public static string[] Analysis(string cmd) | ||
{ | ||
if (!(cmd == null || !cmd.Contains(">"))) | ||
{ | ||
if (anRex.IsMatch(cmd)) | ||
{ | ||
var matchs = anRex.Match(cmd); | ||
if (matchs.Success && matchs.Groups.Count > 5) | ||
{ | ||
return new string[] { | ||
matchs.Groups[1].Value, | ||
matchs.Groups[2].Value, | ||
matchs.Groups[3].Value, | ||
matchs.Groups[4].Value, | ||
matchs.Groups[5].Value, | ||
}; | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<Import Project="..\..\build\common.props" /> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>netcoreapp3.1;net5.0;net6.0;net7.0</TargetFrameworks> | ||
<AssemblyName>$(PackagePrefix).Diagnostics.FreeRedis</AssemblyName> | ||
<PackageId>$(PackagePrefix).Diagnostics.FreeRedis</PackageId> | ||
<PackageTags>SkyWalking;APM;Diagnostics;FreeRedis</PackageTags> | ||
<Description>SkyApm.Diagnostics.FreeRedis notifies of FreeRedis requests.</Description> | ||
<RootNamespace>SkyApm.Diagnostics.FreeRedis</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="FreeRedis" Version="1.0.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\SkyApm.Utilities.DependencyInjection\SkyApm.Utilities.DependencyInjection.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using FreeRedis; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using SkyApm; | ||
using SkyApm.Utilities.DependencyInjection; | ||
using System; | ||
using System.Diagnostics; | ||
|
||
namespace SkyApm.Diagnostics.FreeRedis | ||
{ | ||
|
||
public static class SkyWalkingBuilderExtensions | ||
{ | ||
public static readonly DiagnosticListener dl = new DiagnosticListener("FreeRedisDiagnosticListener"); | ||
|
||
public static SkyApmExtensions AddFreeRedis(this SkyApmExtensions extensions, RedisClient redisClient, bool includeAuth = false) | ||
{ | ||
if (extensions == null) | ||
{ | ||
throw new ArgumentNullException(nameof(extensions)); | ||
} | ||
extensions.Services.AddSingleton<ITracingDiagnosticProcessor, FreeRedisTracingDiagnosticProcessor>(); | ||
if (redisClient != null) | ||
{ | ||
ConfigAop(redisClient, includeAuth); | ||
} | ||
return extensions; | ||
} | ||
|
||
|
||
public static void ConfigAop(RedisClient redisClient, bool includeAuth = false) | ||
{ | ||
redisClient.Notice += (s, e) => | ||
{ | ||
if (!string.IsNullOrWhiteSpace(e.Log) && (includeAuth || (!e.Log.Contains("> AUTH ")))) | ||
{ | ||
dl.Write(FreeRedisTracingDiagnosticProcessor.FreeRedis_Notice, e); | ||
} | ||
}; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guochen2 Please register 3018 ID in the main repository.