ClientJaegerTracingInterceptor.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using Grpc.Core;
  2. using Grpc.Core.Interceptors;
  3. using OpenTracing.Util;
  4. using System;
  5. using Grpc.Extension.Common;
  6. using System.Linq;
  7. using OpenTracing;
  8. using Grpc.Extension.Abstract;
  9. namespace Grpc.Extension.Client.Interceptors
  10. {
  11. internal class ClientJaegerTracingInterceptor : ClientInterceptor
  12. {
  13. public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
  14. {
  15. var tracer = GlobalTracer.Instance;
  16. var method = $"{context.Method.ServiceName}/{context.Method.Name}";
  17. var span = tracer.BuildSpan(method).AsChildOf(tracer.ActiveSpan).WithTag("Request", request?.ToJson() ?? "").Start();
  18. context = SetJaegerHeader(context, span);
  19. try
  20. {
  21. return continuation(request, context);
  22. }
  23. catch (Exception ex)
  24. {
  25. span.SetTag("Error", ex.ToString());
  26. throw;
  27. }
  28. finally
  29. {
  30. span.Finish();
  31. }
  32. }
  33. public override TResponse BlockingUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, BlockingUnaryCallContinuation<TRequest, TResponse> continuation)
  34. {
  35. var tracer = GlobalTracer.Instance;
  36. var method = $"{context.Method.ServiceName}/{context.Method.Name}";
  37. var span = tracer.BuildSpan(method).AsChildOf(tracer.ActiveSpan).WithTag("Request", request?.ToJson() ?? "").Start();
  38. context = SetJaegerHeader(context, span);
  39. try
  40. {
  41. return continuation(request, context);
  42. }
  43. catch (Exception ex)
  44. {
  45. span.SetTag("Error", ex.ToString());
  46. throw;
  47. }
  48. finally
  49. {
  50. span.Finish();
  51. }
  52. }
  53. private ClientInterceptorContext<TRequest, TResponse> SetJaegerHeader<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, ISpan span)
  54. where TRequest : class
  55. where TResponse : class
  56. {
  57. var header = context.Options.Headers?.Where(p => p.Key == Consts.OpenTraceId).FirstOrDefault();
  58. if (header == null)
  59. {
  60. var metaEntry = new Metadata.Entry(Consts.OpenTraceId, span.Context.ToString());
  61. if (context.Options.Headers == null)
  62. {
  63. var meta = new Metadata();
  64. meta.Add(metaEntry);
  65. var callOptions = context.Options.WithHeaders(meta);
  66. context = new ClientInterceptorContext<TRequest, TResponse>(context.Method, context.Host, callOptions);
  67. }
  68. else
  69. {
  70. context.Options.Headers.Add(metaEntry);
  71. }
  72. }
  73. return context;
  74. }
  75. }
  76. }