module OpenTelemetry.Exporter.InMemory
( inMemoryChannelExporter
, inMemoryListExporter
, module Control.Concurrent.Chan.Unagi
) where
import Control.Concurrent.Async
import Control.Concurrent.Chan.Unagi
import Control.Monad.IO.Class
import Data.IORef
import OpenTelemetry.Trace.Core
import OpenTelemetry.Processor
-- | Access exported spans via a concurrently accessible channel that produces spans.
-- The spans are exported in the order that the spans end.
inMemoryChannelExporter :: MonadIO m => m (Processor, OutChan ImmutableSpan)
inMemoryChannelExporter = liftIO $ do
(inChan, outChan) <- newChan
let processor = Processor
{ processorOnStart = \_ _ -> pure ()
, processorOnEnd = \ref -> do
writeChan inChan =<< readIORef ref
, processorShutdown = do
async $ pure ShutdownSuccess
, processorForceFlush = pure ()
}
pure (processor, outChan)
-- | Access exported spans via a mutable reference to a list of spans. The spans
-- are not guaranteed to be exported in a particular order.
inMemoryListExporter :: MonadIO m => m (Processor, IORef [ImmutableSpan])
inMemoryListExporter = liftIO $ do
listRef <- newIORef []
let processor = Processor
{ processorOnStart = \_ _ -> pure ()
, processorOnEnd = \ref -> do
s <- readIORef ref
atomicModifyIORef listRef (\l -> (s : l, ()))
, processorShutdown = do
async $ pure ShutdownSuccess
, processorForceFlush = pure ()
}
pure (processor, listRef)