git.delta.rocks / fleet / refs/commits / 51d5ea52f7ad

difftreelog

console

zvwsqmxmYaroslav Bolyukin2026-07-01parent: #b66112e.patch.diff

10 files changed

added.cargo/config.tomldiffbeforeafterboth

no changes

modifiedCargo.lockdiffbeforeafterboth
445 "fs_extra",445 "fs_extra",
446]446]
447
448[[package]]
449name = "axum"
450version = "0.8.9"
451source = "registry+https://github.com/rust-lang/crates.io-index"
452checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90"
453dependencies = [
454 "axum-core",
455 "bytes",
456 "futures-util",
457 "http",
458 "http-body",
459 "http-body-util",
460 "itoa",
461 "matchit",
462 "memchr",
463 "mime",
464 "percent-encoding",
465 "pin-project-lite",
466 "serde_core",
467 "sync_wrapper",
468 "tower",
469 "tower-layer",
470 "tower-service",
471]
472
473[[package]]
474name = "axum-core"
475version = "0.5.6"
476source = "registry+https://github.com/rust-lang/crates.io-index"
477checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
478dependencies = [
479 "bytes",
480 "futures-core",
481 "http",
482 "http-body",
483 "http-body-util",
484 "mime",
485 "pin-project-lite",
486 "sync_wrapper",
487 "tower-layer",
488 "tower-service",
489]
447490
448[[package]]491[[package]]
449name = "backon"492name = "backon"
995 "windows-sys 0.61.2",1038 "windows-sys 0.61.2",
996]1039]
1040
1041[[package]]
1042name = "console-api"
1043version = "0.9.0"
1044source = "registry+https://github.com/rust-lang/crates.io-index"
1045checksum = "e8599749b6667e2f0c910c1d0dff6901163ff698a52d5a39720f61b5be4b20d3"
1046dependencies = [
1047 "futures-core",
1048 "prost",
1049 "prost-types",
1050 "tonic",
1051 "tonic-prost",
1052 "tracing-core",
1053]
1054
1055[[package]]
1056name = "console-subscriber"
1057version = "0.5.0"
1058source = "registry+https://github.com/rust-lang/crates.io-index"
1059checksum = "fb4915b7d8dd960457a1b6c380114c2944f728e7c65294ab247ae6b6f1f37592"
1060dependencies = [
1061 "console-api",
1062 "crossbeam-channel",
1063 "crossbeam-utils",
1064 "futures-task",
1065 "hdrhistogram",
1066 "humantime",
1067 "hyper-util",
1068 "prost",
1069 "prost-types",
1070 "serde",
1071 "serde_json",
1072 "thread_local",
1073 "tokio",
1074 "tokio-stream",
1075 "tonic",
1076 "tracing",
1077 "tracing-core",
1078 "tracing-subscriber",
1079]
9971080
998[[package]]1081[[package]]
999name = "const-hex"1082name = "const-hex"
1834 "clap_complete",1917 "clap_complete",
1835 "fleet-base",1918 "fleet-base",
1836 "futures",1919 "futures",
1837 "human-repr",1920 "goodlog-subscriber",
1838 "indicatif",
1839 "itertools 0.15.0",1921 "itertools 0.15.0",
1840 "nix-eval",1922 "nix-eval",
1841 "opentelemetry",
1842 "opentelemetry-appender-tracing",
1843 "opentelemetry-exporter-env",
1844 "opentelemetry_sdk",
1845 "remowt-fleet",1923 "remowt-fleet",
1846 "serde",1924 "serde",
1847 "serde_json",1925 "serde_json",
1850 "tempfile",1928 "tempfile",
1851 "tokio",1929 "tokio",
1852 "tracing",1930 "tracing",
1853 "tracing-indicatif",
1854 "tracing-opentelemetry",
1855 "tracing-subscriber",
1856]1931]
18571932
1858[[package]]1933[[package]]
2242 "wasm-bindgen",2317 "wasm-bindgen",
2243]2318]
2319
2320[[package]]
2321name = "goodlog-subscriber"
2322version = "0.1.9"
2323dependencies = [
2324 "anyhow",
2325 "clap",
2326 "console-subscriber",
2327 "human-repr",
2328 "indicatif",
2329 "opentelemetry",
2330 "opentelemetry-appender-tracing",
2331 "opentelemetry-exporter-env",
2332 "opentelemetry_sdk",
2333 "tracing",
2334 "tracing-indicatif",
2335 "tracing-opentelemetry",
2336 "tracing-subscriber",
2337]
22442338
2245[[package]]2339[[package]]
2246name = "group"2340name = "group"
2283 "foldhash",2377 "foldhash",
2284]2378]
2379
2380[[package]]
2381name = "hdrhistogram"
2382version = "7.5.4"
2383source = "registry+https://github.com/rust-lang/crates.io-index"
2384checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d"
2385dependencies = [
2386 "base64 0.21.7",
2387 "byteorder",
2388 "flate2",
2389 "nom 7.1.3",
2390 "num-traits",
2391]
22852392
2286[[package]]2393[[package]]
2287name = "heck"2394name = "heck"
2491source = "registry+https://github.com/rust-lang/crates.io-index"2598source = "registry+https://github.com/rust-lang/crates.io-index"
2492checksum = "f58b778a5761513caf593693f8951c97a5b610841e754788400f32102eefdff1"2599checksum = "f58b778a5761513caf593693f8951c97a5b610841e754788400f32102eefdff1"
2600
2601[[package]]
2602name = "humantime"
2603version = "2.3.0"
2604source = "registry+https://github.com/rust-lang/crates.io-index"
2605checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
24932606
2494[[package]]2607[[package]]
2495name = "hybrid-array"2608name = "hybrid-array"
3368 "regex-automata",3481 "regex-automata",
3369]3482]
3483
3484[[package]]
3485name = "matchit"
3486version = "0.8.4"
3487source = "registry+https://github.com/rust-lang/crates.io-index"
3488checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
33703489
3371[[package]]3490[[package]]
3372name = "md5"3491name = "md5"
3389 "autocfg",3508 "autocfg",
3390]3509]
3510
3511[[package]]
3512name = "mime"
3513version = "0.3.17"
3514source = "registry+https://github.com/rust-lang/crates.io-index"
3515checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
33913516
3392[[package]]3517[[package]]
3393name = "minimal-lexical"3518name = "minimal-lexical"
6440checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef"6565checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef"
6441dependencies = [6566dependencies = [
6442 "async-trait",6567 "async-trait",
6568 "axum",
6443 "base64 0.22.1",6569 "base64 0.22.1",
6444 "bytes",6570 "bytes",
6445 "flate2",6571 "flate2",
6572 "h2",
6446 "http",6573 "http",
6447 "http-body",6574 "http-body",
6448 "http-body-util",6575 "http-body-util",
6451 "hyper-util",6578 "hyper-util",
6452 "percent-encoding",6579 "percent-encoding",
6453 "pin-project",6580 "pin-project",
6581 "socket2",
6454 "sync_wrapper",6582 "sync_wrapper",
6455 "tokio",6583 "tokio",
6456 "tokio-stream",6584 "tokio-stream",
modifiedCargo.tomldiffbeforeafterboth
39chrono = { version = "0.4.41", features = ["serde"] }39chrono = { version = "0.4.41", features = ["serde"] }
40clap = { version = "4.5", features = ["derive", "env", "unicode", "wrap_help"] }40clap = { version = "4.5", features = ["derive", "env", "unicode", "wrap_help"] }
41clap_complete = "4.5"41clap_complete = "4.5"
42console-subscriber = "0.5.0"
42cxx = "1.0.168"43cxx = "1.0.168"
43cxx-build = "1.0.168"44cxx-build = "1.0.168"
44ed25519-dalek = "3.0.0-rc.0"45ed25519-dalek = "3.0.0-rc.0"
72test-log = { version = "0.2.19", features = ["trace"] }73test-log = { version = "0.2.19", features = ["trace"] }
73thiserror = "2.0.12"74thiserror = "2.0.12"
74time = "0.3.41"75time = "0.3.41"
75tokio = { version = "1.45.1", features = ["fs", "macros", "rt", "rt-multi-thread", "sync", "time"] }76tokio = { version = "1.45.1", features = ["fs", "macros", "rt", "rt-multi-thread", "sync", "time", "tracing"] }
76tracing = "0.1"77tracing = "0.1"
77tracing-indicatif = "0.3.13"78tracing-indicatif = "0.3.13"
78tracing-journald = "0.3.2"79tracing-journald = "0.3.2"
86x25519-dalek = { version = "2.0.1", features = ["getrandom"] }87x25519-dalek = { version = "2.0.1", features = ["getrandom"] }
87zbus = "5.16.0"88zbus = "5.16.0"
88zbus_polkit = "5.0.0"89zbus_polkit = "5.0.0"
90goodlog-subscriber = { version = "0.1.9", path = "crates/goodlog-subscriber" }
8991
90[profile.dev]92[profile.dev]
91panic = "abort"93panic = "abort"
modifiedcmds/fleet/Cargo.tomldiffbeforeafterboth
20tempfile.workspace = true20tempfile.workspace = true
21tokio.workspace = true21tokio.workspace = true
22tracing.workspace = true22tracing.workspace = true
23tracing-subscriber.workspace = true
2423
25futures.workspace = true24futures.workspace = true
26itertools.workspace = true25itertools.workspace = true
27shlex.workspace = true26shlex.workspace = true
28tabled.workspace = true27tabled.workspace = true
2928
30human-repr = { workspace = true, optional = true }
31indicatif = { workspace = true, optional = true }
32opentelemetry.workspace = true29goodlog-subscriber.workspace = true
33opentelemetry-appender-tracing.workspace = true
34opentelemetry-exporter-env.workspace = true
35opentelemetry_sdk.workspace = true
36tracing-indicatif = { workspace = true, optional = true }
37tracing-opentelemetry.workspace = true
3830
39[features]31[features]
40default = ["indicatif"]32default = ["indicatif"]
41# Not quite stable33# Not quite stable
42indicatif = [34indicatif = ["nix-eval/indicatif", "goodlog-subscriber/indicatif"]
43 "dep:tracing-indicatif",
44 "dep:indicatif",
45 "dep:human-repr",
46 "nix-eval/indicatif",
47]
4835
deletedcmds/fleet/src/log_tree.rsdiffbeforeafterboth

no changes

modifiedcmds/fleet/src/main.rsdiffbeforeafterboth
1#![recursion_limit = "512"]1#![recursion_limit = "512"]
22
3pub(crate) mod cmds;3pub(crate) mod cmds;
4mod log_tree;
54
6use std::{process::ExitCode, sync::Arc};5use std::{process::ExitCode, sync::Arc};
76
18};17};
19use fleet_base::{host::Config, opts::FleetOpts};18use fleet_base::{host::Config, opts::FleetOpts};
20use futures::{TryStreamExt, stream::FuturesUnordered};19use futures::{TryStreamExt, stream::FuturesUnordered};
21#[cfg(feature = "indicatif")]
22use human_repr::HumanCount;
23#[cfg(feature = "indicatif")]
24use indicatif::{ProgressState, ProgressStyle};20use goodlog_subscriber::{LogOpts, setup_logging};
25use log_tree::TreeLayer;
26use nix_eval::{21use nix_eval::{
27 eval_store, gc_register_my_thread, gc_unregister_my_thread, init_libraries, init_tokio_for_nix,22 eval_store, gc_register_my_thread, gc_unregister_my_thread, init_libraries, init_tokio_for_nix,
28};23};
29use opentelemetry::trace::TracerProvider;
30use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
31use opentelemetry_exporter_env::{
32 OtlpBaseSettings, OtlpLogsSettings, OtlpTracesSettings, ResolvedOtlpSettings,
33};
34use opentelemetry_sdk::{logs::SdkLoggerProvider, trace::SdkTracerProvider};
35use tokio::task::spawn_blocking;24use tokio::task::spawn_blocking;
36use tracing::{Instrument, error, info, info_span};25use tracing::{Instrument, error, info, info_span};
37#[cfg(feature = "indicatif")]
38use tracing_indicatif::IndicatifLayer;
39use tracing_subscriber::{EnvFilter, prelude::*};
4026
41#[derive(Parser)]27#[derive(Parser)]
42struct Prefetch {}28struct Prefetch {}
102 fleet_opts: FleetOpts,88 fleet_opts: FleetOpts,
103 #[clap(subcommand)]89 #[clap(subcommand)]
104 command: Opts,90 command: Opts,
105 #[clap(long, next_help_heading = "Telemetry", env = "OTEL_FLEET")]91
106 otel: bool,
107 #[clap(flatten)]92 #[clap(flatten)]
108 otlp_base: OtlpBaseSettings,93 log: LogOpts,
109 #[clap(flatten)]
110 otel_logs: OtlpLogsSettings,
111 #[clap(flatten)]
112 otel_traces: OtlpTracesSettings,
113}94}
11495
115async fn run_command(config: &Config, opts: FleetOpts, command: Opts) -> Result<()> {96async fn run_command(config: &Config, opts: FleetOpts, command: Opts) -> Result<()> {
127 Ok(())108 Ok(())
128}109}
129
130fn setup_logging(opts: &RootOpts) -> Result<()> {
131 #[cfg(feature = "indicatif")]
132 let indicatif_layer = {
133 use std::fmt;
134 use std::time::Duration;
135
136 IndicatifLayer::new().with_max_progress_bars(10, Some(ProgressStyle::default_spinner()))
137 .with_span_child_prefix_indent(" ")
138 .with_span_child_prefix_symbol("")
139 .with_progress_style(
140 ProgressStyle::with_template(
141 "{span_child_prefix:.magenta}{chevron:.magenta}{span_name:<18.blue.bold} {wide_msg} {span_fields:.dim} {color_start}{download_progress} {elapsed}{color_end}",
142 )
143 .unwrap()
144 .with_key("chevron", |_: &ProgressState, writer: &mut dyn fmt::Write| {
145 let _ = write!(writer, "> ");
146 })
147 .with_key("download_progress", |state: &ProgressState, writer: &mut dyn fmt::Write| {
148 let Some(len) = state.len() else {
149 return;
150 };
151 let pos = state.pos();
152 if pos > len {
153 let _ = write!(writer, "{}", pos.human_count_bare());
154 } else {
155 let _ = write!(writer, "{} / {}", pos.human_count_bare(), len.human_count_bare());
156 }
157 })
158 .with_key(
159 "color_start",
160 |state: &ProgressState, writer: &mut dyn fmt::Write| {
161 let elapsed = state.elapsed();
162
163 if elapsed > Duration::from_secs(60) {
164 // Red
165 let _ = write!(writer, "\x1b[{}m", 1 + 30);
166 } else if elapsed > Duration::from_secs(30) {
167 // Yellow
168 let _ = write!(writer, "\x1b[{}m", 3 + 30);
169 }
170 },
171 )
172 .with_key(
173 "color_end",
174 |state: &ProgressState, writer: &mut dyn fmt::Write| {
175 if state.elapsed() > Duration::from_secs(30) {
176 let _ = write!(writer, "\x1b[0m");
177 }
178 },
179 ),
180 )
181 };
182
183 let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("noq_udp=warn,info"));
184
185 let tree = {
186 #[cfg(feature = "indicatif")]
187 let writer = indicatif_layer.get_stderr_writer();
188 #[cfg(not(feature = "indicatif"))]
189 let writer = || std::io::stderr();
190 TreeLayer::new(writer)
191 };
192
193 let reg = tracing_subscriber::registry().with(tree.with_filter(filter));
194
195 #[cfg(feature = "indicatif")]
196 let reg = reg.with(indicatif_layer);
197
198 if opts.otel {
199 let traces = ResolvedOtlpSettings::traces(&opts.otlp_base, &opts.otel_traces)?;
200 let span_exporter = traces.span_exporter()?;
201 let logs = ResolvedOtlpSettings::logs(&opts.otlp_base, &opts.otel_logs)?;
202 let log_exporter = logs.log_exporter()?;
203
204 let span_provider = SdkTracerProvider::builder()
205 .with_batch_exporter(span_exporter)
206 .build();
207 let log_provider = SdkLoggerProvider::builder()
208 .with_batch_exporter(log_exporter)
209 .build();
210
211 let logger = OpenTelemetryTracingBridge::new(&log_provider);
212 let tracer = span_provider.tracer("fleet");
213
214 reg.with(tracing_opentelemetry::layer().with_tracer(tracer))
215 .with(logger)
216 .init();
217 } else {
218 reg.init();
219 }
220
221 Ok(())
222}
223110
224fn main() -> ExitCode {111fn main() -> ExitCode {
225 let opts = RootOpts::parse();112 let opts = RootOpts::parse();
228 return ExitCode::SUCCESS;115 return ExitCode::SUCCESS;
229 }116 }
230117
231 if let Err(e) = setup_logging(&opts) {118 if let Err(e) = setup_logging(&opts.log) {
232 eprintln!("{e:#}");119 eprintln!("{e:#}");
233 return ExitCode::FAILURE;120 return ExitCode::FAILURE;
234 }121 }
250 init_tokio_for_nix(runtime.clone());137 init_tokio_for_nix(runtime.clone());
251138
252 runtime.block_on(async {139 runtime.block_on(async {
253 tokio::task::spawn(async move {
254 if let Err(e) = main_real(opts).await {140 if let Err(e) = main_real(opts).await {
255 error!("{e:#}");141 error!("{e:#}");
256 ExitCode::FAILURE142 ExitCode::FAILURE
257 } else {143 } else {
258 ExitCode::SUCCESS144 ExitCode::SUCCESS
259 }145 }
260 })
261 .await
262 .expect("primary task panicked")
263 })146 })
264}147}
265148
addedcrates/goodlog-subscriber/Cargo.tomldiffbeforeafterboth

no changes

addedcrates/goodlog-subscriber/src/lib.rsdiffbeforeafterboth

no changes

addedcrates/goodlog-subscriber/src/log_tree.rsdiffbeforeafterboth

no changes

modifiedpkgs/fleet.nixdiffbeforeafterboth
31 # TODO: built-in fleet prompter should be a prodash widget, or it should require31 # TODO: built-in fleet prompter should be a prodash widget, or it should require
32 # tty remowt prompter running on host machine idk.32 # tty remowt prompter running on host machine idk.
33 ROFI = "${rofi}/bin/rofi";33 ROFI = "${rofi}/bin/rofi";
34 RUSTFLAGS = "--cfg tokio_unstable";
3435
35 buildInputs = [36 buildInputs = [
36 inputs.nix.packages.${system}.nix-expr-c37 inputs.nix.packages.${system}.nix-expr-c