core-telemetry 0.1.6.0 → 0.1.6.1
raw patch · 4 files changed
+89/−28 lines, 4 filesdep ~core-datadep ~core-program
Dependency ranges changed: core-data, core-program
Files
- core-telemetry.cabal +3/−3
- lib/Core/Telemetry/Console.hs +7/−2
- lib/Core/Telemetry/Honeycomb.hs +1/−0
- lib/Core/Telemetry/Observability.hs +78/−23
core-telemetry.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: core-telemetry-version: 0.1.6.0+version: 0.1.6.1 synopsis: Advanced telemetry description: This is part of a library to help build command-line programs, both tools and longer-running daemons.@@ -49,8 +49,8 @@ , bytestring , chronologique , core-data- , core-program >=0.3.0- , core-text >=0.3.2+ , core-program >=0.3.0.7+ , core-text >=0.3.5 , exceptions , http-streams , io-streams
lib/Core/Telemetry/Console.hs view
@@ -50,7 +50,6 @@ where processOne :: Datum -> IO () processOne datum = do- now <- getCurrentTimeNanoseconds let start = spanTimeFrom datum let text = (intoEscapes pureGrey)@@ -61,7 +60,13 @@ in List.foldl' f emptyRope pairs <> (intoEscapes resetColour) - let result = formatLogMessage start now SeverityDebug text+ now <- getCurrentTimeNanoseconds+ let result =+ formatLogMessage+ start+ now+ SeverityDebug+ text atomically $ do writeTQueue out (Just result)
lib/Core/Telemetry/Honeycomb.hs view
@@ -151,6 +151,7 @@ let json = JsonArray (fmap convertDatumToJson datums) postEventToHoneycombAPI apikey dataset json +-- implements the spec described at <https://docs.honeycomb.io/getting-data-in/tracing/send-trace-data/> convertDatumToJson :: Datum -> JsonValue convertDatumToJson datum = let spani = spanIdentifierFrom datum
lib/Core/Telemetry/Observability.hs view
@@ -5,8 +5,29 @@ {-# LANGUAGE RankNTypes #-} {- |+Traditional \"monitoring\" systems were concerned with gathering together obscene+quantities of metrics and graphing them. This makes for /very/ pretty billboard+displays in Network Operations Centers which impress visitors tremendously,+but (it turns out) are of limited use when actually trying to troubleshoot+problems or improve the performance of our systems. We all put a lot of+effort into trying to detect anamolies but really, despite person-centuries of+effort, graphing raw system metrics doesn't get us as far as we would have liked.++Experience with large-scale distributed systems has led to the insight that+what you need is to be able to trace the path a request takes as it moves+through a system, correlating and comparing this trace to others like it. This+has led to the modern \"observability\" movement, more concerned with metrics+which descirbe user-visible experience, service levels, error budgets, and+being able to do ad-hoc analysis of evolving situations.++This library aims to support both models of using telemetry, with the primary+emphasis being on the /traces/ and /spans/ that can be connected together by+an observability tool.++= Usage+ To use this capability, first you need to initialize the telemetry subsystem-with an appropriate exporter.+with an appropriate exporter: @ import "Core.Program"@@ -19,11 +40,18 @@ 'Core.Program.Execute.executeWith' context' program @ -/Traces and Spans/+Then when you run your program you can pick the exporter: -For spans to be connected together by an observability tool they need to be-part of a /trace/.+@+\$ burgerservice --telemetry=console+@ +to activate sending telemetry to, in this case, the console. Other exporters+add additional command-line options with which to configure how and where the+metrics will be sent.++= Traces and Spans+ At the top of your program or request loop you need to start a new trace (with 'beginTrace') or continue one inherited from another service (with 'usingTrace'):@@ -32,30 +60,52 @@ program :: 'Core.Program.Execute.Program' 'Core.Program.Execute.None' () program = do 'beginTrace' $ do- 'encloseSpan' \"Service Request\" $ do+ 'encloseSpan' \"Service request\" $ do -- do stuff!- + ... - -- add appropriate telemetry values to the span + obs <- currentSkyObservation+ temp <- currentAirTemperature++ ...++ -- add appropriate telemetry values to the span 'telemetry'- [ 'metric' \"colour\" currentSkyObservation- , 'metric' \"temperature" currentAirTemperature+ [ 'metric' \"sky_colour\" (colourFrom obs)+ , 'metric' \"temperature" temp ] @ -will result in @colour=\"Blue\"@ and @temperature=26.1@ or whatever being sent-by the telemetry system to the observability service that's been activated.+will result in @sky_colour=\"Blue\"@ and @temperature=26.1@ or whatever being+sent by the telemetry system to the observability service that's been+activated. The real magic here is that spans /nest/. As you go into each subcomponent on-your request path you can again call 'encloseSpan' creating a new span. Any-metrics added before entering the new span will be inherited by the subspan-and sent when it finishes so you don't have to keep re-attaching data if it's-common across all the spans in your trace.+your request path you can again call 'encloseSpan' creating a new span, which+can have its own telemetry: -/Events/+@+currentSkyObservation :: 'Core.Program.Execute.Program' 'Core.Program.Execute.None' Observation+currentSkyObservation = do+ 'encloseSpan' "Observe sky" $ do+ ... + 'telemetry'+ [ 'metric' \"radar_frequency\" freq+ , 'metric' \"cloud_cover\" blockageLevel+ ]++ 'pure' result+@++Any metrics added before entering the new span will be inherited by the+subspan and sent when it finishes so you don't have to keep re-attaching data+if it's common across all the spans in your trace.++= Events+ In other circumstances you will just want to send metrics: @@@ -245,7 +295,7 @@ This will allow you to then select the appropriate backend at runtime: @-$ burger-service --telemetry=console+\$ burgerservice --telemetry=console @ which will result in it spitting out metrics as it goes,@@ -422,11 +472,11 @@ @ program :: 'Core.Program.Execute.Program' 'Core.Program.Execute.None' () program = do- + -- do something that gets the trace ID trace <- ... - -- and somethign to get the parent span ID+ -- and something to get the parent span ID parent <- ... 'usingTrace' ('Trace' trace) ('Just' ('Span' span)) $ do@@ -514,17 +564,22 @@ Record telemetry about an event. Specify a label for the event and then whichever metrics you wish to record. + The emphasis of this package is to create traces and spans. There are, however, times when you just want to send telemetry about an event. You can-use 'sendEvent' to accomplush this.+use 'sendEvent' to accomplish this. -If you call 'sendEvent' within an enclosing span created with 'encloseSpan'+If you do call 'sendEvent' within an enclosing span created with 'encloseSpan' (the usual and expected use case) then this event will be \"linked\" to this span so that the observability tool can deisplay it attached to the span in the in which it occured. -Not every situation is in the context of traces and spans and so you can use-this to send arbitrary telemetry.+@+ sendEvent+ "Make tea"+ [ metric "sugar" False+ ]+@ -} sendEvent :: Label -> [MetricValue] -> Program τ () sendEvent label values = do