{-# language FlexibleInstances #-} {-# language MultiParamTypeClasses #-} {-# language OverloadedStrings #-} {-# language PolyKinds #-} {-# language UndecidableInstances #-} {-# language ViewPatterns #-} {-| Description : Distributed tracing for Mu This module injects distributed tracing for Mu servers. Currently it only supports Zipkin as backend. In order to use this module, you need to follow these steps: 1. Establish a connection with 'newZipkin'. 2. Wrap the server using 'zipkin', giving information for the root. 3. Run the server using the transformer version of your protocol, like |grpcAppTrans|. -} module Mu.Instrumentation.Tracing ( -- * Distributed tracing MuTracing(..) , zipkin , runZipkin -- ** Establish connection , newZipkin , defaultZipkinSettings , Settings(..) -- * Useful re-exports , module Monitor.Tracing ) where import Control.Applicative ((<|>)) import Control.Monad.IO.Class import Control.Monad.Trace import Control.Monad.Trace.Class import qualified Data.Map.Strict as M import Data.Text import Monitor.Tracing import Monitor.Tracing.Zipkin import Mu.Rpc import Mu.Server data MuTracing = MuTracing { samplingPolicy :: SamplingPolicy , rootName :: Text } -- | Runs with a given 'Zipkin' connection. -- You can create one with 'newZipkin'. runZipkin :: Zipkin -> TraceT m a -> m a runZipkin = flip run -- | Create a new connection to 'Zipkin'. newZipkin :: Settings -> IO Zipkin newZipkin = new defaultZipkinSettings :: Settings defaultZipkinSettings = defaultSettings -- | Wraps a server to do distributed tracing -- using 'Zipkin' as backend. zipkin :: (MonadIO m, MonadTrace m) => MuTracing -> ServerT chn i p m topHs -> ServerT chn i p m topHs zipkin m = wrapServer (zipkinTracing m) zipkinTracing :: (MonadIO m, MonadTrace m) => MuTracing -> RpcInfo i -> m a -> m a zipkinTracing zpk NoRpcInfo h = rootSpan (samplingPolicy zpk) (rootName zpk) h zipkinTracing zpk (RpcInfo _ _ _ (M.fromList -> hdrs) _) h = case getB3 of Nothing -> rootSpan (samplingPolicy zpk) (rootName zpk) h Just spn -> serverSpan spn h where getB3 = (b3FromHeaderValue =<< M.lookup "b3" hdrs) <|> b3FromHeaders hdrs