serilog / serilog-sinks-opentelemetry

A Serilog OpenTelemetry Protocol (OTLP) sink
Apache License 2.0
119 stars 18 forks source link

Unable to get this working #32

Closed rcdailey closed 1 year ago

rcdailey commented 1 year ago

This is mostly a help request; I am not sure I'm dealing with bugs here.

First of all I find it very confusing how this library works. Despite the examples I see in the test directory, it's unclear to me what I'm doing wrong. I do not think I'm seeing logs sent to my collector.

I'll explain the issue/situation and then provide a dump of config/code/etc below.

What I'm doing is hitting a particular endpoint in my app service using Postman, which in its controller does a _log.Information("blah blah"). I expect to see that log in the console output from the ADOT collector. However, I don't think I'm seeing it (I don't see the "blah blah" message anywhere in the output).

I'm not sure why. Is it the hostname? I'm not sure where the /v1/logs endpoint comes from; is that officially documented somewhere? And why is the hostname specified separately from the same one I specify in the official OTel library configuration (I assume because the two are completely separate and this logging sink does not tie into it)?

Lastly, I know that logs can be attached to spans as events, or sent as actual logs (and that use the logs exporter type in the collector pipeline config). I'm still figuring out the difference between the two in terms of what to use and when, but I assume that the Serilogs should be attached to spans as events, since the one log in particular I'm testing with is done in the middle of the Get() method in the controller.

Please let me know what I'm doing wrong and where my misunderstandings lie. Thank you. Detailed information follows.

I'm using these packages:

    <PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.4.0-rc.3" />
    <PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.4.0-rc.3" />
    <PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.0.0-rc9.12" />
    <PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.0.0-rc9.12" />
    <PackageVersion Include="Serilog.AspNetCore" Version="6.1.0" />
    <PackageVersion Include="Serilog.Sinks.OpenTelemetry" Version="0.5.0-dev-00078" />

Here is how I'm setting up OpenTelemetry in my ASP.NET WebApi project (using dotnet 7):

    private static void SetupOpenTelemetry(IServiceCollection services)
    {
        const string serviceName = "Monitor.Deployment";
        var resourceBuilder = ResourceBuilder.CreateDefault()
            .AddService(serviceName, GitVersionInformation.SemVer);

        var meter = new Meter(serviceName);
        var counter = meter.CreateCounter<long>("app.request-counter");

        services.AddOpenTelemetry()
            .WithTracing(builder => builder
                .AddSource(serviceName)
                .SetResourceBuilder(resourceBuilder)
                .AddHttpClientInstrumentation()
                .AddAspNetCoreInstrumentation()
                .AddOtlpExporter(options =>
                {
                    options.Endpoint = new Uri("http://otel:4317");
                }))
            .WithMetrics(builder => builder
                .AddMeter(meter.Name)
                .SetResourceBuilder(resourceBuilder)
                .AddHttpClientInstrumentation()
                .AddAspNetCoreInstrumentation()
                .AddOtlpExporter(options =>
                {
                    options.Endpoint = new Uri("http://otel:4317");
                }))
            .StartWithHost();

        services.AddTransient<IRequestCounter>(_ => new RequestCounter(counter));
    }

And here is the logger set up in C# code (I won't share appsettings.json since it's simple and just sets up the console sink):

builder.Host.UseSerilog((_, c, logConfig) => logConfig
    .ReadFrom.Configuration(c.GetRequiredService<IConfiguration>())
    .Enrich.FromLogContext()
    .Enrich.WithTraceIdAndSpanId()
    .WriteTo.OpenTelemetry("http://otel:4317/v1/logs"));

The hostname for the collector endpoint, otel, is the docker DNS name. I am using my app and the collector together in a docker compose stack, as shown below (docker-compose.yml):

networks:
  app_network:

services:
  app:
    image: snip
    build: context
    networks: [app_network]
    ports:
      - 5054:80
    volumes:
      - ${HOME}/.aws:/root/.aws:ro
    environment:
      - AWS_REGION=us-east-1
      - AWS_PROFILE
      - ASPNETCORE_ENVIRONMENT=Development
      - DeploymentsBucketName
      - DeploymentsTableName

  otel:
    image: amazon/aws-otel-collector
    command: ["--config=/config/otel-collector-config.yml"]
    networks: [app_network]
    environment:
      - AWS_REGION=us-east-1
      - AWS_PROFILE
    volumes:
      - ./otel-config:/config:ro
      - $HOME/.aws:/root/.aws:ro

Here is my collector config:

receivers:
  otlp:
    protocols:
      grpc:

processors:
  batch:

exporters:
  logging:
    verbosity: detailed
  awsxray:

extensions:
  health_check:
  pprof:
  zpages:

service:
  extensions: [health_check, pprof, zpages]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [awsxray, logging]
julealgon commented 1 year ago

@nblumhardt /@loomis any chance one of you could enable the 'Discussions' feature for the repo and move these types of issues over there?

rcdailey commented 1 year ago

It's worth noting that if the discussion tab had been there, I would have used that in the first place. I always check for that first as I understand the annoyance of having questions posted as issues.

loomis commented 1 year ago

I'll take a look at this later today. The discussion area was opened, you can move it there if you want, but can also reply here.

rcdailey commented 1 year ago

I'm happy to keep it here if you are. There's a "Convert to Discussion" option on the right side, that only repo members can use.

I want to also update that I'm seeing this working if I enable service.pipelines.logs in the collector YAML. However, I was hoping the logs would get added to the span as an event, since the logs occur within the scope of an HTTP request.

Perhaps once you take a look you can help clarify my understanding of why logs show up as disconnected data instead of span events.

Thank you.