hotel-california-0.0.1.0: src/HotelCalifornia/Tracing/TraceParent.hs
-- | This module defines the type of 'TraceParent' which can be parsed
module HotelCalifornia.Tracing.TraceParent where
import Data.Foldable (for_)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8
import qualified Data.Text.Encoding as TE
import qualified Data.Text as Text
import OpenTelemetry.Propagator.W3CTraceContext
import OpenTelemetry.Trace.Core (SpanContext, isRemote, wrapSpanContext, Span)
import System.Environment
import OpenTelemetry.Context.ThreadLocal
import qualified OpenTelemetry.Context as Ctxt
-- | This function looks up the @TRACEPARENT@ and @TRACECONTEXT@ environment
-- variables and returns a @'Maybe' 'SpanContext'@ constructed from them.
spanContextFromEnvironment :: IO (Maybe SpanContext)
spanContextFromEnvironment = do
mtraceParent <- lookupEnvBS "TRACEPARENT"
mtraceContext <- lookupEnvBS "TRACESTATE"
pure $ decodeSpanContext mtraceParent mtraceContext
where
lookupEnvBS :: String -> IO (Maybe BS.ByteString)
lookupEnvBS str = fmap (TE.encodeUtf8 . Text.pack) <$> lookupEnv str
-- | This function takes the given 'Span' and converts it into a list of
-- environment variables consisting of:
--
-- @
-- [ ( "TRACEPARENT", traceParent)
-- , ( "TRACESTATE", traceState)
-- ]
-- @
spanContextToEnvironment :: Span -> IO [(String, String)]
spanContextToEnvironment spanContext = do
(traceParent, traceState) <- encodeSpanContext spanContext
pure
[ ("TRACEPARENT", BS8.unpack traceParent)
, ("TRACESTATE", BS8.unpack traceState)
]
-- | This function should be called after you've initialized and attached the
-- thread local 'Context'.
setParentSpanFromEnvironment :: IO ()
setParentSpanFromEnvironment = do
mspanContext <- spanContextFromEnvironment
for_ mspanContext \spanContext -> do
adjustContext $ Ctxt.insertSpan (wrapSpanContext (spanContext {isRemote = True}))