Skip to content

Commit dbdf486

Browse files
committed
More compact thread presentation for Tracy
1 parent 33cb217 commit dbdf486

File tree

7 files changed

+57
-35
lines changed

7 files changed

+57
-35
lines changed

.github/workflows/ci.yml

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ jobs:
1010
runs-on: ubuntu-latest
1111
strategy:
1212
matrix:
13-
ghc: ['8.6', '8.8', '8.10', '9.0']
13+
ghc: ['8.6', '8.8', '8.10']
14+
fail-fast: false
1415
steps:
1516
- uses: actions/[email protected]
1617
- uses: actions/[email protected]
@@ -48,6 +49,7 @@ jobs:
4849
strategy:
4950
matrix:
5051
stack-yaml: ['stack-8.10.yaml']
52+
fail-fast: false
5153
steps:
5254
- uses: actions/[email protected]
5355
- uses: actions/[email protected]
@@ -75,6 +77,7 @@ jobs:
7577
strategy:
7678
matrix:
7779
stack-yaml: ['stack-8.10.yaml']
80+
fail-fast: false
7881
steps:
7982
- uses: actions/[email protected]
8083
- uses: actions/[email protected]
@@ -101,7 +104,7 @@ jobs:
101104
runs-on: windows-latest
102105
strategy:
103106
matrix:
104-
ghc: ['8.10', '9.0.1']
107+
ghc: ['8.10']
105108
steps:
106109
- uses: actions/[email protected]
107110
- uses: actions/[email protected]

megaexample/Main.hs

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import Control.Concurrent
66
import Control.Concurrent.Async
7+
import Control.Monad
78
import qualified Data.ByteString.Char8 as BS
89
import qualified Data.ByteString.Lazy.Char8 as LBS
910
import Data.Function
@@ -85,8 +86,11 @@ microservice httpRequestCounter = \req respond -> withSpan "handle_http_request"
8586
respond $ Wai.responseLBS status200 [] result
8687
_ -> do
8788
bg_work <- async $ withSpan_ "background_task" do
88-
threadDelay 10000
89-
pure ()
89+
replicateM_ 3 $ do
90+
tasks <- forM [1..5] (\i ->
91+
async $ withSpan_ (BS.pack $ printf "task %d" (i :: Int)) $ threadDelay 10000)
92+
mapM_ wait tasks
93+
threadDelay 10000
9094
addEvent sp "message" "started bg work"
9195
rtsStats <- withSpan_ "getRTSStats" getRTSStats
9296
() <- wait bg_work

opentelemetry-extra/exe/eventlog-to-tracy/Main.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ main = do
3939
["-h"] -> help
4040
["--help"] -> help
4141
["help"] -> help
42-
[eventlogFile] -> work eventlogFile CollapseThreads
42+
[eventlogFile] -> work eventlogFile SplitThreads
4343
["--collapse-threads", eventlogFile] -> work eventlogFile CollapseThreads
4444
["--split-threads", eventlogFile] -> work eventlogFile SplitThreads
4545
_ -> help
4646

47-
work :: FilePath -> DoWeCollapseThreads -> IO ()
47+
work :: FilePath -> ThreadPresentation -> IO ()
4848
work inputFile doWeCollapseThreads = do
4949
let chromeFile = inputFile ++ ".trace.json"
5050
tracyFile = inputFile ++ ".tracy"

opentelemetry-extra/src/OpenTelemetry/ChromeExporter.hs

+13-14
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ module OpenTelemetry.ChromeExporter where
44

55
import Control.Monad
66
import qualified Data.ByteString as BS
7-
import qualified Data.ByteString.Lazy as LBS
87
import Data.Coerce
98
import Data.Function
109
import Data.HashMap.Strict as HM
@@ -42,7 +41,7 @@ jChromeBeginSpan Span {..} =
4241
[ ("ph", J.textString "B"),
4342
("name", J.textString spanOperation),
4443
("pid", J.intNumber 1),
45-
("tid", J.intNumber $ fromIntegral spanThreadId),
44+
("tid", J.intNumber $ fromIntegral spanDisplayThreadId),
4645
("ts", J.wordNumber . fromIntegral $ div spanStartedAt 1000),
4746
( "args",
4847
J.object
@@ -63,31 +62,31 @@ jChromeEndSpan Span {..} =
6362
[ ("ph", J.textString "E"),
6463
("name", J.textString spanOperation),
6564
("pid", J.intNumber 1),
66-
("tid", J.intNumber $ fromIntegral spanThreadId),
65+
("tid", J.intNumber $ fromIntegral spanDisplayThreadId),
6766
("ts", J.wordNumber . fromIntegral $ div spanFinishedAt 1000)
6867
]
6968

7069
createChromeExporter :: FilePath -> IO (Exporter Span, Exporter Metric)
7170
createChromeExporter path = createChromeExporter' path SplitThreads
7271

73-
createChromeExporter' :: FilePath -> DoWeCollapseThreads -> IO (Exporter Span, Exporter Metric)
74-
createChromeExporter' path doWeCollapseThreads = do
72+
createChromeExporter' :: FilePath -> ThreadPresentation -> IO (Exporter Span, Exporter Metric)
73+
createChromeExporter' path threadPresentation = do
7574
f <- openFile path WriteMode
7675
hPutStrLn f "[ "
77-
let modifyThreadId = case doWeCollapseThreads of
78-
CollapseThreads -> const 1
79-
SplitThreads -> id
76+
let modifyThreadId = case threadPresentation of
77+
CollapseThreads -> pure . const 1
78+
SplitThreads -> pure
8079
span_exporter =
8180
Exporter
8281
( \sps -> do
8382
mapM_
84-
( \sp -> do
85-
let sp' = sp {spanThreadId = modifyThreadId (spanThreadId sp)}
86-
let Span {spanThreadId, spanEvents} = sp'
83+
( \sp@(Span {spanEvents}) -> do
84+
tid' <- modifyThreadId (spanDisplayThreadId sp)
85+
let sp' = sp {spanDisplayThreadId = tid'}
8786
BS.hPutStr f $ J.toByteString $ jChromeBeginSpan sp'
8887
BS.hPutStr f ",\n"
8988
forM_ (sortOn spanEventTimestamp spanEvents) $ \ev -> do
90-
BS.hPutStr f $ J.toByteString $ jChromeEvent $ ChromeEvent (modifyThreadId spanThreadId) ev
89+
BS.hPutStr f $ J.toByteString $ jChromeEvent $ ChromeEvent tid' ev
9190
BS.hPutStr f ",\n"
9291
BS.hPutStr f $ J.toByteString $ jChromeEndSpan sp'
9392
BS.hPutStr f ",\n"
@@ -120,9 +119,9 @@ createChromeExporter' path doWeCollapseThreads = do
120119
(pure ())
121120
pure (span_exporter, metric_exporter)
122121

123-
data DoWeCollapseThreads = CollapseThreads | SplitThreads
122+
data ThreadPresentation = CollapseThreads | SplitThreads
124123

125-
eventlogToChrome :: FilePath -> FilePath -> DoWeCollapseThreads -> IO ()
124+
eventlogToChrome :: FilePath -> FilePath -> ThreadPresentation -> IO ()
126125
eventlogToChrome eventlogFile chromeFile doWeCollapseThreads = do
127126
(span_exporter, metric_exporter) <- createChromeExporter' chromeFile doWeCollapseThreads
128127
exportEventlog span_exporter metric_exporter eventlogFile

opentelemetry-extra/src/OpenTelemetry/Common.hs

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ data Span = Span
6464
{ spanContext :: {-# UNPACK #-} !SpanContext,
6565
spanOperation :: T.Text,
6666
spanThreadId :: Word32,
67+
spanDisplayThreadId :: Word32,
6768
spanStartedAt :: !Timestamp,
6869
spanFinishedAt :: !Timestamp,
6970
spanTags :: !(HM.HashMap TagName TagValue),

opentelemetry-extra/src/OpenTelemetry/EventlogStreaming_Internal.hs

+29-11
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ data WatDoOnEOF = StopOnEOF | SleepAndRetryOnEOF
3535

3636
data State = S
3737
{ originTimestamp :: !Timestamp,
38-
threadMap :: IM.IntMap ThreadId,
38+
cap2thread :: IM.IntMap ThreadId,
3939
spans :: HM.HashMap SpanId Span,
4040
instrumentMap :: HM.HashMap InstrumentId CaptureInstrument,
4141
traceMap :: HM.HashMap ThreadId TraceId,
4242
serial2sid :: HM.HashMap Word64 SpanId,
4343
thread2sid :: HM.HashMap ThreadId SpanId,
44+
thread2displayThread :: HM.HashMap ThreadId ThreadId, -- https://github.com/ethercrow/opentelemetry-haskell/issues/40
4445
gcRequestedAt :: !Timestamp,
4546
gcStartedAt :: !Timestamp,
4647
gcGeneration :: !Int,
@@ -52,7 +53,7 @@ data State = S
5253
deriving (Show)
5354

5455
initialState :: Word64 -> R.SMGen -> State
55-
initialState timestamp = S timestamp mempty mempty mempty mempty mempty mempty 0 0 0 0 0 0
56+
initialState timestamp = S timestamp mempty mempty mempty mempty mempty mempty mempty 0 0 0 0 0 0
5657

5758
data EventSource
5859
= EventLogHandle Handle WatDoOnEOF
@@ -142,9 +143,9 @@ parseOpenTelemetry UserBinaryMessage {payload} = parseByteString payload
142143
parseOpenTelemetry _ = Nothing
143144

144145
processEvent :: Event -> State -> (State, [Span], [Metric])
145-
processEvent (Event ts ev m_cap) st@(S {..}) =
146+
processEvent (Event ts ev m_cap) st@S {..} =
146147
let now = originTimestamp + ts
147-
m_thread_id = m_cap >>= flip IM.lookup threadMap
148+
m_thread_id = m_cap >>= flip IM.lookup cap2thread
148149
m_trace_id = m_thread_id >>= flip HM.lookup traceMap
149150
in case (ev, m_cap, m_thread_id) of
150151
(WallClockTime {sec, nsec}, _, _) ->
@@ -158,12 +159,13 @@ processEvent (Event ts ev m_cap) st@(S {..}) =
158159
[Metric threadsI [MetricDatapoint now 1]]
159160
)
160161
(RunThread tid, Just cap, _) ->
161-
(st {threadMap = IM.insert cap tid threadMap}, [], [])
162+
(st {cap2thread = IM.insert cap tid cap2thread}, [], [])
162163
(StopThread tid tstatus, Just cap, _)
163164
| isTerminalThreadStatus tstatus ->
164165
( st
165-
{ threadMap = IM.delete cap threadMap,
166-
traceMap = HM.delete tid traceMap
166+
{ cap2thread = IM.delete cap cap2thread,
167+
traceMap = HM.delete tid traceMap,
168+
thread2displayThread = HM.delete tid thread2displayThread
167169
},
168170
[],
169171
[Metric threadsI [MetricDatapoint now (-1)]]
@@ -187,6 +189,7 @@ processEvent (Event ts ev m_cap) st@(S {..}) =
187189
spanStartedAt = gcStartedAt,
188190
spanFinishedAt = now,
189191
spanThreadId = maxBound,
192+
spanDisplayThreadId = maxBound,
190193
spanTags = mempty,
191194
spanEvents = [],
192195
spanParentId = Nothing,
@@ -200,6 +203,7 @@ processEvent (Event ts ev m_cap) st@(S {..}) =
200203
spanStartedAt = gcRequestedAt,
201204
spanFinishedAt = gcStartedAt,
202205
spanThreadId = maxBound,
206+
spanDisplayThreadId = maxBound,
203207
spanTags = mempty,
204208
spanEvents = [],
205209
spanParentId = Nothing,
@@ -284,12 +288,14 @@ handleOpenTelemetryEventlogEvent m st (tid, now, m_trace_id) =
284288
case HM.lookup serial $ serial2sid st of
285289
Nothing ->
286290
let (st', span_id) = inventSpanId serial st
291+
(st'', display_tid) = inventDisplayTid tid st'
287292
parent = HM.lookup tid (thread2sid st)
288293
sp =
289294
Span
290295
{ spanContext = SpanContext span_id (fromMaybe (TId 42) m_trace_id),
291296
spanOperation = "",
292297
spanThreadId = tid,
298+
spanDisplayThreadId = display_tid,
293299
spanStartedAt = 0,
294300
spanFinishedAt = now,
295301
spanTags = mempty,
@@ -298,20 +304,23 @@ handleOpenTelemetryEventlogEvent m st (tid, now, m_trace_id) =
298304
spanNanosecondsSpentInGC = 0,
299305
spanParentId = parent
300306
}
301-
in (createSpan span_id sp st', [], [])
307+
in (createSpan span_id sp st'', [], [])
302308
Just span_id ->
303309
let (st', sp) = emitSpan serial span_id st
304-
in (st', [sp {spanFinishedAt = now}], [])
310+
(st'', display_tid) = inventDisplayTid tid st'
311+
in (st'', [sp {spanFinishedAt = now, spanDisplayThreadId = display_tid}], [])
305312
BeginSpanEv (SpanInFlight serial) (SpanName operation) ->
306313
case HM.lookup serial (serial2sid st) of
307314
Nothing ->
308315
let (st', span_id) = inventSpanId serial st
309316
parent = HM.lookup tid (thread2sid st)
317+
(st'', display_tid) = inventDisplayTid tid st'
310318
sp =
311319
Span
312320
{ spanContext = SpanContext span_id (fromMaybe (TId 42) m_trace_id),
313321
spanOperation = operation,
314322
spanThreadId = tid,
323+
spanDisplayThreadId = display_tid,
315324
spanStartedAt = now,
316325
spanFinishedAt = 0,
317326
spanTags = mempty,
@@ -320,10 +329,11 @@ handleOpenTelemetryEventlogEvent m st (tid, now, m_trace_id) =
320329
spanNanosecondsSpentInGC = 0,
321330
spanParentId = parent
322331
}
323-
in (createSpan span_id sp st', [], [])
332+
in (createSpan span_id sp st'', [], [])
324333
Just span_id ->
325334
let (st', sp) = emitSpan serial span_id st
326-
in (st', [sp {spanOperation = operation, spanStartedAt = now, spanThreadId = tid}], [])
335+
(st'', display_tid) = inventDisplayTid tid st'
336+
in (st'', [sp {spanOperation = operation, spanStartedAt = now, spanThreadId = tid, spanDisplayThreadId = display_tid}], [])
327337
DeclareInstrumentEv iType iId iName ->
328338
(st {instrumentMap = HM.insert iId (CaptureInstrument iType iName) (instrumentMap st)}, [], [])
329339
MetricCaptureEv instrumentId val -> case HM.lookup instrumentId (instrumentMap st) of
@@ -396,6 +406,14 @@ inventSpanId serial st = (st', sid)
396406
(SId -> sid, randomGen') = R.nextWord64 randomGen
397407
st' = st {serial2sid = HM.insert serial sid serial2sid, randomGen = randomGen'}
398408

409+
inventDisplayTid :: ThreadId -> State -> (State, ThreadId)
410+
inventDisplayTid tid st@(S {thread2displayThread}) =
411+
case HM.lookup tid thread2displayThread of
412+
Nothing ->
413+
let new_dtid = fromIntegral (HM.size thread2displayThread)
414+
in (st {thread2displayThread = HM.insert tid new_dtid thread2displayThread}, new_dtid)
415+
Just dtid -> (st, dtid)
416+
399417
parseText :: [T.Text] -> Maybe OpenTelemetryEventlogEvent
400418
parseText =
401419
\case

stack-8.10.yaml

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
resolver: nightly-2021-01-05
1+
resolver: nightly-2021-04-02
22

33
packages:
44
- megaexample
@@ -10,8 +10,5 @@ packages:
1010
allow-newer: true
1111

1212
extra-deps:
13-
- ghc-events-0.13.0
14-
- ghc-trace-events-0.1.0.1
15-
- hvega-0.9.1.0
1613
- jsonifier-0.1.0.5
1714
- ptr-poker-0.1.1.3

0 commit comments

Comments
 (0)