Skip to content

Commit 1f9e765

Browse files
authored
Also print datetime in human friendly format for stdout (#1206)
1 parent 6603a58 commit 1f9e765

File tree

4 files changed

+72
-72
lines changed

4 files changed

+72
-72
lines changed

opentelemetry-stdout/src/common.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{
55
time::{SystemTime, UNIX_EPOCH},
66
};
77

8+
use chrono::{LocalResult, TimeZone, Utc};
89
use ordered_float::OrderedFloat;
910
use serde::{Serialize, Serializer};
1011

@@ -239,6 +240,41 @@ impl From<opentelemetry_sdk::Scope> for Scope {
239240
}
240241
}
241242

243+
pub(crate) fn as_human_readable<S>(time: &SystemTime, serializer: S) -> Result<S::Ok, S::Error>
244+
where
245+
S: Serializer,
246+
{
247+
let duration_since_epoch = time.duration_since(UNIX_EPOCH).unwrap_or_default();
248+
249+
match Utc.timestamp_opt(
250+
duration_since_epoch.as_secs() as i64,
251+
duration_since_epoch.subsec_nanos(),
252+
) {
253+
LocalResult::Single(datetime) => serializer.serialize_str(
254+
datetime
255+
.format("%Y-%m-%d %H:%M:%S.%3f")
256+
.to_string()
257+
.as_ref(),
258+
),
259+
_ => Err(serde::ser::Error::custom("Invalid Timestamp.")),
260+
}
261+
}
262+
263+
#[allow(dead_code)]
264+
// Used for serde serialization. Not used in traces.
265+
pub(crate) fn as_opt_human_readable<S>(
266+
time: &Option<SystemTime>,
267+
serializer: S,
268+
) -> Result<S::Ok, S::Error>
269+
where
270+
S: Serializer,
271+
{
272+
match time {
273+
None => serializer.serialize_none(),
274+
Some(time) => as_human_readable(time, serializer),
275+
}
276+
}
277+
242278
pub(crate) fn as_unix_nano<S>(time: &SystemTime, serializer: S) -> Result<S::Ok, S::Error>
243279
where
244280
S: Serializer,
@@ -250,3 +286,17 @@ where
250286

251287
serializer.serialize_u128(nanos)
252288
}
289+
290+
#[allow(dead_code)]
291+
pub(crate) fn as_opt_unix_nano<S>(
292+
time: &Option<SystemTime>,
293+
serializer: S,
294+
) -> Result<S::Ok, S::Error>
295+
where
296+
S: Serializer,
297+
{
298+
match time {
299+
None => serializer.serialize_none(),
300+
Some(time) => as_unix_nano(time, serializer),
301+
}
302+
}

opentelemetry-stdout/src/logs/transform.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use std::{borrow::Cow, collections::HashMap, time::SystemTime};
22

3-
use crate::common::{as_unix_nano, KeyValue, Resource, Scope, Value};
3+
use crate::common::{
4+
as_human_readable, as_opt_human_readable, as_opt_unix_nano, as_unix_nano, KeyValue, Resource,
5+
Scope, Value,
6+
};
47
use opentelemetry_sdk::AttributeSet;
5-
use serde::{Serialize, Serializer};
8+
use serde::Serialize;
69

710
/// Transformed logs data that can be serialized.
811
#[derive(Debug, Serialize)]
@@ -69,13 +72,14 @@ struct ScopeLogs {
6972
#[derive(Debug, Serialize)]
7073
#[serde(rename_all = "camelCase")]
7174
struct LogRecord {
72-
#[serde(
73-
skip_serializing_if = "Option::is_none",
74-
serialize_with = "opt_as_unix_nano"
75-
)]
75+
#[serde(serialize_with = "as_opt_unix_nano")]
7676
time_unix_nano: Option<SystemTime>,
77+
#[serde(serialize_with = "as_opt_human_readable")]
78+
time: Option<SystemTime>,
7779
#[serde(serialize_with = "as_unix_nano")]
7880
observed_time_unix_nano: SystemTime,
81+
#[serde(serialize_with = "as_human_readable")]
82+
observed_time: SystemTime,
7983
severity_number: u32,
8084
#[serde(skip_serializing_if = "Option::is_none")]
8185
severity_text: Option<Cow<'static, str>>,
@@ -110,7 +114,9 @@ impl From<opentelemetry_sdk::export::logs::LogData> for LogRecord {
110114
.map(|c| c.trace_flags.map(|f| f.to_u8()))
111115
.unwrap_or_default(),
112116
time_unix_nano: value.record.timestamp,
117+
time: value.record.timestamp,
113118
observed_time_unix_nano: value.record.observed_timestamp,
119+
observed_time: value.record.observed_timestamp,
114120
severity_number: value
115121
.record
116122
.severity_number
@@ -132,10 +138,3 @@ impl From<opentelemetry_sdk::export::logs::LogData> for LogRecord {
132138
}
133139
}
134140
}
135-
136-
fn opt_as_unix_nano<S>(time: &Option<SystemTime>, serializer: S) -> Result<S::Ok, S::Error>
137-
where
138-
S: Serializer,
139-
{
140-
as_unix_nano(time.as_ref().unwrap(), serializer)
141-
}

opentelemetry-stdout/src/metrics/transform.rs

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
use crate::common::{AttributeSet, KeyValue, Resource, Scope};
2-
use chrono::{LocalResult, TimeZone, Utc};
32
use opentelemetry::{global, metrics::MetricsError};
43
use opentelemetry_sdk::metrics::data;
54
use serde::{Serialize, Serializer};
6-
use std::{
7-
any::Any,
8-
borrow::Cow,
9-
time::{SystemTime, UNIX_EPOCH},
10-
};
5+
use std::{any::Any, borrow::Cow, time::SystemTime};
6+
7+
use crate::common::{as_human_readable, as_opt_human_readable, as_opt_unix_nano, as_unix_nano};
118

129
/// Transformed metrics data that can be serialized
1310
#[derive(Serialize, Debug, Clone)]
@@ -328,58 +325,6 @@ struct Exemplar {
328325
trace_id: String,
329326
}
330327

331-
fn as_human_readable<S>(time: &SystemTime, serializer: S) -> Result<S::Ok, S::Error>
332-
where
333-
S: Serializer,
334-
{
335-
let duration_since_epoch = time.duration_since(UNIX_EPOCH).unwrap_or_default();
336-
337-
match Utc.timestamp_opt(
338-
duration_since_epoch.as_secs() as i64,
339-
duration_since_epoch.subsec_nanos(),
340-
) {
341-
LocalResult::Single(datetime) => serializer.serialize_str(
342-
datetime
343-
.format("%Y-%m-%d %H:%M:%S.%3f")
344-
.to_string()
345-
.as_ref(),
346-
),
347-
_ => Err(serde::ser::Error::custom("Invalid Timestamp.")),
348-
}
349-
}
350-
351-
fn as_opt_human_readable<S>(time: &Option<SystemTime>, serializer: S) -> Result<S::Ok, S::Error>
352-
where
353-
S: Serializer,
354-
{
355-
match time {
356-
None => serializer.serialize_none(),
357-
Some(time) => as_human_readable(time, serializer),
358-
}
359-
}
360-
361-
fn as_unix_nano<S>(time: &SystemTime, serializer: S) -> Result<S::Ok, S::Error>
362-
where
363-
S: Serializer,
364-
{
365-
let nanos = time
366-
.duration_since(UNIX_EPOCH)
367-
.unwrap_or_default()
368-
.as_nanos();
369-
370-
serializer.serialize_u128(nanos)
371-
}
372-
373-
fn as_opt_unix_nano<S>(time: &Option<SystemTime>, serializer: S) -> Result<S::Ok, S::Error>
374-
where
375-
S: Serializer,
376-
{
377-
match time {
378-
None => serializer.serialize_none(),
379-
Some(time) => as_unix_nano(time, serializer),
380-
}
381-
}
382-
383328
impl<T: Into<DataValue> + Copy> From<&data::Exemplar<T>> for Exemplar {
384329
fn from(value: &data::Exemplar<T>) -> Self {
385330
Exemplar {

opentelemetry-stdout/src/trace/transform.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::common::{as_unix_nano, KeyValue, Resource, Scope};
1+
use crate::common::{as_human_readable, as_unix_nano, KeyValue, Resource, Scope};
22
use opentelemetry_sdk::AttributeSet;
33
use serde::{Serialize, Serializer};
44
use std::{borrow::Cow, collections::HashMap, time::SystemTime};
@@ -73,8 +73,12 @@ struct Span {
7373
kind: SpanKind,
7474
#[serde(serialize_with = "as_unix_nano")]
7575
start_time_unix_nano: SystemTime,
76+
#[serde(serialize_with = "as_human_readable")]
77+
start_time: SystemTime,
7678
#[serde(serialize_with = "as_unix_nano")]
7779
end_time_unix_nano: SystemTime,
80+
#[serde(serialize_with = "as_human_readable")]
81+
end_time: SystemTime,
7882
attributes: Vec<KeyValue>,
7983
dropped_attributes_count: u32,
8084
#[serde(skip_serializing_if = "Vec::is_empty")]
@@ -98,7 +102,9 @@ impl From<opentelemetry_sdk::export::trace::SpanData> for Span {
98102
name: value.name,
99103
kind: value.span_kind.into(),
100104
start_time_unix_nano: value.start_time,
105+
start_time: value.start_time,
101106
end_time_unix_nano: value.end_time,
107+
end_time: value.end_time,
102108
dropped_attributes_count: value.attributes.dropped_count(),
103109
attributes: value.attributes.into_iter().map(Into::into).collect(),
104110
dropped_events_count: value.events.dropped_count(),

0 commit comments

Comments
 (0)