core-telemetry 0.2.8.0 → 0.2.9.0
raw patch · 2 files changed
+59/−7 lines, 2 files
Files
- core-telemetry.cabal +2/−2
- lib/Core/Telemetry/Honeycomb.hs +57/−5
core-telemetry.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: core-telemetry-version: 0.2.8.0+version: 0.2.9.0 synopsis: Advanced telemetry description: This is part of a library to help build command-line programs, both tools and longer-running daemons.@@ -28,7 +28,7 @@ license-file: LICENSE build-type: Simple tested-with:- GHC == 8.10.7, GHC == 9.2.5+ GHC == 8.10.7, GHC == 9.2.7 extra-doc-files: HoneycombTraceExample.png honeycomb-sad-trace.png
lib/Core/Telemetry/Honeycomb.hs view
@@ -67,12 +67,15 @@ module Core.Telemetry.Honeycomb ( Dataset , honeycombExporter+ , setDatasetName ) where import Codec.Compression.GZip qualified as GZip (compress)+import Control.Concurrent.MVar (modifyMVar_) import Control.Exception.Safe qualified as Safe (catch, finally, throw)+import Control.Monad (forM_) import Core.Data.Clock (Time, getCurrentTimeNanoseconds, unTime)-import Core.Data.Structures (Map, fromMap, insertKeyValue, intoMap, lookupKeyValue)+import Core.Data.Structures (Map, emptyMap, fromMap, insertKeyValue, intoMap, lookupKeyValue) import Core.Encoding.Json import Core.Program.Arguments import Core.Program.Context@@ -123,6 +126,34 @@ , setupActionFrom = setupHoneycombAction } +{- |+Override the dataset being used for telemetry.++Under normal circumstances this shouldn't be necessary. The default dataset+for your program's telemetry is set by the infrastructure using the+@--dataset=@ command-line option, and typically matches the single service+name set by 'setServiceName'. For most applications this is sufficient. There+are, however, times when you need to send events or spans to a /different/+dataset. If there are two completely unrelated behaviours in a given+application that occur with wildly different latency ranges then you /may/+find it appropriate to segment the telemetry into two different datasets.++This override will be inherited by any spans that come into scope below the+one where this is called.++@since 0.2.9+-}+setDatasetName :: Dataset -> Program τ ()+setDatasetName dataset = do+ context <- getContext++ liftIO $ do+ -- get the map out+ let v = currentDatumFrom context+ modifyMVar_+ v+ (\datum -> pure datum {datasetFrom = Just dataset})+ -- so this is annoying: we're _under_ (and indeed, before) the Program monad -- and in the guts of the library. So all the work we've done to provide -- sensible access to environment variables etc isn't available here and we@@ -214,11 +245,30 @@ -- use partually applied process :: IORef (Maybe Connection) -> Hostname -> ApiKey -> Dataset -> [Datum] -> IO () process r honeycombHost apikey dataset datums = do- let json = JsonArray (fmap convertDatumToJson datums)- postEventToHoneycombAPI r honeycombHost apikey dataset json+ let targets = List.foldl' f emptyMap datums :: Map Dataset [JsonValue]+ let pairs = fromMap targets :: [(Dataset, [JsonValue])] + forM_ pairs $ \(dataset', values') -> do+ let json = JsonArray values'+ postEventToHoneycombAPI r honeycombHost apikey dataset' json+ where+ f :: Map Dataset [JsonValue] -> Datum -> Map Dataset [JsonValue]+ f acc datum =+ let+ (override, point) = convertDatumToJson datum++ dataset' = case override of+ Nothing -> dataset+ Just value -> value++ list' = case lookupKeyValue dataset' acc of+ Nothing -> point : []+ Just list -> point : list+ in+ insertKeyValue dataset' list' acc+ -- implements the spec described at <https://docs.honeycomb.io/getting-data-in/tracing/send-trace-data/>-convertDatumToJson :: Datum -> JsonValue+convertDatumToJson :: Datum -> (Maybe Dataset, JsonValue) convertDatumToJson datum = let spani = spanIdentifierFrom datum trace = traceIdentifierFrom datum@@ -263,7 +313,9 @@ , (JsonKey "data", JsonObject meta6) ] )- in point++ override = datasetFrom datum+ in (override, point) acquireConnection :: IORef (Maybe Connection) -> Hostname -> IO Connection acquireConnection r honeycombHost = do