Skip to content

Commit

Permalink
allow to write structured logs to stdout
Browse files Browse the repository at this point in the history
  • Loading branch information
zh-jq-b committed Aug 15, 2024
1 parent fb78c97 commit ff37469
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 20 deletions.
2 changes: 1 addition & 1 deletion g3proxy/doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
project = 'g3proxy'
copyright = '2024, Zhang Jingqiang'
author = 'Zhang Jingqiang'
release = '1.9.7'
release = '1.9.8'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
6 changes: 6 additions & 0 deletions g3proxy/doc/configuration/log/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ The value could be a simple string, which is the driver name, such as

send logs to syslogd directly.

- stdout

send logs to stdout.

.. versionadded:: 1.9.8

In such case, a default driver is used as default log config for all loggers.

The value could be a map, with the following keys:
Expand Down
2 changes: 1 addition & 1 deletion g3tiles/doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
project = 'g3tiles'
copyright = '2024, Zhang Jingqiang'
author = 'Zhang Jingqiang'
release = '0.3.4'
release = '0.3.5'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
6 changes: 6 additions & 0 deletions g3tiles/doc/configuration/log/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ The value could be a simple string, which is the driver name, such as

send logs to syslogd directly.

- stdout

send logs to stdout.

.. versionadded:: 0.3.5

In such case, a default driver is used as default log config for all loggers.

The value could be a map, with the following keys:
Expand Down
5 changes: 5 additions & 0 deletions lib/g3-daemon/src/log/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub enum LogConfigDriver {
Journal(JournalConfig),
Syslog(SyslogBuilder),
Fluentd(Arc<FluentdClientConfig>),
Stdout,
}

#[derive(Clone)]
Expand Down Expand Up @@ -96,6 +97,10 @@ impl LogConfig {
"journal" => Ok(LogConfig::default_journal(program_name)),
"syslog" => Ok(LogConfig::default_syslog(program_name)),
"fluentd" => Ok(LogConfig::default_fluentd(program_name)),
"stdout" => Ok(LogConfig::with_driver(
LogConfigDriver::Stdout,
program_name,
)),
_ => Err(anyhow!("invalid log config")),
},
Yaml::Hash(map) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/g3-daemon/src/log/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub fn setup(args: &DaemonArgs) {
g3_syslog::SyslogBuilder::with_ident(args.process_name).start_async(&async_conf);
Logger::root(drain.fuse(), slog_o!())
} else {
let drain = g3_stdlog::new_async_logger(&async_conf, true);
let drain = g3_stdlog::new_async_logger(&async_conf, true, false);
Logger::root(drain.fuse(), slog_o!())
};

Expand Down
28 changes: 13 additions & 15 deletions lib/g3-daemon/src/log/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,42 +45,33 @@ pub fn create_logger<T>(
where
T: SendSyncRefUnwindSafeKV + 'static,
{
let async_conf = AsyncLogConfig {
channel_capacity: config.async_channel_size,
thread_number: config.async_thread_number,
thread_name: logger_name.clone(),
};

match config.driver.clone() {
LogConfigDriver::Discard => {
let drain = slog::Discard {};
Logger::root(drain, common_values)
}
#[cfg(target_os = "linux")]
LogConfigDriver::Journal(journal_conf) => {
let async_conf = AsyncLogConfig {
channel_capacity: config.async_channel_size,
thread_number: config.async_thread_number,
thread_name: logger_name.clone(),
};
let drain = g3_journal::new_async_logger(&async_conf, journal_conf);
let logger_stats = LoggerStats::new(&logger_name, drain.get_stats());
super::registry::add(logger_name.clone(), Arc::new(logger_stats));
let drain = ReportLogIoError::new(drain, &logger_name, config.io_err_sampling_mask);
Logger::root(drain, common_values)
}
LogConfigDriver::Syslog(builder) => {
let async_conf = AsyncLogConfig {
channel_capacity: config.async_channel_size,
thread_number: config.async_thread_number,
thread_name: logger_name.clone(),
};
let drain = builder.start_async(&async_conf);
let logger_stats = LoggerStats::new(&logger_name, drain.get_stats());
super::registry::add(logger_name.clone(), Arc::new(logger_stats));
let drain = ReportLogIoError::new(drain, &logger_name, config.io_err_sampling_mask);
Logger::root(drain, common_values)
}
LogConfigDriver::Fluentd(fluentd_conf) => {
let async_conf = AsyncLogConfig {
channel_capacity: config.async_channel_size,
thread_number: config.async_thread_number,
thread_name: logger_name.clone(),
};
let drain = g3_fluentd::new_async_logger(
&async_conf,
&fluentd_conf,
Expand All @@ -91,5 +82,12 @@ where
let drain = ReportLogIoError::new(drain, &logger_name, config.io_err_sampling_mask);
Logger::root(drain, common_values)
}
LogConfigDriver::Stdout => {
let drain = g3_stdlog::new_async_logger(&async_conf, false, true);
let logger_stats = LoggerStats::new(&logger_name, drain.get_stats());
super::registry::add(logger_name.clone(), Arc::new(logger_stats));
let drain = slog::IgnoreResult::new(drain);
Logger::root(drain, common_values)
}
}
}
18 changes: 16 additions & 2 deletions lib/g3-stdlog/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub struct StdLogValue {
pub fn new_async_logger(
async_conf: &AsyncLogConfig,
append_code_position: bool,
use_stdout: bool,
) -> AsyncLogger<StdLogValue, StdLogFormatter> {
let (sender, receiver) = flume::bounded::<StdLogValue>(async_conf.channel_capacity);

Expand All @@ -52,7 +53,11 @@ pub fn new_async_logger(
let _detached_thread = std::thread::Builder::new()
.name(async_conf.thread_name.clone())
.spawn(move || {
io_thread.run_to_end();
if use_stdout {
io_thread.run_with_stdout();
} else {
io_thread.run_with_stderr();
}
});

AsyncLogger::new(sender, StdLogFormatter::new(append_code_position), stats)
Expand All @@ -71,7 +76,7 @@ impl AsyncIoThread {
Ok(())
}

fn run_to_end(self) {
fn run_with_stderr(self) {
let stderr = io::stderr();
if stderr.is_terminal() {
self.run_console(stderr)
Expand All @@ -80,6 +85,15 @@ impl AsyncIoThread {
}
}

fn run_with_stdout(self) {
let stdout = io::stdout();
if stdout.is_terminal() {
self.run_console(stdout)
} else {
self.run_plain(stdout)
}
}

fn run_plain<IO: Write>(&self, mut io: IO) {
let mut buf: Vec<u8> = Vec::with_capacity(1024);
while let Ok(v) = self.receiver.recv() {
Expand Down

0 comments on commit ff37469

Please sign in to comment.