Skip to content

Commit

Permalink
feat: gRPC Access Log Service (ALS) sink (#3626)
Browse files Browse the repository at this point in the history
* feat: gRPC Access Log Service (ALS) logging sink

Signed-off-by: David Alger <davidmalger@gmail.com>

* update examples

Signed-off-by: zirain <zirain2009@gmail.com>

* lint

Signed-off-by: zirain <zirain2009@gmail.com>

* update

Signed-off-by: zirain <zirain2009@gmail.com>

* e2e

Signed-off-by: zirain <zirain2009@gmail.com>

* fix test

Signed-off-by: zirain <zirain2009@gmail.com>

* update

Signed-off-by: zirain <zirain2009@gmail.com>

* use LoadBalancer service

Signed-off-by: zirain <zirain2009@gmail.com>

* fix accesslog cluster name

Signed-off-by: zirain <zirain2009@gmail.com>

* lint

Signed-off-by: zirain <zirain2009@gmail.com>

* fix gen

Signed-off-by: zirain <zirain2009@gmail.com>

* fix rebase

Signed-off-by: zirain <zirain2009@gmail.com>

* fix gen after merge main

Signed-off-by: zirain <zirain2009@gmail.com>

* nit

Signed-off-by: zirain <zirain2009@gmail.com>

---------

Signed-off-by: David Alger <davidmalger@gmail.com>
Signed-off-by: zirain <zirain2009@gmail.com>
Co-authored-by: David Alger <davidmalger@gmail.com>
  • Loading branch information
zirain and davidalger authored Jul 3, 2024
1 parent acce649 commit 2ecfa06
Show file tree
Hide file tree
Showing 31 changed files with 1,304 additions and 104 deletions.
39 changes: 39 additions & 0 deletions examples/kubernetes/accesslog/als-accesslog.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: als-access-logging
namespace: envoy-gateway-system
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: als-access-logging
namespace: envoy-gateway-system
spec:
telemetry:
accessLog:
settings:
- format:
type: JSON
json:
attr1: val1
attr2: val2
sinks:
- type: ALS
als:
backendRefs:
- name: envoy-als
namespace: monitoring
port: 9000
http:
requestHeaders:
- x-client-ip-address
responseHeaders:
- cache-control
type: HTTP
7 changes: 7 additions & 0 deletions examples/kubernetes/accesslog/multi-sinks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ spec:
- type: File
file:
path: /dev/stdout
- type: ALS
als:
backendRefs:
- name: envoy-als
namespace: monitoring
port: 9000
type: HTTP
- type: OpenTelemetry
openTelemetry:
host: otel-collector.monitoring.svc.cluster.local
Expand Down
50 changes: 47 additions & 3 deletions internal/gatewayapi/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *

irAccessLog := &ir.AccessLog{}
// translate the access log configuration to the IR
for idx, accessLog := range envoyproxy.Spec.Telemetry.AccessLog.Settings {
for _, sink := range accessLog.Sinks {
for i, accessLog := range envoyproxy.Spec.Telemetry.AccessLog.Settings {
for j, sink := range accessLog.Sinks {
switch sink.Type {
case egv1a1.ProxyAccessLogSinkTypeFile:
if sink.File == nil {
Expand All @@ -273,6 +273,50 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
}
irAccessLog.JSON = append(irAccessLog.JSON, al)
}
case egv1a1.ProxyAccessLogSinkTypeALS:
if sink.ALS == nil {
continue
}

var logName string
if sink.ALS.LogName != nil {
logName = *sink.ALS.LogName
} else {
logName = fmt.Sprintf("%s/%s", envoyproxy.Namespace, envoyproxy.Name)
}

// TODO: how to get authority from the backendRefs?
ds, err := t.processBackendRefs(sink.ALS.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}

al := &ir.ALSAccessLog{
LogName: logName,
Destination: ir.RouteDestination{
Name: fmt.Sprintf("accesslog_als_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing?
Settings: ds,
},
Type: sink.ALS.Type,
}

if al.Type == egv1a1.ALSEnvoyProxyAccessLogTypeHTTP && sink.ALS.HTTP != nil {
http := &ir.ALSAccessLogHTTP{
RequestHeaders: sink.ALS.HTTP.RequestHeaders,
ResponseHeaders: sink.ALS.HTTP.ResponseHeaders,
ResponseTrailers: sink.ALS.HTTP.ResponseTrailers,
}
al.HTTP = http
}

switch accessLog.Format.Type {
case egv1a1.ProxyAccessLogFormatTypeJSON:
al.Attributes = accessLog.Format.JSON
case egv1a1.ProxyAccessLogFormatTypeText:
al.Text = accessLog.Format.Text
}

irAccessLog.ALS = append(irAccessLog.ALS, al)
case egv1a1.ProxyAccessLogSinkTypeOpenTelemetry:
if sink.OpenTelemetry == nil {
continue
Expand All @@ -289,7 +333,7 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
return nil, err
}
al.Destination = ir.RouteDestination{
Name: fmt.Sprintf("accesslog-%d", idx), // TODO: rename this, so that we can share backend with tracing?
Name: fmt.Sprintf("accesslog_otel_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing?
Settings: ds,
}

Expand Down
132 changes: 132 additions & 0 deletions internal/gatewayapi/testdata/envoyproxy-accesslog-als-json.in.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
envoyProxyForGatewayClass:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
namespace: envoy-gateway-system
name: test
spec:
telemetry:
accessLog:
settings:
- format:
type: JSON
json:
attr1: val1
attr2: val2
sinks:
- type: ALS
als:
logName: accesslog
backendRefs:
- name: envoy-als
namespace: monitoring
port: 9000
http:
requestHeaders:
- x-client-ip-address
responseHeaders:
- cache-control
responseTrailers:
- expires
type: HTTP
- type: ALS
als:
backendRefs:
- name: envoy-als
namespace: monitoring
port: 9000
type: TCP
provider:
type: Kubernetes
kubernetes:
envoyService:
type: LoadBalancer
envoyDeployment:
replicas: 2
container:
env:
- name: env_a
value: env_a_value
- name: env_b
value: env_b_name
image: "envoyproxy/envoy:distroless-dev"
resources:
requests:
cpu: 100m
memory: 512Mi
securityContext:
runAsUser: 2000
allowPrivilegeEscalation: false
pod:
annotations:
key1: val1
key2: val2
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cloud.google.com/gke-nodepool
operator: In
values:
- router-node
tolerations:
- effect: NoSchedule
key: node-type
operator: Exists
value: "router"
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
fsGroupChangePolicy: "OnRootMismatch"
volumes:
- name: certs
secret:
secretName: envoy-cert
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
services:
- apiVersion: v1
kind: Service
metadata:
name: envoy-als
namespace: monitoring
spec:
type: ClusterIP
ports:
- name: grpc
port: 9000
protocol: TCP
targetPort: 9000
endpointSlices:
- apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: endpointslice-envoy-als
namespace: monitoring
labels:
kubernetes.io/service-name: envoy-als
addressType: IPv4
ports:
- name: grpc
protocol: TCP
port: 9090
endpoints:
- addresses:
- "10.240.0.10"
conditions:
ready: true
Loading

0 comments on commit 2ecfa06

Please sign in to comment.