Feat/opentracing (#1243)

This commit is contained in:
Tom Pallister
2020-05-25 18:42:48 +01:00
committed by GitHub
parent 3439be8927
commit 865520f2d7
13 changed files with 929 additions and 76 deletions

View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Version>0.0.0-dev</Version>
<Authors>Kjell-Åke Gafvelin</Authors>
<Description>This package provides OpenTracing support to Ocelot.</Description>
<PackageProjectUrl>https://github.com/ThreeMammals/Ocelot</PackageProjectUrl>
<PackageTags>API Gateway;.NET core; OpenTracing</PackageTags>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenTracing" Version="0.12.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@
namespace Ocelot.Tracing.OpenTracing
{
using Microsoft.Extensions.DependencyInjection.Extensions;
using Ocelot.DependencyInjection;
using Ocelot.Logging;
public static class OcelotBuilderExtensions
{
public static IOcelotBuilder AddOpenTracing(this IOcelotBuilder builder)
{
builder.Services.TryAddSingleton<ITracer, OpenTracingTracer>();
return builder;
}
}
}

View File

@ -0,0 +1,75 @@
namespace Ocelot.Tracing.OpenTracing
{
using global::OpenTracing;
using global::OpenTracing.Propagation;
using global::OpenTracing.Tag;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
class OpenTracingTracer : Logging.ITracer
{
private readonly ITracer _tracer;
public OpenTracingTracer(ITracer tracer)
{
_tracer = tracer ?? throw new ArgumentNullException(nameof(tracer));
}
public void Event(HttpContext httpContext, string @event)
{
}
public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken,
Action<string> addTraceIdToRepo,
Func<HttpRequestMessage,
CancellationToken,
Task<HttpResponseMessage>> baseSendAsync)
{
using (IScope scope = _tracer.BuildSpan(request.RequestUri.AbsoluteUri).StartActive(finishSpanOnDispose: true))
{
var span = scope.Span;
span.SetTag(Tags.SpanKind, Tags.SpanKindClient)
.SetTag(Tags.HttpMethod, request.Method.Method)
.SetTag(Tags.HttpUrl, request.RequestUri.OriginalString);
addTraceIdToRepo(span.Context.SpanId);
var headers = new Dictionary<string, string>();
_tracer.Inject(span.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(headers));
foreach (var item in headers)
{
request.Headers.Add(item.Key, item.Value);
}
try
{
var response = await baseSendAsync(request, cancellationToken);
span.SetTag(Tags.HttpStatus, (int)response.StatusCode);
return response;
}
catch (HttpRequestException ex)
{
Tags.Error.Set(scope.Span, true);
span.Log(new Dictionary<string, object>(3)
{
{ LogFields.Event, Tags.Error.Key },
{ LogFields.ErrorKind, ex.GetType().Name },
{ LogFields.ErrorObject, ex }
});
throw;
}
}
}
}
}