Skip to content

Commit 45cc538

Browse files
committed
[extension/encoding/googlecloudlogentryencoding] accept short ALPN protocol tokens
handleHTTPRequestField required exactly one "/" in the protocol string, rejecting tokens like "h2" that Google Cloud Load Balancers started using for HTTP/2 in late 2024. This silently dropped affected log entries. Relax the check: if the protocol string contains no "/", store it as-is in network.protocol.name and omit network.protocol.version. If a "/" is present the existing validation (both sides must be non-empty) still applies. Fixes #45214 Signed-off-by: alliasgher <alliasgher123@gmail.com>
1 parent bedd81d commit 45cc538

3 files changed

Lines changed: 43 additions & 13 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
change_type: bug_fix
2+
component: extension/encoding/googlecloudlogentryencoding
3+
note: "Accept short ALPN protocol tokens (e.g. `h2`, `h3`) in `httpRequest.protocol` that do not contain a `/`; previously any protocol string without a slash was rejected with an error, causing log entries from Google Cloud Load Balancers that switched to reporting `h2` for HTTP/2 to be silently dropped."
4+
issues: [45214]
5+
change_logs: [user]

extension/encoding/googlecloudlogentryencodingextension/log_entry.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -232,21 +232,26 @@ func handleHTTPRequestField(attributes pcommon.Map, req *httpRequest) error {
232232
}
233233

234234
if req.Protocol != "" {
235-
if strings.Count(req.Protocol, "/") != 1 {
235+
if strings.Count(req.Protocol, "/") > 1 {
236236
return fmt.Errorf(
237-
`invalid protocol %q: expected exactly one "/" (format "<name>/<version>", e.g. "HTTP/1.1")`,
237+
`invalid protocol %q: expected at most one "/" (format "<name>/<version>", e.g. "HTTP/1.1", or a short token like "h2")`,
238238
req.Protocol,
239239
)
240240
}
241-
name, version, found := strings.Cut(req.Protocol, "/")
242-
if !found || name == "" || version == "" {
243-
return fmt.Errorf(
244-
`invalid protocol %q: name or version is missing (expected format "<name>/<version>", e.g. "HTTP/1.1")`,
245-
req.Protocol,
246-
)
241+
if name, version, hasSlash := strings.Cut(req.Protocol, "/"); hasSlash {
242+
if name == "" || version == "" {
243+
return fmt.Errorf(
244+
`invalid protocol %q: name or version is missing (expected format "<name>/<version>", e.g. "HTTP/1.1")`,
245+
req.Protocol,
246+
)
247+
}
248+
attributes.PutStr(string(conventions.NetworkProtocolNameKey), strings.ToLower(name))
249+
attributes.PutStr(string(conventions.NetworkProtocolVersionKey), version)
250+
} else {
251+
// Short ALPN token with no version component (e.g. "h2", "h3", "h2c").
252+
// Store the full token as the protocol name; no version attribute is set.
253+
attributes.PutStr(string(conventions.NetworkProtocolNameKey), strings.ToLower(req.Protocol))
247254
}
248-
attributes.PutStr(string(conventions.NetworkProtocolNameKey), strings.ToLower(name))
249-
attributes.PutStr(string(conventions.NetworkProtocolVersionKey), version)
250255
}
251256

252257
shared.PutInt(string(conventions.HTTPResponseStatusCodeKey), req.Status, attributes)

extension/encoding/googlecloudlogentryencodingextension/log_entry_test.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,31 @@ func TestHandleHTTPRequestField(t *testing.T) {
112112
expectsErr: "failed to parse request url",
113113
},
114114
{
115-
name: "invalid protocol",
115+
// Short ALPN token — accepted as protocol name without version
116+
// (regression test for https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/45214)
117+
name: "h2 protocol (no slash)",
116118
request: &httpRequest{
117-
Protocol: "invalid",
119+
Protocol: "h2",
118120
},
119-
expectsErr: `expected exactly one "/"`,
121+
expectsAttributes: map[string]any{
122+
"network.protocol.name": "h2",
123+
},
124+
},
125+
{
126+
name: "h3 protocol (no slash)",
127+
request: &httpRequest{
128+
Protocol: "h3",
129+
},
130+
expectsAttributes: map[string]any{
131+
"network.protocol.name": "h3",
132+
},
133+
},
134+
{
135+
name: "invalid protocol — too many slashes",
136+
request: &httpRequest{
137+
Protocol: "a/b/c",
138+
},
139+
expectsErr: `at most one "/"`,
120140
},
121141
{
122142
name: "invalid protocol 2",

0 commit comments

Comments
 (0)