Skip to content

Commit 1e45875

Browse files
authored
refactor!: Diagnostic as a trait (#115)
Signed-off-by: tison <[email protected]>
1 parent 6cfe443 commit 1e45875

File tree

19 files changed

+71
-105
lines changed

19 files changed

+71
-105
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44

55
## Unreleased
66

7+
### Breaking changes
8+
9+
* `Diagnosic` is now a trait. `Visitor`'s method signature is simplified.
10+
711
### New features
812

913
* Add `BlockingRollingFile` and `BlockingSyslog` appenders. They would lock the inner appender and log synchronously. In some lower rate logging scenarios, this would be more efficient than the non-blocking version.

examples/custom_layout_filter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl Filter for CustomFilter {
3737
struct CustomLayout;
3838

3939
impl Layout for CustomLayout {
40-
fn format(&self, record: &Record, _: &[Diagnostic]) -> anyhow::Result<Vec<u8>> {
40+
fn format(&self, record: &Record, _: &[Box<dyn Diagnostic>]) -> anyhow::Result<Vec<u8>> {
4141
Ok(format!("[Alert] {}", record.args()).into_bytes())
4242
}
4343
}

src/append/fastrace.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub struct FastraceEvent {
3838
}
3939

4040
impl Append for FastraceEvent {
41-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
41+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
4242
let message = format!("{}", record.args());
4343

4444
let mut collector = KvCollector { kv: Vec::new() };
@@ -87,13 +87,9 @@ impl<'kvs> log::kv::VisitSource<'kvs> for KvCollector {
8787
}
8888

8989
impl Visitor for KvCollector {
90-
fn visit<'k, 'v, K, V>(&mut self, key: K, value: V)
91-
where
92-
K: Into<Cow<'k, str>>,
93-
V: Into<Cow<'v, str>>,
94-
{
95-
let key = key.into().into_owned();
96-
let value = value.into().into_owned();
90+
fn visit(&mut self, key: Cow<str>, value: Cow<str>) {
91+
let key = key.into_owned();
92+
let value = value.into_owned();
9793
self.kv.push((key, value));
9894
}
9995
}

src/append/journald/mod.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,7 @@ impl<'kvs> log::kv::VisitSource<'kvs> for WriteKeyValues<'_> {
247247
}
248248

249249
impl Visitor for WriteKeyValues<'_> {
250-
fn visit<'k, 'v, K, V>(&mut self, key: K, value: V)
251-
where
252-
K: Into<Cow<'k, str>>,
253-
V: Into<Cow<'v, str>>,
254-
{
255-
let key = key.into();
256-
let value = value.into();
250+
fn visit(&mut self, key: Cow<str>, value: Cow<str>) {
257251
let key = key.as_ref();
258252
let value = value.as_bytes();
259253
field::put_field_length_encoded(self.0, field::FieldName::WriteEscaped(key), value);
@@ -263,7 +257,7 @@ impl Visitor for WriteKeyValues<'_> {
263257
impl Append for Journald {
264258
/// Extract all fields (standard and custom) from `record`, append all `extra_fields` given
265259
/// to this appender, and send the result to journald.
266-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
260+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
267261
use field::*;
268262

269263
let mut buffer = vec![];

src/append/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ pub use self::syslog::Syslog;
5050
/// A trait representing an appender that can process log records.
5151
pub trait Append: fmt::Debug + Send + Sync + 'static {
5252
/// Dispatches a log record to the append target.
53-
fn append(&self, record: &log::Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()>;
53+
fn append(
54+
&self,
55+
record: &log::Record,
56+
diagnostics: &[Box<dyn Diagnostic>],
57+
) -> anyhow::Result<()>;
5458

5559
/// Flushes any buffered records.
5660
fn flush(&self) {}

src/append/opentelemetry.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ pub struct OpentelemetryLog {
235235
}
236236

237237
impl Append for OpentelemetryLog {
238-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
238+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
239239
let mut log_record = self.logger.create_log_record();
240240
log_record.set_observed_timestamp(SystemTime::now());
241241
log_record.set_severity_number(log_level_to_otel_severity(record.level()));
@@ -303,13 +303,9 @@ impl<'kvs> log::kv::VisitSource<'kvs> for KvExtractor<'_> {
303303
}
304304

305305
impl Visitor for KvExtractor<'_> {
306-
fn visit<'k, 'v, K, V>(&mut self, key: K, value: V)
307-
where
308-
K: Into<Cow<'k, str>>,
309-
V: Into<Cow<'v, str>>,
310-
{
311-
let key = key.into().into_owned();
312-
let value = value.into().into_owned();
306+
fn visit(&mut self, key: Cow<str>, value: Cow<str>) {
307+
let key = key.into_owned();
308+
let value = value.into_owned();
313309
self.record.add_attribute(key, value);
314310
}
315311
}

src/append/rolling_file/append.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl BlockingRollingFile {
5050
}
5151

5252
impl Append for BlockingRollingFile {
53-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
53+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
5454
let mut bytes = self.layout.format(record, diagnostics)?;
5555
bytes.push(b'\n');
5656
let mut writer = self.writer.lock().unwrap_or_else(|e| e.into_inner());
@@ -92,7 +92,7 @@ impl RollingFile {
9292
}
9393

9494
impl Append for RollingFile {
95-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
95+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
9696
let mut bytes = self.layout.format(record, diagnostics)?;
9797
bytes.push(b'\n');
9898
self.writer.send(bytes)?;

src/append/stdio.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl Stdout {
6161
}
6262

6363
impl Append for Stdout {
64-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
64+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
6565
let mut bytes = self.layout.format(record, diagnostics)?;
6666
bytes.push(b'\n');
6767
std::io::stdout().write_all(&bytes)?;
@@ -113,7 +113,7 @@ impl Stderr {
113113
}
114114

115115
impl Append for Stderr {
116-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
116+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
117117
let mut bytes = self.layout.format(record, diagnostics)?;
118118
bytes.push(b'\n');
119119
std::io::stderr().write_all(&bytes)?;

src/append/syslog.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl Syslog {
106106
}
107107

108108
impl Append for Syslog {
109-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
109+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
110110
let message = self.formatter.format_message(record, diagnostics)?;
111111
self.writer.send(message)?;
112112
Ok(())
@@ -155,7 +155,7 @@ impl BlockingSyslog {
155155
}
156156

157157
impl Append for BlockingSyslog {
158-
fn append(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<()> {
158+
fn append(&self, record: &Record, diagnostics: &[Box<dyn Diagnostic>]) -> anyhow::Result<()> {
159159
let message = self.formatter.format_message(record, diagnostics)?;
160160
let mut writer = self.writer.lock().unwrap_or_else(|e| e.into_inner());
161161
writer.write_all(message.as_slice())?;
@@ -191,7 +191,7 @@ impl SyslogFormatter {
191191
fn format_message(
192192
&self,
193193
record: &Record,
194-
diagnostics: &[Diagnostic],
194+
diagnostics: &[Box<dyn Diagnostic>],
195195
) -> anyhow::Result<Vec<u8>> {
196196
let severity = log_level_to_otel_severity(record.level());
197197

src/diagnostic/fastrace.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,11 @@ use crate::Diagnostic;
3939
#[non_exhaustive]
4040
pub struct FastraceDiagnostic {}
4141

42-
impl FastraceDiagnostic {
43-
pub fn visit<V: Visitor>(&self, visitor: &mut V) {
42+
impl Diagnostic for FastraceDiagnostic {
43+
fn visit(&self, visitor: &mut dyn Visitor) {
4444
if let Some(span) = fastrace::collector::SpanContext::current_local_parent() {
4545
let trace_id = format!("{:016x}", span.trace_id.0);
46-
visitor.visit("trace_id", trace_id);
46+
visitor.visit("trace_id".into(), trace_id.into());
4747
}
4848
}
4949
}
50-
51-
impl From<FastraceDiagnostic> for Diagnostic {
52-
fn from(diagnostic: FastraceDiagnostic) -> Self {
53-
Diagnostic::Fastrace(diagnostic)
54-
}
55-
}

src/diagnostic/mod.rs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
//! request.
1717
1818
use std::borrow::Cow;
19+
use std::fmt;
1920

2021
#[cfg(feature = "fastrace")]
2122
pub use self::fastrace::FastraceDiagnostic;
@@ -30,29 +31,16 @@ mod thread_local;
3031
/// A visitor to walk through diagnostic key-value pairs.
3132
pub trait Visitor {
3233
/// Visits a key-value pair.
33-
fn visit<'k, 'v, K, V>(&mut self, key: K, value: V)
34-
where
35-
K: Into<Cow<'k, str>>,
36-
V: Into<Cow<'v, str>>;
34+
fn visit(&mut self, key: Cow<str>, value: Cow<str>);
3735
}
3836

39-
/// Represent a Mapped Diagnostic Context (MDC) that provides diagnostic key-values.
40-
#[derive(Debug)]
41-
pub enum Diagnostic {
42-
#[cfg(feature = "fastrace")]
43-
Fastrace(FastraceDiagnostic),
44-
Static(StaticDiagnostic),
45-
ThreadLocal(ThreadLocalDiagnostic),
37+
/// A trait representing a Mapped Diagnostic Context (MDC) that provides diagnostic key-values.
38+
pub trait Diagnostic: fmt::Debug + Send + Sync + 'static {
39+
fn visit(&self, visitor: &mut dyn Visitor);
4640
}
4741

48-
impl Diagnostic {
49-
/// Visits the diagnostic key-value pairs.
50-
pub fn visit<V: Visitor>(&self, visitor: &mut V) {
51-
match self {
52-
#[cfg(feature = "fastrace")]
53-
Diagnostic::Fastrace(diagnostic) => diagnostic.visit(visitor),
54-
Diagnostic::Static(diagnostic) => diagnostic.visit(visitor),
55-
Diagnostic::ThreadLocal(diagnostic) => diagnostic.visit(visitor),
56-
}
42+
impl<T: Diagnostic> From<T> for Box<dyn Diagnostic> {
43+
fn from(value: T) -> Self {
44+
Box::new(value)
5745
}
5846
}

src/diagnostic/static_global.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,12 @@ impl StaticDiagnostic {
4949
pub fn remove(&mut self, key: &str) {
5050
self.kvs.remove(key);
5151
}
52+
}
5253

53-
pub fn visit<V: Visitor>(&self, visitor: &mut V) {
54+
impl Diagnostic for StaticDiagnostic {
55+
fn visit(&self, visitor: &mut dyn Visitor) {
5456
for (key, value) in self.kvs.iter() {
55-
visitor.visit(key, value);
57+
visitor.visit(key.into(), value.into());
5658
}
5759
}
5860
}
59-
60-
impl From<StaticDiagnostic> for Diagnostic {
61-
fn from(diagnostic: StaticDiagnostic) -> Self {
62-
Diagnostic::Static(diagnostic)
63-
}
64-
}

src/diagnostic/thread_local.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,15 @@ impl ThreadLocalDiagnostic {
5151
map.borrow_mut().remove(key);
5252
});
5353
}
54+
}
5455

55-
pub fn visit<V: Visitor>(&self, visitor: &mut V) {
56+
impl Diagnostic for ThreadLocalDiagnostic {
57+
fn visit(&self, visitor: &mut dyn Visitor) {
5658
CONTEXT.with(|map| {
5759
let map = map.borrow();
5860
for (key, value) in map.iter() {
59-
visitor.visit(key, value);
61+
visitor.visit(key.into(), value.into());
6062
}
6163
})
6264
}
6365
}
64-
65-
impl From<ThreadLocalDiagnostic> for Diagnostic {
66-
fn from(diagnostic: ThreadLocalDiagnostic) -> Self {
67-
Diagnostic::ThreadLocal(diagnostic)
68-
}
69-
}

src/layout/json.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,9 @@ impl<'kvs> log::kv::VisitSource<'kvs> for KvCollector<'_> {
8686
}
8787

8888
impl Visitor for KvCollector<'_> {
89-
fn visit<'k, 'v, K, V>(&mut self, key: K, value: V)
90-
where
91-
K: Into<Cow<'k, str>>,
92-
V: Into<Cow<'v, str>>,
93-
{
94-
let key = key.into().into_owned();
95-
let value = value.into().into_owned();
89+
fn visit(&mut self, key: Cow<str>, value: Cow<str>) {
90+
let key = key.into_owned();
91+
let value = value.into_owned();
9692
self.kvs.insert(key, value.into());
9793
}
9894
}
@@ -125,7 +121,11 @@ where
125121
}
126122

127123
impl Layout for JsonLayout {
128-
fn format(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<Vec<u8>> {
124+
fn format(
125+
&self,
126+
record: &Record,
127+
diagnostics: &[Box<dyn Diagnostic>],
128+
) -> anyhow::Result<Vec<u8>> {
129129
let mut kvs = Map::new();
130130
let mut visitor = KvCollector { kvs: &mut kvs };
131131
record.key_values().visit(&mut visitor)?;

src/layout/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ pub use text::TextLayout;
2929
/// A layout for formatting log records.
3030
pub trait Layout: fmt::Debug + Send + Sync + 'static {
3131
/// Formats a log record with optional diagnostics.
32-
fn format(&self, record: &log::Record, diagnostics: &[Diagnostic]) -> anyhow::Result<Vec<u8>>;
32+
fn format(
33+
&self,
34+
record: &log::Record,
35+
diagnostics: &[Box<dyn Diagnostic>],
36+
) -> anyhow::Result<Vec<u8>>;
3337
}
3438

3539
impl<T: Layout> From<T> for Box<dyn Layout> {

src/layout/text.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,11 @@ impl TextLayout {
154154
}
155155

156156
impl Layout for TextLayout {
157-
fn format(&self, record: &Record, diagnostics: &[Diagnostic]) -> anyhow::Result<Vec<u8>> {
157+
fn format(
158+
&self,
159+
record: &Record,
160+
diagnostics: &[Box<dyn Diagnostic>],
161+
) -> anyhow::Result<Vec<u8>> {
158162
let time = match self.tz.clone() {
159163
Some(tz) => Timestamp::now().to_zoned(tz),
160164
None => Zoned::now(),
@@ -204,19 +208,9 @@ impl<'kvs> log::kv::VisitSource<'kvs> for KvWriter {
204208
}
205209

206210
impl Visitor for KvWriter {
207-
fn visit<'k, 'v, K, V>(&mut self, key: K, value: V)
208-
where
209-
K: Into<Cow<'k, str>>,
210-
V: Into<Cow<'v, str>>,
211-
{
211+
fn visit(&mut self, key: Cow<str>, value: Cow<str>) {
212212
// SAFETY: no more than an allocate-less version
213213
// self.text.push_str(&format!(" {key}={value}"))
214-
write!(
215-
&mut self.text,
216-
" {key}={value}",
217-
key = key.into(),
218-
value = value.into()
219-
)
220-
.unwrap();
214+
write!(&mut self.text, " {key}={value}").unwrap();
221215
}
222216
}

src/logger/builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl Builder {
194194
#[derive(Debug)]
195195
pub struct DispatchBuilder<const APPEND: bool> {
196196
filters: Vec<Box<dyn Filter>>,
197-
diagnostics: Vec<Diagnostic>,
197+
diagnostics: Vec<Box<dyn Diagnostic>>,
198198
appends: Vec<Box<dyn Append>>,
199199
}
200200

@@ -242,7 +242,7 @@ impl DispatchBuilder<false> {
242242
/// })
243243
/// .apply();
244244
/// ```
245-
pub fn diagnostic(mut self, diagnostic: impl Into<Diagnostic>) -> Self {
245+
pub fn diagnostic(mut self, diagnostic: impl Into<Box<dyn Diagnostic>>) -> Self {
246246
self.diagnostics.push(diagnostic.into());
247247
self
248248
}

src/logger/log_impl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ impl log::Log for Logger {
6969
#[derive(Debug)]
7070
pub(super) struct Dispatch {
7171
filters: Vec<Box<dyn Filter>>,
72-
diagnostics: Vec<Diagnostic>,
72+
diagnostics: Vec<Box<dyn Diagnostic>>,
7373
appends: Vec<Box<dyn Append>>,
7474
}
7575

7676
impl Dispatch {
7777
pub(super) fn new(
7878
filters: Vec<Box<dyn Filter>>,
79-
diagnostics: Vec<Diagnostic>,
79+
diagnostics: Vec<Box<dyn Diagnostic>>,
8080
appends: Vec<Box<dyn Append>>,
8181
) -> Self {
8282
debug_assert!(

0 commit comments

Comments
 (0)