ntp_daemon/config/
format.rs1use std::str::FromStr;
2
3use serde::Deserialize;
4use thiserror::Error;
5use tracing::Subscriber;
6use tracing_subscriber::{
7 field::RecordFields,
8 fmt::{
9 format::{
10 Compact, DefaultFields, Format, Full, Json, JsonFields, Pretty, PrettyFields, Writer,
11 },
12 FormatEvent, FormatFields,
13 },
14 registry::LookupSpan,
15};
16
17#[derive(Debug, Clone)]
18pub enum LogFormat {
19 Full(Format<Full>),
20 Compact(Format<Compact>),
21 Pretty(Format<Pretty>),
22 Json(Format<Json>),
23}
24
25impl LogFormat {
26 pub fn get_format_fields(&self) -> LogFormatFields {
27 match self {
28 LogFormat::Json(_) => LogFormatFields::Json(JsonFields::default()),
29 LogFormat::Pretty(_) => LogFormatFields::Pretty(PrettyFields::default()),
30 _ => LogFormatFields::Default(DefaultFields::default()),
31 }
32 }
33}
34
35impl<'de> Deserialize<'de> for LogFormat {
36 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37 where
38 D: serde::Deserializer<'de>,
39 {
40 let data: String = Deserialize::deserialize(deserializer)?;
41 LogFormat::from_str(&data).map_err(serde::de::Error::custom)
42 }
43}
44
45impl Default for LogFormat {
46 fn default() -> Self {
47 LogFormat::Full(Default::default())
48 }
49}
50
51#[derive(Error, Debug)]
52#[error("Invalid log format, must be one of full, compact, pretty, json")]
53pub struct InvalidLogFormat;
54
55impl FromStr for LogFormat {
56 type Err = InvalidLogFormat;
57
58 fn from_str(s: &str) -> Result<Self, Self::Err> {
59 match s {
60 "full" => Ok(LogFormat::Full(Default::default())),
61 "compact" => Ok(LogFormat::Compact(Format::default().compact())),
62 "pretty" => Ok(LogFormat::Pretty(Format::default().pretty())),
63 "json" => Ok(LogFormat::Json(Format::default().json().with_ansi(false))),
64 _ => Err(InvalidLogFormat),
65 }
66 }
67}
68
69impl<S, N> FormatEvent<S, N> for LogFormat
70where
71 S: Subscriber + for<'a> LookupSpan<'a>,
72 N: for<'a> FormatFields<'a> + 'static,
73{
74 fn format_event(
75 &self,
76 ctx: &tracing_subscriber::fmt::FmtContext<'_, S, N>,
77 writer: tracing_subscriber::fmt::format::Writer<'_>,
78 event: &tracing::Event<'_>,
79 ) -> std::fmt::Result {
80 match self {
81 LogFormat::Full(f) => f.format_event(ctx, writer, event),
82 LogFormat::Compact(f) => f.format_event(ctx, writer, event),
83 LogFormat::Pretty(f) => f.format_event(ctx, writer, event),
84 LogFormat::Json(f) => f.format_event(ctx, writer, event),
85 }
86 }
87}
88
89pub enum LogFormatFields {
90 Json(JsonFields),
91 Pretty(PrettyFields),
92 Default(DefaultFields),
93}
94
95impl<'a> FormatFields<'a> for LogFormatFields {
96 fn format_fields<R: RecordFields>(&self, writer: Writer<'a>, fields: R) -> std::fmt::Result {
97 match self {
98 LogFormatFields::Json(f) => f.format_fields(writer, fields),
99 LogFormatFields::Pretty(f) => f.format_fields(writer, fields),
100 LogFormatFields::Default(f) => f.format_fields(writer, fields),
101 }
102 }
103}