System.Runtime.CompilerServices命名空间下有4个以“Caller”为前缀命名的Attribute,我们可以将它标注到方法参数上自动获取当前调用上下文的信息,比如当前的方法名、某个参数的表达式、当前源文件的路径,以及当前代码在源文件中的行号 。
一、CallerMemberNameAttribute顾名思义,如果当我们将CallerMemberNameAttribute特性标注到“可缺省参数”上,调用方无需显式指定参数值就可以将表示当前调用方法名赋值给该参数 。如下面的代码片段所示 , 我们为ActivitySource定义了一个名为StartNewActivity的扩展方法,表示Activity名称的name参数是一个“可缺省参数” 。我们在该参数上标准了CallerMemberNameAttribute特性,意味着当前调用的方法名将自动作为参数值 。
public static class Extensions{ public static Activity? StartNewActivity(this ActivitySource activitySource, ActivityKind kind = ActivityKind.Internal, [CallerMemberName] string name = "") => activitySource.StartActivity(name: name, kind: kind);}以Activity/ActivitySource/ActivityListener为核心的模型实际上是对OpenTelemetry的实现,所有我们可以利用上面定义的这个StartNewActivity创建一个代码跟踪操作的Activity(对应OpenTelemetry下的Span) 。针对StartNewActivity方法调用体现在如下这个Invoker类型中 , 它的构造函数中注入了ActivitySource 对象 。InvokeAsync方法内部调用了私有方法FooAsync、后者又调用了BarAsync方法,调用链InvokeAsync->FooAsync->BarAsync的跟踪通过调用ActivitySource的StartNewActivity扩展方法被记录下来 , 我们在调用此方法时并没有指定参数 。
public class Invoker{ private readonly ActivitySource _activitySource; public Invoker(ActivitySource activitySource) => _activitySource = activitySource; public async Task InvokeAsync() { using (_activitySource.StartNewActivity()) { await Task.Delay(100); await FooAsync(); } } private async Task FooAsync() { using (_activitySource.StartNewActivity()) { await Task.Delay(100); await BarAsync(); } } private Task BarAsync() { using (_activitySource.StartNewActivity()) { return Task.Delay(100); } }}我们利用如下的代码利用依赖注入框架将Invoker对象创建出来,并调用其Invoke方法 。
ActivitySource.AddActivityListener(new ActivityListener{ ShouldListenTo = _ => true, Sample = (ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllData, ActivityStopped = activity => { Console.WriteLine(activity.DisplayName); Console.WriteLine($"\tTraceId:{activity.TraceId}"); Console.WriteLine($"\tSpanId:{activity.SpanId}"); Console.WriteLine($"\tDuration:{activity.Duration}"); foreach (var kv in activity.TagObjects) { Console.WriteLine($"\t{kv.Key}:{kv.Value}"); } Console.WriteLine(); }});await new ServiceCollection() .AddSingleton(new ActivitySource("App")) .AddSingleton<Invoker>() .BuildServiceProvider() .GetRequiredService<Invoker>() .InvokeAsync();
推荐阅读
- 去越南必买的十件东西,值得买的越南特产排名,越买越心动
- 剑南春52度有几种版本_剑南春分几个档次
- 野三坡六大特色景区 野三坡景区攻略
- 在Tomcat中启用虚拟线程特性
- 【Java8新特性】- Lambda表达式
- 特工17v18.5版本怎么玩
- 小米11有几个版本_小米11有哪些版本
- 哈利波特:魔法觉醒万圣节卡南瓜拍照怎么做
- 【Java8新特性】- 接口中默认方法修饰为普通方法
- 痔疮用哪些药物?那些年我用过的痔疮膏 今天给大家推荐几个我用过的痔疮药。