{-# LANGUAGE RankNTypes #-}
module Ecluse.Telemetry.Tracing (
telemetryWaiMiddleware,
instrumentDataPlaneManagerSettings,
dataPlaneInstrumentationConfig,
withRuleEvalSpan,
withMirrorEnqueueSpan,
withPackumentGateSpan,
withMetadataFetchSpan,
withMetadataDecodeSpan,
withMirrorJobSpan,
JobSpanOutcome (..),
withDomainSpan,
tracingPortOf,
workerTracingPortOf,
ruleVerdictFields,
) where
import Network.HTTP.Client (ManagerSettings)
import Network.Wai (Middleware)
import OpenTelemetry.Instrumentation.HttpClient (
HttpClientInstrumentationConfig,
httpClientInstrumentationConfig,
instrumentManagerSettings,
)
import OpenTelemetry.Instrumentation.Wai (newOpenTelemetryWaiMiddleware')
import OpenTelemetry.Metric.Core (getMeter)
import OpenTelemetry.Propagator.W3CTraceContext (decodeSpanContext, encodeSpanContext)
import OpenTelemetry.Trace (
NewLink (NewLink, linkAttributes, linkContext),
Span,
SpanArguments (kind, links),
SpanKind (Client, Consumer, Internal, Producer),
SpanStatus (Error),
addAttribute,
defaultSpanArguments,
inSpan',
makeTracer,
setStatus,
tracerOptions,
)
import UnliftIO (MonadUnliftIO, withRunInIO)
import Ecluse.Core.Package (PackageName, renderPackageName)
import Ecluse.Core.Queue (RemoteSpanContext (RemoteSpanContext, rscTraceparent, rscTracestate))
import Ecluse.Core.Server.Response (
RejectReason (BelowIntegrityFloor, ByPolicy, MissingIntegrity, Unavailable, UpstreamInvalid),
Rejection (rejectionMessage, rejectionReason),
RuleName (RuleName),
ServeDecision (Admit, Reject),
)
import Ecluse.Core.Telemetry.Span (JobSpanOutcome (..), TracingPort (..), WorkerTracingPort (..))
import Ecluse.Core.Version (Version, renderVersion)
import Ecluse.Telemetry (
Telemetry,
telemetryMeterProvider,
telemetryTracerProvider,
)
telemetryWaiMiddleware :: Telemetry -> IO Middleware
telemetryWaiMiddleware :: Telemetry -> IO Middleware
telemetryWaiMiddleware Telemetry
telemetry =
case (Telemetry -> Maybe TracerProvider
telemetryTracerProvider Telemetry
telemetry, Telemetry -> Maybe MeterProvider
telemetryMeterProvider Telemetry
telemetry) of
(Just TracerProvider
tracerProvider, Just MeterProvider
meterProvider) -> do
meter <- MeterProvider -> InstrumentationLibrary -> IO Meter
getMeter MeterProvider
meterProvider InstrumentationLibrary
forall s. IsString s => s
ecluseScope
newOpenTelemetryWaiMiddleware' tracerProvider meter
(Maybe TracerProvider, Maybe MeterProvider)
_ -> Middleware -> IO Middleware
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Middleware
forall a. a -> a
id
instrumentDataPlaneManagerSettings :: Telemetry -> ManagerSettings -> IO ManagerSettings
instrumentDataPlaneManagerSettings :: Telemetry -> ManagerSettings -> IO ManagerSettings
instrumentDataPlaneManagerSettings Telemetry
telemetry ManagerSettings
settings =
case Telemetry -> Maybe TracerProvider
telemetryTracerProvider Telemetry
telemetry of
Maybe TracerProvider
Nothing -> ManagerSettings -> IO ManagerSettings
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ManagerSettings
settings
Just TracerProvider
_ -> HttpClientInstrumentationConfig
-> ManagerSettings -> IO ManagerSettings
instrumentManagerSettings HttpClientInstrumentationConfig
dataPlaneInstrumentationConfig ManagerSettings
settings
dataPlaneInstrumentationConfig :: HttpClientInstrumentationConfig
dataPlaneInstrumentationConfig :: HttpClientInstrumentationConfig
dataPlaneInstrumentationConfig = HttpClientInstrumentationConfig
httpClientInstrumentationConfig
withRuleEvalSpan ::
(MonadUnliftIO m) =>
Telemetry ->
PackageName ->
Version ->
m (a, ServeDecision) ->
m a
withRuleEvalSpan :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry -> PackageName -> Version -> m (a, ServeDecision) -> m a
withRuleEvalSpan Telemetry
telemetry PackageName
name Version
version m (a, ServeDecision)
action =
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
withDomainSpan Telemetry
telemetry SpanKind
Internal [] Text
"ecluse.rule.eval" ((Maybe Span -> m a) -> m a) -> (Maybe Span -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Maybe Span
mSpan -> do
Maybe Span -> [(Text, Text)] -> m ()
forall (m :: * -> *).
MonadIO m =>
Maybe Span -> [(Text, Text)] -> m ()
recordFields Maybe Span
mSpan (PackageName -> Version -> [(Text, Text)]
coordinateFields PackageName
name Version
version)
(result, verdict) <- m (a, ServeDecision)
action
recordFields mSpan (ruleVerdictFields verdict)
pure result
withMirrorEnqueueSpan ::
(MonadUnliftIO m) =>
Telemetry ->
PackageName ->
Version ->
Text ->
(a -> Maybe Text) ->
(Maybe RemoteSpanContext -> m a) ->
m a
withMirrorEnqueueSpan :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> PackageName
-> Version
-> Text
-> (a -> Maybe Text)
-> (Maybe RemoteSpanContext -> m a)
-> m a
withMirrorEnqueueSpan Telemetry
telemetry PackageName
name Version
version Text
artifactUrl a -> Maybe Text
project Maybe RemoteSpanContext -> m a
body =
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
withDomainSpan Telemetry
telemetry SpanKind
Producer [] Text
"ecluse.mirror.enqueue" ((Maybe Span -> m a) -> m a) -> (Maybe Span -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Maybe Span
mSpan -> do
Maybe Span -> [(Text, Text)] -> m ()
forall (m :: * -> *).
MonadIO m =>
Maybe Span -> [(Text, Text)] -> m ()
recordFields Maybe Span
mSpan (PackageName -> Version -> [(Text, Text)]
coordinateFields PackageName
name Version
version [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. Semigroup a => a -> a -> a
<> [(Text
"ecluse.mirror.artifact_url", Text
artifactUrl)])
carrier <- (Span -> m RemoteSpanContext)
-> Maybe Span -> m (Maybe RemoteSpanContext)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Maybe a -> f (Maybe b)
traverse Span -> m RemoteSpanContext
forall (m :: * -> *). MonadIO m => Span -> m RemoteSpanContext
captureRemoteContext Maybe Span
mSpan
result <- body carrier
whenJust mSpan $ \Span
theSpan -> Maybe Text -> (Text -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust (a -> Maybe Text
project a
result) (Span -> SpanStatus -> m ()
forall (m :: * -> *). MonadIO m => Span -> SpanStatus -> m ()
setStatus Span
theSpan (SpanStatus -> m ()) -> (Text -> SpanStatus) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> SpanStatus
Error)
pure result
withMirrorJobSpan ::
(MonadUnliftIO m) =>
Telemetry ->
PackageName ->
Version ->
Maybe RemoteSpanContext ->
(a -> JobSpanOutcome) ->
m a ->
m a
withMirrorJobSpan :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> PackageName
-> Version
-> Maybe RemoteSpanContext
-> (a -> JobSpanOutcome)
-> m a
-> m a
withMirrorJobSpan Telemetry
telemetry PackageName
name Version
version Maybe RemoteSpanContext
remoteContext a -> JobSpanOutcome
project m a
action =
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
withDomainSpan Telemetry
telemetry SpanKind
Consumer (Maybe RemoteSpanContext -> [NewLink]
mirrorJobLinks Maybe RemoteSpanContext
remoteContext) Text
"ecluse.mirror.job" ((Maybe Span -> m a) -> m a) -> (Maybe Span -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Maybe Span
mSpan -> do
Maybe Span -> [(Text, Text)] -> m ()
forall (m :: * -> *).
MonadIO m =>
Maybe Span -> [(Text, Text)] -> m ()
recordFields Maybe Span
mSpan (PackageName -> Version -> [(Text, Text)]
coordinateFields PackageName
name Version
version)
result <- m a
action
let JobSpanOutcome label mDetail = project result
recordFields mSpan [("ecluse.mirror.outcome", label)]
whenJust mSpan $ \Span
theSpan -> Maybe Text -> (Text -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust Maybe Text
mDetail (Span -> SpanStatus -> m ()
forall (m :: * -> *). MonadIO m => Span -> SpanStatus -> m ()
setStatus Span
theSpan (SpanStatus -> m ()) -> (Text -> SpanStatus) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> SpanStatus
Error)
pure result
withPackumentGateSpan :: (MonadUnliftIO m) => Telemetry -> PackageName -> m a -> m a
withPackumentGateSpan :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry -> PackageName -> m a -> m a
withPackumentGateSpan Telemetry
telemetry PackageName
name m a
action =
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
withDomainSpan Telemetry
telemetry SpanKind
Internal [] Text
"ecluse.packument.gate" ((Maybe Span -> m a) -> m a) -> (Maybe Span -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Maybe Span
mSpan -> do
Maybe Span -> [(Text, Text)] -> m ()
forall (m :: * -> *).
MonadIO m =>
Maybe Span -> [(Text, Text)] -> m ()
recordFields Maybe Span
mSpan [(Text
"ecluse.package", PackageName -> Text
renderPackageName PackageName
name)]
m a
action
withMetadataFetchSpan :: (MonadUnliftIO m) => Telemetry -> PackageName -> m a -> m a
withMetadataFetchSpan :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry -> PackageName -> m a -> m a
withMetadataFetchSpan Telemetry
telemetry PackageName
name m a
action =
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
withDomainSpan Telemetry
telemetry SpanKind
Client [] Text
"ecluse.metadata.fetch" ((Maybe Span -> m a) -> m a) -> (Maybe Span -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Maybe Span
mSpan -> do
Maybe Span -> [(Text, Text)] -> m ()
forall (m :: * -> *).
MonadIO m =>
Maybe Span -> [(Text, Text)] -> m ()
recordFields Maybe Span
mSpan [(Text
"ecluse.package", PackageName -> Text
renderPackageName PackageName
name)]
m a
action
withMetadataDecodeSpan :: (MonadUnliftIO m) => Telemetry -> PackageName -> m a -> m a
withMetadataDecodeSpan :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry -> PackageName -> m a -> m a
withMetadataDecodeSpan Telemetry
telemetry PackageName
name m a
action =
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
withDomainSpan Telemetry
telemetry SpanKind
Internal [] Text
"ecluse.metadata.decode" ((Maybe Span -> m a) -> m a) -> (Maybe Span -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Maybe Span
mSpan -> do
Maybe Span -> [(Text, Text)] -> m ()
forall (m :: * -> *).
MonadIO m =>
Maybe Span -> [(Text, Text)] -> m ()
recordFields Maybe Span
mSpan [(Text
"ecluse.package", PackageName -> Text
renderPackageName PackageName
name)]
m a
action
tracingPortOf :: Telemetry -> TracingPort
tracingPortOf :: Telemetry -> TracingPort
tracingPortOf Telemetry
telemetry =
TracingPort
{ spanRuleEval :: forall a. PackageName -> Version -> IO (a, ServeDecision) -> IO a
spanRuleEval = Telemetry
-> PackageName -> Version -> IO (a, ServeDecision) -> IO a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry -> PackageName -> Version -> m (a, ServeDecision) -> m a
withRuleEvalSpan Telemetry
telemetry
, spanMirrorEnqueue :: forall a.
PackageName
-> Version
-> Text
-> (a -> Maybe Text)
-> (Maybe RemoteSpanContext -> IO a)
-> IO a
spanMirrorEnqueue = \PackageName
n Version
v Text
url a -> Maybe Text
ok Maybe RemoteSpanContext -> IO a
action -> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. IO a -> IO a) -> IO a) -> IO a)
-> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
runInIO ->
Telemetry
-> PackageName
-> Version
-> Text
-> (a -> Maybe Text)
-> (Maybe RemoteSpanContext -> IO a)
-> IO a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> PackageName
-> Version
-> Text
-> (a -> Maybe Text)
-> (Maybe RemoteSpanContext -> m a)
-> m a
withMirrorEnqueueSpan Telemetry
telemetry PackageName
n Version
v Text
url a -> Maybe Text
ok (IO a -> IO a
forall a. IO a -> IO a
runInIO (IO a -> IO a)
-> (Maybe RemoteSpanContext -> IO a)
-> Maybe RemoteSpanContext
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe RemoteSpanContext -> IO a
action)
, spanPackumentGate :: forall a. PackageName -> IO a -> IO a
spanPackumentGate = \PackageName
n IO a
action -> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. IO a -> IO a) -> IO a) -> IO a)
-> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
runInIO ->
Telemetry -> PackageName -> IO a -> IO a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry -> PackageName -> m a -> m a
withPackumentGateSpan Telemetry
telemetry PackageName
n (IO a -> IO a
forall a. IO a -> IO a
runInIO IO a
action)
, spanMetadataFetch :: forall a. PackageName -> IO a -> IO a
spanMetadataFetch = \PackageName
n IO a
action -> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. IO a -> IO a) -> IO a) -> IO a)
-> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
runInIO ->
Telemetry -> PackageName -> IO a -> IO a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry -> PackageName -> m a -> m a
withMetadataFetchSpan Telemetry
telemetry PackageName
n (IO a -> IO a
forall a. IO a -> IO a
runInIO IO a
action)
, spanMetadataDecode :: forall a. PackageName -> IO a -> IO a
spanMetadataDecode = \PackageName
n IO a
action -> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. IO a -> IO a) -> IO a) -> IO a)
-> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
runInIO ->
Telemetry -> PackageName -> IO a -> IO a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry -> PackageName -> m a -> m a
withMetadataDecodeSpan Telemetry
telemetry PackageName
n (IO a -> IO a
forall a. IO a -> IO a
runInIO IO a
action)
}
workerTracingPortOf :: Telemetry -> WorkerTracingPort
workerTracingPortOf :: Telemetry -> WorkerTracingPort
workerTracingPortOf Telemetry
telemetry =
WorkerTracingPort
{ wtpMirrorJobSpan :: forall a.
PackageName
-> Version
-> Maybe RemoteSpanContext
-> (a -> JobSpanOutcome)
-> IO a
-> IO a
wtpMirrorJobSpan = Telemetry
-> PackageName
-> Version
-> Maybe RemoteSpanContext
-> (a -> JobSpanOutcome)
-> IO a
-> IO a
forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> PackageName
-> Version
-> Maybe RemoteSpanContext
-> (a -> JobSpanOutcome)
-> m a
-> m a
withMirrorJobSpan Telemetry
telemetry
}
ruleVerdictFields :: ServeDecision -> [(Text, Text)]
ruleVerdictFields :: ServeDecision -> [(Text, Text)]
ruleVerdictFields = \case
ServeDecision
Admit -> [(Text
"ecluse.rule.decision", Text
"admit")]
Reject Rejection
rejection ->
[ (Text
"ecluse.rule.decision", Text
"deny")
, (Text
"ecluse.rule.reason_class", RejectReason -> Text
reasonClass (Rejection -> RejectReason
rejectionReason Rejection
rejection))
, (Text
"ecluse.rule.message", Rejection -> Text
rejectionMessage Rejection
rejection)
]
[(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. Semigroup a => a -> a -> a
<> RejectReason -> [(Text, Text)]
ruleNameField (Rejection -> RejectReason
rejectionReason Rejection
rejection)
where
reasonClass :: RejectReason -> Text
reasonClass :: RejectReason -> Text
reasonClass = \case
ByPolicy RuleName
_ -> Text
"by_policy"
Unavailable Transience
_ -> Text
"unavailable"
RejectReason
MissingIntegrity -> Text
"missing_integrity"
RejectReason
BelowIntegrityFloor -> Text
"below_integrity_floor"
RejectReason
UpstreamInvalid -> Text
"upstream_invalid"
ruleNameField :: RejectReason -> [(Text, Text)]
ruleNameField :: RejectReason -> [(Text, Text)]
ruleNameField = \case
ByPolicy (RuleName Text
ruleName) -> [(Text
"ecluse.rule.name", Text
ruleName)]
RejectReason
_ -> []
withDomainSpan ::
(MonadUnliftIO m) =>
Telemetry ->
SpanKind ->
[NewLink] ->
Text ->
(Maybe Span -> m a) ->
m a
withDomainSpan :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Telemetry
-> SpanKind -> [NewLink] -> Text -> (Maybe Span -> m a) -> m a
withDomainSpan Telemetry
telemetry SpanKind
spanKind [NewLink]
spanLinks Text
name Maybe Span -> m a
body =
case Telemetry -> Maybe TracerProvider
telemetryTracerProvider Telemetry
telemetry of
Maybe TracerProvider
Nothing -> Maybe Span -> m a
body Maybe Span
forall a. Maybe a
Nothing
Just TracerProvider
tracerProvider ->
let tracer :: Tracer
tracer = TracerProvider -> InstrumentationLibrary -> TracerOptions -> Tracer
makeTracer TracerProvider
tracerProvider InstrumentationLibrary
forall s. IsString s => s
ecluseScope TracerOptions
tracerOptions
in Tracer -> Text -> SpanArguments -> (Span -> m a) -> m a
forall (m :: * -> *) a.
(MonadUnliftIO m, HasCallStack) =>
Tracer -> Text -> SpanArguments -> (Span -> m a) -> m a
inSpan' Tracer
tracer Text
name SpanArguments
defaultSpanArguments{kind = spanKind, links = spanLinks} (Maybe Span -> m a
body (Maybe Span -> m a) -> (Span -> Maybe Span) -> Span -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Span -> Maybe Span
forall a. a -> Maybe a
Just)
captureRemoteContext :: (MonadIO m) => Span -> m RemoteSpanContext
captureRemoteContext :: forall (m :: * -> *). MonadIO m => Span -> m RemoteSpanContext
captureRemoteContext Span
theSpan = do
(traceparent, tracestate) <- IO (ByteString, ByteString) -> m (ByteString, ByteString)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Span -> IO (ByteString, ByteString)
encodeSpanContext Span
theSpan)
pure
RemoteSpanContext
{ rscTraceparent = decodeUtf8 traceparent
, rscTracestate = decodeUtf8 tracestate
}
mirrorJobLinks :: Maybe RemoteSpanContext -> [NewLink]
mirrorJobLinks :: Maybe RemoteSpanContext -> [NewLink]
mirrorJobLinks Maybe RemoteSpanContext
Nothing = []
mirrorJobLinks (Just RemoteSpanContext
remote) =
case Maybe ByteString -> Maybe ByteString -> Maybe SpanContext
decodeSpanContext (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 (RemoteSpanContext -> Text
rscTraceparent RemoteSpanContext
remote))) Maybe ByteString
tracestateHeader of
Maybe SpanContext
Nothing -> []
Just SpanContext
ctx -> [NewLink{linkContext :: SpanContext
linkContext = SpanContext
ctx, linkAttributes :: AttributeMap
linkAttributes = AttributeMap
forall a. Monoid a => a
mempty}]
where
tracestateHeader :: Maybe ByteString
tracestateHeader :: Maybe ByteString
tracestateHeader
| RemoteSpanContext -> Text
rscTracestate RemoteSpanContext
remote Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"" = Maybe ByteString
forall a. Maybe a
Nothing
| Bool
otherwise = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 (RemoteSpanContext -> Text
rscTracestate RemoteSpanContext
remote))
recordFields :: (MonadIO m) => Maybe Span -> [(Text, Text)] -> m ()
recordFields :: forall (m :: * -> *).
MonadIO m =>
Maybe Span -> [(Text, Text)] -> m ()
recordFields Maybe Span
Nothing [(Text, Text)]
_ = m ()
forall (f :: * -> *). Applicative f => f ()
pass
recordFields (Just Span
theSpan) [(Text, Text)]
fields = ((Text, Text) -> m ()) -> [(Text, Text)] -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ((Text -> Text -> m ()) -> (Text, Text) -> m ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Span -> Text -> Text -> m ()
forall (m :: * -> *) a.
(MonadIO m, ToAttribute a) =>
Span -> Text -> a -> m ()
addAttribute Span
theSpan)) [(Text, Text)]
fields
coordinateFields :: PackageName -> Version -> [(Text, Text)]
coordinateFields :: PackageName -> Version -> [(Text, Text)]
coordinateFields PackageName
name Version
version =
[ (Text
"ecluse.package", PackageName -> Text
renderPackageName PackageName
name)
, (Text
"ecluse.version", Version -> Text
renderVersion Version
version)
]
ecluseScope :: (IsString s) => s
ecluseScope :: forall s. IsString s => s
ecluseScope = s
"ecluse"