1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//! Structured instrumentation for Goldy.
//!
//! Provides named observation points with structured context data.
//! Zero-cost when the `instrumentation` feature is disabled.
//!
//! # Observation Points
//!
//! Goldy uses hierarchical dot-notation for observation point names:
//!
//! | Category | Point Name | Emitted Data |
//! |----------|------------|--------------|
//! | **Slang** | `slang.library.load` | `path`, `success` |
//! | | `slang.compile.start` | `target`, `entry_points`, `bindless` |
//! | | `slang.compile.end` | `duration_ms`, `output_size`, `success` |
//! | | `slang.reflection.extract` | `parameter_blocks`, `fields` |
//! | **Shader** | `shader.module.create` | `backend`, `shader_type` |
//! | | `shader.pipeline.create` | `pipeline_type`, `bind_groups` |
//! | **Resource** | `resource.buffer.create` | `size`, `usage` |
//! | | `resource.texture.create` | `dimensions`, `format` |
//! | | `resource.bind_group.create` | `bindings_count` |
//! | **Render** | `render.frame.start` | `frame_id` |
//! | | `render.compute.dispatch` | `workgroups`, `pipeline` |
//! | | `render.draw` | `vertices`, `instances` |
//! | | `render.frame.end` | `frame_id`, `duration_ms` |
//!
//! # Usage
//!
//! ```rust,ignore
//! use goldy::{goldy_span, goldy_event};
//!
//! fn render(&mut self) {
//! let _frame_span = goldy_span!("render.frame", frame_id = self.frame_count).entered();
//!
//! // ... rendering code ...
//!
//! goldy_event!("render.frame.end", frame_id = self.frame_count);
//! }
//! ```
//!
//! # Filtering
//!
//! Use environment variables to filter instrumentation output:
//! - `RUST_LOG=goldy=debug` - Enable all Goldy instrumentation
//! - `RUST_LOG=goldy::render=trace` - Enable only render-related points
pub use JsonFileLayer;
/// Target name for all Goldy instrumentation (enables filtering).
pub const TARGET: &str = "goldy";
/// Create a span for timing a section of code.
///
/// Spans automatically track entry/exit timing and support nested hierarchies.
///
/// # Example
///
/// ```rust,ignore
/// use goldy::goldy_span;
///
/// fn compile_shader(&self) {
/// let _span = goldy_span!("slang.compile", target = "metal").entered();
/// // ... compilation code ...
/// // Span automatically records duration when dropped
/// }
/// ```
;
}
/// No-op version when instrumentation is disabled.
;
}
/// Emit a structured event at an observation point.
///
/// Events are instantaneous markers with associated data.
///
/// # Example
///
/// ```rust,ignore
/// use goldy::goldy_event;
///
/// goldy_event!("slang.library.load",
/// path = %lib_path.display(),
/// success = true
/// );
/// ```
;
}
/// No-op version when instrumentation is disabled.
;
}
/// A no-op span guard that does nothing when instrumentation is disabled.
;
/// Install a JSON file logger for Goldy instrumentation.
///
/// This creates a tracing subscriber that writes structured JSON logs to the
/// specified file path. Only events targeting "goldy" are captured.
///
/// # Example
///
/// ```rust,ignore
/// use goldy::instrumentation::install_json_logger;
///
/// // At application startup
/// install_json_logger("/tmp/goldy-debug.json")?;
///
/// // Now all goldy_span!/goldy_event! calls will be logged to the file
/// ```
/// No-op version when instrumentation is disabled.