{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
module OpenTelemetry.Trace (
TracerProvider,
initializeGlobalTracerProvider,
initializeTracerProvider,
getTracerProviderInitializationOptions,
getTracerProviderInitializationOptions',
shutdownTracerProvider,
getGlobalTracerProvider,
setGlobalTracerProvider,
Tracer,
tracerName,
getTracer,
makeTracer,
TracerOptions (..),
tracerOptions,
HasTracer (..),
InstrumentationLibrary (..),
Span,
inSpan,
defaultSpanArguments,
SpanArguments (..),
SpanKind (..),
NewLink (..),
inSpan',
updateName,
addAttribute,
addAttributes,
recordException,
setStatus,
SpanStatus (..),
NewEvent (..),
addEvent,
inSpan'',
createTracerProvider,
TracerProviderOptions (..),
emptyTracerProviderOptions,
detectBuiltInResources,
detectSampler,
createSpan,
createSpanWithoutCallStack,
endSpan,
spanGetAttributes,
ToAttribute (..),
ToPrimitiveAttribute (..),
Attribute (..),
PrimitiveAttribute (..),
Link,
Event,
SpanContext (..),
ImmutableSpan (..),
) where
import qualified Data.ByteString.Char8 as B
import Data.Either (partitionEithers)
import qualified Data.HashMap.Strict as H
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8)
import Network.HTTP.Types.Header
import OpenTelemetry.Attributes (AttributeLimits (..), defaultAttributeLimits)
import OpenTelemetry.Baggage (decodeBaggageHeader)
import qualified OpenTelemetry.Baggage as Baggage
import OpenTelemetry.Context (Context)
import OpenTelemetry.Exporter (Exporter)
import OpenTelemetry.Exporter.OTLP (loadExporterEnvironmentVariables, otlpExporter)
import OpenTelemetry.Processor (Processor)
import OpenTelemetry.Processor.Batch (BatchTimeoutConfig (..), batchProcessor, batchTimeoutConfig)
import OpenTelemetry.Propagator (Propagator)
import OpenTelemetry.Propagator.B3 (b3MultiTraceContextPropagator, b3TraceContextPropagator)
import OpenTelemetry.Propagator.W3CBaggage (w3cBaggagePropagator)
import OpenTelemetry.Propagator.W3CTraceContext (w3cTraceContextPropagator)
import OpenTelemetry.Resource
import OpenTelemetry.Resource.Host.Detector (detectHost)
import OpenTelemetry.Resource.OperatingSystem.Detector (detectOperatingSystem)
import OpenTelemetry.Resource.Process.Detector (detectProcess, detectProcessRuntime)
import OpenTelemetry.Resource.Service.Detector (detectService)
import OpenTelemetry.Resource.Telemetry.Detector (detectTelemetry)
import OpenTelemetry.Trace.Core
import OpenTelemetry.Trace.Id.Generator.Default (defaultIdGenerator)
import OpenTelemetry.Trace.Sampler (Sampler, alwaysOff, alwaysOn, parentBased, parentBasedOptions, traceIdRatioBased)
import System.Environment (lookupEnv)
import Text.Read (readMaybe)
knownPropagators :: [(T.Text, Propagator Context RequestHeaders ResponseHeaders)]
knownPropagators :: [(Text, Propagator Context RequestHeaders RequestHeaders)]
knownPropagators =
[ (Text
"tracecontext", Propagator Context RequestHeaders RequestHeaders
w3cTraceContextPropagator)
, (Text
"baggage", Propagator Context RequestHeaders RequestHeaders
w3cBaggagePropagator)
, (Text
"b3", Propagator Context RequestHeaders RequestHeaders
b3TraceContextPropagator)
, (Text
"b3multi", Propagator Context RequestHeaders RequestHeaders
b3MultiTraceContextPropagator)
, (Text
"jaeger", forall a. HasCallStack => [Char] -> a
error [Char]
"Jaeger not yet implemented")
]
readRegisteredPropagators :: IO [(T.Text, Propagator Context RequestHeaders ResponseHeaders)]
readRegisteredPropagators :: IO [(Text, Propagator Context RequestHeaders RequestHeaders)]
readRegisteredPropagators = forall (f :: * -> *) a. Applicative f => a -> f a
pure [(Text, Propagator Context RequestHeaders RequestHeaders)]
knownPropagators
initializeGlobalTracerProvider :: IO TracerProvider
initializeGlobalTracerProvider :: IO TracerProvider
initializeGlobalTracerProvider = do
TracerProvider
t <- IO TracerProvider
initializeTracerProvider
forall (m :: * -> *). MonadIO m => TracerProvider -> m ()
setGlobalTracerProvider TracerProvider
t
forall (f :: * -> *) a. Applicative f => a -> f a
pure TracerProvider
t
initializeTracerProvider :: IO TracerProvider
initializeTracerProvider :: IO TracerProvider
initializeTracerProvider = do
([Processor]
processors, TracerProviderOptions
opts) <- IO ([Processor], TracerProviderOptions)
getTracerProviderInitializationOptions
forall (m :: * -> *).
MonadIO m =>
[Processor] -> TracerProviderOptions -> m TracerProvider
createTracerProvider [Processor]
processors TracerProviderOptions
opts
getTracerProviderInitializationOptions :: IO ([Processor], TracerProviderOptions)
getTracerProviderInitializationOptions :: IO ([Processor], TracerProviderOptions)
getTracerProviderInitializationOptions = forall (any :: Maybe Symbol).
(ResourceMerge 'Nothing any ~ 'Nothing) =>
Resource any -> IO ([Processor], TracerProviderOptions)
getTracerProviderInitializationOptions' (forall a. Monoid a => a
mempty :: Resource 'Nothing)
getTracerProviderInitializationOptions' :: (ResourceMerge 'Nothing any ~ 'Nothing) => Resource any -> IO ([Processor], TracerProviderOptions)
getTracerProviderInitializationOptions' :: forall (any :: Maybe Symbol).
(ResourceMerge 'Nothing any ~ 'Nothing) =>
Resource any -> IO ([Processor], TracerProviderOptions)
getTracerProviderInitializationOptions' Resource any
rs = do
Sampler
sampler <- IO Sampler
detectSampler
AttributeLimits
attrLimits <- IO AttributeLimits
detectAttributeLimits
SpanLimits
spanLimits <- IO SpanLimits
detectSpanLimits
Propagator Context RequestHeaders RequestHeaders
propagators <- IO (Propagator Context RequestHeaders RequestHeaders)
detectPropagators
BatchTimeoutConfig
processorConf <- IO BatchTimeoutConfig
detectBatchProcessorConfig
[Exporter ImmutableSpan]
exporters <- IO [Exporter ImmutableSpan]
detectExporters
Resource 'Nothing
builtInRs <- IO (Resource 'Nothing)
detectBuiltInResources
Resource 'Nothing
envVarRs <- forall (r :: Maybe Symbol). [Maybe (Text, Attribute)] -> Resource r
mkResource forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO [(Text, Attribute)]
detectResourceAttributes
let allRs :: Resource (ResourceMerge 'Nothing any)
allRs = forall (old :: Maybe Symbol) (new :: Maybe Symbol).
Resource old -> Resource new -> Resource (ResourceMerge old new)
mergeResources (Resource 'Nothing
builtInRs forall a. Semigroup a => a -> a -> a
<> Resource 'Nothing
envVarRs) Resource any
rs
[Processor]
processors <- case [Exporter ImmutableSpan]
exporters of
[] -> do
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
Exporter ImmutableSpan
e : [Exporter ImmutableSpan]
_ -> do
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadIO m =>
BatchTimeoutConfig -> Exporter ImmutableSpan -> m Processor
batchProcessor BatchTimeoutConfig
processorConf Exporter ImmutableSpan
e
let providerOpts :: TracerProviderOptions
providerOpts =
TracerProviderOptions
emptyTracerProviderOptions
{ tracerProviderOptionsIdGenerator :: IdGenerator
tracerProviderOptionsIdGenerator = IdGenerator
defaultIdGenerator
, tracerProviderOptionsSampler :: Sampler
tracerProviderOptionsSampler = Sampler
sampler
, tracerProviderOptionsAttributeLimits :: AttributeLimits
tracerProviderOptionsAttributeLimits = AttributeLimits
attrLimits
, tracerProviderOptionsSpanLimits :: SpanLimits
tracerProviderOptionsSpanLimits = SpanLimits
spanLimits
, tracerProviderOptionsPropagators :: Propagator Context RequestHeaders RequestHeaders
tracerProviderOptionsPropagators = Propagator Context RequestHeaders RequestHeaders
propagators
, tracerProviderOptionsResources :: MaterializedResources
tracerProviderOptionsResources = forall (schema :: Maybe Symbol).
MaterializeResource schema =>
Resource schema -> MaterializedResources
materializeResources Resource (ResourceMerge 'Nothing any)
allRs
}
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Processor]
processors, TracerProviderOptions
providerOpts)
detectPropagators :: IO (Propagator Context RequestHeaders ResponseHeaders)
detectPropagators :: IO (Propagator Context RequestHeaders RequestHeaders)
detectPropagators = do
[(Text, Propagator Context RequestHeaders RequestHeaders)]
registeredPropagators <- IO [(Text, Propagator Context RequestHeaders RequestHeaders)]
readRegisteredPropagators
Maybe [Text]
propagatorsInEnv <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Text -> [Text]
T.splitOn Text
"," forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Text
T.pack) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO (Maybe [Char])
lookupEnv [Char]
"OTEL_PROPAGATORS"
if Maybe [Text]
propagatorsInEnv forall a. Eq a => a -> a -> Bool
== forall a. a -> Maybe a
Just [Text
"none"]
then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
else do
let envPropagators :: [Text]
envPropagators = forall a. a -> Maybe a -> a
fromMaybe [Text
"tracecontext", Text
"baggage"] Maybe [Text]
propagatorsInEnv
propagatorsAndRegistryEntry :: [Either Text (Propagator Context RequestHeaders RequestHeaders)]
propagatorsAndRegistryEntry = forall a b. (a -> b) -> [a] -> [b]
map (\Text
k -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. a -> Either a b
Left Text
k) forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
k [(Text, Propagator Context RequestHeaders RequestHeaders)]
registeredPropagators) [Text]
envPropagators
([Text]
_notFound, [Propagator Context RequestHeaders RequestHeaders]
propagators) = forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either Text (Propagator Context RequestHeaders RequestHeaders)]
propagatorsAndRegistryEntry
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat [Propagator Context RequestHeaders RequestHeaders]
propagators
knownSamplers :: [(T.Text, Maybe T.Text -> Maybe Sampler)]
knownSamplers :: [(Text, Maybe Text -> Maybe Sampler)]
knownSamplers =
[ (Text
"always_on", forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure Sampler
alwaysOn)
, (Text
"always_off", forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure Sampler
alwaysOff)
,
( Text
"traceidratio"
, \case
Maybe Text
Nothing -> forall a. Maybe a
Nothing
Just Text
val -> case forall a. Read a => [Char] -> Maybe a
readMaybe (Text -> [Char]
T.unpack Text
val) of
Maybe Double
Nothing -> forall a. Maybe a
Nothing
Just Double
ratioVal -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Double -> Sampler
traceIdRatioBased Double
ratioVal
)
, (Text
"parentbased_always_on", forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ ParentBasedOptions -> Sampler
parentBased forall a b. (a -> b) -> a -> b
$ Sampler -> ParentBasedOptions
parentBasedOptions Sampler
alwaysOn)
, (Text
"parentbased_always_off", forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ ParentBasedOptions -> Sampler
parentBased forall a b. (a -> b) -> a -> b
$ Sampler -> ParentBasedOptions
parentBasedOptions Sampler
alwaysOff)
,
( Text
"parentbased_traceidratio"
, \case
Maybe Text
Nothing -> forall a. Maybe a
Nothing
Just Text
val -> case forall a. Read a => [Char] -> Maybe a
readMaybe (Text -> [Char]
T.unpack Text
val) of
Maybe Double
Nothing -> forall a. Maybe a
Nothing
Just Double
ratioVal -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ ParentBasedOptions -> Sampler
parentBased forall a b. (a -> b) -> a -> b
$ Sampler -> ParentBasedOptions
parentBasedOptions forall a b. (a -> b) -> a -> b
$ Double -> Sampler
traceIdRatioBased Double
ratioVal
)
]
detectSampler :: IO Sampler
detectSampler :: IO Sampler
detectSampler = do
Maybe [Char]
envSampler <- [Char] -> IO (Maybe [Char])
lookupEnv [Char]
"OTEL_TRACES_SAMPLER"
Maybe [Char]
envArg <- [Char] -> IO (Maybe [Char])
lookupEnv [Char]
"OTEL_TRACES_SAMPLER_ARG"
let sampler :: Sampler
sampler = forall a. a -> Maybe a -> a
fromMaybe (ParentBasedOptions -> Sampler
parentBased forall a b. (a -> b) -> a -> b
$ Sampler -> ParentBasedOptions
parentBasedOptions Sampler
alwaysOn) forall a b. (a -> b) -> a -> b
$ do
[Char]
samplerName <- Maybe [Char]
envSampler
Maybe Text -> Maybe Sampler
samplerConstructor <- forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup ([Char] -> Text
T.pack [Char]
samplerName) [(Text, Maybe Text -> Maybe Sampler)]
knownSamplers
Maybe Text -> Maybe Sampler
samplerConstructor ([Char] -> Text
T.pack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Char]
envArg)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Sampler
sampler
detectBatchProcessorConfig :: IO BatchTimeoutConfig
detectBatchProcessorConfig :: IO BatchTimeoutConfig
detectBatchProcessorConfig =
Int -> Int -> Int -> Int -> BatchTimeoutConfig
BatchTimeoutConfig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Read a => [Char] -> a -> IO a
readEnvDefault [Char]
"OTEL_BSP_MAX_QUEUE_SIZE" (BatchTimeoutConfig -> Int
maxQueueSize BatchTimeoutConfig
batchTimeoutConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Read a => [Char] -> a -> IO a
readEnvDefault [Char]
"OTEL_BSP_SCHEDULE_DELAY" (BatchTimeoutConfig -> Int
scheduledDelayMillis BatchTimeoutConfig
batchTimeoutConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Read a => [Char] -> a -> IO a
readEnvDefault [Char]
"OTEL_BSP_EXPORT_TIMEOUT" (BatchTimeoutConfig -> Int
exportTimeoutMillis BatchTimeoutConfig
batchTimeoutConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Read a => [Char] -> a -> IO a
readEnvDefault [Char]
"OTEL_BSP_MAX_EXPORT_BATCH_SIZE" (BatchTimeoutConfig -> Int
maxExportBatchSize BatchTimeoutConfig
batchTimeoutConfig)
detectAttributeLimits :: IO AttributeLimits
detectAttributeLimits :: IO AttributeLimits
detectAttributeLimits =
Maybe Int -> Maybe Int -> AttributeLimits
AttributeLimits
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Read a => [Char] -> a -> IO a
readEnvDefault [Char]
"OTEL_ATTRIBUTE_COUNT_LIMIT" (AttributeLimits -> Maybe Int
attributeCountLimit AttributeLimits
defaultAttributeLimits)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. Read a => [Char] -> Maybe a
readMaybe) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO (Maybe [Char])
lookupEnv [Char]
"OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT")
detectSpanLimits :: IO SpanLimits
detectSpanLimits :: IO SpanLimits
detectSpanLimits =
Maybe Int
-> Maybe Int
-> Maybe Int
-> Maybe Int
-> Maybe Int
-> Maybe Int
-> SpanLimits
SpanLimits
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Read a => [Char] -> IO (Maybe a)
readEnv [Char]
"OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT"
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Read a => [Char] -> IO (Maybe a)
readEnv [Char]
"OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT"
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Read a => [Char] -> IO (Maybe a)
readEnv [Char]
"OTEL_SPAN_EVENT_COUNT_LIMIT"
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Read a => [Char] -> IO (Maybe a)
readEnv [Char]
"OTEL_SPAN_LINK_COUNT_LIMIT"
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Read a => [Char] -> IO (Maybe a)
readEnv [Char]
"OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT"
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Read a => [Char] -> IO (Maybe a)
readEnv [Char]
"OTEL_LINK_ATTRIBUTE_COUNT_LIMIT"
knownExporters :: [(T.Text, IO (Exporter ImmutableSpan))]
knownExporters :: [(Text, IO (Exporter ImmutableSpan))]
knownExporters =
[
( Text
"otlp"
, do
OTLPExporterConfig
otlpConfig <- forall (m :: * -> *). MonadIO m => m OTLPExporterConfig
loadExporterEnvironmentVariables
forall (m :: * -> *).
MonadIO m =>
OTLPExporterConfig -> m (Exporter ImmutableSpan)
otlpExporter OTLPExporterConfig
otlpConfig
)
, (Text
"jaeger", forall a. HasCallStack => [Char] -> a
error [Char]
"Jaeger exporter not implemented")
, (Text
"zipkin", forall a. HasCallStack => [Char] -> a
error [Char]
"Zipkin exporter not implemented")
]
detectExporters :: IO [Exporter ImmutableSpan]
detectExporters :: IO [Exporter ImmutableSpan]
detectExporters = do
Maybe [Text]
exportersInEnv <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Text -> [Text]
T.splitOn Text
"," forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Text
T.pack) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO (Maybe [Char])
lookupEnv [Char]
"OTEL_TRACES_EXPORTER"
if Maybe [Text]
exportersInEnv forall a. Eq a => a -> a -> Bool
== forall a. a -> Maybe a
Just [Text
"none"]
then forall (f :: * -> *) a. Applicative f => a -> f a
pure []
else do
let envExporters :: [Text]
envExporters = forall a. a -> Maybe a -> a
fromMaybe [Text
"otlp"] Maybe [Text]
exportersInEnv
exportersAndRegistryEntry :: [Either Text (IO (Exporter ImmutableSpan))]
exportersAndRegistryEntry = forall a b. (a -> b) -> [a] -> [b]
map (\Text
k -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. a -> Either a b
Left Text
k) forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
k [(Text, IO (Exporter ImmutableSpan))]
knownExporters) [Text]
envExporters
([Text]
_notFound, [IO (Exporter ImmutableSpan)]
exporterIntializers) = forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either Text (IO (Exporter ImmutableSpan))]
exportersAndRegistryEntry
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [IO (Exporter ImmutableSpan)]
exporterIntializers
detectResourceAttributes :: IO [(T.Text, Attribute)]
detectResourceAttributes :: IO [(Text, Attribute)]
detectResourceAttributes = do
Maybe [Char]
mEnv <- [Char] -> IO (Maybe [Char])
lookupEnv [Char]
"OTEL_RESOURCE_ATTRIBUTES"
case Maybe [Char]
mEnv of
Maybe [Char]
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure []
Just [Char]
envVar -> case ByteString -> Either [Char] Baggage
decodeBaggageHeader forall a b. (a -> b) -> a -> b
$ [Char] -> ByteString
B.pack [Char]
envVar of
Left [Char]
err -> do
[Char] -> IO ()
putStrLn [Char]
err
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
Right Baggage
ok ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map (\(Token
k, Element
v) -> (ByteString -> Text
decodeUtf8 forall a b. (a -> b) -> a -> b
$ Token -> ByteString
Baggage.tokenValue Token
k, forall a. ToAttribute a => a -> Attribute
toAttribute forall a b. (a -> b) -> a -> b
$ Element -> Text
Baggage.value Element
v)) forall a b. (a -> b) -> a -> b
$
forall k v. HashMap k v -> [(k, v)]
H.toList forall a b. (a -> b) -> a -> b
$
Baggage -> HashMap Token Element
Baggage.values Baggage
ok
readEnvDefault :: forall a. (Read a) => String -> a -> IO a
readEnvDefault :: forall a. Read a => [Char] -> a -> IO a
readEnvDefault [Char]
k a
defaultValue =
forall a. a -> Maybe a -> a
fromMaybe a
defaultValue forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. Read a => [Char] -> Maybe a
readMaybe) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO (Maybe [Char])
lookupEnv [Char]
k
readEnv :: forall a. (Read a) => String -> IO (Maybe a)
readEnv :: forall a. Read a => [Char] -> IO (Maybe a)
readEnv [Char]
k = (forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. Read a => [Char] -> Maybe a
readMaybe) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO (Maybe [Char])
lookupEnv [Char]
k
detectBuiltInResources :: IO (Resource 'Nothing)
detectBuiltInResources :: IO (Resource 'Nothing)
detectBuiltInResources = do
Service
svc <- IO Service
detectService
Process
processInfo <- IO Process
detectProcess
OperatingSystem
osInfo <- IO OperatingSystem
detectOperatingSystem
Host
host <- IO Host
detectHost
let rs :: Resource
(ResourceMerge
(ResourceMerge
(ResourceMerge
(ResourceMerge (ResourceMerge 'Nothing 'Nothing) 'Nothing)
'Nothing)
'Nothing)
'Nothing)
rs =
forall a. ToResource a => a -> Resource (ResourceSchema a)
toResource Service
svc
forall (old :: Maybe Symbol) (new :: Maybe Symbol).
Resource old -> Resource new -> Resource (ResourceMerge old new)
`mergeResources` forall a. ToResource a => a -> Resource (ResourceSchema a)
toResource Telemetry
detectTelemetry
forall (old :: Maybe Symbol) (new :: Maybe Symbol).
Resource old -> Resource new -> Resource (ResourceMerge old new)
`mergeResources` forall a. ToResource a => a -> Resource (ResourceSchema a)
toResource ProcessRuntime
detectProcessRuntime
forall (old :: Maybe Symbol) (new :: Maybe Symbol).
Resource old -> Resource new -> Resource (ResourceMerge old new)
`mergeResources` forall a. ToResource a => a -> Resource (ResourceSchema a)
toResource Process
processInfo
forall (old :: Maybe Symbol) (new :: Maybe Symbol).
Resource old -> Resource new -> Resource (ResourceMerge old new)
`mergeResources` forall a. ToResource a => a -> Resource (ResourceSchema a)
toResource OperatingSystem
osInfo
forall (old :: Maybe Symbol) (new :: Maybe Symbol).
Resource old -> Resource new -> Resource (ResourceMerge old new)
`mergeResources` forall a. ToResource a => a -> Resource (ResourceSchema a)
toResource Host
host
forall (f :: * -> *) a. Applicative f => a -> f a
pure Resource
(ResourceMerge
(ResourceMerge
(ResourceMerge
(ResourceMerge (ResourceMerge 'Nothing 'Nothing) 'Nothing)
'Nothing)
'Nothing)
'Nothing)
rs