Skip to content

Commit

Permalink
Add custom serde encoding/decoding for timestamp (open-telemetry#1666)
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Apr 17, 2024
1 parent 2286378 commit 758cdd7
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"parentSpanId": "",
"name": "Sub operation...",
"kind": 1,
"startTimeUnixNano": 1703985537070566698,
"endTimeUnixNano": 1703985537070572718,
"startTimeUnixNano": "1703985537070566698",
"endTimeUnixNano": "1703985537070572718",
"attributes": [
{
"key": "lemons",
Expand All @@ -35,7 +35,7 @@
],
"events": [
{
"timeUnixNano": 1703985537070567697,
"timeUnixNano": "1703985537070567697",
"name": "Sub span event"
}
],
Expand Down Expand Up @@ -68,8 +68,8 @@
"parentSpanId": "cd7cf7bf939930b7",
"name": "operation",
"kind": 1,
"startTimeUnixNano": 1703985537070558635,
"endTimeUnixNano": 1703985537070580454,
"startTimeUnixNano": "1703985537070558635",
"endTimeUnixNano": "1703985537070580454",
"attributes": [
{
"key": "ex.com/another",
Expand All @@ -80,7 +80,7 @@
],
"events": [
{
"timeUnixNano": 1703985537070563326,
"timeUnixNano": "1703985537070563326",
"name": "Nice operation!",
"attributes": [
{
Expand Down
12 changes: 6 additions & 6 deletions opentelemetry-otlp/tests/integration_test/expected/traces.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"parentSpanId": "d58cf2d702a061e0",
"name": "Sub operation...",
"kind": 1,
"startTimeUnixNano": 1703985537070566698,
"endTimeUnixNano": 1703985537070572718,
"startTimeUnixNano": "1703985537070566698",
"endTimeUnixNano": "1703985537070572718",
"attributes": [
{
"key": "lemons",
Expand All @@ -35,7 +35,7 @@
],
"events": [
{
"timeUnixNano": 1703985537070567697,
"timeUnixNano": "1703985537070567697",
"name": "Sub span event"
}
],
Expand Down Expand Up @@ -68,8 +68,8 @@
"parentSpanId": "",
"name": "operation",
"kind": 1,
"startTimeUnixNano": 1703985537070558635,
"endTimeUnixNano": 1703985537070580454,
"startTimeUnixNano": "1703985537070558635",
"endTimeUnixNano": "1703985537070580454",
"attributes": [
{
"key": "ex.com/another",
Expand All @@ -80,7 +80,7 @@
],
"events": [
{
"timeUnixNano": 1703985537070563326,
"timeUnixNano": "1703985537070563326",
"name": "Nice operation!",
"attributes": [
{
Expand Down
14 changes: 14 additions & 0 deletions opentelemetry-proto/src/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,21 @@ pub(crate) mod serializers {
Ok(Some(AnyValue { value }))
}

pub fn serialize_u64_to_string<S>(value: &u64, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = value.to_string();
serializer.serialize_str(&s)
}

pub fn deserialize_string_to_u64<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{
let s: String = Deserialize::deserialize(deserializer)?;
s.parse::<u64>().map_err(de::Error::custom)
}
}

#[cfg(feature = "gen-tonic-messages")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ pub struct Span {
///
/// This field is semantically required and it is expected that end_time >= start_time.
#[prost(fixed64, tag = "7")]
#[cfg_attr(
feature = "with-serde",
serde(
serialize_with = "crate::proto::serializers::serialize_u64_to_string",
deserialize_with = "crate::proto::serializers::deserialize_string_to_u64"
)
)]
pub start_time_unix_nano: u64,
/// end_time_unix_nano is the end time of the span. On the client side, this is the time
/// kept by the local machine where the span execution ends. On the server side, this
Expand All @@ -174,6 +181,13 @@ pub struct Span {
///
/// This field is semantically required and it is expected that end_time >= start_time.
#[prost(fixed64, tag = "8")]
#[cfg_attr(
feature = "with-serde",
serde(
serialize_with = "crate::proto::serializers::serialize_u64_to_string",
deserialize_with = "crate::proto::serializers::deserialize_string_to_u64"
)
)]
pub end_time_unix_nano: u64,
/// attributes is a collection of key/value pairs. Note, global attributes
/// like server name can be set using the resource API. Examples of attributes:
Expand Down Expand Up @@ -227,6 +241,13 @@ pub mod span {
pub struct Event {
/// time_unix_nano is the time the event occurred.
#[prost(fixed64, tag = "1")]
#[cfg_attr(
feature = "with-serde",
serde(
serialize_with = "crate::proto::serializers::serialize_u64_to_string",
deserialize_with = "crate::proto::serializers::deserialize_string_to_u64"
)
)]
pub time_unix_nano: u64,
/// name of the event.
/// This field is semantically required to be set to non-empty string.
Expand Down
13 changes: 13 additions & 0 deletions opentelemetry-proto/tests/grpc_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ fn build_tonic() {
.field_attribute(path, "#[cfg_attr(feature = \"with-serde\", serde(serialize_with = \"crate::proto::serializers::serialize_to_hex_string\", deserialize_with = \"crate::proto::serializers::deserialize_from_hex_string\"))]")
}

// special serializer and deserializer for timestamp
// OTLP/JSON format may uses string for timestamp
// the proto file uses u64 for timestamp
// Thus, special serializer and deserializer are needed
for path in [
"trace.v1.Span.start_time_unix_nano",
"trace.v1.Span.end_time_unix_nano",
"trace.v1.Span.Event.time_unix_nano",
] {
builder = builder
.field_attribute(path, "#[cfg_attr(feature = \"with-serde\", serde(serialize_with = \"crate::proto::serializers::serialize_u64_to_string\", deserialize_with = \"crate::proto::serializers::deserialize_string_to_u64\"))]")
}

// add custom serializer and deserializer for AnyValue
builder = builder
.field_attribute("common.v1.KeyValue.value", "#[cfg_attr(feature =\"with-serde\", serde(serialize_with = \"crate::proto::serializers::serialize_to_value\", deserialize_with = \"crate::proto::serializers::deserialize_from_value\"))]");
Expand Down
6 changes: 3 additions & 3 deletions opentelemetry-proto/tests/json_deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ mod json_deserialize {
"spanId": "EEE19B7EC3C1B174",
"parentSpanId": "EEE19B7EC3C1B173",
"name": "I'm a server span",
"startTimeUnixNano": 1544712660000000000,
"endTimeUnixNano": 1544712661000000000,
"startTimeUnixNano": "1544712660000000000",
"endTimeUnixNano": "1544712661000000000",
"kind": 2,
"attributes": [
{
Expand Down Expand Up @@ -73,7 +73,7 @@ mod json_deserialize {
const EVENT_JSON: &str = r#"
{
"name": "my_event",
"time_unix_nano": 1234567890
"time_unix_nano": "1234567890"
}
"#;

Expand Down

0 comments on commit 758cdd7

Please sign in to comment.