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
//! Logging initialization and configuration.
//!
//! # Why colour is off
//!
//! The layer below is built with `with_ansi(false)`, and that is not a style
//! choice. The `fmt` layer colours its output whenever `tracing-subscriber`'s
//! `ansi` feature is compiled in, and that default asks nothing about what is
//! downstream: it does not test whether stderr is a terminal, and on Windows
//! it does not enable the console's virtual-terminal mode either. Escapes
//! therefore reached every consumer of the logs — the file a service
//! definition redirects to, an agent reading the pipe, and consoles that
//! print them literally as `←[2m` in front of every line.
//!
//! Colour is switched off rather than made conditional, because the condition
//! cannot be answered honestly here. `IsTerminal` alone does not settle it on
//! Windows, where a console handle reports as a terminal whether or not it
//! will interpret an escape; answering it properly means enabling
//! virtual-terminal mode through the Win32 console API and falling back when
//! that fails — a direct platform dependency and a block of `unsafe` FFI,
//! bought for decoration on a headless gateway whose output is read by service
//! managers, log files and agents far more often than by a person. The one
//! surface an operator actually reads, the startup banner, is `println!` on
//! stdout and was never coloured.
//!
//! This also holds the program's own logs to the rule its command output
//! already follows: piped output is escape-free, because that is what makes it
//! usable as structured data.
//!
//! `tests/main_startup_e2e.rs::the_log_stream_carries_no_ansi_escapes` is what
//! keeps this true. A record's *text* is identical either way, so only a real
//! process writing to a real pipe can tell the two apart — no unit test in
//! this module can.
use ;
/// Initialize the logging system.
///
/// Uses the `RUST_LOG` environment variable for filtering. If not set,
/// defaults to `shell_tunnel=info`.
///
/// Diagnostics go to stderr, which leaves stdout for the things a caller wants
/// to read: the public URL, the API key, the command to try. Sharing one stream
/// means `shell-tunnel --tunnel | grep "Public URL"` picks up log lines instead.
///
/// # Panics
///
/// Panics if called more than once, or if another tracing subscriber
/// has already been set.
/// Try to initialize the logging system.
///
/// Returns `Ok(())` if successful, or `Err` if logging has already been
/// initialized.
///
/// This is the whole implementation; `init` is this plus a panic. The two used
/// to assemble the same filter and the same layer separately, and a change to
/// either had to be made twice — the `with_ansi(false)` above is there because
/// that is exactly what happened once already.