{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeOperators #-}
module Datadog.Agent where
import Data.Aeson
import Data.Int (Int32, Int64)
import Data.Map.Strict (Map)
import Data.Maybe (catMaybes)
import Data.Text (Text)
import Data.Text.Arbitrary ()
import Data.Word (Word64)
import Generic.Random (genericArbitraryU)
import GHC.Generics (Generic)
import Servant.API
import Test.QuickCheck (Arbitrary, arbitrary)
type Traces4 = "v0.4" :> "traces"
:> ReqBody '[JSON] [Trace]
:> Put '[JSON] TraceResponse
type Traces3 = "v0.3" :> "traces" :> ReqBody '[JSON] [Trace] :> Put '[JSON] ()
newtype Trace = Trace [Span] deriving (ToJSON, FromJSON)
data Span = Span
{ spanService :: Text
, spanName :: Text
, spanResource :: Text
, spanTraceId :: Word64
, spanId :: Word64
, spanParentId :: Maybe Word64
, spanStart :: Int64
, spanDuration :: Int64
, spanError :: Maybe Int32
, spanMeta :: Maybe (Map Text Text)
, spanMetrics :: Maybe (Map Text Text)
, spanType :: Maybe Text
} deriving (Generic)
instance Arbitrary Span where
arbitrary = genericArbitraryU
instance ToJSON Span where
toJSON Span{..} = object'
[ "service" .= spanService
, "name" .= spanName
, "resource" .= spanResource
, "trace_id" .= spanTraceId
, "span_id" .= spanId
, "start" .= spanStart
, "duration" .= spanDuration
]
[ "parent_id" .=? spanParentId
, "error" .=? spanError
, "meta" .=? spanMeta
, "metrics" .=? spanMetrics
, "type" .=? spanType
]
where
key .=? value = (key .=) <$> value
object' required optional = object $ required <> catMaybes optional
instance FromJSON Span where
parseJSON = withObject "Span" $ \v ->
Span <$> v .: "service"
<*> v .: "name"
<*> v .: "resource"
<*> v .: "trace_id"
<*> v .: "span_id"
<*> v .:? "parent_id" .!= Nothing
<*> v .: "start"
<*> v .: "duration"
<*> v .:? "error" .!= Nothing
<*> v .:? "meta" .!= Nothing
<*> v .:? "metrics" .!= Nothing
<*> v .:? "type" .!= Nothing
data TraceResponse = TraceResponse
{ trRateByService :: Map Text Double
}
instance ToJSON TraceResponse where
toJSON (TraceResponse rates) = object
[ "rate_by_service" .= rates
]
instance FromJSON TraceResponse where
parseJSON = withObject "TraceResponse" $ \v ->
TraceResponse <$> v .: "rate_by_service"