core-telemetry 0.2.0.1 → 0.2.2.0
raw patch · 4 files changed
+94/−6 lines, 4 filesdep ~core-programPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: core-program
API changes (from Hackage documentation)
+ Core.Telemetry.Identifiers: setIdentifierSpan :: Span -> Program t ()
+ Core.Telemetry.Observability: usingTrace' :: Trace -> Program τ α -> Program τ α
Files
- core-telemetry.cabal +2/−2
- lib/Core/Telemetry.hs +1/−1
- lib/Core/Telemetry/Identifiers.hs +27/−1
- lib/Core/Telemetry/Observability.hs +64/−2
core-telemetry.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: core-telemetry-version: 0.2.0.1+version: 0.2.2.0 synopsis: Advanced telemetry description: This is part of a library to help build command-line programs, both tools and longer-running daemons.@@ -54,7 +54,7 @@ , bytestring , chronologique , core-data >=0.3.2.2- , core-program >=0.4.5.3+ , core-program >=0.4.6.1 , core-text >=0.3.6.0 , exceptions , http-streams
lib/Core/Telemetry.hs view
@@ -33,7 +33,7 @@ -- * Internals -- |- -- Various elper functions.+ -- Various helper functions. module Core.Telemetry.Identifiers ) where
lib/Core/Telemetry/Identifiers.hs view
@@ -18,6 +18,7 @@ -- * Traces and Spans getIdentifierTrace, getIdentifierSpan,+ setIdentifierSpan, -- * Internals createIdentifierTrace,@@ -32,8 +33,9 @@ toHexReversed32, ) where -import Control.Concurrent.MVar (readMVar)+import Control.Concurrent.MVar (modifyMVar_, readMVar) import Core.Program.Context+import Core.Program.Logging import Core.System (unsafePerformIO) import Core.System.Base (liftIO) import Core.System.External (TimeStamp (unTimeStamp))@@ -291,3 +293,27 @@ datum <- readMVar v pure (spanIdentifierFrom datum)++{- |+Override the identifier of the current span, if you are currently within a+span created by 'Core.Telemetry.Observability.encloseSpan'. This is an unsafe+action, specifically and only for the situation where you need create a parent+span for an asynchronous process whose unique identifier has already been+nominated. In this scenario all child spans would already have been created+with this span identifier as their parent, leaving you with the final task of+creating a "root" span within the trace with that parent identifier.++@since 0.2.1+-}+setIdentifierSpan :: Span -> Program t ()+setIdentifierSpan unique = do+ context <- getContext++ internal ("span = " <> unSpan unique)++ liftIO $ do+ -- get the map out+ let v = currentDatumFrom context+ modifyMVar_+ v+ (\datum -> pure datum{spanIdentifierFrom = Just unique})
lib/Core/Telemetry/Observability.hs view
@@ -144,6 +144,7 @@ Span (..), beginTrace, usingTrace,+ usingTrace', setServiceName, -- * Spans@@ -452,6 +453,16 @@ Right value -> pure value {- |+Send a span value up by hand.++This handles a number of convenient things for you, and takes care of a few edge+cases.+++@since 0.2.1+-}++{- | Start a new trace. A random identifier will be generated. You /must/ have a single \"root span\" immediately below starting a new trace.@@ -511,6 +522,51 @@ encloseTrace trace (Just parent) action +{- |+Create a new trace with the specified 'Trace' identifier. Unlike 'usingTrace'+this does /not/ set the parent 'Span' identifier, thereby marking this as a+new trace and causing the first span enclosed within this trace to be+considered the \"root\" span of the trace. This is unusual and should only+expected to be used in concert with the 'setIdentifierSpan' override to create+a root spans in asynchronous processes /after/ all the child spans have+already been composed and sent.++Most times, you don't need this. You're much better off using 'beginTrace' to+create a root span. However, life is not kind, and sometimes bad things happen+to good abstractions. Maybe you're tracing your build system, which isn't+obliging enough to be all contained in one Haskell process, but is a+half-dozen steps shotgunned across several different processes. In situations+like this, it's useful to be able to generate a 'Trace' identifier and 'Span'+identifier, use that as the parent across several different process+executions, hanging children spans off of this as you go, then manually send+up the root span at the end of it all.++@+ trace <- ...+ unique <- ...++ -- many child spans in other processes have used these as trace+ -- identifiers and parent span identifier. Now form the root span thereby+ -- finishing the trace.++ 'usingTrace'' trace $ do+ 'encloseSpan' \"Launch Missiles\" $ do+ 'setStartTime' start+ 'setIdentifierSpan' unique+ 'telemetry'+ [ 'metric' ...+ ]+@++@since 0.2.1+-}+usingTrace' :: Trace -> Program τ α -> Program τ α+usingTrace' trace action = do+ internal "Using trace"+ internal ("trace = " <> unTrace trace)++ encloseTrace trace Nothing action+ encloseTrace :: Trace -> Maybe Span -> Program τ α -> Program τ α encloseTrace trace possibleParent action = do context <- getContext@@ -578,7 +634,10 @@ ) where f :: Map JsonKey JsonValue -> MetricValue -> Map JsonKey JsonValue- f acc (MetricValue k v) = insertKeyValue k v acc+ f acc (MetricValue k@(JsonKey text) v) =+ if nullRope text+ then error "Empty metric field name not allowed"+ else insertKeyValue k v acc {- | Record telemetry about an event. Specify a label for the event and then@@ -629,7 +688,10 @@ writeTQueue tel (Just datum') where f :: Map JsonKey JsonValue -> MetricValue -> Map JsonKey JsonValue- f acc (MetricValue k v) = insertKeyValue k v acc+ f acc (MetricValue k@(JsonKey text) v) =+ if nullRope text+ then error "Empty metric field name not allowed"+ else insertKeyValue k v acc -- get current time after digging out datum and override spanTimeFrom before -- sending Datum