effectful-tracing-0.1.0.0: src/Effectful/Tracing/Attribute.hs
-- |
-- Module : Effectful.Tracing.Attribute
-- Description : Attribute values and conversions.
-- Copyright : (c) The effectful-tracing contributors
-- License : BSD-3-Clause
-- Stability : experimental
--
-- Span attributes are typed key/value pairs. Following the OpenTelemetry data
-- model, a value is a scalar ('AttrText', 'AttrBool', 'AttrInt', 'AttrDouble')
-- or a /homogeneous/ array of one of those scalar types. Heterogeneous arrays
-- are unrepresentable by construction.
--
-- Use '(.=)' with the 'ToAttributeValue' class to build attributes ergonomically:
--
-- @
-- import Effectful.Tracing.Attribute
--
-- attrs :: [Attribute]
-- attrs =
-- [ \"http.method\" '.=' (\"GET\" :: Text)
-- , \"http.status_code\" '.=' (200 :: Int)
-- , \"http.request.header.accept\" '.=' ([\"application\/json\"] :: [Text])
-- ]
-- @
module Effectful.Tracing.Attribute
( AttributeValue (..)
, Attribute (..)
, (.=)
, ToAttributeValue (..)
) where
import Data.Int (Int64)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Vector (Vector)
import Data.Vector qualified as V
-- | A typed attribute value: a scalar or a homogeneous array of scalars.
data AttributeValue
= AttrText !Text
| AttrBool !Bool
| AttrInt !Int64
| AttrDouble !Double
| AttrTextArray !(Vector Text)
| AttrBoolArray !(Vector Bool)
| AttrIntArray !(Vector Int64)
| AttrDoubleArray !(Vector Double)
deriving (Eq, Show)
-- | A key/value attribute attached to a span, event, or link.
data Attribute = Attribute
{ attributeKey :: !Text
, attributeValue :: !AttributeValue
}
deriving (Eq, Show)
-- | Build an 't:Attribute' from a key and any 'ToAttributeValue'.
(.=) :: (ToAttributeValue v) => Text -> v -> Attribute
key .= value = Attribute key (toAttributeValue value)
infixr 8 .=
-- | Types that can be used directly as an 'AttributeValue'.
--
-- Scalar instances cover 'Text', 'String', 'Bool', 'Int', 'Int64', 'Double',
-- and 'Float'. List and 'Vector' instances of those scalar types map to the
-- corresponding homogeneous array variants. @Int@ widens to @Int64@ and @Float@
-- widens to @Double@ to match the underlying representation.
class ToAttributeValue a where
toAttributeValue :: a -> AttributeValue
instance ToAttributeValue AttributeValue where
toAttributeValue = id
instance ToAttributeValue Text where
toAttributeValue = AttrText
instance ToAttributeValue String where
toAttributeValue = AttrText . T.pack
instance ToAttributeValue Bool where
toAttributeValue = AttrBool
instance ToAttributeValue Int where
toAttributeValue = AttrInt . fromIntegral
instance ToAttributeValue Int64 where
toAttributeValue = AttrInt
instance ToAttributeValue Double where
toAttributeValue = AttrDouble
instance ToAttributeValue Float where
toAttributeValue = AttrDouble . realToFrac
instance ToAttributeValue (Vector Text) where
toAttributeValue = AttrTextArray
instance ToAttributeValue (Vector Bool) where
toAttributeValue = AttrBoolArray
instance ToAttributeValue (Vector Int64) where
toAttributeValue = AttrIntArray
instance ToAttributeValue (Vector Double) where
toAttributeValue = AttrDoubleArray
instance ToAttributeValue [Text] where
toAttributeValue = AttrTextArray . V.fromList
instance ToAttributeValue [Bool] where
toAttributeValue = AttrBoolArray . V.fromList
instance ToAttributeValue [Int64] where
toAttributeValue = AttrIntArray . V.fromList
instance ToAttributeValue [Int] where
toAttributeValue = AttrIntArray . V.fromList . map fromIntegral
instance ToAttributeValue [Double] where
toAttributeValue = AttrDoubleArray . V.fromList
instance ToAttributeValue [Float] where
toAttributeValue = AttrDoubleArray . V.fromList . map realToFrac