packages feed

otel-effectful-1.0.0: src/Effectful/OpenTelemetry/Protocol/Export.hs

{-# LANGUAGE AllowAmbiguousTypes #-}

module Effectful.OpenTelemetry.Protocol.Export {-# WARNING in "x-unstable-interface" "This is an unstable interface." #-} where

import Data.Aeson qualified as Aeson
import Data.List qualified as List
import Effectful.OpenTelemetry.Protocol.Resource qualified as Resource
import Network.GRPC.HTTP2.Proto3Wire (RPC)
import Network.URI (URI (..))
import Network.URI qualified as URI
import Numeric.Natural (Natural)
import Proto3.Wire.Encode (MessageBuilder)
import Proto3.Wire.Encode.Class qualified as Proto
import Prelude

-- | How to export a batch of signal @a@ via OTLP: HTTP paths, the gRPC RPC descriptor,
-- JSON\/proto encoders, the @OTEL_EXPORTER_OTLP_\<SIGNAL\>_*@ variable name, and batching defaults.
-- Implemented once per signal type (e.g. 'Effectful.OpenTelemetry.Tracing.Span.Span').
class Request a where
    exportHttpPathComponents :: [String]

    exportGrpcRPC :: RPC

    exportJson :: [Resource.Items a] -> Aeson.Value

    exportProto :: [Resource.Items a] -> MessageBuilder
    default exportProto :: (Proto.Encode a) => [Resource.Items a] -> MessageBuilder
    exportProto = foldMap (Proto.encodeField 1)

    transportSignalEnvName :: String
    exportSignalEnvName :: String
    exportSignalEnvName = transportSignalEnvName @a

    batchEnvPrefix :: Maybe String

    appendExportPath :: URI -> URI
    appendExportPath uri = uri{uriPath = base <> encodedPath}
      where
        base = List.dropWhileEnd (== '/') (uriPath uri)
        encodedPath =
            concatMap (('/' :) . URI.escapeURIString URI.isUnescapedInURIComponent) $
                exportHttpPathComponents @a

    defaultConfig :: Config

-- | Batch-processor / metric-reader configuration.
--
-- See <https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor>.
data Config = Config
    { batch :: Maybe BatchConfig
    , exportTimeoutMs :: Natural
    }
    deriving stock (Show, Eq)

data BatchConfig = BatchConfig
    { maxQueueSize :: Natural
    -- ^ Maximum number of items held in the queue before new items are dropped.
    , scheduledDelayMs :: Natural
    -- ^ Delay between export attempts in milliseconds.
    , maxBatchSize :: Natural
    -- ^ Maximum number of items forwarded to the exporter per call.
    }
    deriving stock (Show, Eq)