iand675 / hs-opentelemetry

OpenTelemetry support for the Haskell programming language
https://iankduncan.com/projects/opentelemetry
BSD 3-Clause "New" or "Revised" License
73 stars 34 forks source link

Help logging to stdout #73

Closed JonathanLorimer closed 1 year ago

JonathanLorimer commented 1 year ago

Hello, I am trying to figure out the best way to log tracing events in stdout for development. I have considered 2 approaches, but not sure which would be best (and couldn't find any documentation on this).

This first approach is to use the inMemoryChannelExporter in a setup like this:

    withTracerDev :: ((TracerOptions -> Tracer) -> IO c) -> IO c
    withTracerDev f = bracket
      -- Install the SDK, pulling configuration from the environment
      (do
        (processor, chann) <- inMemoryChannelExporter
        provider <- createTracerProvider [processor]
          TracerProviderOptions
            { tracerProviderOptionsIdGenerator = _
            , tracerProviderOptionsSampler = _
            , tracerProviderOptionsResources = _
            , tracerProviderOptionsAttributeLimits = _
            , tracerProviderOptionsSpanLimits = _
            , tracerProviderOptionsPropagators
            , tracerProviderOptionsLogger = _
            }
        pure (provider, chann)
      )
      -- Ensure that any spans that haven't been exported yet are flushed
      (shutdownTracerProvider . fst)
      -- Get a tracer so you can create spans
      (\(tracerProvider, chann) -> f chann $ makeTracer tracerProvider "my-service")

Then I would just fork a thread, read from the channel, then write to stdout.

The second approach uses the logger option on TracerProviderOptions. But I couldn't figure out what the semantics of this action are just from the source.

iand675 commented 1 year ago

I'd probably recommend using the Exporter interface directly to do what you want. Implementing one is quite simple: https://hackage.haskell.org/package/hs-opentelemetry-api-0.0.3.8/docs/OpenTelemetry-Exporter.html

There's also an (unpublished) package that logs to whatever handle you like that you could either pull in from GitHub, or else copy-paste directly into your project: https://github.com/iand675/hs-opentelemetry/blob/main/exporters/handle/src/OpenTelemetry/Exporter/Handle.hs For this one, you'd use the stdout Handle provided in System.IO

PRs to improve the Handle exporter package would be most welcome.

iand675 commented 1 year ago

BTW, the logger option on TracerProviderOptions is not what you're looking for. That's intended to send error messages that occur within the OTEL API somewhere useful instead of just shunting them straight to stdout or stderr.

JonathanLorimer commented 1 year ago

@iand675 How do you register an Exporter? I can't find it documented anywhere.

iand675 commented 1 year ago

You use it to construct a span processor (see OpenTelemetry.Processor.Simple or OpenTelemetry.Processor.Batch), and then provide that span processor to the TracerProviderOptions. Tracers created from that TracerProvider will export to the supplied exporter.