0

I have been experimenting with using opentelemetry this week and I would appreciate some advice.

I have instrumented an .net Core API application written in C# with the following opentelemetry libraries and initially installed Jaeger to collect and display the results. I have jaeger running in a docker container on my local machine.

The code I added to ConfigureServices in the StartUp.cs file is as follows:

            services.AddOpenTelemetryTracing(builder =>
            {
                builder.AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation()
                    .AddSqlClientInstrumentation()
                    .AddSource(nameof(CORSBaseController))
                    .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyAppAPI"))
                    .AddJaegerExporter(opts =>
                    {
                        opts.AgentHost = Configuration["Jaeger:AgentHost"];
                        opts.AgentPort = Convert.ToInt32(Configuration["Jaeger:AgentPort"]);
                    });
            });

In the Jaeger front end when I search for traces received in the past hour I get two listed services after using the front end that connects to the API 'jaeger-query' and 'MyAppAPI'. I can drill into the 'MyAppAPI' and see the spans showing the telemetry data that has been collected. So far so good.

Jeager UI showing both services

I installed the opentelemetry-collector-contrib on my machine. I used the contrib as I eventually want to export the results into newrelic and need their library. I started the controller using docker using the example docker-compose yaml file:

version: "3"
services:
  # Jaeger
  jaeger:
    image: jaegertracing/all-in-one:latest
    ports:
      - "16686:16686"
      - "14268"
      - "14250"

  #Zipkin
  zipkin:
    image: openzipkin/zipkin
    container_name: zipkin
    ports:
      - 9411:9411

  otel-collector:
    build:
      context: ../..
      dockerfile: examples/tracing/Dockerfile
    command: ["--config=/etc/otel-collector-config.yml"]
    volumes:
      - ./otel-collector-config.yml:/etc/otel-collector-config.yml
    ports:
      - "1888:1888"   # pprof extension
      - "8888:8888"   # Prometheus metrics exposed by the collector
      - "8889:8889"   # Prometheus exporter metrics
      - "13133:13133" # health_check extension
      - "9411"   # Zipkin receiver
      - "55679:55679" # zpages extension
    depends_on:
      - jaeger
      - zipkin

  # Expose the frontend on http://localhost:8081
  frontend:
    image: openzipkin/example-sleuth-webmvc
    command: Frontend
    environment:
      JAVA_OPTS: -Dspring.zipkin.baseUrl=http://otel-collector:9511
    ports:
      - 8081:8081
    depends_on:
      - otel-collector

  # Expose the backend on http://localhost:9000
  backend:
    image: openzipkin/example-sleuth-webmvc
    command: Backend
    environment:
      JAVA_OPTS: -Dspring.zipkin.baseUrl=http://otel-collector:9511
    ports:
      - 9000:9000
    depends_on:
      - otel-collector

The otel-collector-config.yml file referenced in the docker compose file looks like the following exposing both 'otlp' and 'zipkin' as receivers.

receivers:
  otlp:
    protocols:
      grpc:
  zipkin:

exporters:
  logging:
  zipkin:
    endpoint: "http://zipkin:9411/api/v2/spans"

processors:
  batch:

extensions:
  health_check:
  pprof:
  zpages:

service:
  extensions: [pprof, zpages, health_check]
  pipelines:
    traces:
      receivers: [otlp, zipkin]
      exporters: [zipkin, logging]
      processors: [batch]

I altered my code in my .Net project to the following to use the otlp exporter sending data to the collector as follows:

            services.AddOpenTelemetryTracing(builder =>
            {
                builder.AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation()
                    .AddSqlClientInstrumentation()
                    .AddAspNetCoreInstrumentation()
                    .AddSource(nameof(CORSBaseController))
                    .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyAppAPI"))
                    .AddZipkinExporter(opts => 
                    {
                        opts.Endpoint = new Uri("http://localhost:9411/api/v2/spans");
                    });
            });

Now when I use my front end to send requests to the API and can no longer see the MyAppAPI as one of the services in jaeger (should have been using zipkin). All I can see is the jaeger-query spans that correspond with the time I am using the front end.

Jaeger frontend using collector

Edit: I have got this working. It was due to an incorrect call in the startup.cs file to the zipkin collector. Plus when I wrote out the question I realised I was exporting to zipkin not jaeger, so I can now see my traces in the zipkin front end on http://localhost:9411.

The code above has been corrected so it works.

dickiebow
  • 92
  • 1
  • 1
  • 12

0 Answers0