Skip to content

Commit edd1e1e

Browse files
committed
in_opentelemetry: Ignore unknown field in JSON
This commit will support following specification. > OTLP/JSON receivers MUST ignore message fields with unknown names and MUST unmarshal the message as if the unknown field was not present in the payload. Signed-off-by: Shizuo Fujita <[email protected]>
1 parent 71c0f9a commit edd1e1e

File tree

6 files changed

+417
-4
lines changed

6 files changed

+417
-4
lines changed

lib/fluent/plugin/opentelemetry/request.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Logs
1212
def initialize(body)
1313
@request =
1414
if body.start_with?("{")
15-
Opentelemetry::Proto::Collector::Logs::V1::ExportLogsServiceRequest.decode_json(body)
15+
Opentelemetry::Proto::Collector::Logs::V1::ExportLogsServiceRequest.decode_json(body, ignore_unknown_fields: true)
1616
else
1717
Opentelemetry::Proto::Collector::Logs::V1::ExportLogsServiceRequest.decode(body)
1818
end
@@ -31,7 +31,7 @@ class Metrics
3131
def initialize(body)
3232
@request =
3333
if body.start_with?("{")
34-
Opentelemetry::Proto::Collector::Metrics::V1::ExportMetricsServiceRequest.decode_json(body)
34+
Opentelemetry::Proto::Collector::Metrics::V1::ExportMetricsServiceRequest.decode_json(body, ignore_unknown_fields: true)
3535
else
3636
Opentelemetry::Proto::Collector::Metrics::V1::ExportMetricsServiceRequest.decode(body)
3737
end
@@ -50,7 +50,7 @@ class Traces
5050
def initialize(body)
5151
@request =
5252
if body.start_with?("{")
53-
Opentelemetry::Proto::Collector::Trace::V1::ExportTraceServiceRequest.decode_json(body)
53+
Opentelemetry::Proto::Collector::Trace::V1::ExportTraceServiceRequest.decode_json(body, ignore_unknown_fields: true)
5454
else
5555
Opentelemetry::Proto::Collector::Trace::V1::ExportTraceServiceRequest.decode(body)
5656
end

test/fluent/plugin/test_in_opentelemetry.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,24 @@ def config
9999
request_data: TestData::JSON::LOGS,
100100
record_type: Fluent::Plugin::Opentelemetry::RECORD_TYPE_LOGS,
101101
record_data: TestData::JSON::LOGS
102+
},
103+
"metrics contained unknown fields" => {
104+
request_path: "/v1/metrics",
105+
request_data: TestData::JSON::METRICS_CONTAINED_UNKNOWN_FIELD,
106+
record_type: Fluent::Plugin::Opentelemetry::RECORD_TYPE_METRICS,
107+
record_data: TestData::JSON::METRICS
108+
},
109+
"traces contained unknown fields" => {
110+
request_path: "/v1/traces",
111+
request_data: TestData::JSON::TRACES_CONTAINED_UNKNOWN_FIELD,
112+
record_type: Fluent::Plugin::Opentelemetry::RECORD_TYPE_TRACES,
113+
record_data: TestData::JSON::TRACES
114+
},
115+
"logs contained unknown fields" => {
116+
request_path: "/v1/logs",
117+
request_data: TestData::JSON::LOGS_CONTAINED_UNKNOWN_FIELD,
118+
record_type: Fluent::Plugin::Opentelemetry::RECORD_TYPE_LOGS,
119+
record_data: TestData::JSON::LOGS
102120
})
103121
def test_receive_json(data)
104122
d = create_driver
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"resourceLogs": [
3+
{
4+
"unknown_field": "foobarbaz",
5+
6+
"resource": {},
7+
"scopeLogs": [
8+
{
9+
"scope": {
10+
"name": "test-unit",
11+
"version": "0.0.0"
12+
},
13+
"logRecords": [
14+
{
15+
"timeUnixNano": "1744261044119140009",
16+
"severityText": "INFO",
17+
"body": {
18+
"stringValue": "This is sample log."
19+
},
20+
"attributes": [
21+
{
22+
"key": "cedar",
23+
"value": {
24+
"boolValue": true
25+
}
26+
}
27+
],
28+
"observedTimeUnixNano": "1744261044119142403"
29+
}
30+
]
31+
}
32+
]
33+
}
34+
]
35+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
{
2+
"resourceMetrics": [
3+
{
4+
"unknown_field": "foobarbaz",
5+
6+
"resource": {
7+
"attributes": [
8+
{
9+
"key": "service.name",
10+
"value": {
11+
"stringValue": "test-unit"
12+
}
13+
},
14+
{
15+
"key": "process.pid",
16+
"value": {
17+
"intValue": "28670"
18+
}
19+
},
20+
{
21+
"key": "process.command",
22+
"value": {
23+
"stringValue": "metrics.rb"
24+
}
25+
},
26+
{
27+
"key": "process.runtime.name",
28+
"value": {
29+
"stringValue": "ruby"
30+
}
31+
},
32+
{
33+
"key": "process.runtime.version",
34+
"value": {
35+
"stringValue": "3.4.2"
36+
}
37+
},
38+
{
39+
"key": "process.runtime.description",
40+
"value": {
41+
"stringValue": "ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x86_64-linux]"
42+
}
43+
},
44+
{
45+
"key": "telemetry.sdk.name",
46+
"value": {
47+
"stringValue": "opentelemetry"
48+
}
49+
},
50+
{
51+
"key": "telemetry.sdk.language",
52+
"value": {
53+
"stringValue": "ruby"
54+
}
55+
},
56+
{
57+
"key": "telemetry.sdk.version",
58+
"value": {
59+
"stringValue": "1.8.0"
60+
}
61+
}
62+
]
63+
},
64+
"scopeMetrics": [
65+
{
66+
"scope": {
67+
"name": "SAMPLE_METER_NAME"
68+
},
69+
"metrics": [
70+
{
71+
"name": "gauge",
72+
"description": "desscription",
73+
"unit": "cpu",
74+
"gauge": {
75+
"dataPoints": [
76+
{
77+
"startTimeUnixNano": "1744246311257468167",
78+
"timeUnixNano": "1744246311257652701",
79+
"asInt": "67",
80+
"attributes": [
81+
{
82+
"key": "cpuid",
83+
"value": {
84+
"stringValue": "1"
85+
}
86+
},
87+
{
88+
"key": "type",
89+
"value": {
90+
"stringValue": "user"
91+
}
92+
}
93+
]
94+
},
95+
{
96+
"startTimeUnixNano": "1744246311257468167",
97+
"timeUnixNano": "1744246311257652701",
98+
"asInt": "42",
99+
"attributes": [
100+
{
101+
"key": "cpuid",
102+
"value": {
103+
"stringValue": "2"
104+
}
105+
},
106+
{
107+
"key": "type",
108+
"value": {
109+
"stringValue": "user"
110+
}
111+
}
112+
]
113+
}
114+
]
115+
}
116+
}
117+
]
118+
}
119+
]
120+
}
121+
]
122+
}

0 commit comments

Comments
 (0)