packages feed

hs-opentelemetry-sdk-1.0.0.0: src/OpenTelemetry/SDK.hs

{-# LANGUAGE ScopedTypeVariables #-}

{- |
Module      :  OpenTelemetry.SDK
Copyright   :  (c) Ian Duncan, 2026
License     :  BSD-3
Description :  Unified SDK initialization for all three signals (traces, metrics, logs).
Stability   :  stable

= Overview

This is the recommended entry point for applications using the
OpenTelemetry SDK. It initializes all three signal providers
(TracerProvider, MeterProvider, LoggerProvider) from environment
variables in a single call.

= Quick example

@
import OpenTelemetry.SDK

main :: IO ()
main = withOpenTelemetry $ \otel -> do
  let tracer = makeTracer (otelTracerProvider otel) "my-app" tracerOptions
  -- ... application code ...
@

All configuration is via the standard @OTEL_*@ environment variables:

* @OTEL_SERVICE_NAME@ — service name resource attribute
* @OTEL_TRACES_EXPORTER@ — trace exporter (default: @otlp@)
* @OTEL_METRICS_EXPORTER@ — metrics exporter (default: @otlp@)
* @OTEL_LOGS_EXPORTER@ — logs exporter (default: @otlp@)
* @OTEL_EXPORTER_OTLP_ENDPOINT@ — OTLP endpoint
* @OTEL_METRIC_EXPORT_INTERVAL@ — metrics export interval (ms, default: 60000)

See "OpenTelemetry.Trace", "OpenTelemetry.Metric", and "OpenTelemetry.Log"
for signal-specific configuration and per-signal initialization.
-}
module OpenTelemetry.SDK (
  -- * Unified initialization
  OTelSignals (..),
  initializeOpenTelemetry,
  withOpenTelemetry,
) where

import Control.Exception (SomeException, bracket, catch)
import Control.Monad (void)
import OpenTelemetry.Configuration.Create (OTelSignals (..))
import OpenTelemetry.Log (initializeGlobalLoggerProvider, shutdownLoggerProvider)
import OpenTelemetry.Metric (initializeGlobalMeterProvider, shutdownMeterProvider)
import OpenTelemetry.Trace (initializeGlobalTracerProvider, shutdownTracerProvider)


{- | Initialize all three signal providers from @OTEL_*@ environment variables,
install them as globals, and return an 'OTelSignals' with a unified shutdown handle.

@since 1.0.0.0
-}
initializeOpenTelemetry :: IO OTelSignals
initializeOpenTelemetry = do
  tp <- initializeGlobalTracerProvider
  mp <- initializeGlobalMeterProvider
  lp <- initializeGlobalLoggerProvider
  let shutdown = do
        void (shutdownTracerProvider tp Nothing) `catch` \(_ :: SomeException) -> pure ()
        void (shutdownMeterProvider mp Nothing) `catch` \(_ :: SomeException) -> pure ()
        void (shutdownLoggerProvider lp Nothing) `catch` \(_ :: SomeException) -> pure ()
  pure
    OTelSignals
      { otelTracerProvider = tp
      , otelMeterProvider = mp
      , otelLoggerProvider = lp
      , otelPropagators = mempty
      , otelShutdown = shutdown
      }


{- | Initialize all signal providers, run an action, then shut everything down.

@
main = withOpenTelemetry $ \otel -> do
  -- use otelTracerProvider, otelMeterProvider, otelLoggerProvider
  runMyApp
@

@since 1.0.0.0
-}
withOpenTelemetry :: (OTelSignals -> IO a) -> IO a
withOpenTelemetry = bracket initializeOpenTelemetry otelShutdown