packages feed

zipkin (empty) → 0.1.0.0

raw patch · 6 files changed

+165/−0 lines, 6 filesdep +basedep +bytestringdep +mersenne-random-pure64setup-changed

Dependencies added: base, bytestring, mersenne-random-pure64, mtl, safe

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Sam Rijs++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Control/Monad/Zipkin.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module Control.Monad.Zipkin+  ( Identifier, parseIdentifier+  , TraceInfo(..), fromHeaders, toHeaders, newTraceInfo+  , TraceT, getTraceInfo, forkTraceInfo, runTraceT+  ) where++import Control.Monad.State.Strict+import System.Random.Mersenne.Pure64++import Data.Zipkin.Types+import qualified Data.Zipkin.Context as Ctx++newtype TraceT m a = TraceT { run :: StateT Ctx.TraceContext m a }+  deriving (Functor, Applicative, Monad, MonadTrans)++newTraceInfo :: IO TraceInfo+newTraceInfo = evalState Ctx.newTraceInfo <$> newPureMT++getTraceInfo :: Monad m => TraceT m TraceInfo+getTraceInfo = TraceT Ctx.getTraceInfo++forkTraceInfo :: Monad m => TraceT m TraceInfo+forkTraceInfo = TraceT Ctx.forkTraceInfo++runTraceT :: Monad m => TraceT m a -> TraceInfo -> m a+runTraceT m = evalStateT (run m) . Ctx.mkContext
+ src/Data/Zipkin/Context.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE FlexibleContexts #-}++module Data.Zipkin.Context where++import Data.Bits (xor)+import Control.Monad.State.Strict+import System.Random.Mersenne.Pure64++import Data.Zipkin.Types++data TraceContext = TraceContext+  { traceInfo :: TraceInfo+  , traceGen :: PureMT+  }++mkContext :: TraceInfo -> TraceContext+mkContext info = TraceContext+  { traceInfo = info+  , traceGen = pureMT $ hashTraceInfo info+  }++getTraceInfo :: MonadState TraceContext m => m TraceInfo+getTraceInfo = gets traceInfo++newTraceInfo :: MonadState PureMT m => m TraceInfo+newTraceInfo = do+  traceId <- Identifier <$> state randomWord64+  spanId <- Identifier <$> state randomWord64+  return $ TraceInfo traceId spanId Nothing++forkTraceInfo :: MonadState TraceContext m => m TraceInfo+forkTraceInfo = do+  (TraceContext info gen) <- get+  let (newId, gen') = randomWord64 gen+  put (TraceContext info gen')+  return $ TraceInfo (traceId info) (Identifier newId) (Just (spanId info))
+ src/Data/Zipkin/Types.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE OverloadedStrings #-}++module Data.Zipkin.Types where++import Data.Bits (xor)+import Data.ByteString (ByteString)+import Data.ByteString.Char8 (pack, unpack)+import Data.Maybe (maybeToList)+import Data.String (IsString)+import Data.Word (Word64)+import Numeric (showHex, readHex)+import Safe (readMay)+import System.Random.Mersenne.Pure64++newtype Identifier = Identifier { toWord64 :: Word64 }++instance Show Identifier where+  show (Identifier x) = let hex = showHex x "" in replicate (16 - length hex) '0' ++ hex++instance Read Identifier where+  readsPrec _ = fmap (fmap (\(x, s) -> (Identifier x, s))) readHex++parseIdentifier :: String -> Maybe Identifier+parseIdentifier = readMay++data TraceInfo = TraceInfo+  { traceId :: Identifier+  , spanId :: Identifier+  , parentSpanId :: Maybe Identifier+  }++hashTraceInfo :: TraceInfo -> Word64+hashTraceInfo (TraceInfo traceId spanId parentSpanId) = maybe h (xor h . toWord64) parentSpanId+  where h = toWord64 traceId `xor` toWord64 spanId++fromHeaders :: (Eq s, IsString s) => [(s, ByteString)] -> Maybe TraceInfo+fromHeaders hs = do+  traceId <- lookup "X-B3-TraceId" hs >>= parseIdentifier . unpack+  spanId <- lookup "X-B3-SpanId" hs >>= parseIdentifier . unpack+  let parentSpanId = lookup "X-B3-ParentSpanId" hs >>= parseIdentifier . unpack+  return $ TraceInfo traceId spanId parentSpanId++toHeaders :: IsString s => TraceInfo -> [(s, ByteString)]+toHeaders (TraceInfo traceId spanId parentSpanId) =+  [ Just ("X-B3-TraceId", pack (show traceId))+  , Just ("X-B3-SpanId", pack (show spanId))+  , (\x -> ("X-B3-ParentSpanId", pack (show x))) <$> parentSpanId+  ] >>= maybeToList
+ zipkin.cabal view
@@ -0,0 +1,31 @@+-- Initial trace-ids.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++name:                zipkin+version:             0.1.0.0+synopsis:            Zipkin-style request tracing monad+-- description:         +homepage:            https://github.com/srijs/haskell-zipkin+license:             MIT+license-file:        LICENSE+author:              Sam Rijs+maintainer:          srijs@airpost.net+-- copyright:           +category:            Network+build-type:          Simple+-- extra-source-files:  +cabal-version:       >=1.10++library+  exposed-modules:     Control.Monad.Zipkin+  other-modules:       Data.Zipkin.Context+                       Data.Zipkin.Types+  -- other-modules:       +  -- other-extensions:    +  build-depends:       base >=4.8 && <4.9,+                       bytestring >=0.10,+                       mersenne-random-pure64 >=0.2,+                       mtl >=2.2,+                       safe >=0.3+  hs-source-dirs:      src+  default-language:    Haskell2010