Skip to content

Commit

Permalink
Merge pull request #17 from itsharppro/dev
Browse files Browse the repository at this point in the history
(#16) udpate tracing library
  • Loading branch information
SaintAngeLs authored Sep 29, 2024
2 parents 21eb9a2 + 837a033 commit 76499ce
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 41 deletions.
17 changes: 17 additions & 0 deletions src/Nuar.Tracing/src/Nuar.Tracing/DefaultTracer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Reflection;
using Jaeger;
using Jaeger.Reporters;
using Jaeger.Samplers;
using OpenTracing;

namespace Nuar.Tracing
{
public class DefaultTracer
{
public static ITracer Create()
=> new Tracer.Builder(Assembly.GetEntryAssembly().FullName)
.WithReporter(new NoopReporter())
.WithSampler(new ConstSampler(false))
.Build();
}
}
59 changes: 59 additions & 0 deletions src/Nuar.Tracing/src/Nuar.Tracing/JaegerHTTPMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using OpenTracing;
using OpenTracing.Tag;
using System.Collections.Generic;

namespace Nuar.Extensions.Tracing
{
internal sealed class JaegerHttpMiddleware
{
private readonly RequestDelegate _next;

public JaegerHttpMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task Invoke(HttpContext context, ITracer tracer)
{
IScope scope = null;
var span = tracer.ActiveSpan;
var method = context.Request.Method;

if (span == null)
{
var spanBuilder = tracer.BuildSpan($"HTTP {method}");
scope = spanBuilder.StartActive(true);
span = scope.Span;
}

span.Log(new Dictionary<string, object>
{
{ "event", "request_processing" },
{ "method", method },
{ "path", context.Request.Path.ToString() }
});

try
{
await _next(context);
}
catch (Exception ex)
{
span.SetTag(Tags.Error, true);
span.Log(new Dictionary<string, object>
{
{ "event", "error" },
{ "message", ex.Message }
});
throw;
}
finally
{
scope?.Dispose();
}
}
}
}
14 changes: 7 additions & 7 deletions src/Nuar.Tracing/src/Nuar.Tracing/Nuar.Tracing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<!-- <PackageReference Include="Jaeger" Version="1.0.3" /> -->

<PackageReference Include="Jaeger" Version="1.0.3" />
<PackageReference Include="Nuar" Version="*" />
<PackageReference Include="OpenTelemetry" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.5.1" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageReference Include="OpenTracing.Contrib.NetCore" Version="0.9.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging " Version="8.0.0" />

</ItemGroup>

</Project>
92 changes: 58 additions & 34 deletions src/Nuar.Tracing/src/Nuar.Tracing/TracingExtension.cs
Original file line number Diff line number Diff line change
@@ -1,63 +1,87 @@
using System;
using System.Linq;
using Jaeger;
using Jaeger.Reporters;
using Jaeger.Samplers;
using Jaeger.Senders;
using Jaeger.Senders.Thrift;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using OpenTelemetry.Exporter;

using Nuar.Tracing;
using OpenTracing;
using OpenTracing.Contrib.NetCore.Configuration;
using OpenTracing.Util;

namespace Nuar.Extensions.Tracing
{
public class TracingExtension : IExtension
{
public string Name => "tracing";
public string Description => "Distributed tracing using OpenTelemetry and Jaeger";
public string Description => "Open Tracing using Jaeger";
public string Version => "1.0.0";

public void Add(IServiceCollection services, IOptionsProvider optionsProvider)
{
var options = optionsProvider.GetForExtension<TracingOptions>(Name);

var options = optionsProvider.GetForExtension<TracingOptions>("tracing");
services.AddOpenTracing();
services.AddSingleton(options);

// Use empty tracer if specified in options
if (options.UseEmptyTracer)
{
services.AddOpenTelemetry();
var defaultTracer = DefaultTracer.Create();
services.AddSingleton(defaultTracer);
return;
}


// Handle path exclusions if specified
if (options.ExcludePaths is not null)
{
services.Configure<AspNetCoreDiagnosticOptions>(o =>
{
foreach (var path in options.ExcludePaths)
{
o.Hosting.IgnorePatterns.Add(x => x.Request.Path == path);
}
});
}

services.AddSingleton<ITracer>(sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();

var reporter = new RemoteReporter.Builder()
.WithSender(new UdpSender(options.UdpHost, options.UdpPort, options.MaxPacketSize))
.WithLoggerFactory(loggerFactory)
.Build();

var sampler = GetSampler(options);

var tracer = new Tracer.Builder(options.ServiceName)
.WithLoggerFactory(loggerFactory)
.WithReporter(reporter)
.WithSampler(sampler)
.Build();

GlobalTracer.Register(tracer);

return tracer;
});
}

public void Use(IApplicationBuilder app, IOptionsProvider optionsProvider)
{
// Middleware to ensure tracing is active
var logger = app.ApplicationServices.GetRequiredService<ILogger<TracingExtension>>();
logger.LogInformation("Tracing with OpenTelemetry and Jaeger has been configured.");
app.UseMiddleware<JaegerHttpMiddleware>();
}

private void ConfigureSampler(TracerProviderBuilder builder, TracingOptions options)
private static ISampler GetSampler(TracingOptions options)
{
// Use OpenTelemetry samplers instead of Jaeger's samplers
switch (options.Sampler?.ToLower())
return options.Sampler switch
{
case "const":
// Always sample
builder.SetSampler(new AlwaysOnSampler());
break;
case "probabilistic":
// Use the provided sampling rate
builder.SetSampler(new TraceIdRatioBasedSampler(options.SamplingRate));
break;

default:
// Default sampler: sample based on configuration
builder.SetSampler(new ParentBasedSampler(new TraceIdRatioBasedSampler(options.SamplingRate)));
break;
}
"const" => new ConstSampler(true),
"rate" => new RateLimitingSampler(options.MaxTracesPerSecond),
"probabilistic" => new ProbabilisticSampler(options.SamplingRate),
_ => new ConstSampler(true),
};
}
}
}

0 comments on commit 76499ce

Please sign in to comment.