Skip to content

Commit

Permalink
Logging config
Browse files Browse the repository at this point in the history
  • Loading branch information
bryn committed Nov 8, 2023
1 parent 7f55f46 commit 670d28a
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 202 deletions.
33 changes: 0 additions & 33 deletions apollo-router/src/plugins/telemetry/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ pub(crate) struct Conf {
#[serde(rename = "experimental_logging", default)]
pub(crate) logging: Logging,

#[cfg(feature = "telemetry_next")]
#[serde(rename = "logging", default)]
#[allow(dead_code)]
pub(crate) new_logging: config_new::logging::Logging,
Expand Down Expand Up @@ -167,14 +166,6 @@ pub(crate) struct Tracing {
#[derive(Clone, Debug, Deserialize, JsonSchema, Default)]
#[serde(deny_unknown_fields, default)]
pub(crate) struct Logging {
/// Log format
pub(crate) format: LoggingFormat,
/// Display the target in the logs
pub(crate) display_target: bool,
/// Display the filename in the logs
pub(crate) display_filename: bool,
/// Display the line number in the logs
pub(crate) display_line_number: bool,
/// Log configuration to log request and response for subgraphs and supergraph
pub(crate) when_header: Vec<HeaderLoggingCondition>,
}
Expand Down Expand Up @@ -711,10 +702,6 @@ mod tests {
#[test]
fn test_logging_conf_validation() {
let logging_conf = Logging {
format: LoggingFormat::default(),
display_target: false,
display_filename: false,
display_line_number: false,
when_header: vec![HeaderLoggingCondition::Value {
name: "test".to_string(),
value: String::new(),
Expand All @@ -726,10 +713,6 @@ mod tests {
logging_conf.validate().unwrap();

let logging_conf = Logging {
format: LoggingFormat::default(),
display_target: false,
display_filename: false,
display_line_number: false,
when_header: vec![HeaderLoggingCondition::Value {
name: "test".to_string(),
value: String::new(),
Expand All @@ -746,10 +729,6 @@ mod tests {
#[test]
fn test_logging_conf_should_log() {
let logging_conf = Logging {
format: LoggingFormat::default(),
display_target: false,
display_filename: false,
display_line_number: false,
when_header: vec![HeaderLoggingCondition::Matching {
name: "test".to_string(),
matching: Regex::new("^foo*").unwrap(),
Expand All @@ -764,10 +743,6 @@ mod tests {
assert_eq!(logging_conf.should_log(&req), (true, false));

let logging_conf = Logging {
format: LoggingFormat::default(),
display_target: false,
display_filename: false,
display_line_number: false,
when_header: vec![HeaderLoggingCondition::Value {
name: "test".to_string(),
value: String::from("foobar"),
Expand All @@ -778,10 +753,6 @@ mod tests {
assert_eq!(logging_conf.should_log(&req), (true, false));

let logging_conf = Logging {
format: LoggingFormat::default(),
display_target: false,
display_filename: false,
display_line_number: false,
when_header: vec![
HeaderLoggingCondition::Matching {
name: "test".to_string(),
Expand All @@ -800,10 +771,6 @@ mod tests {
assert_eq!(logging_conf.should_log(&req), (true, true));

let logging_conf = Logging {
format: LoggingFormat::default(),
display_target: false,
display_filename: false,
display_line_number: false,
when_header: vec![HeaderLoggingCondition::Matching {
name: "testtest".to_string(),
matching: Regex::new("^foo*").unwrap(),
Expand Down
97 changes: 41 additions & 56 deletions apollo-router/src/plugins/telemetry/config_new/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,22 @@ pub(crate) struct LoggingCommon {
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Default, Debug)]
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(deny_unknown_fields, default)]
pub(crate) struct StdOut {
/// Set to true to log to stdout.
pub(crate) enabled: bool,
/// The format to log to stdout.
pub(crate) format: Format,
}
impl Default for StdOut {
fn default() -> Self {
StdOut {
enabled: true,
format: Format::default(),
}
}
}

/// Log to a file
#[allow(dead_code)]
Expand All @@ -61,37 +69,30 @@ pub(crate) struct File {
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub(crate) enum Format {
/// https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData-discoverable-fields.html
Aws,
/// https://github.com/trentm/node-bunyan
Bunyan,
/// https://go2docs.graylog.org/5-0/getting_in_log_data/ingest_gelf.html#:~:text=The%20Graylog%20Extended%20Log%20Format,UDP%2C%20TCP%2C%20or%20HTTP.
Gelf,

/// https://cloud.google.com/logging/docs/structured-logging
Google,
/// https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-appender-log
OpenTelemetry,

/// https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Json.html
#[serde(rename = "json")]
JsonDefault,
// /// https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData-discoverable-fields.html
// Aws,
// /// https://github.com/trentm/node-bunyan
// Bunyan,
// /// https://go2docs.graylog.org/5-0/getting_in_log_data/ingest_gelf.html#:~:text=The%20Graylog%20Extended%20Log%20Format,UDP%2C%20TCP%2C%20or%20HTTP.
// Gelf,
//
// /// https://cloud.google.com/logging/docs/structured-logging
// Google,
// /// https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-appender-log
// OpenTelemetry,
/// https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Json.html
Json(JsonFormat),

/// https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Full.html
#[serde(rename = "text")]
TextDefault,
/// https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Full.html
Text(TextFormat),
}

impl Default for Format {
fn default() -> Self {
if std::io::stdout().is_terminal() {
Format::TextDefault
Format::Text(TextFormat::default())
} else {
Format::JsonDefault
Format::Json(JsonFormat::default())
}
}
}
Expand All @@ -101,34 +102,31 @@ impl Default for Format {
#[serde(deny_unknown_fields, rename_all = "snake_case", default)]
pub(crate) struct JsonFormat {
/// Move all span attributes to the top level json object.
flatten_event: bool,
/// Use ansi escape codes.
ansi: bool,
pub(crate) flatten_event: bool,
/// Include the timestamp with the log event.
display_timestamp: bool,
pub(crate) display_timestamp: bool,
/// Include the target with the log event.
display_target: bool,
pub(crate) display_target: bool,
/// Include the level with the log event.
display_level: bool,
pub(crate) display_level: bool,
/// Include the thread_id with the log event.
display_thread_id: bool,
pub(crate) display_thread_id: bool,
/// Include the thread_name with the log event.
display_thread_name: bool,
pub(crate) display_thread_name: bool,
/// Include the filename with the log event.
display_filename: bool,
pub(crate) display_filename: bool,
/// Include the line number with the log event.
display_line_number: bool,
pub(crate) display_line_number: bool,
/// Include the current span in this log event.
display_current_span: bool,
pub(crate) display_current_span: bool,
/// Include all of the containing span information with the log event.
display_span_list: bool,
pub(crate) display_span_list: bool,
}

impl Default for JsonFormat {
fn default() -> Self {
JsonFormat {
flatten_event: false,
ansi: false,
display_timestamp: true,
display_target: true,
display_level: true,
Expand All @@ -146,32 +144,29 @@ impl Default for JsonFormat {
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(deny_unknown_fields, rename_all = "snake_case", default)]
pub(crate) struct TextFormat {
/// The type of text output, one of `default`, `compact`, or `full`.
flavor: TextFlavor,
/// Use ansi escape codes.
ansi: bool,
pub(crate) ansi: bool,
/// Include the timestamp with the log event.
display_timestamp: bool,
pub(crate) display_timestamp: bool,
/// Include the target with the log event.
display_target: bool,
pub(crate) display_target: bool,
/// Include the level with the log event.
display_level: bool,
pub(crate) display_level: bool,
/// Include the thread_id with the log event.
display_thread_id: bool,
pub(crate) display_thread_id: bool,
/// Include the thread_name with the log event.
display_thread_name: bool,
pub(crate) display_thread_name: bool,
/// Include the filename with the log event.
display_filename: bool,
pub(crate) display_filename: bool,
/// Include the line number with the log event.
display_line_number: bool,
pub(crate) display_line_number: bool,
/// Include the location with the log event.
display_location: bool,
pub(crate) display_location: bool,
}

impl Default for TextFormat {
fn default() -> Self {
TextFormat {
flavor: TextFlavor::Default,
ansi: false,
display_timestamp: true,
display_target: false,
Expand All @@ -185,16 +180,6 @@ impl Default for TextFormat {
}
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Default, Debug)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub(crate) enum TextFlavor {
#[default]
Default,
Compact,
Full,
}

/// The period to rollover the log file.
#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Default, Debug)]
Expand Down
51 changes: 51 additions & 0 deletions apollo-router/src/plugins/telemetry/fmt_layer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use tracing_subscriber::fmt::format::JsonFields;
use tracing_subscriber::Layer;

use crate::plugins::telemetry::config;
use crate::plugins::telemetry::config_new::logging::Format;
use crate::plugins::telemetry::formatters::filter_metric_events;
use crate::plugins::telemetry::formatters::json::Json;
use crate::plugins::telemetry::formatters::text::Text;
use crate::plugins::telemetry::formatters::FilteringFormatter;
use crate::plugins::telemetry::reload::LayeredTracer;

pub(crate) fn create_fmt_layer(
config: &config::Conf,
) -> Box<dyn Layer<LayeredTracer> + Send + Sync> {
let config = &config.new_logging.stdout;
match &config.format {
Format::Json(config) => {
let format = Json::default()
.with_level(config.display_level)
.with_target(config.display_target)
.with_level(config.display_level)
.with_span_list(config.display_span_list)
.with_current_span(config.display_current_span)
.with_file(config.display_filename)
.with_line_number(config.display_line_number)
.with_thread_ids(config.display_thread_id)
.with_thread_names(config.display_thread_name)
.with_timestamp(config.display_timestamp);

tracing_subscriber::fmt::layer()
.event_format(FilteringFormatter::new(format, filter_metric_events))
.fmt_fields(JsonFields::new())
.boxed()
}

Format::Text(config) => {
let format = Text::default()
.with_level(config.display_level)
.with_target(config.display_target)
.with_level(config.display_level)
.with_file(config.display_filename)
.with_line_number(config.display_line_number)
.with_thread_ids(config.display_thread_id)
.with_thread_names(config.display_thread_name);
tracing_subscriber::fmt::layer()
.event_format(FilteringFormatter::new(format, filter_metric_events))
.fmt_fields(tracing_subscriber::fmt::format::DefaultFields::new())
.boxed()
}
}
}
43 changes: 37 additions & 6 deletions apollo-router/src/plugins/telemetry/formatters/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub(crate) struct Json {
pub(crate) display_target: bool,
pub(crate) display_line_number: bool,
pub(crate) display_span_list: bool,
pub(crate) display_level: bool,
pub(crate) display_thread_id: bool,
pub(crate) display_thread_name: bool,
pub(crate) display_timestamp: bool,
}

impl Json {
Expand Down Expand Up @@ -70,6 +74,24 @@ impl Json {
self.display_span_list = display_span_list;
self
}
pub(crate) fn with_level(mut self, display_level: bool) -> Self {
self.display_level = display_level;
self
}
pub(crate) fn with_thread_ids(mut self, display_thread_id: bool) -> Self {
self.display_thread_id = display_thread_id;
self
}

pub(crate) fn with_thread_names(mut self, display_thread_name: bool) -> Self {
self.display_thread_name = display_thread_name;
self
}

pub(crate) fn with_timestamp(mut self, display_timestamp: bool) -> Self {
self.display_timestamp = display_timestamp;
self
}
}

struct SerializableContext<'a, Span, N>(Option<SpanRef<'a, Span>>, std::marker::PhantomData<N>)
Expand Down Expand Up @@ -210,18 +232,23 @@ where
where
S: Subscriber + for<'a> LookupSpan<'a>,
{
let timestamp = time::OffsetDateTime::now_utc();

let meta = event.metadata();

let mut visit = || {
let mut serializer = Serializer::new(WriteAdaptor::new(&mut writer));

let mut serializer = serializer.serialize_map(None)?;

serializer.serialize_entry("timestamp", &timestamp)?;
if self.display_timestamp {
let timestamp = time::OffsetDateTime::now_utc()
.format(&time::format_description::well_known::Iso8601::DEFAULT)
.map_err(|e| serde::ser::Error::custom(e.to_string()))?;
serializer.serialize_entry("timestamp", &timestamp)?;
}

serializer.serialize_entry("level", &meta.level().as_serde())?;
if self.display_level {
serializer.serialize_entry("level", &meta.level().as_serde())?;
}

let format_field_marker: std::marker::PhantomData<N> = std::marker::PhantomData;

Expand Down Expand Up @@ -279,9 +306,13 @@ impl Default for Json {
flatten_event: false,
display_current_span: true,
display_span_list: true,
display_filename: true,
display_line_number: true,
display_level: false,
display_thread_id: false,
display_thread_name: false,
display_filename: false,
display_line_number: false,
display_target: true,
display_timestamp: true,
}
}
}
Expand Down
Loading

0 comments on commit 670d28a

Please sign in to comment.