Skip to content

Commit 0ca923b

Browse files
authored
Merge branch 'main' into manual-pipeline-trigger
2 parents 7143063 + 00d226e commit 0ca923b

105 files changed

Lines changed: 6012 additions & 5395 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/audit.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: Security audit
22
on:
33
push:
44
paths:
5+
- '.github/workflows/audit.yml'
56
- '**/Cargo.toml'
67
- '**/Cargo.lock'
78
schedule:
@@ -10,6 +11,7 @@ on:
1011
permissions:
1112
checks: write
1213
contents: read
14+
issues: write
1315

1416
jobs:
1517
security_audit:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ target/
77
.agents/skills/
88
.claude/
99
.zed/
10+
.progress/

Cargo.lock

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ repository = "https://github.com/dial9-rs/dial9-tokio-telemetry"
2222

2323
[workspace.dependencies]
2424
libc = "0.2"
25-
dial9-perf-self-profile = { version = "0.4.3", path = "perf-self-profile" }
25+
dial9-perf-self-profile = { version = "0.4.4", path = "perf-self-profile" }
2626
dial9-trace-format = { version = "0.4.1", path = "dial9-trace-format" }
2727
dial9-trace-format-derive = { version = "0.4.1", path = "dial9-trace-format-derive" }
2828
dial9-macro = { version = "0.3.7", path = "dial9-macro" }

dial9-macro/src/lib.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ struct MainArgs {
1616
const MISSING_CONFIG_HELP: &str = "missing required `config` argument, e.g.\n \
1717
#[dial9_tokio_telemetry::main(config = my_config_fn)]\n\
1818
or with an inline closure:\n \
19-
#[dial9_tokio_telemetry::main(config = || Dial9Config::builder().base_path(...).max_total_size(...).build().unwrap())]";
19+
#[dial9_tokio_telemetry::main(config = || Dial9Config::builder().on_disk_buffer(...).max_total_size(...).build().unwrap())]";
2020

2121
const CONFIG_MUST_BE_ZERO_ARG_HELP: &str = "`config` must be a zero-argument function path or a zero-argument closure, e.g.\n \
2222
#[dial9_tokio_telemetry::main(config = my_config_fn)]\n\
2323
or with an inline closure:\n \
24-
#[dial9_tokio_telemetry::main(config = || Dial9Config::builder().base_path(...).max_total_size(...).build().unwrap())]";
24+
#[dial9_tokio_telemetry::main(config = || Dial9Config::builder().on_disk_buffer(...).max_total_size(...).build().unwrap())]";
2525
impl Parse for MainArgs {
2626
fn parse(input: ParseStream) -> syn::Result<Self> {
2727
if input.is_empty() {
@@ -118,20 +118,19 @@ fn expand_main(args: MainArgs, input: ItemFn) -> Result<TokenStream2, syn::Error
118118
/// * `config` — a zero-argument function path or a zero-argument closure
119119
/// returning any value convertible into a `TracedRuntime`. In
120120
/// practice that means one of:
121-
/// - `Dial9Config` from `Dial9Config::builder().build()` (strict):
122-
/// any builder validation or writer-I/O failure surfaces from
123-
/// `.build()` as a `Dial9ConfigBuilderError`; runtime construction
121+
/// - `Dial9Config` from `Dial9Config::builder().on_disk_buffer(..)..build()`
122+
/// or `..in_memory_buffer()..build()` (strict): a writer-I/O failure surfaces
123+
/// from `.build()` as a `Dial9ConfigBuilderError`; runtime construction
124124
/// under the macro panics on tokio-builder or telemetry-core I/O.
125-
/// - `Dial9Config` from `Dial9Config::builder().build_or_disabled()`
126-
/// (lenient): the same `Dial9Config` type, but validation and
127-
/// writer-I/O failures are logged at `error!` and downgraded to a
128-
/// disabled config that still preserves your `with_tokio`
129-
/// configurators.
125+
/// - `Dial9Config` from `..build_or_disabled()` (lenient): the same
126+
/// `Dial9Config` type, but writer-I/O failures are logged at `error!`
127+
/// and downgraded to a disabled config that still preserves your
128+
/// `with_tokio` configurators.
130129
/// - The deprecated positional `dial9_tokio_telemetry::config::Dial9Config`,
131130
/// kept compatible via a bridge impl.
132131
///
133-
/// Use `.enabled(false)` on the builder to run without telemetry
134-
/// while keeping your `with_tokio` configurators.
132+
/// Use `.enabled(false)` to run without telemetry while keeping your
133+
/// `with_tokio` configurators.
135134
///
136135
/// # Examples
137136
///
@@ -142,7 +141,7 @@ fn expand_main(args: MainArgs, input: ItemFn) -> Result<TokenStream2, syn::Error
142141
///
143142
/// fn my_config() -> Dial9Config {
144143
/// Dial9Config::builder()
145-
/// .base_path("/tmp/trace.bin")
144+
/// .on_disk_buffer("/tmp/trace.bin")
146145
/// .max_file_size(1024 * 1024)
147146
/// .max_total_size(16 * 1024 * 1024)
148147
/// .build()
@@ -164,7 +163,7 @@ fn expand_main(args: MainArgs, input: ItemFn) -> Result<TokenStream2, syn::Error
164163
/// ```rust,ignore
165164
/// #[dial9_tokio_telemetry::main(config = || {
166165
/// Dial9Config::builder()
167-
/// .base_path("/tmp/trace.bin")
166+
/// .on_disk_buffer("/tmp/trace.bin")
168167
/// .max_file_size(1024 * 1024)
169168
/// .max_total_size(16 * 1024 * 1024)
170169
/// .build()
@@ -181,7 +180,7 @@ fn expand_main(args: MainArgs, input: ItemFn) -> Result<TokenStream2, syn::Error
181180
/// ```rust,ignore
182181
/// #[dial9_tokio_telemetry::main(config = || {
183182
/// Dial9Config::builder()
184-
/// .base_path("/tmp/trace.bin")
183+
/// .on_disk_buffer("/tmp/trace.bin")
185184
/// .max_file_size(1024 * 1024)
186185
/// .max_total_size(16 * 1024 * 1024)
187186
/// .build_or_disabled()
@@ -197,6 +196,7 @@ fn expand_main(args: MainArgs, input: ItemFn) -> Result<TokenStream2, syn::Error
197196
/// ```rust,ignore
198197
/// #[dial9_tokio_telemetry::main(config = || {
199198
/// Dial9Config::builder()
199+
/// .on_disk_buffer("/tmp/trace.bin")
200200
/// .enabled(false)
201201
/// .build()
202202
/// .expect("config build failed")
@@ -205,6 +205,22 @@ fn expand_main(args: MainArgs, input: ItemFn) -> Result<TokenStream2, syn::Error
205205
/// /* ... */
206206
/// }
207207
/// ```
208+
///
209+
/// In-memory writer (no telemetry on disk), select it with `.in_memory_buffer()`.
210+
///
211+
/// ```rust,ignore
212+
/// #[dial9_tokio_telemetry::main(config = || {
213+
/// Dial9Config::builder()
214+
/// .in_memory_buffer()
215+
/// .max_total_size(16 * 1024 * 1024)
216+
/// .with_runtime(|r| r.with_custom_pipeline(|p| p.pipe(MyUploader)))
217+
/// .build()
218+
/// .expect("config build failed")
219+
/// })]
220+
/// async fn main() {
221+
/// /* ... */
222+
/// }
223+
/// ```
208224
#[proc_macro_attribute]
209225
pub fn main(attr: TokenStream, item: TokenStream) -> TokenStream {
210226
let args = parse_macro_input!(attr as MainArgs);

dial9-tokio-telemetry/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ name = "pipeline_heap_bench"
167167
harness = false
168168
required-features = ["cpu-profiling"]
169169

170+
[[example]]
171+
name = "block_in_place_workload"
172+
required-features = ["cpu-profiling"]
173+
170174
[[example]]
171175
name = "blocking_pool_tracking"
172176
required-features = ["cpu-profiling"]
@@ -191,10 +195,6 @@ required-features = ["analysis"]
191195
name = "trace_to_jsonl"
192196
required-features = ["analysis"]
193197

194-
[[example]]
195-
name = "trace_to_fat_jsonl"
196-
required-features = ["analysis"]
197-
198198
[[example]]
199199
name = "kernel_sched_events"
200200
required-features = ["cpu-profiling", "analysis"]

dial9-tokio-telemetry/README.md

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use dial9_tokio_telemetry::{main, Dial9Config, telemetry::TelemetryHandle};
4141
4242
fn my_config() -> Dial9Config {
4343
Dial9Config::builder()
44-
.base_path("/tmp/my_traces/trace.bin")
44+
.on_disk_buffer("/tmp/my_traces/trace.bin")
4545
.max_total_size(5 * 1024 * 1024) // keep at most 5 MiB on disk
4646
.max_file_size(1024 * 1024) // optional: defaults to min(100 MiB, max_total_size / 4)
4747
.rotation_period(std::time::Duration::from_secs(300)) // optional: rotate every 5 min (default: 60 s)
@@ -167,7 +167,7 @@ fn my_config() -> Dial9Config {
167167
.build();
168168

169169
Dial9Config::builder()
170-
.base_path("/tmp/my_traces/trace.bin")
170+
.on_disk_buffer("/tmp/my_traces/trace.bin")
171171
.max_file_size(100 * 1024 * 1024)
172172
.max_total_size(500 * 1024 * 1024)
173173
.with_tokio(|t| { t.worker_threads(4); })
@@ -440,6 +440,37 @@ record_event(
440440
# }
441441
```
442442
443+
### Custom event callbacks
444+
445+
You can also register a callback that runs from dial9's flush thread and emits
446+
custom events. This is useful for draining application-owned queues or taking
447+
periodic snapshots without passing a [`TelemetryHandle`] through your code:
448+
449+
```rust,no_run
450+
use dial9_trace_format::TraceEvent;
451+
use dial9_tokio_telemetry::telemetry::{CustomEventsConfig, TracedRuntime};
452+
453+
#[derive(TraceEvent)]
454+
struct CacheEvent {
455+
#[traceevent(timestamp)]
456+
timestamp_ns: u64,
457+
entries: u64,
458+
}
459+
460+
let (_runtime, _guard) = TracedRuntime::builder()
461+
.with_custom_events(CustomEventsConfig::default(), move |ctx| {
462+
while let Ok(event) = rx.try_recv() {
463+
ctx.record_event(event);
464+
}
465+
})
466+
.build_and_start_with_writer(builder, writer)?;
467+
```
468+
469+
`CustomEventsConfig::default()` runs the callback every flush cycle
470+
while telemetry is enabled, which fits drain-style callbacks. For polling-style
471+
callbacks, configure `minimum_interval(...)` to limit how often dial9 invokes
472+
the callback.
473+
443474
### Custom Runtime Hooks
444475
445476
dial9 installs callbacks on all 8 Tokio runtime hooks to collect telemetry. If you need to run your own logic alongside dial9's instrumentation, use `with_tokio_hooks`:
@@ -498,7 +529,8 @@ fn my_config() -> Dial9Config {
498529
.build();
499530
500531
Dial9Config::builder()
501-
// ...
532+
.on_disk_buffer("/tmp/dial9/trace.bin")
533+
.max_total_size(1 << 30)
502534
.with_runtime(|r| {
503535
r.with_task_tracking(true)
504536
.with_s3_uploader(s3_config)

0 commit comments

Comments
 (0)