Spaces:
Build error
Build error
File size: 2,799 Bytes
d8435ba |
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 |
use std::collections::HashSet;
use std::sync::Mutex;
use std::{fs, io};
use anyhow::Context as _;
use common::ext::OptionExt;
use serde::{Deserialize, Serialize};
use tracing_subscriber::prelude::*;
use tracing_subscriber::{filter, fmt, registry};
use super::*;
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
#[serde(default)]
pub struct Config {
pub enabled: Option<bool>,
pub log_file: Option<String>,
pub log_level: Option<String>,
pub span_events: Option<HashSet<config::SpanEvent>>,
}
impl Config {
pub fn merge(&mut self, other: Self) {
let Self {
enabled,
log_file,
log_level,
span_events,
} = other;
self.enabled.replace_if_some(enabled);
self.log_file.replace_if_some(log_file);
self.log_level.replace_if_some(log_level);
self.span_events.replace_if_some(span_events);
}
}
#[rustfmt::skip] // `rustfmt` formats this into unreadable single line :/
pub type Logger<S> = filter::Filtered<
Option<Layer<S>>,
filter::EnvFilter,
S,
>;
#[rustfmt::skip] // `rustfmt` formats this into unreadable single line :/
pub type Layer<S> = fmt::Layer<
S,
fmt::format::DefaultFields,
fmt::format::Format,
MakeWriter,
>;
pub type MakeWriter = Mutex<io::BufWriter<fs::File>>;
pub fn new_logger<S>(config: &mut Config) -> Logger<S>
where
S: tracing::Subscriber + for<'span> registry::LookupSpan<'span>,
{
let layer = match new_layer(config) {
Ok(layer) => layer,
Err(err) => {
eprintln!(
"failed to enable logging into {} log-file: {err}",
config.log_file.as_deref().unwrap_or(""),
);
config.enabled = Some(false);
None
}
};
let filter = new_filter(config);
layer.with_filter(filter)
}
pub fn new_layer<S>(config: &Config) -> anyhow::Result<Option<Layer<S>>>
where
S: tracing::Subscriber + for<'span> registry::LookupSpan<'span>,
{
if !config.enabled.unwrap_or_default() {
return Ok(None);
}
let Some(log_file) = &config.log_file else {
return Err(anyhow::format_err!("log file is not specified"));
};
let writer = fs::OpenOptions::new()
.create(true)
.append(true)
.open(log_file)
.with_context(|| format!("failed to open {log_file} log-file"))?;
let layer = fmt::Layer::default()
.with_writer(Mutex::new(io::BufWriter::new(writer)))
.with_span_events(config::SpanEvent::unwrap_or_default_config(
&config.span_events,
))
.with_ansi(false);
Ok(Some(layer))
}
pub fn new_filter(config: &Config) -> filter::EnvFilter {
filter(config.log_level.as_deref().unwrap_or(""))
}
|