Skip to content

Commit d9120ee

Browse files
committed
imp(cli): add log filtering
1 parent c7dfec6 commit d9120ee

File tree

6 files changed

+105
-13
lines changed

6 files changed

+105
-13
lines changed

pyroscope_cli/Cargo.lock

Lines changed: 44 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyroscope_cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ utils = { path = "utils" }
2525
cli = { path = "cli"}
2626
core = { path = "core" }
2727
human-panic = "1.0.3"
28+
pretty_env_logger = "0.4.0"
2829
better-panic = "0.3.0"
2930
log = "=0.4.11"
3031

pyroscope_cli/utils/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ edition = "2021"
88
[dependencies]
99
thiserror = "1.0.30"
1010
color-backtrace = "0.5.1"
11-
config = "0.11.0"
11+
config = "=0.11.0"
1212
lazy_static = "1.4.0"
1313
slog = "2.7.0"
1414
slog-term = "2.8.0"

pyroscope_cli/utils/src/app_config.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,22 @@ pub struct AppConfig {
2020
pub pid: Option<i32>,
2121
pub spy_name: Spy,
2222
pub application_name: Option<String>,
23-
// TODO: placeholder for future implementation
24-
//pub auth_token: Option<String>,
2523
pub detect_subprocesses: Option<bool>,
2624
pub no_logging: Option<bool>,
2725
pub log_level: LogLevel,
2826
pub no_root_drop: Option<bool>,
29-
pub pyspy_blocking: Option<bool>,
3027
pub rbspy_blocking: Option<bool>,
28+
pub pyspy_blocking: Option<bool>,
29+
pub pyspy_idle: Option<bool>,
30+
pub pyspy_gil: Option<bool>,
31+
pub pyspy_native: Option<bool>,
3132
pub sample_rate: Option<u32>,
3233
pub server_address: Option<String>,
3334
pub tag: Option<String>,
3435
// TODO: placeholder for future implementation
3536
//pub upstream_request_timeout: Option<String>,
3637
//pub upstream_threads: Option<u32>,
38+
//pub auth_token: Option<String>,
3739
pub user_name: Option<u32>,
3840
pub group_name: Option<u32>,
3941
pub command: Option<String>,

pyroscope_cli/utils/src/logger.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use slog::o;
22
use slog::Drain;
33

4+
use super::app_config::AppConfig;
45
use super::error::Result;
6+
use super::types::LogLevel;
57

68
pub fn setup_logging() -> Result<slog_scope::GlobalLoggerGuard> {
79
// Setup Logging
@@ -15,9 +17,11 @@ pub fn default_root_logger() -> Result<slog::Logger> {
1517
// Create drains
1618
let drain = slog::Duplicate(default_discard()?, default_discard()?).fuse();
1719

18-
// TODO: Link logging to config
1920
// Merge drains
20-
//let drain = slog::Duplicate(default_term_drain().unwrap_or(default_discard()?), drain).fuse();
21+
let drain = slog::Duplicate(default_term_drain().unwrap_or(default_discard()?), drain).fuse();
22+
23+
// Filter drain
24+
let drain = LevelFilter { drain }.fuse();
2125

2226
// Create Logger
2327
let logger = slog::Logger::root(drain, o!("who" => "pyroscope-cli"));
@@ -34,10 +38,52 @@ fn default_discard() -> Result<slog_async::Async> {
3438

3539
// term drain: Log to Terminal
3640
fn default_term_drain() -> Result<slog_async::Async> {
37-
let plain = slog_term::PlainSyncDecorator::new(std::io::stdout());
38-
let term = slog_term::FullFormat::new(plain);
41+
let decorator = slog_term::TermDecorator::new().build();
42+
let term = slog_term::FullFormat::new(decorator);
3943

4044
let drain = slog_async::Async::default(term.build().fuse());
4145

4246
Ok(drain)
4347
}
48+
49+
struct LevelFilter<D> {
50+
drain: D,
51+
}
52+
53+
impl<D> Drain for LevelFilter<D>
54+
where
55+
D: Drain,
56+
{
57+
type Ok = Option<D::Ok>;
58+
type Err = Option<D::Err>;
59+
60+
fn log(
61+
&self, record: &slog::Record, values: &slog::OwnedKVList,
62+
) -> std::result::Result<Self::Ok, Self::Err> {
63+
// Discard logs if no_logging flag is set
64+
let logging = AppConfig::get::<bool>("no_logging").unwrap_or(false);
65+
if logging {
66+
return Ok(None);
67+
}
68+
69+
// TODO: This is probably expensive (and should be cached)
70+
let log_level = AppConfig::get::<LogLevel>("log_level").unwrap_or(LogLevel::Info);
71+
72+
// convert log level to slog level
73+
let current_level = match log_level {
74+
LogLevel::Trace => slog::Level::Trace,
75+
LogLevel::Debug => slog::Level::Debug,
76+
LogLevel::Info => slog::Level::Info,
77+
LogLevel::Warn => slog::Level::Warning,
78+
LogLevel::Error => slog::Level::Error,
79+
LogLevel::Critical => slog::Level::Critical,
80+
};
81+
82+
// check if log level is above current level
83+
if record.level().is_at_least(current_level) {
84+
self.drain.log(record, values).map(Some).map_err(Some)
85+
} else {
86+
Ok(None)
87+
}
88+
}
89+
}

pyroscope_cli/utils/src/types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::str::FromStr;
66

77
#[derive(Debug, Serialize, Deserialize, Copy, Clone, ArgEnum)]
88
pub enum LogLevel {
9+
#[serde(rename = "trace")]
10+
Trace,
911
#[serde(rename = "debug")]
1012
Debug,
1113
#[serde(rename = "info")]
@@ -14,6 +16,8 @@ pub enum LogLevel {
1416
Warn,
1517
#[serde(rename = "error")]
1618
Error,
19+
#[serde(rename = "critical")]
20+
Critical,
1721
}
1822

1923
impl FromStr for LogLevel {

0 commit comments

Comments
 (0)