Skip to content

Commit 77e66d2

Browse files
committed
feat: enable OTLP access log ingestion in Envoy Gateway and update Vector collector and e2e tests accordingly
1 parent 90159e7 commit 77e66d2

3 files changed

Lines changed: 74 additions & 13 deletions

File tree

config/dev/downstream_resources/downstream-gateway.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@ spec:
111111
duration: "%DURATION%"
112112
route_name: "%ROUTE_NAME%"
113113
project_name: "%REQ(X-DATUM-PROJECT-NAME)%"
114+
# Push access logs straight to the node-local Vector agent over OTLP.
115+
# The JSON fields above are delivered as OTLP log-record attributes,
116+
# which Vector's `envoy_access_logs` opentelemetry source parses into
117+
# billing CloudEvents. internalTrafficPolicy: Local on the Vector
118+
# Service keeps this hop on-node.
119+
sinks:
120+
- type: OpenTelemetry
121+
openTelemetry:
122+
host: billing-usage-collector-vector.billing-system.svc.cluster.local
123+
port: 4317
124+
# OTLP has no custom URL path; identify this stream via an OTel
125+
# resource attribute instead. Surfaces in Vector under
126+
# `.resources` and can be used to route/filter signals.
127+
resources:
128+
service.name: nso-httproute-signals
114129
---
115130
apiVersion: gateway.networking.k8s.io/v1
116131
kind: GatewayClass

config/tools/billing-usage-collector/kustomization.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,32 @@ helmCharts:
3838
path: "/logs"
3939
decoding:
4040
codec: json
41+
# Envoy Gateway pushes access logs here via its OpenTelemetry access
42+
# log sink (OTLP). The JSON access log fields arrive as OTLP log-record
43+
# attributes (i.e. under `.attributes.*`). This is the real ingestion
44+
# path for live traffic; the `nso_logs` http_server above is only used
45+
# by the e2e test to inject hand-crafted log lines.
46+
envoy_access_logs:
47+
type: opentelemetry
48+
grpc:
49+
address: "0.0.0.0:4317"
50+
http:
51+
address: "0.0.0.0:4318"
4152
transforms:
4253
parse_nso_logs:
4354
type: remap
4455
inputs:
4556
- nso_logs
57+
- envoy_access_logs.logs
4658
source: |
59+
# The OpenTelemetry source (Envoy push) nests the access log fields
60+
# under `.attributes`; the http_server source (e2e test injection)
61+
# delivers them at the top level. Normalize both to top-level fields
62+
# so the rest of this transform is source-agnostic.
63+
if exists(.attributes) {
64+
. = object(.attributes) ?? .
65+
}
66+
4767
parsed_route, err = parse_regex(.route_name, r'^httproute/(?P<namespace>[^/]+)/(?P<name>[^/]+)')
4868
if err != null || is_null(parsed_route) {
4969
abort
@@ -223,5 +243,16 @@ helmCharts:
223243
port: 9881
224244
protocol: TCP
225245
targetPort: 9881
246+
# OTLP endpoints for Envoy Gateway's OpenTelemetry access log sink.
247+
# internalTrafficPolicy: Local keeps each Envoy pod talking to the
248+
# Vector agent on its own node.
249+
- name: otlp-grpc
250+
port: 4317
251+
protocol: TCP
252+
targetPort: 4317
253+
- name: otlp-http
254+
port: 4318
255+
protocol: TCP
256+
targetPort: 4318
226257
podMonitor:
227258
enabled: true

test/e2e/billing/chainsaw-test.yaml

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,20 @@ spec:
156156
accessLog:
157157
settings:
158158
- sinks:
159+
# File sink: the test still scrapes stdout to derive the
160+
# expected metric values (bytes, duration, project_name).
159161
- type: File
160162
file:
161163
path: /dev/stdout
164+
# OpenTelemetry sink: Envoy pushes the access log to the
165+
# node-local Vector agent automatically, exercising the
166+
# real production ingestion path (no manual forwarding).
167+
- type: OpenTelemetry
168+
openTelemetry:
169+
host: billing-usage-collector-vector.billing-system.svc.cluster.local
170+
port: 4317
171+
resources:
172+
service.name: nso-httproute-signals
162173
format:
163174
type: JSON
164175
json:
@@ -534,26 +545,31 @@ spec:
534545
curl -kvf -H \"Host: ${PRIMARY_HOSTNAME}\" -d 'hello world' http://\${GATEWAY_SERVICE_NAME}.\${GATEWAY_SERVICE_NAMESPACE}.svc.cluster.local/delay/2; \
535546
"
536547
537-
# Verify Vector processes it and check exact counts
548+
# Verify Vector emitted the CloudEvents. Envoy pushed the access log to
549+
# Vector automatically via its OpenTelemetry sink when the request above
550+
# was served, so this step only derives the expected values and polls the
551+
# mock billing gateway for the result.
538552
- script:
539553
timeout: 45s
540554
cluster: nso-infra
541555
env:
542556
- name: DOWNSTREAM_NAMESPACE
543557
value: ($downstreamNamespaceName)
544-
- name: STANDARD_NAMESPACE
545-
value: ($namespace)
546558
content: |
547559
# =====================================================================
548560
# Validates the full HTTP metering pipeline, end to end:
549561
#
550-
# Envoy access log --(raw POST)--> Vector /logs source
562+
# Envoy access log --(OTLP push)--> Vector opentelemetry source
551563
# | |
552-
# | (one JSON line per request) | (VRL transform fans the
553-
# | | single log line out into
564+
# | (also written to stdout for | (VRL transform fans the
565+
# | capturing expected values) | log record out into
554566
# v v CloudEvents)
555567
# captured here (STEP 1-2) mock-billing-gateway (STEP 4)
556568
#
569+
# Envoy pushes the access log to Vector automatically (OpenTelemetry
570+
# sink on custom-proxy-config -> billing-usage-collector-vector:4317)
571+
# when the request is served -- the test does NOT forward it manually.
572+
#
557573
# A single access log line is expected to produce FOUR CloudEvents,
558574
# one per usage dimension, all sharing the same subject
559575
# ("projects/<project-control-plane-namespace-uid>"):
@@ -605,13 +621,12 @@ spec:
605621
echo " - Duration ms (expected): $DURATION_MS ($EXPECTED_DURATION seconds)"
606622
echo " - Project name (expected): $PROJECT_NAME"
607623
608-
# --- STEP 3: feed the raw access log into Vector --------------------
609-
# POST the exact captured line to Vector's http_server /logs source.
610-
# Vector's VRL transform parses it and emits the four CloudEvents to
611-
# the mock-billing-gateway sink.
612-
kubectl -n $STANDARD_NAMESPACE exec -i test-pod -- sh -c " \
613-
curl -v -X POST -H 'Content-Type: application/json' -d '$ENVOY_LOG' http://billing-usage-collector-vector.billing-system.svc.cluster.local:9881/logs \
614-
"
624+
# --- STEP 3: (no manual forwarding) --------------------------------
625+
# The request above already caused Envoy to push this access log to
626+
# Vector automatically via its OpenTelemetry sink (custom-proxy-config
627+
# -> billing-usage-collector-vector:4317). Vector's VRL transform
628+
# parses it and emits the four CloudEvents to the mock-billing-gateway
629+
# sink, so there is nothing to POST here -- we just poll for the result.
615630
616631
# --- STEP 4: verify the CloudEvents the mock billing gateway received
617632
# Poll the mock gateway's request log (Vector may take a moment to

0 commit comments

Comments
 (0)