{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Instana.SDK.Span.Span
( Span (Entry, Exit)
, SpanKind (EntryKind, ExitKind, IntermediateKind)
, addAnnotation
, addAnnotationAt
, addAnnotationValueAt
, addJsonValueAt
, addToErrorCount
, correlationId
, correlationType
, errorCount
, initialData
, parentId
, serviceName
, setCorrelationId
, setCorrelationType
, setServiceName
, setSynthetic
, setTpFlag
, setW3cTraceContext
, spanData
, spanId
, spanKind
, spanName
, spanType
, synthetic
, timestamp
, tpFlag
, traceId
, w3cTraceContext
) where
import Data.Aeson (ToJSON)
import Data.List as List
import Data.Text as T
import GHC.Generics
import Instana.SDK.Internal.Id (Id)
import Instana.SDK.Internal.W3CTraceContext (W3CTraceContext)
import Instana.SDK.Span.EntrySpan (EntrySpan)
import qualified Instana.SDK.Span.EntrySpan as EntrySpan
import Instana.SDK.Span.ExitSpan (ExitSpan)
import qualified Instana.SDK.Span.ExitSpan as ExitSpan
import Instana.SDK.Span.SpanData (Annotation,
AnnotationValue,
SpanData (SpanData))
import qualified Instana.SDK.Span.SpanData as SpanData
import Instana.SDK.Span.SpanType (SpanType (RegisteredSpan, SdkSpan))
data SpanKind =
EntryKind
| ExitKind
| IntermediateKind
deriving (SpanKind -> SpanKind -> Bool
(SpanKind -> SpanKind -> Bool)
-> (SpanKind -> SpanKind -> Bool) -> Eq SpanKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SpanKind -> SpanKind -> Bool
$c/= :: SpanKind -> SpanKind -> Bool
== :: SpanKind -> SpanKind -> Bool
$c== :: SpanKind -> SpanKind -> Bool
Eq, (forall x. SpanKind -> Rep SpanKind x)
-> (forall x. Rep SpanKind x -> SpanKind) -> Generic SpanKind
forall x. Rep SpanKind x -> SpanKind
forall x. SpanKind -> Rep SpanKind x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SpanKind x -> SpanKind
$cfrom :: forall x. SpanKind -> Rep SpanKind x
Generic, Int -> SpanKind -> ShowS
[SpanKind] -> ShowS
SpanKind -> String
(Int -> SpanKind -> ShowS)
-> (SpanKind -> String) -> ([SpanKind] -> ShowS) -> Show SpanKind
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SpanKind] -> ShowS
$cshowList :: [SpanKind] -> ShowS
show :: SpanKind -> String
$cshow :: SpanKind -> String
showsPrec :: Int -> SpanKind -> ShowS
$cshowsPrec :: Int -> SpanKind -> ShowS
Show)
data Span =
Entry EntrySpan
| Exit ExitSpan
deriving (Span -> Span -> Bool
(Span -> Span -> Bool) -> (Span -> Span -> Bool) -> Eq Span
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Span -> Span -> Bool
$c/= :: Span -> Span -> Bool
== :: Span -> Span -> Bool
$c== :: Span -> Span -> Bool
Eq, (forall x. Span -> Rep Span x)
-> (forall x. Rep Span x -> Span) -> Generic Span
forall x. Rep Span x -> Span
forall x. Span -> Rep Span x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Span x -> Span
$cfrom :: forall x. Span -> Rep Span x
Generic, Int -> Span -> ShowS
[Span] -> ShowS
Span -> String
(Int -> Span -> ShowS)
-> (Span -> String) -> ([Span] -> ShowS) -> Show Span
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Span] -> ShowS
$cshowList :: [Span] -> ShowS
show :: Span -> String
$cshow :: Span -> String
showsPrec :: Int -> Span -> ShowS
$cshowsPrec :: Int -> Span -> ShowS
Show)
traceId :: Span -> Id
traceId :: Span -> Id
traceId span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Id
EntrySpan.traceId EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> Id
ExitSpan.traceId ExitSpan
exit
spanId :: Span -> Id
spanId :: Span -> Id
spanId span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Id
EntrySpan.spanId EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> Id
ExitSpan.spanId ExitSpan
exit
parentId :: Span -> Maybe Id
parentId :: Span -> Maybe Id
parentId span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Maybe Id
EntrySpan.parentId EntrySpan
entry
Exit exit :: ExitSpan
exit -> Id -> Maybe Id
forall a. a -> Maybe a
Just (Id -> Maybe Id) -> Id -> Maybe Id
forall a b. (a -> b) -> a -> b
$ ExitSpan -> Id
ExitSpan.parentId ExitSpan
exit
spanType :: Span -> SpanType
spanType :: Span -> SpanType
spanType span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> SpanType
EntrySpan.spanType EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> SpanType
ExitSpan.spanType ExitSpan
exit
spanName :: Span -> Text
spanName :: Span -> Text
spanName span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Text
EntrySpan.spanName EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> Text
ExitSpan.spanName ExitSpan
exit
spanKind :: Span -> SpanKind
spanKind :: Span -> SpanKind
spanKind span_ :: Span
span_ =
case Span
span_ of
Entry _ -> SpanKind
EntryKind
Exit _ -> SpanKind
ExitKind
timestamp :: Span -> Int
timestamp :: Span -> Int
timestamp span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Int
EntrySpan.timestamp EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> Int
ExitSpan.timestamp ExitSpan
exit
errorCount :: Span -> Int
errorCount :: Span -> Int
errorCount span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Int
EntrySpan.errorCount EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> Int
ExitSpan.errorCount ExitSpan
exit
addToErrorCount :: Int -> Span -> Span
addToErrorCount :: Int -> Span -> Span
addToErrorCount increment :: Int
increment span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry ->
EntrySpan -> Span
Entry (EntrySpan -> Span) -> EntrySpan -> Span
forall a b. (a -> b) -> a -> b
$ Int -> EntrySpan -> EntrySpan
EntrySpan.addToErrorCount Int
increment EntrySpan
entry
Exit exit :: ExitSpan
exit ->
ExitSpan -> Span
Exit (ExitSpan -> Span) -> ExitSpan -> Span
forall a b. (a -> b) -> a -> b
$ Int -> ExitSpan -> ExitSpan
ExitSpan.addToErrorCount Int
increment ExitSpan
exit
serviceName :: Span -> Maybe Text
serviceName :: Span -> Maybe Text
serviceName span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Maybe Text
EntrySpan.serviceName EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> Maybe Text
ExitSpan.serviceName ExitSpan
exit
setServiceName :: Text -> Span -> Span
setServiceName :: Text -> Span -> Span
setServiceName serviceName_ :: Text
serviceName_ span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry ->
EntrySpan -> Span
Entry (EntrySpan -> Span) -> EntrySpan -> Span
forall a b. (a -> b) -> a -> b
$ Text -> EntrySpan -> EntrySpan
EntrySpan.setServiceName Text
serviceName_ EntrySpan
entry
Exit exit :: ExitSpan
exit ->
ExitSpan -> Span
Exit (ExitSpan -> Span) -> ExitSpan -> Span
forall a b. (a -> b) -> a -> b
$ Text -> ExitSpan -> ExitSpan
ExitSpan.setServiceName Text
serviceName_ ExitSpan
exit
correlationType :: Span -> Maybe Text
correlationType :: Span -> Maybe Text
correlationType span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Maybe Text
EntrySpan.correlationType EntrySpan
entry
Exit _ -> Maybe Text
forall a. Maybe a
Nothing
setCorrelationType :: Text -> Span -> Span
setCorrelationType :: Text -> Span -> Span
setCorrelationType correlationType_ :: Text
correlationType_ span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry ->
EntrySpan -> Span
Entry (EntrySpan -> Span) -> EntrySpan -> Span
forall a b. (a -> b) -> a -> b
$ Text -> EntrySpan -> EntrySpan
EntrySpan.setCorrelationType Text
correlationType_ EntrySpan
entry
Exit _ ->
Span
span_
correlationId :: Span -> Maybe Text
correlationId :: Span -> Maybe Text
correlationId span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Maybe Text
EntrySpan.correlationId EntrySpan
entry
Exit _ -> Maybe Text
forall a. Maybe a
Nothing
setCorrelationId :: Text -> Span -> Span
setCorrelationId :: Text -> Span -> Span
setCorrelationId correlationId_ :: Text
correlationId_ span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry ->
EntrySpan -> Span
Entry (EntrySpan -> Span) -> EntrySpan -> Span
forall a b. (a -> b) -> a -> b
$ Text -> EntrySpan -> EntrySpan
EntrySpan.setCorrelationId Text
correlationId_ EntrySpan
entry
Exit _ ->
Span
span_
w3cTraceContext :: Span -> Maybe W3CTraceContext
w3cTraceContext :: Span -> Maybe W3CTraceContext
w3cTraceContext span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Maybe W3CTraceContext
EntrySpan.w3cTraceContext EntrySpan
entry
Exit exit :: ExitSpan
exit -> W3CTraceContext -> Maybe W3CTraceContext
forall a. a -> Maybe a
Just (W3CTraceContext -> Maybe W3CTraceContext)
-> W3CTraceContext -> Maybe W3CTraceContext
forall a b. (a -> b) -> a -> b
$ ExitSpan -> W3CTraceContext
ExitSpan.w3cTraceContext ExitSpan
exit
setW3cTraceContext :: W3CTraceContext -> Span -> Span
setW3cTraceContext :: W3CTraceContext -> Span -> Span
setW3cTraceContext w3cTraceContext_ :: W3CTraceContext
w3cTraceContext_ span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry ->
EntrySpan -> Span
Entry (EntrySpan -> Span) -> EntrySpan -> Span
forall a b. (a -> b) -> a -> b
$ W3CTraceContext -> EntrySpan -> EntrySpan
EntrySpan.setW3cTraceContext W3CTraceContext
w3cTraceContext_ EntrySpan
entry
Exit exit :: ExitSpan
exit ->
ExitSpan -> Span
Exit (ExitSpan -> Span) -> ExitSpan -> Span
forall a b. (a -> b) -> a -> b
$ W3CTraceContext -> ExitSpan -> ExitSpan
ExitSpan.setW3cTraceContext W3CTraceContext
w3cTraceContext_ ExitSpan
exit
tpFlag :: Span -> Bool
tpFlag :: Span -> Bool
tpFlag span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Bool
EntrySpan.tpFlag EntrySpan
entry
Exit _ -> Bool
False
setTpFlag :: Span -> Span
setTpFlag :: Span -> Span
setTpFlag span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry ->
EntrySpan -> Span
Entry (EntrySpan -> Span) -> EntrySpan -> Span
forall a b. (a -> b) -> a -> b
$ EntrySpan -> EntrySpan
EntrySpan.setTpFlag EntrySpan
entry
Exit _ ->
Span
span_
synthetic :: Span -> Bool
synthetic :: Span -> Bool
synthetic span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Bool
EntrySpan.synthetic EntrySpan
entry
Exit _ -> Bool
False
setSynthetic :: Bool -> Span -> Span
setSynthetic :: Bool -> Span -> Span
setSynthetic synthetic_ :: Bool
synthetic_ span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry ->
EntrySpan -> Span
Entry (EntrySpan -> Span) -> EntrySpan -> Span
forall a b. (a -> b) -> a -> b
$ Bool -> EntrySpan -> EntrySpan
EntrySpan.setSynthetic Bool
synthetic_ EntrySpan
entry
Exit _ ->
Span
span_
spanData :: Span -> SpanData
spanData :: Span -> SpanData
spanData span_ :: Span
span_ =
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> SpanData
EntrySpan.spanData EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> SpanData
ExitSpan.spanData ExitSpan
exit
addAnnotation :: Annotation -> Span -> Span
addAnnotation :: Annotation -> Span -> Span
addAnnotation annotation :: Annotation
annotation span_ :: Span
span_ =
let
wrappedAnnotation :: Annotation
wrappedAnnotation = Span -> Annotation -> Annotation
wrapAnnotationIfNecessary Span
span_ Annotation
annotation
in
case Span
span_ of
Entry entry :: EntrySpan
entry -> EntrySpan -> Span
Entry (EntrySpan -> Span) -> EntrySpan -> Span
forall a b. (a -> b) -> a -> b
$ Annotation -> EntrySpan -> EntrySpan
EntrySpan.addAnnotation Annotation
wrappedAnnotation EntrySpan
entry
Exit exit :: ExitSpan
exit -> ExitSpan -> Span
Exit (ExitSpan -> Span) -> ExitSpan -> Span
forall a b. (a -> b) -> a -> b
$ Annotation -> ExitSpan -> ExitSpan
ExitSpan.addAnnotation Annotation
wrappedAnnotation ExitSpan
exit
addAnnotationAt :: Text -> Annotation -> Span -> Span
addAnnotationAt :: Text -> Annotation -> Span -> Span
addAnnotationAt path :: Text
path annotation :: Annotation
annotation span_ :: Span
span_ =
let
pathPrefix :: [Text]
pathPrefix = Text -> Text -> [Text]
T.splitOn "." Text
path
newData :: Annotation
newData = (Text -> Annotation -> Annotation)
-> Annotation -> [Text] -> Annotation
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr
(\nextPathSegment :: Text
nextPathSegment accumulated :: Annotation
accumulated ->
Text -> [Annotation] -> Annotation
SpanData.objectAnnotation Text
nextPathSegment [Annotation
accumulated]
)
Annotation
annotation
[Text]
pathPrefix
in
Annotation -> Span -> Span
addAnnotation Annotation
newData Span
span_
addAnnotationValueAt :: Text -> AnnotationValue -> Span -> Span
addAnnotationValueAt :: Text -> AnnotationValue -> Span -> Span
addAnnotationValueAt path :: Text
path value :: AnnotationValue
value span_ :: Span
span_ =
let
pathSegments :: [Text]
pathSegments = Text -> Text -> [Text]
T.splitOn "." Text
path
lastPathSegment :: Text
lastPathSegment = [Text] -> Text
forall a. [a] -> a
List.last [Text]
pathSegments
pathPrefix :: [Text]
pathPrefix = Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
List.take ([Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
List.length [Text]
pathSegments Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) [Text]
pathSegments
newData :: Annotation
newData = (Text -> Annotation -> Annotation)
-> Annotation -> [Text] -> Annotation
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr
(\nextPathSegment :: Text
nextPathSegment accumulated :: Annotation
accumulated ->
Text -> [Annotation] -> Annotation
SpanData.objectAnnotation Text
nextPathSegment [Annotation
accumulated]
)
(Text -> AnnotationValue -> Annotation
SpanData.singleAnnotation Text
lastPathSegment AnnotationValue
value)
[Text]
pathPrefix
in
Annotation -> Span -> Span
addAnnotation Annotation
newData Span
span_
addJsonValueAt :: ToJSON a => Text -> a -> Span -> Span
addJsonValueAt :: Text -> a -> Span -> Span
addJsonValueAt path :: Text
path value :: a
value span_ :: Span
span_ =
Text -> AnnotationValue -> Span -> Span
addAnnotationValueAt Text
path (a -> AnnotationValue
forall a. ToJSON a => a -> AnnotationValue
SpanData.simpleValue a
value) Span
span_
wrapAnnotationIfNecessary :: Span -> Annotation -> Annotation
wrapAnnotationIfNecessary :: Span -> Annotation -> Annotation
wrapAnnotationIfNecessary span_ :: Span
span_ annotation :: Annotation
annotation =
case Span -> SpanType
spanType Span
span_ of
RegisteredSpan _ ->
Annotation
annotation
SdkSpan _ ->
( Text -> [Annotation] -> Annotation
SpanData.objectAnnotation "sdk" [
Text -> [Annotation] -> Annotation
SpanData.objectAnnotation "custom" [
Text -> [Annotation] -> Annotation
SpanData.objectAnnotation "tags" [
Annotation
annotation
]
]
]
)
initialData :: SpanKind -> SpanType -> SpanData
initialData :: SpanKind -> SpanType -> SpanData
initialData kind :: SpanKind
kind (SdkSpan s :: Text
s) = SpanKind -> Text -> SpanData
initialSdkData SpanKind
kind Text
s
initialData _ (RegisteredSpan _) = SpanData
SpanData.empty
initialSdkData :: SpanKind -> Text -> SpanData
initialSdkData :: SpanKind -> Text -> SpanData
initialSdkData kind :: SpanKind
kind spanName_ :: Text
spanName_ =
let
sdkKind :: Text
sdkKind :: Text
sdkKind =
case SpanKind
kind of
EntryKind -> "entry"
ExitKind -> "exit"
IntermediateKind -> "intermediate"
in
[Annotation] -> SpanData
SpanData
[ Text -> [Annotation] -> Annotation
SpanData.objectAnnotation "sdk"
[ Text -> Text -> Annotation
forall a. ToJSON a => Text -> a -> Annotation
SpanData.simpleAnnotation "name" Text
spanName_
, Text -> Text -> Annotation
forall a. ToJSON a => Text -> a -> Annotation
SpanData.simpleAnnotation "type" Text
sdkKind
]
]