Skip to content

Commit 464601d

Browse files
authored
Add render/show_logs to chrome_trace (#540)
1 parent 8d59e9f commit 464601d

File tree

6 files changed

+81
-1
lines changed

6 files changed

+81
-1
lines changed

Diff for: Project.toml

+3
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,19 @@ julia = "1.8"
4646
[extensions]
4747
GraphVizExt = "GraphViz"
4848
GraphVizSimpleExt = "Colors"
49+
JSON3Ext = "JSON3"
4950
PlotsExt = ["DataFrames", "Plots"]
5051

5152
[extras]
5253
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
5354
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
5455
GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0"
56+
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
5557
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
5658

5759
[weakdeps]
5860
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
5961
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
6062
GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0"
63+
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
6164
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

Diff for: docs/src/logging-visualization.md

+4
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ and `render_logs` take not a `Val` but a raw `Symbol`, which will be internally
1717
converted to a `Val` for dispatch purposes
1818
(i.e. `render_logs(logs::Dict, :myrenderer)` -> `render_logs(logs, Val{:myrenderer}())`).
1919

20+
Built-in `IO` support exists for:
21+
- `show_logs(io, logs, :chrome_trace)` to write a task execution timeline in the chrome-trace format (view in [perfetto web UI](https://ui.perfetto.dev/) or `about:tracing` in a chrome-based browser)
22+
2023
Built-in rendering support exists for:
2124
- `render_logs(logs, :graphviz)` to generate a graph diagram of executed tasks and their dependencies
2225
- `render_logs(logs, :plots_gantt)` to generate a Gantt chart of task execution across all processors
26+
- `render_logs(logs, :chrome_trace)` to generate a `String` with chrome-trace formatted task execution timeline
2327

2428
The latter (`MultiEventLog`) allows for continuously rendering logs as they're
2529
generated, permitting real-time visualization of Dagger's operations. This

Diff for: ext/JSON3Ext.jl

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
module JSON3Ext
2+
3+
if isdefined(Base, :get_extension)
4+
using JSON3
5+
else
6+
using ..JSON3
7+
end
8+
9+
using Dagger
10+
11+
function logs_to_chrome_trace(logs::Dict)
12+
execution_logs = Dict{Int,Any}()
13+
add_unknown_procs_metadata = false
14+
Dagger.logs_event_pairs(logs) do w, start_idx, finish_idx
15+
category = logs[w][:core][start_idx].category
16+
if category == :compute
17+
tid = logs[w][:id][start_idx].thunk_id # thunk id
18+
if !haskey(execution_logs, tid)
19+
execution_logs[tid] = Dict{Symbol,Any}()
20+
end
21+
t_start = logs[w][:core][start_idx].timestamp / 1e3 # us
22+
t_stop = logs[w][:core][finish_idx].timestamp / 1e3 # us
23+
proc = logs[w][:id][start_idx].processor
24+
execution_logs[tid][:ts] = t_start
25+
execution_logs[tid][:dur] = t_stop - t_start
26+
if proc isa Dagger.ThreadProc
27+
execution_logs[tid][:pid] = proc.owner
28+
execution_logs[tid][:tid] = proc.tid # thread id
29+
else
30+
@warn "Compute event for [$tid] executed on non-Dagger.ThreadProc processor. Assigning unknown pid and tid"
31+
execution_logs[tid][:pid] = -1
32+
execution_logs[tid][:tid] = -1
33+
add_unknown_procs_metadata = true
34+
end
35+
elseif category == :add_thunk
36+
tid = logs[w][:id][start_idx].thunk_id
37+
if !haskey(execution_logs, tid)
38+
execution_logs[tid] = Dict{Symbol,Any}()
39+
end
40+
taskname = logs[w][:tasknames][start_idx]
41+
fname = first(split(taskname, ' '))
42+
execution_logs[tid][:name] = fname
43+
end
44+
end
45+
events = Vector{Dict{Symbol,Any}}()
46+
for (_, v) in execution_logs
47+
v[:ph] = "X"
48+
v[:cat] = "compute"
49+
push!(events, v)
50+
end
51+
if add_unknown_procs_metadata
52+
push!(events, Dict(:name => "process_name", :ph => "M", :cat => "__metadata", :pid => -1, :args => Dict(:name => "Unknown")))
53+
push!(events, Dict(:name => "thread_name", :ph => "M", :cat => "__metadata", :pid => -1, :tid => -1, :args => Dict(:name => "Unknown")))
54+
end
55+
return Dict(:traceEvents => events)
56+
end
57+
58+
function Dagger.render_logs(logs::Dict, ::Val{:chrome_trace})
59+
return JSON3.write(logs_to_chrome_trace(logs))
60+
end
61+
62+
function Dagger.show_logs(io::IO, logs::Dict, ::Val{:chrome_trace})
63+
JSON3.write(io, logs_to_chrome_trace(logs))
64+
end
65+
66+
end # module JSON3Ext

Diff for: src/Dagger.jl

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ function __init__()
115115
# Gantt chart HTTP server
116116
include("ui/gantt-mux.jl")
117117
end
118+
@require JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" begin
119+
include(joinpath(dirname(@__DIR__), "ext", "JSON3Ext.jl"))
120+
end
118121
end
119122
# TODO: Move to Pkg extensions
120123
@require ProfileSVG="132c30aa-f267-4189-9183-c8a63c7e05e6" begin

Diff for: test/Project.toml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
55
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
66
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
77
GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0"
8+
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
89
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
910
MemPool = "f9f48841-c794-520a-933b-121f7ba6ed94"
1011
OnlineStats = "a15396b6-48d5-5d58-9928-6d29437db91e"

Diff for: test/logging.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import TimespanLogging
22
import TimespanLogging: Timespan, Event, Events, LocalEventLog, MultiEventLog
3-
import Colors, GraphViz, DataFrames, Plots
3+
import Colors, GraphViz, DataFrames, Plots, JSON3
44

55
@testset "Logging" begin
66
@testset "LocalEventLog" begin
@@ -180,6 +180,9 @@ import Colors, GraphViz, DataFrames, Plots
180180
# PlotsExt
181181
@test Dagger.render_logs(logs, :plots_gantt) !== nothing
182182

183+
# JSON3Ext
184+
@test Dagger.render_logs(logs, :chrome_trace) !== nothing
185+
183186
Dagger.disable_logging!()
184187
end
185188
end

0 commit comments

Comments
 (0)