@@ -13,23 +13,28 @@ In order produced spans to have correct code locations, all the functions across
1313`inSpanM` call must have `HasCallStack` constraint, because
1414[GHC is never inferring it](https://downloads.haskell.org/ghc/9.8.4/docs/users_guide/exts/callstack.html) for us.
1515-}
16- module PostgREST.OpenTelemetry (Tracer , withTracer , middleware , inSpanM ) where
16+ module PostgREST.OpenTelemetry (Tracer , withTracer , middleware , inSpanM , renderTraceContext ) where
1717
18- import Control.Monad.Catch (MonadMask )
19- import Network.Wai (Middleware )
20- import OpenTelemetry.Attributes (emptyAttributes )
21- import OpenTelemetry.Instrumentation.Wai (newOpenTelemetryWaiMiddleware' )
22- import OpenTelemetry.Trace (InstrumentationLibrary (.. ),
23- SpanArguments , Tracer ,
24- initializeGlobalTracerProvider ,
25- makeTracer ,
26- shutdownTracerProvider ,
27- tracerOptions )
28- import OpenTelemetry.Trace.Core (getTracerTracerProvider )
29- import OpenTelemetry.Utils.Exceptions (inSpanM'' )
30- import PostgREST.AppState (AppState , getOTelTracer )
31- import PostgREST.Version (prettyVersion )
32- import Protolude
18+ import Control.Monad.Catch (MonadMask )
19+ import Network.Wai (Middleware )
20+ import OpenTelemetry.Attributes (emptyAttributes )
21+ import qualified OpenTelemetry.Context as Context
22+ import OpenTelemetry.Context.ThreadLocal (getContext )
23+ import OpenTelemetry.Instrumentation.Wai (newOpenTelemetryWaiMiddleware' )
24+ import OpenTelemetry.Propagator.W3CTraceContext (encodeSpanContext )
25+ import OpenTelemetry.Trace (InstrumentationLibrary (.. ),
26+ SpanArguments ,
27+ Tracer ,
28+ initializeGlobalTracerProvider ,
29+ makeTracer ,
30+ shutdownTracerProvider ,
31+ tracerOptions )
32+ import OpenTelemetry.Trace.Core (getTracerTracerProvider )
33+ import OpenTelemetry.Utils.Exceptions (inSpanM'' )
34+ import PostgREST.AppState (AppState ,
35+ getOTelTracer )
36+ import PostgREST.Version (prettyVersion )
37+ import Protolude
3338
3439{- | Wrap user's code with OpenTelemetry Tracer, initializing it with sensible defaults -}
3540withTracer :: (Tracer -> IO c ) -> IO c
@@ -69,3 +74,17 @@ inSpanM
6974 -> m a
7075inSpanM (Just t) n args m = inSpanM'' t callStack n args (const m)
7176inSpanM Nothing _ _ m = m
77+
78+ renderTraceContext :: IO (Maybe ByteString )
79+ renderTraceContext = do
80+ -- Render TraceContext in W3C Trace Context format
81+ -- https://www.w3.org/TR/trace-context/#traceparent-header
82+ -- https://www.w3.org/TR/trace-context/#tracestate-header
83+ --
84+ ctx <- getContext
85+ case Context. lookupSpan ctx of
86+ Nothing -> pure Nothing
87+ Just span -> do
88+ (tParent, _tState) <- encodeSpanContext span
89+ let traceContext = " traceparent='" <> tParent <> " '"
90+ pure $ Just traceContext
0 commit comments