Search code examples
c#.net-corejaegeropentracing

Connecting to remote Jaegertracing with C# .Net Core


Im having some issues here with Opentracing and Jaegertracing when it comes to C#. I have had this working before, but with Java projects. So I start to wonder what Im missing when it comes to C# .NET Core web service.

This is my class to start my tracer to be used

    public static class MyTracer
    {
        public static ITracer tracer = null;

        public static ITracer InitTracer()
        {
            Environment.SetEnvironmentVariable("JAEGER_SERVICE_NAME", "my-store");
            Environment.SetEnvironmentVariable("JAEGER_AGENT_HOST", "192.168.2.27");
            Environment.SetEnvironmentVariable("JAEGER_AGENT_PORT", "6831");
            Environment.SetEnvironmentVariable("JAEGER_SAMPLER_TYPE", "const");                     
            Environment.SetEnvironmentVariable("JAEGER_REPORTER_LOG_SPANS", "false");
            Environment.SetEnvironmentVariable("JAEGER_SAMPLER_PARAM","1");
            Environment.SetEnvironmentVariable("JAEGER_SAMPLER_MANAGER_HOST_PORT", "5778");
            Environment.SetEnvironmentVariable("JAEGER_REPORTER_FLUSH_INTERVAL" , "1000");
            Environment.SetEnvironmentVariable("JAEGER_REPORTER_MAX_QUEUE_SIZE" , "100");


            var loggerFactory = new LoggerFactory();

            var config = Configuration.FromEnv(loggerFactory);

            tracer = config.GetTracer();

            if (!GlobalTracer.IsRegistered())
            {
                GlobalTracer.Register(tracer);
            }
            return tracer;
        }
    }

Controller code that should report to the Jaeger agent and collector for show in the UI.

[Route("api/[controller]")]
[ApiController]
public class ComponentController : ControllerBase
{
    private readonly ITracer tracer;

    public ComponentController(ITracer tracer)
    {
        this.tracer = tracer;
    }

    /// <summary>
    /// Get component by ID
    /// </summary>
    /// <returns></returns>
    [HttpGet("GetComponent")]
    public ActionResult<ComponentModel> GetComponent(string id)
    {   
        var builder = tracer.BuildSpan("operationName");            
        var span = builder.Start();
        // Set some context data
        span.Log("Getting data");
        span.SetTag(Tags.SpanKind, "Getting data request");
        span.Finish();                     

        ComponentModel component = ComponentManager.GetComponent(id);    

        return component;
    }


}

Startup.cs

    public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        // Use "OpenTracing.Contrib.NetCore" to automatically generate spans for ASP.NET Core, Entity Framework Core, ...
        // See https://github.com/opentracing-contrib/csharp-netcore for details.
        services.AddOpenTracing();

        //Init tracer
        services.AddSingleton<ITracer>(t => MyTracer.InitTracer());

        services.AddHealthChecks();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

But this is not working at all. What am I missing here to get it work with a remote server?


Solution

  • Iv finally found the solution. It seemed to have to do with how the reporter is started up. Anyhow, I changed my tracer class to this.

        public static class MyTracer
    {
        public static ITracer tracer = null;
        public static ITracer InitTracer(IServiceProvider serviceProvider)
        {
            string serviceName = serviceProvider.GetRequiredService<IHostingEnvironment>().ApplicationName;
    
            Environment.SetEnvironmentVariable("JAEGER_SERVICE_NAME", "my-store");
            //Environment.SetEnvironmentVariable("JAEGER_AGENT_HOST", "192.168.2.27");
            //Environment.SetEnvironmentVariable("JAEGER_AGENT_PORT", "6831");
            //Environment.SetEnvironmentVariable("JAEGER_SAMPLER_TYPE", "const");                     
            //Environment.SetEnvironmentVariable("JAEGER_REPORTER_LOG_SPANS", "false");
            //Environment.SetEnvironmentVariable("JAEGER_SAMPLER_PARAM","1");
            //Environment.SetEnvironmentVariable("JAEGER_SAMPLER_MANAGER_HOST_PORT", "5778");
            //Environment.SetEnvironmentVariable("JAEGER_REPORTER_FLUSH_INTERVAL" , "1000");
            //Environment.SetEnvironmentVariable("JAEGER_REPORTER_MAX_QUEUE_SIZE" , "100");
            //application - server - id = server - x
    
            var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
    
            var sampler = new ConstSampler(sample: true);
            var reporter = new RemoteReporter.Builder()
             .WithLoggerFactory(loggerFactory)
             .WithSender(new UdpSender("192.168.2.27", 6831, 0))
             .Build();
    
            tracer = new Tracer.Builder(serviceName)
             .WithLoggerFactory(loggerFactory)
             .WithSampler(sampler)
             .WithReporter(reporter)
             .Build();
    
            if (!GlobalTracer.IsRegistered())
            {
                GlobalTracer.Register(tracer);
            }
            return tracer;
        }
    }
    

    I know there are several inactive variables here right now. Will see if they still can be of use some how. But none is needed right now to get it rolling. Hope this might help someone else trying to get the .NET Core working properly together with a remote Jeagertracing server.