{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Instana.SDK.Span.Span
( Span (Entry, Exit)
, SpanKind (EntryKind, ExitKind, IntermediateKind)
, traceId
, spanId
, spanKind
, parentId
, spanName
, timestamp
, errorCount
, addToErrorCount
, serviceName
, setServiceName
, spanData
, addRegisteredData
, addRegisteredDataAt
, addTag
, addTagAt
) where
import Data.Aeson (Value, (.=))
import qualified Data.Aeson as Aeson
import qualified Data.List as List
import Data.Text as T
import Data.Text (Text)
import GHC.Generics
import Instana.SDK.Internal.Id (Id)
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
data SpanKind =
EntryKind
| ExitKind
| IntermediateKind
deriving (Eq, Generic, Show)
data Span =
Entry EntrySpan
| Exit ExitSpan
deriving (Eq, Generic, Show)
traceId :: Span -> Id
traceId span_ =
case span_ of
Entry entry -> EntrySpan.traceId entry
Exit exit -> ExitSpan.traceId exit
spanId :: Span -> Id
spanId span_ =
case span_ of
Entry entry -> EntrySpan.spanId entry
Exit exit -> ExitSpan.spanId exit
parentId :: Span -> Maybe Id
parentId span_ =
case span_ of
Entry entry -> EntrySpan.parentId entry
Exit exit -> Just $ ExitSpan.parentId exit
spanName :: Span -> Text
spanName span_ =
case span_ of
Entry entry -> EntrySpan.spanName entry
Exit exit -> ExitSpan.spanName exit
spanKind :: Span -> SpanKind
spanKind span_ =
case span_ of
Entry _ -> EntryKind
Exit _ -> ExitKind
timestamp :: Span -> Int
timestamp span_ =
case span_ of
Entry entry -> EntrySpan.timestamp entry
Exit exit -> ExitSpan.timestamp exit
errorCount :: Span -> Int
errorCount span_ =
case span_ of
Entry entry -> EntrySpan.errorCount entry
Exit exit -> ExitSpan.errorCount exit
addToErrorCount :: Int -> Span -> Span
addToErrorCount increment span_ =
case span_ of
Entry entry ->
Entry $ EntrySpan.addToErrorCount increment entry
Exit exit ->
Exit $ ExitSpan.addToErrorCount increment exit
serviceName :: Span -> Maybe Text
serviceName span_ =
case span_ of
Entry entry -> EntrySpan.serviceName entry
Exit exit -> ExitSpan.serviceName exit
setServiceName :: Text -> Span -> Span
setServiceName serviceName_ span_ =
case span_ of
Entry entry ->
Entry $ EntrySpan.setServiceName serviceName_ entry
Exit exit ->
Exit $ ExitSpan.setServiceName serviceName_ exit
spanData :: Span -> Value
spanData span_ =
case span_ of
Entry entry -> EntrySpan.spanData entry
Exit exit -> ExitSpan.spanData exit
addTag :: Value -> Span -> Span
addTag value span_ =
addRegisteredDataAt "sdk.custom.tags" value span_
addTagAt :: Aeson.ToJSON a => Text -> a -> Span -> Span
addTagAt path value span_ =
addRegisteredDataAt (T.concat ["sdk.custom.tags.", path]) value span_
addRegisteredData :: Value -> Span -> Span
addRegisteredData value span_ =
case span_ of
Entry entry -> Entry $ EntrySpan.addData value entry
Exit exit -> Exit $ ExitSpan.addData value exit
addRegisteredDataAt :: Aeson.ToJSON a => Text -> a -> Span -> Span
addRegisteredDataAt path value span_ =
let
pathSegments = T.splitOn "." path
newData = List.foldr
(\nextPathSegment accumulatedAesonValue ->
Aeson.object [
nextPathSegment .= accumulatedAesonValue
]
)
(Aeson.toJSON value)
pathSegments
in
addRegisteredData newData span_