| Copyright | Copyright 2022 Shea Levy. |
|---|---|
| License | Apache-2.0 |
| Maintainer | shea@shealevy.com |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Observe.Event.Backend
Description
This is the primary module needed to write new EventBackends.
Synopsis
- newtype EventBackend m r s = EventBackend {}
- data Event m r f = Event {
- reference :: !r
- addField :: !(f -> m ())
- addReference :: !(Reference r -> m ())
- finalize :: !(Maybe SomeException -> m ())
- data Reference r = Reference !ReferenceType !r
- data ReferenceType
- unitEventBackend :: Applicative m => EventBackend m () s
- pairEventBackend :: Applicative m => EventBackend m a s -> EventBackend m b s -> EventBackend m (a, b) s
- noopEventBackend :: Applicative m => r -> EventBackend m r s
- hoistEventBackend :: Functor m => (forall x. m x -> n x) -> EventBackend m r s -> EventBackend n r s
- hoistEvent :: (forall x. m x -> n x) -> Event m r f -> Event n r f
- type InjectSelector s t = forall f. s f -> forall a. (forall g. t g -> (f -> g) -> a) -> a
- injectSelector :: (forall f. s f -> t f) -> InjectSelector s t
- idInjectSelector :: InjectSelector s s
- narrowEventBackend :: Functor m => InjectSelector s t -> EventBackend m r t -> EventBackend m r s
- setDefaultReferenceEventBackend :: PrimMonad m => Reference r -> EventBackend m r s -> EventBackend m r s
- setAncestorEventBackend :: PrimMonad m => r -> EventBackend m r s -> EventBackend m r s
- setInitialCauseEventBackend :: PrimMonad m => r -> EventBackend m r s -> EventBackend m r s
- setReferenceEventBackend :: Monad m => Reference r -> EventBackend m r s -> EventBackend m r s
- setParentEventBackend :: Monad m => r -> EventBackend m r s -> EventBackend m r s
- setProximateEventBackend :: Monad m => r -> EventBackend m r s -> EventBackend m r s
Core interface
newtype EventBackend m r s Source #
A backend for creating Events.
Different EventBackends will be used to emit instrumentation to
different systems. Multiple backends can be combined with
pairEventBackend.
A simple EventBackend for logging to a Handle can be
created with jsonHandleBackend.
Typically the entrypoint for some eventuo11y-instrumented code will
take an EventBackend, polymorphic in r and possibly m. Calling
code can use subEventBackend to place the resulting
events in its hierarchy.
From an EventBackend, new events can be created via selectors
(of type s f for some field type f), typically with the
resource-safe allocation functions.
Selectors are values which designate the general category of event
being created, as well as the type of fields that can be added to it.
For example, a web service's selector type may have a ServicingRequest
constructor, whose field type includes a ResponseCode constructor which
records the HTTP status code.
Selectors are intended to be of a domain specific type per unit of functionality within an instrumented codebase, implemented as a GADT (but see DynamicEventSelector for a generic option).
Implementations must ensure that EventBackends and their underlying Events
are safe to use across threads.
m- The monad we're instrumenting in.
r- The type of event references used in this
EventBackend. Seereference. s- The type of event selectors. See
newEvent.
Constructors
| EventBackend | |
Fields
| |
An instrumentation event.
Events are the core of the instrumenting user's interface
to eventuo11y. Typical usage would be to create an Event
using withEvent and add fields to the Event at appropriate
points in your code with addField.
Constructors
| Event | |
Fields
| |
data ReferenceType Source #
Instances
| Eq ReferenceType Source # | |
Defined in Observe.Event.Backend Methods (==) :: ReferenceType -> ReferenceType -> Bool # (/=) :: ReferenceType -> ReferenceType -> Bool # | |
Backend composition
unitEventBackend :: Applicative m => EventBackend m () s Source #
A no-op EventBackend.
This can be used if calling instrumented code from an un-instrumented context, or to purposefully ignore instrumentation from some call.
unitEventBackend is the algebraic unit of pairEventBackend.
pairEventBackend :: Applicative m => EventBackend m a s -> EventBackend m b s -> EventBackend m (a, b) s Source #
An EventBackend which sequentially generates Events in the two given EventBackends.
This can be used to emit instrumentation in multiple ways (e.g. logs to grafana and metrics on a prometheus HTML page).
noopEventBackend :: Applicative m => r -> EventBackend m r s Source #
A no-op EventBackend that can be integrated with other backends.
This can be used to purposefully ignore instrumentation from some call.
All events will have the given reference, so can be connected to appropriate events in non-no-op backends, but not in a way that can distinguish between different events from the same no-op backend.
Backend transformation
hoistEventBackend :: Functor m => (forall x. m x -> n x) -> EventBackend m r s -> EventBackend n r s Source #
Hoist an EventBackend along a given natural transformation into a new monad.
hoistEvent :: (forall x. m x -> n x) -> Event m r f -> Event n r f Source #
Hoist an Event along a given natural transformation into a new monad.
type InjectSelector s t = forall f. s f -> forall a. (forall g. t g -> (f -> g) -> a) -> a Source #
Inject a narrower selector and its fields into a wider selector.
See injectSelector for a simple way to construct one of these.
injectSelector :: (forall f. s f -> t f) -> InjectSelector s t Source #
Construct an InjectSelector with a straightforward injection from s to t
idInjectSelector :: InjectSelector s s Source #
The identity InjectSelector
narrowEventBackend :: Functor m => InjectSelector s t -> EventBackend m r t -> EventBackend m r s Source #
Narrow an EventBackend to a new selector type via a given injection function.
A typical usage, where component A calls component B, would be to have A's selector
type have a constructor to take any value of B's selector type (and preserve the field)
and then call narrowEventBackend with that constructor when invoking functions in B.
setDefaultReferenceEventBackend :: PrimMonad m => Reference r -> EventBackend m r s -> EventBackend m r s Source #
Transform an EventBackend so all of its Events have a given Reference, if they
haven't been given a Reference of the same ReferenceType by the time they are finalized.
See setReferenceEventBackend if the Reference should be applied unconditionally.
setAncestorEventBackend :: PrimMonad m => r -> EventBackend m r s -> EventBackend m r s Source #
Transform an EventBackend so all of its Events have a given parent, if they
are not given another parent by the time they are finalized.
See setParentEventBackend if the parent should be set unconditionally.
setInitialCauseEventBackend :: PrimMonad m => r -> EventBackend m r s -> EventBackend m r s Source #
Transform an EventBackend so all of its Events have a given proximate cause,
if they are not given another proximate cause by the time they are finalized.
See setProximateEventBackend if the proximate cause should be set unconditionally.
setReferenceEventBackend :: Monad m => Reference r -> EventBackend m r s -> EventBackend m r s Source #
Transform an EventBackend so all of its Events have a given Reference.
You likely want setDefaultReferenceEventBackend, if your monad supports it.
setParentEventBackend :: Monad m => r -> EventBackend m r s -> EventBackend m r s Source #
Transform an EventBackend so all of its Events have a given parent.
You likely want setAncestorEventBackend, if your monad supports it.
setProximateEventBackend :: Monad m => r -> EventBackend m r s -> EventBackend m r s Source #
Transform an EventBackend so all of its Events have a given proximate cause.
You likely want setInitialCauseEventBackend, if your monad supports it.