Skip to content
This repository was archived by the owner on Oct 19, 2024. It is now read-only.

Commit 09820af

Browse files
authored
Distributed tracing (#206)
1 parent 2e60f4d commit 09820af

File tree

22 files changed

+565
-135
lines changed

22 files changed

+565
-135
lines changed

cabal.project

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ packages: compendium-client/
1717
grpc/client/
1818
grpc/server/
1919
graphql/
20-
instrumentation/prometheus
20+
instrumentation/prometheus/
21+
instrumentation/tracing/
2122

2223
source-repository-package
2324
type: git

core/rpc/mu-rpc.cabal

+2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ library
3030
build-depends:
3131
base >=4.12 && <5
3232
, conduit >=1.3.2 && <1.4
33+
, http-types >=0.12 && <0.13
3334
, mtl >=2.2 && <2.3
3435
, mu-schema ==0.3.*
3536
, sop-core >=0.5 && <0.6
3637
, template-haskell >=2.14 && <2.16
3738
, text >=1.2 && <1.3
39+
, wai >=3.2 && <4
3840

3941
hs-source-dirs: src
4042
default-language: Haskell2010

core/rpc/src/Mu/Rpc.hs

+10-8
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ module Mu.Rpc (
2828
) where
2929

3030
import Data.Kind
31-
import Data.Text (Text)
32-
import qualified Data.Text as T
31+
import Data.Text (Text)
32+
import qualified Data.Text as T
3333
import GHC.TypeLits
34-
import qualified Language.Haskell.TH as TH
34+
import qualified Language.Haskell.TH as TH
35+
import Network.HTTP.Types.Header
3536
import Type.Reflection
3637

3738
import Mu.Schema
@@ -136,6 +137,7 @@ data RpcInfo i
136137
| RpcInfo { packageInfo :: Package Text Text Text TyInfo
137138
, serviceInfo :: Service Text Text Text TyInfo
138139
, methodInfo :: Method Text Text Text TyInfo
140+
, headers :: RequestHeaders
139141
, extraInfo :: i
140142
}
141143

@@ -148,13 +150,13 @@ data TyInfo
148150
instance Show (RpcInfo i) where
149151
show NoRpcInfo
150152
= "<no info>"
151-
show (RpcInfo (Package Nothing _) (Service s _) (Method m _ _) _)
153+
show (RpcInfo (Package Nothing _) (Service s _) (Method m _ _) _ _)
152154
= T.unpack (s <> ":" <> m)
153-
show (RpcInfo (Package (Just p) _) (Service s _) (Method m _ _) _)
155+
show (RpcInfo (Package (Just p) _) (Service s _) (Method m _ _) _ _)
154156
= T.unpack (p <> ":" <> s <> ":" <> m)
155157

156158
class ReflectRpcInfo (p :: Package') (s :: Service') (m :: Method') where
157-
reflectRpcInfo :: Proxy p -> Proxy s -> Proxy m -> i -> RpcInfo i
159+
reflectRpcInfo :: Proxy p -> Proxy s -> Proxy m -> RequestHeaders -> i -> RpcInfo i
158160
class ReflectService (s :: Service') where
159161
reflectService :: Proxy s -> Service Text Text Text TyInfo
160162
class ReflectMethod (m :: Method') where
@@ -199,10 +201,10 @@ instance (ReflectArg m, ReflectArgs ms)
199201

200202
instance (KnownMaySymbol pname, ReflectServices ss, ReflectService s, ReflectMethod m)
201203
=> ReflectRpcInfo ('Package pname ss) s m where
202-
reflectRpcInfo _ ps pm
204+
reflectRpcInfo _ ps pm req extra
203205
= RpcInfo (Package (maySymbolVal (Proxy @pname))
204206
(reflectServices (Proxy @ss)))
205-
(reflectService ps) (reflectMethod pm)
207+
(reflectService ps) (reflectMethod pm) req extra
206208

207209
instance (KnownSymbol sname, ReflectMethods ms)
208210
=> ReflectService ('Service sname ms) where

default.nix

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
let
2-
haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/9d491b5.tar.gz) {};
2+
haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/d3edb6e.tar.gz) {};
33
nixpkgsSrc = haskellNix.sources.nixpkgs-2003;
44
nixpkgsArgs = haskellNix.nixpkgsArgs;
55
in
@@ -31,4 +31,5 @@ in {
3131
mu-protobuf = hnPkgs.mu-protobuf.components.all;
3232
mu-rpc = hnPkgs.mu-rpc.components.library;
3333
mu-schema = hnPkgs.mu-schema.components.library;
34+
mu-tracing = hnPkgs.mu-tracing.components.library;
3435
}

examples/health-check/mu-example-health-check.cabal

+3
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@ executable health-server
3131
, mu-protobuf >=0.4.0
3232
, mu-rpc >=0.4.0
3333
, mu-schema >=0.3.0
34+
, mu-tracing >=0.4.0
35+
, prometheus-client >= 1 && <2
3436
, stm >=2.5 && <3
3537
, stm-conduit >=4 && <5
3638
, stm-containers >=1.1 && <2
3739
, text >=1.2 && <2
40+
, tracing-control >=0.0.6
3841
, wai >=3.2 && <4
3942
, warp >=3.3 && <4
4043

examples/health-check/src/Server.hs

+43-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{-# language DataKinds #-}
2+
{-# language FlexibleContexts #-}
23
{-# language OverloadedStrings #-}
34
{-# language PartialTypeSignatures #-}
5+
{-# language PolyKinds #-}
46
{-# language TypeApplications #-}
57
{-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
68

@@ -9,34 +11,48 @@ module Main where
911
import Control.Concurrent.Async
1012
import Control.Concurrent.STM
1113
import Control.Monad.IO.Class
14+
import Control.Monad.Trace
1215
import Data.Conduit
1316
import qualified Data.Conduit.Combinators as C
1417
import Data.Conduit.TMChan
1518
import Data.Maybe (fromMaybe)
1619
import Data.Proxy
1720
import qualified Data.Text as T
1821
import DeferredFolds.UnfoldlM
22+
import Monitor.Tracing.Zipkin (Endpoint (..))
1923
import Network.Wai.Handler.Warp
24+
import Prometheus
2025
import qualified StmContainers.Map as M
2126

2227
import Mu.GraphQL.Server
2328
import Mu.GRpc.Server
2429
import Mu.Instrumentation.Prometheus
30+
import Mu.Instrumentation.Tracing
2531
import Mu.Server
2632

2733
import Definition
2834

2935
main :: IO ()
3036
main = do
37+
-- Initialize prometheus
38+
met <- initPrometheus "health"
39+
-- Initialize zipkin
40+
zpk <- newZipkin defaultZipkinSettings
41+
{ settingsPublishPeriod = Just 1
42+
, settingsEndpoint = Just $ Endpoint (Just "me") Nothing Nothing Nothing }
43+
let rootInfo = MuTracing alwaysSampled "health-check"
44+
-- Initialize app
3145
m <- M.newIO
3246
upd <- newTBMChanIO 100
33-
met <- initPrometheus "health"
47+
-- Put together the server
48+
let s = zipkin rootInfo $ prometheus met $ server m upd
49+
-- Run the app
3450
putStrLn "running health check application"
35-
let s = prometheus met (server m upd)
3651
runConcurrently $ (\_ _ _ -> ())
37-
<$> Concurrently (runner 50051 (gRpcApp msgProtoBuf s))
38-
<*> Concurrently (runner 50052 (gRpcApp msgAvro s))
39-
<*> Concurrently (runner 50053 (graphQLAppQuery s (Proxy @"HealthCheckServiceFS2")))
52+
<$> Concurrently (runner 50051 (gRpcAppTrans msgProtoBuf (runZipkin zpk) s))
53+
<*> Concurrently (runner 50052 (gRpcAppTrans msgAvro (runZipkin zpk) s))
54+
<*> Concurrently (runner 50053 (graphQLAppTransQuery (runZipkin zpk) s
55+
(Proxy @"HealthCheckServiceFS2")))
4056
where runner p app = run p (prometheusWai ["metrics"] app)
4157

4258
-- Server implementation
@@ -45,7 +61,9 @@ main = do
4561
type StatusMap = M.Map T.Text T.Text
4662
type StatusUpdates = TBMChan HealthStatusMsg
4763

48-
server :: StatusMap -> StatusUpdates -> ServerIO info HealthCheckService _
64+
server :: (MonadServer m, MonadTrace m)
65+
=> StatusMap -> StatusUpdates
66+
-> ServerT '[] info HealthCheckService m _
4967
server m upd
5068
= wrapServer (\info h -> liftIO (print info) >> h) $
5169
singleService ( method @"setStatus" $ setStatus_ m upd
@@ -55,30 +73,36 @@ server m upd
5573
, method @"cleanAll" $ cleanAll_ m
5674
, method @"watch" $ watch_ upd)
5775

58-
setStatus_ :: StatusMap -> StatusUpdates -> HealthStatusMsg -> ServerErrorIO ()
76+
setStatus_ :: (MonadServer m, MonadTrace m)
77+
=> StatusMap -> StatusUpdates -> HealthStatusMsg
78+
-> m ()
5979
setStatus_ m upd
6080
s@(HealthStatusMsg (Just (HealthCheckMsg nm)) (Just (ServerStatusMsg ss)))
61-
= alwaysOk $ do
81+
= childSpan "setStatus" $ alwaysOk $ do
6282
putStr "setStatus: " >> print (nm, ss)
6383
atomically $ do
6484
M.insert ss nm m
6585
writeTBMChan upd s
6686
setStatus_ _ _ _ = serverError (ServerError Invalid "name or status missing")
6787

68-
checkH_ :: StatusMap -> HealthCheckMsg -> ServerErrorIO ServerStatusMsg
88+
checkH_ :: (MonadServer m, MonadTrace m)
89+
=> StatusMap -> HealthCheckMsg
90+
-> m ServerStatusMsg
6991
checkH_ _ (HealthCheckMsg "") = serverError (ServerError Invalid "no server name given")
7092
checkH_ m (HealthCheckMsg nm) = alwaysOk $ do
7193
putStr "check: " >> print nm
7294
ss <- atomically $ M.lookup nm m
7395
pure $ ServerStatusMsg (fromMaybe "" ss)
7496

75-
clearStatus_ :: StatusMap -> HealthCheckMsg -> ServerErrorIO ()
97+
clearStatus_ :: (MonadServer m, MonadTrace m)
98+
=> StatusMap -> HealthCheckMsg -> m ()
7699
clearStatus_ _ (HealthCheckMsg "") = serverError (ServerError Invalid "no server name given")
77100
clearStatus_ m (HealthCheckMsg nm) = alwaysOk $ do
78101
putStr "clearStatus: " >> print nm
79102
atomically $ M.delete nm m
80103

81-
checkAll_ :: StatusMap -> ServerErrorIO AllStatusMsg
104+
checkAll_ :: (MonadServer m, MonadTrace m)
105+
=> StatusMap -> m AllStatusMsg
82106
checkAll_ m = alwaysOk $ do
83107
putStrLn "checkAll"
84108
AllStatusMsg <$> atomically (consumeValues kvToStatus (M.unfoldlM m))
@@ -87,15 +111,17 @@ checkAll_ m = alwaysOk $ do
87111
consumeValues f = foldlM' (\xs (x,y) -> pure (f x y:xs)) []
88112
kvToStatus k v = HealthStatusMsg (Just (HealthCheckMsg k)) (Just (ServerStatusMsg v))
89113

90-
cleanAll_ :: StatusMap -> ServerErrorIO ()
114+
cleanAll_ :: (MonadServer m, MonadTrace m)
115+
=> StatusMap -> m ()
91116
cleanAll_ m = alwaysOk $ do
92117
putStrLn "cleanAll"
93118
atomically $ M.reset m
94119

95-
watch_ :: StatusUpdates
120+
watch_ :: (MonadServer m, MonadTrace m)
121+
=> StatusUpdates
96122
-> HealthCheckMsg
97-
-> ConduitT ServerStatusMsg Void ServerErrorIO ()
98-
-> ServerErrorIO ()
123+
-> ConduitT ServerStatusMsg Void m ()
124+
-> m ()
99125
watch_ upd hcm@(HealthCheckMsg nm) sink = do
100126
alwaysOk (putStr "watch: " >> print nm)
101127
runConduit $ sourceTBMChan upd
@@ -109,3 +135,5 @@ watch_ upd hcm@(HealthCheckMsg nm) sink = do
109135
Just (Just y) -> yield y >> catMaybesC
110136
Just Nothing -> catMaybesC
111137
Nothing -> pure ()
138+
139+
instance MonadMonitor m => MonadMonitor (TraceT m)

0 commit comments

Comments
 (0)