In this guide, you use an Inja function to extract an environment variable value from the gateway proxy pod and add this value to the dynamic metadata filter in Envoy. Then, you inject the value that you stored in the dynamic metadata filter when writing access logs.

Before you begin

  1. Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.

  2. Get the external address of the gateway and save it in an environment variable.

Enable access logs

  1. Create a ListenerOption resource to define your access logging rules. The following example writes access logs to the stdout stream of the gateway proxy container by using a custom string format that is defined in the jsonFormat field. If no custom string format is defined, the default Envoy format is used.

      kubectl apply -f- <<EOF
    apiVersion: gateway.solo.io/v1
    kind: ListenerOption
    metadata:
      name: access-logs
      namespace: gloo-system
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: Gateway
        name: http
      options:
        accessLoggingService:
          accessLog:
          - fileSink:
              path: /dev/stdout
              jsonFormat:
                  start_time: "%START_TIME%"
                  method: "%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%"
                  path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
                  protocol: "%PROTOCOL%"
                  response_code: "%RESPONSE_CODE%"
                  response_flags: "%RESPONSE_FLAGS%"
                  bytes_received: "%BYTES_RECEIVED%"
                  bytes_sent: "%BYTES_SENT%"
                  total_duration: "%DURATION%"
                  resp_upstream_service_time: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
                  req_x_forwarded_for: "%REQ(X-FORWARDED-FOR)%"
                  user_agent: "%REQ(USER-AGENT)%"
                  request_id: "%REQ(X-REQUEST-ID)%"
                  authority: "%REQ(:AUTHORITY)%"
                  upstreamHost: "%UPSTREAM_HOST%"
                  upstreamCluster: "%UPSTREAM_CLUSTER%"
    EOF
      
  2. Send a request to the httpbin app on the www.example.com domain. Verify that your request succeeds and that you get back a 200 HTTP response code.

    Example output:

      HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    date: Fri, 07 Jun 2024 21:10:03 GMT
    x-envoy-upstream-service-time: 2
    server: envoy
    transfer-encoding: chunked
      
  3. Get the logs for the gateway pod and verify that you see an entry for each request that you sent to the httpbin app.

      kubectl -n gloo-system logs deployments/gloo-proxy-http | tail -1 | jq --sort-keys
      

    Example output:

      {
      "authority": "www.example.com:8080",
      "bytes_received": 0,
      "bytes_sent": 0,
      "method": "GET",
      "path": "/status/200",
      "protocol": "HTTP/1.1",
      "req_x_forwarded_for": null,
      "request_id": "a6758866-0f26-4c95-95d9-4032c365c498",
      "resp_upstream_service_time": "0",
      "response_code": 200,
      "response_flags": "-",
      "start_time": "2024-08-19T20:57:57.511Z",
      "total_duration": 1,
      "upstreamCluster": "kube-svc:httpbin-httpbin-8000_httpbin",
      "upstreamHost": "10.36.0.14:8080",
      "user_agent": "curl/7.77.0"
    }
      

Enrich access logs

  1. Create a RouteOption or VirtualHostOption resource with the following transformation rules:

    • The env Inja function is used to extract the POD_NAME environment variable from the gateway proxy pod.
    • The value of the environment variable is added to the pod_name key in the dynamic metadata values.
  2. Update the ListenerOption resource to include the pod_name from the dynamic metadata values.

      kubectl apply -f- <<EOF
    apiVersion: gateway.solo.io/v1
    kind: ListenerOption
    metadata:
      name: access-logs
      namespace: gloo-system
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: Gateway
        name: http
      options:
        accessLoggingService:
          accessLog:
          - fileSink:
              path: /dev/stdout
              jsonFormat:
                  start_time: "%START_TIME%"
                  method: "%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%"
                  path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
                  protocol: "%PROTOCOL%"
                  response_code: "%RESPONSE_CODE%"
                  response_flags: "%RESPONSE_FLAGS%"
                  bytes_received: "%BYTES_RECEIVED%"
                  bytes_sent: "%BYTES_SENT%"
                  total_duration: "%DURATION%"
                  resp_upstream_service_time: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
                  req_x_forwarded_for: "%REQ(X-FORWARDED-FOR)%"
                  user_agent: "%REQ(USER-AGENT)%"
                  request_id: "%REQ(X-REQUEST-ID)%"
                  authority: "%REQ(:AUTHORITY)%"
                  upstreamHost: "%UPSTREAM_HOST%"
                  upstreamCluster: "%UPSTREAM_CLUSTER%"
                  pod_name: '%DYNAMIC_METADATA(io.solo.transformation:pod_name)%'
    EOF
      
  3. Send another request to the httpbin app.

  4. Review the access logs and verify that the pod_name is now injected into your access logs.

      kubectl -n gloo-system logs deployments/gloo-proxy-http | tail -1 | jq --sort-keys
      

    Example output:

       {
         "authority": "www.example.com:8080",
         "bytes_received": 0,
         "bytes_sent": 0,
         "method": "GET",
         "path": "/status/200",
         "pod_name": "gloo-proxy-http-844ff8bc4d-dh4pn",
         "protocol": "HTTP/1.1",
         "req_x_forwarded_for": null,
         "request_id": "132892e6-085e-400f-98da-c055ca04b714",
         "resp_upstream_service_time": "2",
         "response_code": 200,
         "response_flags": "-",
         "start_time": "2025-05-14T16:43:07.506Z",
         "total_duration": 2,
         "upstreamCluster": "kube-svc_httpbin-httpbin-8000_httpbin_httpbin_httpbin_8000",
         "upstreamHost": "10.0.12.250:8080",
         "user_agent": "curl/8.7.1"
       }
       

Cleanup

You can remove the resources that you created in this guide.

  kubectl delete virtualhostoption transformation -n gloo-system
kubectl delete routeoption transformation -n httpbin
kubectl delete listeneroption access-logs -n gloo-system