Skip to content

Commit 56fe7b5

Browse files
committed
wip
1 parent 3439be8 commit 56fe7b5

File tree

9 files changed

+760
-0
lines changed

9 files changed

+760
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Worker">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Jaeger" Version="0.3.7" />
10+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.3" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\..\src\Ocelot.Tracing.OpenTracing\Ocelot.Tracing.OpenTracing.csproj" />
15+
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<Content Update="appsettings.Development.json">
20+
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
21+
</Content>
22+
<Content Update="appsettings.json">
23+
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
24+
</Content>
25+
<Content Update="ocelot.json">
26+
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
27+
</Content>
28+
</ItemGroup>
29+
30+
</Project>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.Extensions.Configuration;
3+
using Microsoft.Extensions.Hosting;
4+
using System.IO;
5+
using Ocelot.DependencyInjection;
6+
using Ocelot.Middleware;
7+
using Microsoft.Extensions.Logging;
8+
using Ocelot.Tracing.OpenTracing;
9+
using Jaeger;
10+
using Microsoft.Extensions.DependencyInjection;
11+
using OpenTracing;
12+
using OpenTracing.Util;
13+
14+
namespace OcelotOpenTracing
15+
{
16+
internal static class Program
17+
{
18+
private static void Main(string[] args)
19+
{
20+
21+
Host.CreateDefaultBuilder()
22+
.ConfigureWebHostDefaults(webBuilder =>
23+
{
24+
webBuilder
25+
.UseContentRoot(Directory.GetCurrentDirectory())
26+
.UseKestrel()
27+
.ConfigureAppConfiguration((hostingContext, config) =>
28+
{
29+
config
30+
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
31+
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
32+
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json",
33+
optional: true, reloadOnChange: false)
34+
.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true)
35+
.AddEnvironmentVariables();
36+
})
37+
.ConfigureServices((context, services) =>
38+
{
39+
services
40+
.AddOcelot()
41+
.AddOpenTracing();
42+
43+
services.AddSingleton<ITracer>(sp =>
44+
{
45+
var loggerFactory = sp.GetService<ILoggerFactory>();
46+
Configuration config = new Configuration(context.HostingEnvironment.ApplicationName, loggerFactory);
47+
48+
var tracer = config.GetTracer();
49+
GlobalTracer.Register(tracer);
50+
return tracer;
51+
});
52+
53+
})
54+
.ConfigureLogging(logging =>
55+
{
56+
logging.AddConsole();
57+
})
58+
.Configure(app =>
59+
{
60+
app.UseOcelot().Wait();
61+
});
62+
})
63+
.Build()
64+
.Run();
65+
}
66+
}
67+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft": "Warning",
6+
"Microsoft.Hosting.Lifetime": "Information"
7+
}
8+
}
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft": "Warning",
6+
"Microsoft.Hosting.Lifetime": "Information"
7+
}
8+
},
9+
"AllowedHosts": "*"
10+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"ReRoutes": [
3+
{
4+
"HttpHandlerOptions": {
5+
"UseTracing": true
6+
},
7+
"DownstreamPathTemplate": "/todos/{id}",
8+
"DownstreamScheme": "https",
9+
"DownstreamHostAndPorts": [
10+
{
11+
"Host": "jsonplaceholder.typicode.com",
12+
"Port": 443
13+
}
14+
],
15+
"UpstreamPathTemplate": "/posts/{id}",
16+
"UpstreamHttpMethod": [
17+
"Get"
18+
]
19+
}
20+
],
21+
"GlobalConfiguration": {
22+
"BaseUrl": "https://localhost:5000"
23+
}
24+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<Version>0.0.0-dev</Version>
6+
<Authors>Kjell-Åke Gafvelin</Authors>
7+
<Description>This package provides OpenTracing support to Ocelot.</Description>
8+
<PackageProjectUrl>https://github.com/ThreeMammals/Ocelot</PackageProjectUrl>
9+
<PackageTags>API Gateway;.NET core; OpenTracing</PackageTags>
10+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="OpenTracing" Version="0.12.1" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
19+
</ItemGroup>
20+
21+
</Project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Ocelot.DependencyInjection;
3+
using Ocelot.Logging;
4+
using System;
5+
6+
namespace Ocelot.Tracing.OpenTracing
7+
{
8+
public static class OcelotBuilderExtensions
9+
{
10+
public static IOcelotBuilder AddOpenTracing(this IOcelotBuilder builder)
11+
{
12+
builder.Services.AddSingleton<ITracer, OpenTracingTracer>();
13+
14+
return builder;
15+
}
16+
}
17+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using Microsoft.AspNetCore.Http;
2+
using OpenTracing;
3+
using OpenTracing.Propagation;
4+
using OpenTracing.Tag;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Net.Http;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
11+
namespace Ocelot.Tracing.OpenTracing
12+
{
13+
class OpenTracingTracer : Logging.ITracer
14+
{
15+
private readonly ITracer tracer;
16+
17+
public OpenTracingTracer(ITracer tracer)
18+
{
19+
this.tracer = tracer ?? throw new ArgumentNullException(nameof(tracer));
20+
}
21+
22+
public void Event(HttpContext httpContext, string @event)
23+
{
24+
}
25+
26+
public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken,
27+
Action<string> addTraceIdToRepo, Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> baseSendAsync)
28+
{
29+
using (IScope scope = this.tracer.BuildSpan(request.RequestUri.AbsoluteUri).StartActive(finishSpanOnDispose: true))
30+
{
31+
var span = scope.Span;
32+
33+
span.SetTag(Tags.SpanKind, Tags.SpanKindClient)
34+
.SetTag(Tags.HttpMethod, request.Method.Method)
35+
.SetTag(Tags.HttpUrl, request.RequestUri.OriginalString);
36+
37+
addTraceIdToRepo(span.Context.SpanId);
38+
39+
var headers = new Dictionary<string, string>();
40+
41+
this.tracer.Inject(span.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(headers));
42+
43+
foreach (var item in headers)
44+
{
45+
request.Headers.Add(item.Key, item.Value);
46+
}
47+
48+
try
49+
{
50+
var response = await baseSendAsync(request, cancellationToken);
51+
52+
span.SetTag(Tags.HttpStatus, (int)response.StatusCode);
53+
54+
return response;
55+
}
56+
catch (HttpRequestException ex)
57+
{
58+
Tags.Error.Set(scope.Span, true);
59+
60+
span.Log(new Dictionary<string, object>(3)
61+
{
62+
{ LogFields.Event, Tags.Error.Key },
63+
{ LogFields.ErrorKind, ex.GetType().Name },
64+
{ LogFields.ErrorObject, ex }
65+
});
66+
throw;
67+
}
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)