diff --git a/README.md b/README.md index 127f28cb5..392e5b6d6 100644 --- a/README.md +++ b/README.md @@ -1580,7 +1580,7 @@ I believe that this can be easily and effectively applied to sending a large num ## Experimentals ### OpenTelemetry -MagicOnion.OpenTelemetry is implementation of [open\-telemetry/opentelemetry\-dotnet: OpenTelemetry \.NET SDK](https://github.com/open-telemetry/opentelemetry-dotnet), so you can use any OpenTelemetry exporter, like [Prometheus](https://prometheus.io/), [StackDriver](https://cloud.google.com/stackdriver/pricing), [Zipkin](https://zipkin.io/) and others. +MagicOnion.OpenTelemetry is implementation of [open\-telemetry/opentelemetry\-dotnet: OpenTelemetry \.NET SDK](https://github.com/open-telemetry/opentelemetry-dotnet), so you can use any OpenTelemetry exporter, like [Jaeger](https://www.jaegertracing.io/), [Zipkin](https://zipkin.io/), [StackDriver](https://cloud.google.com/stackdriver) and others. See details at [MagicOnion.Server.OpenTelemetry](src/MagicOnion.Server.OpenTelemetry) diff --git a/samples/ChatApp.Telemetry/ChatApp.Server/ChatHub.cs b/samples/ChatApp.Telemetry/ChatApp.Server/ChatHub.cs index 9cd52e5c5..586ff35df 100644 --- a/samples/ChatApp.Telemetry/ChatApp.Server/ChatHub.cs +++ b/samples/ChatApp.Telemetry/ChatApp.Server/ChatHub.cs @@ -19,25 +19,27 @@ public class ChatHub : StreamingHubBase, IChatHub private string myName; private readonly ActivitySource mysqlActivity; private readonly ActivitySource redisActivity; + private readonly MagicOnionOpenTelemetryOptions options; - public ChatHub(BackendActivitySources backendActivity) + public ChatHub(BackendActivitySources backendActivity, MagicOnionOpenTelemetryOptions options) { - this.mysqlActivity = backendActivity.Get("mysql"); - this.redisActivity = backendActivity.Get("redis"); + this.options = options; + mysqlActivity = backendActivity.Get("mysql"); + redisActivity = backendActivity.Get("redis"); } public async Task JoinAsync(JoinRequest request) { - var random = new Random(); - this.room = await this.Group.AddAsync(request.RoomName); - this.myName = request.UserName; - - this.Broadcast(this.room).OnJoin(request.UserName); + room = await this.Group.AddAsync(request.RoomName); + myName = request.UserName; + Broadcast(this.room).OnJoin(request.UserName); // dummy external operation db. + var random = new Random(); using (var activity = mysqlActivity.StartActivity("room/insert", ActivityKind.Internal)) { // this is sample. use orm or any safe way. + activity.SetTag("service.name", options.ServiceName); activity.SetTag("table", "rooms"); activity.SetTag("query", $"INSERT INTO rooms VALUES (0, '@room', '@username', '1');"); activity.SetTag("parameter.room", request.RoomName); @@ -46,6 +48,7 @@ public async Task JoinAsync(JoinRequest request) } using (var activity = redisActivity.StartActivity($"member/status", ActivityKind.Internal)) { + activity.SetTag("service.name", options.ServiceName); activity.SetTag("command", "set"); activity.SetTag("parameter.key", this.myName); activity.SetTag("parameter.value", "1"); @@ -59,15 +62,15 @@ public async Task JoinAsync(JoinRequest request) public async Task LeaveAsync() { - var random = new Random(); await this.room.RemoveAsync(this.Context); - this.Broadcast(this.room).OnLeave(this.myName); // dummy external operation. + var random = new Random(); using (var activity = mysqlActivity.StartActivity("room/update", ActivityKind.Internal)) { // this is sample. use orm or any safe way. + activity.SetTag("service.name", options.ServiceName); activity.SetTag("table", "rooms"); activity.SetTag("query", $"UPDATE rooms SET status=0 WHERE id='room' AND name='@username';"); activity.SetTag("parameter.room", this.room.GroupName); @@ -77,6 +80,7 @@ public async Task LeaveAsync() using (var activity = redisActivity.StartActivity($"member/status", ActivityKind.Internal)) { + activity.SetTag("service.name", options.ServiceName); activity.SetTag("command", "set"); activity.SetTag("parameter.key", this.myName); activity.SetTag("parameter.value", "0"); @@ -86,13 +90,14 @@ public async Task LeaveAsync() public async Task SendMessageAsync(string message) { - var random = new Random(); var response = new MessageResponse { UserName = this.myName, Message = message }; this.Broadcast(this.room).OnSendMessage(response); // dummy external operation. + var random = new Random(); using (var activity = redisActivity.StartActivity($"chat_latest_message", ActivityKind.Internal)) { + activity.SetTag("service.name", options.ServiceName); activity.SetTag("command", "set"); activity.SetTag("parameter.key", room.GroupName); activity.SetTag("parameter.value", $"{myName}={message}"); @@ -104,13 +109,14 @@ public async Task SendMessageAsync(string message) public async Task GenerateException(string message) { - var random = new Random(); var ex = new Exception(message); // dummy external operation. + var random = new Random(); using (var activity = mysqlActivity.StartActivity("errors/insert", ActivityKind.Internal)) { // this is sample. use orm or any safe way. + activity.SetTag("service.name", options.ServiceName); activity.SetTag("table", "errors"); activity.SetTag("query", $"INSERT INTO rooms VALUES ('{ex.Message}', '{ex.StackTrace}');"); await Task.Delay(TimeSpan.FromMilliseconds(random.Next(2, 20))); diff --git a/samples/ChatApp.Telemetry/ChatApp.Server/ChatService.cs b/samples/ChatApp.Telemetry/ChatApp.Server/ChatService.cs index 4c8e4cb04..2195b313f 100644 --- a/samples/ChatApp.Telemetry/ChatApp.Server/ChatService.cs +++ b/samples/ChatApp.Telemetry/ChatApp.Server/ChatService.cs @@ -24,7 +24,7 @@ public ChatService(BackendActivitySources backendActivity, MagicOnionOpenTelemet { this.options = options; this.mysqlSource = backendActivity.Get("mysql"); - this.s2sSource = backendActivity.Get("chatapp.s2s"); + this.s2sSource = backendActivity.Get("chatapp.server.s2s"); this.logger = logger; } @@ -35,6 +35,7 @@ public async UnaryResult GenerateException(string message) using (var activity = this.mysqlSource.StartActivity("errors/insert", ActivityKind.Internal)) { // this is sample. use orm or any safe way. + activity.SetTag("service.name", options.ServiceName); activity.SetTag("table", "errors"); activity.SetTag("query", $"INSERT INTO rooms VALUES ('{ex.Message}', '{ex.StackTrace}');"); await Task.Delay(TimeSpan.FromMilliseconds(2)); @@ -50,13 +51,14 @@ public async UnaryResult SendReportAsync(string message) using (var activity = this.mysqlSource.StartActivity("report/insert", ActivityKind.Internal)) { // this is sample. use orm or any safe way. + activity.SetTag("service.name", options.ServiceName); activity.SetTag("table", "report"); activity.SetTag("query", $"INSERT INTO report VALUES ('foo', 'bar');"); await Task.Delay(TimeSpan.FromMilliseconds(2)); } // Server to Server operation - var channel = GrpcChannel.ForAddress("http://localhost:4999"); + var channel = GrpcChannel.ForAddress(Environment.GetEnvironmentVariable("Server2ServerEndpoint", EnvironmentVariableTarget.Process) ?? "http://localhost:4999"); var client = MagicOnionClient.Create(channel, new[] { // propagate trace context from ChatApp.Server to MicroServer @@ -68,6 +70,7 @@ public async UnaryResult SendReportAsync(string message) using (var activity = this.mysqlSource.StartActivity("report/get", ActivityKind.Internal)) { // this is sample. use orm or any safe way. + activity.SetTag("service.name", options.ServiceName); activity.SetTag("table", "report"); activity.SetTag("query", $"INSERT INTO report VALUES ('foo', 'bar');"); await Task.Delay(TimeSpan.FromMilliseconds(1)); diff --git a/samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile b/samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile index 459cab1ff..aa36ba31a 100644 --- a/samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile +++ b/samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile @@ -4,11 +4,16 @@ WORKDIR /app FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /src -COPY ["ChatApp.Server/ChatApp.Server.csproj", "ChatApp.Server/"] -COPY ["ChatApp.Shared/ChatApp.Shared.csproj", "ChatApp.Shared/"] -RUN dotnet restore "ChatApp.Server/ChatApp.Server.csproj" +COPY ["samples/ChatApp.Telemetry/ChatApp.Server/ChatApp.Server.csproj", "samples/ChatApp.Telemetry/ChatApp.Server/"] +COPY ["samples/ChatApp.Telemetry/ChatApp.Shared/ChatApp.Shared.csproj", "samples/ChatApp.Telemetry/ChatApp.Shared/"] +COPY ["src/MagicOnion/MagicOnion.csproj", "src/MagicOnion/"] +COPY ["src/MagicOnion.Abstractions/MagicOnion.Abstractions.csproj", "src/MagicOnion.Abstractions/"] +COPY ["src/MagicOnion.Server/MagicOnion.Server.csproj", "src/MagicOnion.Server/"] +COPY ["src/MagicOnion.Server.OpenTelemetry/MagicOnion.Server.OpenTelemetry.csproj", "src/MagicOnion.Server.OpenTelemetry/"] +COPY ["src/MagicOnion.Shared/MagicOnion.Shared.csproj", "src/MagicOnion.Shared/"] +RUN dotnet restore "samples/ChatApp.Telemetry/ChatApp.Server/ChatApp.Server.csproj" COPY . . -WORKDIR "/src/ChatApp.Server" +WORKDIR "/src/samples/ChatApp.Telemetry/ChatApp.Server" RUN dotnet build "ChatApp.Server.csproj" -c Debug -o /app FROM build AS publish diff --git a/samples/ChatApp.Telemetry/ChatApp.Server/Startup.cs b/samples/ChatApp.Telemetry/ChatApp.Server/Startup.cs index 411617296..248280fbc 100644 --- a/samples/ChatApp.Telemetry/ChatApp.Server/Startup.cs +++ b/samples/ChatApp.Telemetry/ChatApp.Server/Startup.cs @@ -74,7 +74,7 @@ public void ConfigureServices(IServiceCollection services) }); // additional Tracer for user's own service. - services.AddAdditionalTracer(Configuration, new[] { "chatapp.s2s", "mysql", "redis" }); + services.AddAdditionalTracer(Configuration); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -108,8 +108,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) public static class TelemetryExtensions { - public static void AddAdditionalTracer(this IServiceCollection services, IConfiguration configuration, string[] serviceNames) + public static void AddAdditionalTracer(this IServiceCollection services, IConfiguration configuration) { + var serviceNames = new[] { "chatapp.server.s2s", "mysql", "redis" }; var exporter = configuration.GetValue("UseExporter").ToLowerInvariant(); foreach (var service in serviceNames) { @@ -125,6 +126,7 @@ public static void AddAdditionalTracer(this IServiceCollection services, IConfig case "zipkin": OpenTelemetry.Sdk.CreateTracerProviderBuilder() .AddSource(service) + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(service)) .AddZipkinExporter() .Build(); break; diff --git a/samples/ChatApp.Telemetry/ChatApp.Server/appsettings.json b/samples/ChatApp.Telemetry/ChatApp.Server/appsettings.json index 51b0218dc..e8bf9f3b3 100644 --- a/samples/ChatApp.Telemetry/ChatApp.Server/appsettings.json +++ b/samples/ChatApp.Telemetry/ChatApp.Server/appsettings.json @@ -13,6 +13,7 @@ }, "MagicOnion": { "OpenTelemetry": { + "ServiceName": "ChatApp.Server", // "ExposeRpcScope": false, "TracingTags": { "foo": "bar" diff --git a/samples/ChatApp.Telemetry/MicroServer.Shared/Class1.cs b/samples/ChatApp.Telemetry/MicroServer.Shared/IMessageService.cs similarity index 100% rename from samples/ChatApp.Telemetry/MicroServer.Shared/Class1.cs rename to samples/ChatApp.Telemetry/MicroServer.Shared/IMessageService.cs diff --git a/samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile.full b/samples/ChatApp.Telemetry/MicroServer/Dockerfile similarity index 65% rename from samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile.full rename to samples/ChatApp.Telemetry/MicroServer/Dockerfile index aa36ba31a..c79c2399f 100644 --- a/samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile.full +++ b/samples/ChatApp.Telemetry/MicroServer/Dockerfile @@ -4,22 +4,22 @@ WORKDIR /app FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /src -COPY ["samples/ChatApp.Telemetry/ChatApp.Server/ChatApp.Server.csproj", "samples/ChatApp.Telemetry/ChatApp.Server/"] +COPY ["samples/ChatApp.Telemetry/MicroServer/MicroServer.csproj", "samples/ChatApp.Telemetry/MicroServer/"] COPY ["samples/ChatApp.Telemetry/ChatApp.Shared/ChatApp.Shared.csproj", "samples/ChatApp.Telemetry/ChatApp.Shared/"] COPY ["src/MagicOnion/MagicOnion.csproj", "src/MagicOnion/"] COPY ["src/MagicOnion.Abstractions/MagicOnion.Abstractions.csproj", "src/MagicOnion.Abstractions/"] COPY ["src/MagicOnion.Server/MagicOnion.Server.csproj", "src/MagicOnion.Server/"] COPY ["src/MagicOnion.Server.OpenTelemetry/MagicOnion.Server.OpenTelemetry.csproj", "src/MagicOnion.Server.OpenTelemetry/"] COPY ["src/MagicOnion.Shared/MagicOnion.Shared.csproj", "src/MagicOnion.Shared/"] -RUN dotnet restore "samples/ChatApp.Telemetry/ChatApp.Server/ChatApp.Server.csproj" +RUN dotnet restore "samples/ChatApp.Telemetry/MicroServer/MicroServer.csproj" COPY . . -WORKDIR "/src/samples/ChatApp.Telemetry/ChatApp.Server" -RUN dotnet build "ChatApp.Server.csproj" -c Debug -o /app +WORKDIR "/src/samples/ChatApp.Telemetry/MicroServer" +RUN dotnet build "MicroServer.csproj" -c Debug -o /app FROM build AS publish -RUN dotnet publish "ChatApp.Server.csproj" -c Debug -o /app +RUN dotnet publish "MicroServer.csproj" -c Debug -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . -ENTRYPOINT ["dotnet", "ChatApp.Server.dll"] \ No newline at end of file +ENTRYPOINT ["dotnet", "MicroServer.dll"] \ No newline at end of file diff --git a/samples/ChatApp.Telemetry/MicroServer/MessageService.cs b/samples/ChatApp.Telemetry/MicroServer/MessageService.cs index 484367df1..4a1a12c93 100644 --- a/samples/ChatApp.Telemetry/MicroServer/MessageService.cs +++ b/samples/ChatApp.Telemetry/MicroServer/MessageService.cs @@ -1,6 +1,5 @@ using MagicOnion; using MagicOnion.Server; -using MessagePack; using MicroServer.Shared; using System; using System.Threading.Tasks; diff --git a/samples/ChatApp.Telemetry/MicroServer/appsettings.json b/samples/ChatApp.Telemetry/MicroServer/appsettings.json index 0d5b82025..cb6023ee6 100644 --- a/samples/ChatApp.Telemetry/MicroServer/appsettings.json +++ b/samples/ChatApp.Telemetry/MicroServer/appsettings.json @@ -13,6 +13,8 @@ }, "MagicOnion": { "OpenTelemetry": { + "ServiceName": "MicroServer", + // "ExposeRpcScope": false, "TracingTags": { "foo": "bar" } diff --git a/samples/ChatApp.Telemetry/README.md b/samples/ChatApp.Telemetry/README.md index 76fc07b39..ded15a662 100644 --- a/samples/ChatApp.Telemetry/README.md +++ b/samples/ChatApp.Telemetry/README.md @@ -4,27 +4,24 @@ This is Sample to run MagicOnion with OpenTelemetry implementation. ## Getting started -To run simple ChatApp.Server, +Option1. Run ChatApp.Server on VisualStudio, and run zipkin, jeager in docker. 1. Run `docker-compose -f docker-compose.telemetry.yaml up`. 1. Launch `ChatApp.Server.Telemetry` from VisualStudio. -1. Run `ChatScene` from UnityEditor. +1. Launch UnityEditor for `sample/ChatApp/ChatApp.Unity`, open `ChatScene` then do any operations. 1. Access Telemery's Web UI. -Server and Telemetries are fully containernized. +Option2. Run all ChatApp.Server, zipkin and jeager in container 1. Run `docker-compose -f docker-compose.yaml -f docker-compose.telemetry.yaml up`. -1. Run `ChatScene` from UnityEditor. +1. Launch UnityEditor for `sample/ChatApp/ChatApp.Unity`, open `ChatScene` then do any operations. 1. Access Telemery's Web UI. -Telemetry's Web UI address. +Telemetry's Web UI address. (default send to jeager) * [jaeger](http://localhost:16686/) * [zipkin](http://localhost:9411/) - * no data on default. you can switch with jaeger. -* [prometheus](http://localhost:9090/) -* [grafana](http://localhost:3000/) - * user/password is `admin/admin`. + * no data on default. you can switch by appsettings.json ## Projects @@ -34,6 +31,8 @@ There are 3 projects for this sample. 1. ChatApp.Shared (samples/ChatApp.Telemetry/) 1. ChatApp.Unity (samples/ChatApp/) +and optional Server to Server + **ChatApp.Server** is Serverside MagicOnion implementation with OpenTelemetry. **ChatApp.Shared** is class library shared with both ChatApp.Server and ChatApp.Unity. diff --git a/samples/ChatApp.Telemetry/docker-compose.telemetry.yaml b/samples/ChatApp.Telemetry/docker-compose.telemetry.yaml index daaa118b6..b21502795 100644 --- a/samples/ChatApp.Telemetry/docker-compose.telemetry.yaml +++ b/samples/ChatApp.Telemetry/docker-compose.telemetry.yaml @@ -65,3 +65,14 @@ services: ports: - 6831:6831/udp # client post - 16686:16686 # web + + # Server to Server + microserver: + image: cysharp/magiconion_sample_chatapp_microserver:4.3.1-1.0.0.rc4 + environment: + - DOTNET_ENVIRONMENT=Development + - UseExporter=jaeger + - Jaeger__AgentHost=jaeger + - Zipkin__Endpoint=http://zipkin:9411/api/v2/spans + ports: + - 4999:80 diff --git a/samples/ChatApp.Telemetry/docker-compose.yaml b/samples/ChatApp.Telemetry/docker-compose.yaml index 963820271..509ecf6f2 100644 --- a/samples/ChatApp.Telemetry/docker-compose.yaml +++ b/samples/ChatApp.Telemetry/docker-compose.yaml @@ -5,11 +5,9 @@ services: image: cysharp/magiconion_sample_chatapp_telemetry:4.3.1-1.0.0.rc4 ports: - 5000:80 - - 9184:9184 environment: - DOTNET_ENVIRONMENT=Development - - MagicOnion__OpenTelemetry__MetricsExporterEndpoint=http://127.0.0.1:9184/metrics/ - - MagicOnion__OpenTelemetry__MetricsExporterHostingEndpoint=http://+:9184/metrics/ - UseExporter=jaeger - - Jaeger__Host=jaeger + - Jaeger__AgentHost=jaeger - Zipkin__Endpoint=http://zipkin:9411/api/v2/spans + - Server2ServerEndpoint=http://microserver:80 diff --git a/samples/ChatApp.Telemetry/docker_build.bat b/samples/ChatApp.Telemetry/docker_build.bat index 7c5aa69ca..9421d1430 100644 --- a/samples/ChatApp.Telemetry/docker_build.bat +++ b/samples/ChatApp.Telemetry/docker_build.bat @@ -1,3 +1,5 @@ :: run from Repository Root :: cysharp/magiconion_sample_chatapp_telemetry -docker build -t chatapp_magiconion:latest -f samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile.full . +:: cysharp/magiconion_sample_microserver +docker build -t chatapp_magiconion:latest -f samples/ChatApp.Telemetry/ChatApp.Server/Dockerfile . +docker build -t chatapp_microserver:latest -f samples/ChatApp.Telemetry/MicroServer/Dockerfile . diff --git a/samples/ChatApp.Telemetry/docker_push.bat b/samples/ChatApp.Telemetry/docker_push.bat index a8012b1c3..fd7bac9dc 100644 --- a/samples/ChatApp.Telemetry/docker_push.bat +++ b/samples/ChatApp.Telemetry/docker_push.bat @@ -4,3 +4,8 @@ docker tag chatapp_magiconion:latest cysharp/magiconion_sample_chatapp_telemetry docker tag chatapp_magiconion:latest cysharp/magiconion_sample_chatapp_telemetry:4.3.1-1.0.0.rc4 docker push cysharp/magiconion_sample_chatapp_telemetry:latest docker push cysharp/magiconion_sample_chatapp_telemetry:4.3.1-1.0.0.rc4 + +docker tag chatapp_microserver:latest cysharp/magiconion_sample_chatapp_microserver:latest +docker tag chatapp_microserver:latest cysharp/magiconion_sample_chatapp_microserver:4.3.1-1.0.0.rc4 +docker push cysharp/magiconion_sample_chatapp_microserver:latest +docker push cysharp/magiconion_sample_chatapp_microserver:4.3.1-1.0.0.rc4 diff --git a/samples/ChatApp.Telemetry/docker_run.bat b/samples/ChatApp.Telemetry/docker_run.bat index 9a2943f1d..1f003ddfa 100644 --- a/samples/ChatApp.Telemetry/docker_run.bat +++ b/samples/ChatApp.Telemetry/docker_run.bat @@ -1 +1 @@ -docker-compose -f docker-compose.yaml -f docker-compose.telemetry.yaml up \ No newline at end of file +docker-compose -f docker-compose.yaml -f docker-compose.telemetry.yaml up diff --git a/src/MagicOnion.Server.OpenTelemetry/Internal/OpenTelemetryHelper.cs b/src/MagicOnion.Server.OpenTelemetry/Internal/OpenTelemetryHelper.cs index c1e00117f..6f7b69f5e 100644 --- a/src/MagicOnion.Server.OpenTelemetry/Internal/OpenTelemetryHelper.cs +++ b/src/MagicOnion.Server.OpenTelemetry/Internal/OpenTelemetryHelper.cs @@ -2,7 +2,7 @@ namespace MagicOnion.Server.OpenTelemetry.Internal { - public static class OpenTelemetryHelper + internal static class OpenTelemetryHelper { /// /// Convert gRPC StatusCode to OpenTelemetry Status. diff --git a/src/MagicOnion.Server.OpenTelemetry/Internal/SemanticConventions.cs b/src/MagicOnion.Server.OpenTelemetry/Internal/SemanticConventions.cs index d84eaf494..0b1eaf195 100644 --- a/src/MagicOnion.Server.OpenTelemetry/Internal/SemanticConventions.cs +++ b/src/MagicOnion.Server.OpenTelemetry/Internal/SemanticConventions.cs @@ -6,6 +6,7 @@ namespace MagicOnion.Server.OpenTelemetry.Internal internal static class SemanticConventions { // tag spec: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/rpc.md#grpc + public const string AttributeServiceName = "service.name"; public const string AttributeException = "exception"; public const string AttributeHttpHost = "http.host"; diff --git a/src/MagicOnion.Server.OpenTelemetry/MagicOnionOpenTelemetryClientFilter.cs b/src/MagicOnion.Server.OpenTelemetry/MagicOnionOpenTelemetryClientFilter.cs index b9b3e3502..8b72dbe1d 100644 --- a/src/MagicOnion.Server.OpenTelemetry/MagicOnionOpenTelemetryClientFilter.cs +++ b/src/MagicOnion.Server.OpenTelemetry/MagicOnionOpenTelemetryClientFilter.cs @@ -27,7 +27,7 @@ public MagicOnionOpenTelemetryClientFilter(ActivitySource activitySource, MagicO public async ValueTask SendAsync(RequestContext context, Func> next) { var rpcService = context.MethodPath.Split('/')[0]; - using var rpcScope = new ClientRpcScope(rpcService, context.MethodPath, context, source); + using var rpcScope = new ClientRpcScope(rpcService, context.MethodPath, context, source, options); rpcScope.SetTags(options.TracingTags); try @@ -51,7 +51,8 @@ public async ValueTask SendAsync(RequestContext context, Func - /// Application specific OpenTelemetry Tracing tags + /// ServiceName for Tracer. Especially Zipkin use service.name tag to identify service name. /// - public Dictionary TracingTags { get; set; } = new Dictionary(); + /// input to tag `service.name` + public string ServiceName { get; set; } /// /// Expose RpsScope to the ServiceContext.Items. RpsScope key begin with .TraceContext /// public bool ExposeRpcScope { get; set; } = true; + + /// + /// Application specific OpenTelemetry Tracing tags + /// + public Dictionary TracingTags { get; set; } = new Dictionary(); } } \ No newline at end of file diff --git a/src/MagicOnion.Server.OpenTelemetry/MagicOnionOpenTelemetryTracerFilterAttributes.cs b/src/MagicOnion.Server.OpenTelemetry/MagicOnionOpenTelemetryTracerFilterAttributes.cs index 9cfd1dd65..1ef65c798 100644 --- a/src/MagicOnion.Server.OpenTelemetry/MagicOnionOpenTelemetryTracerFilterAttributes.cs +++ b/src/MagicOnion.Server.OpenTelemetry/MagicOnionOpenTelemetryTracerFilterAttributes.cs @@ -40,7 +40,7 @@ public MagicOnionOpenTelemetryTracerFilterAttribute(ActivitySource activitySourc public override async ValueTask Invoke(ServiceContext context, Func next) { - using var rpcScope = new ServerRpcScope(context.ServiceType.Name, context.CallContext.Method.TrimStart('/'), context.CallContext, source); + using var rpcScope = new ServerRpcScope(context.ServiceType.Name, context.CallContext.Method.TrimStart('/'), context.CallContext, source, options); if (options.ExposeRpcScope) { @@ -114,7 +114,7 @@ public MagicOnionOpenTelemetryStreamingTracerFilterAttribute(ActivitySource acti public override async ValueTask Invoke(StreamingHubContext context, Func next) { - using var rpcScope = new ServerRpcScope(context.ServiceContext.ServiceType.Name, context.Path, context.ServiceContext.CallContext, source); + using var rpcScope = new ServerRpcScope(context.ServiceContext.ServiceType.Name, context.Path, context.ServiceContext.CallContext, source, options); if (options.ExposeRpcScope) { @@ -161,8 +161,8 @@ public override async ValueTask Invoke(StreamingHubContext context, Func @@ -96,6 +98,7 @@ protected void SetActivity(Activity activity) return; } + this.activity.SetTag(SemanticConventions.AttributeServiceName, ServiceName); this.activity.SetTag(SemanticConventions.AttributeRpcSystem, "grpc"); this.activity.SetTag(SemanticConventions.AttributeRpcService, RpcService); this.activity.SetTag(SemanticConventions.AttributeRpcMethod, RpcMethod);