Skip to content

Commit b11b01a

Browse files
authored
Add post: Enriching Kubernetes Ingress Logs with Better User and Request Insights (#7)
1 parent 6b700cc commit b11b01a

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
title: Enriching Kubernetes Ingress Logs with Better User and Request Insights
3+
description: Adding user identity and essential request details for improved monitoring in controller logs
4+
author: hemantapkh
5+
date: 2025-04-20 16:37:00 +0000
6+
categories: [Monitoring]
7+
tags: [kubernetes, nginx, ingress, observability, logging, devops]
8+
pin: false
9+
math: false
10+
mermaid: false
11+
image:
12+
path: https://assets.hemantapkh.com/blog/enriching-controller-logs/thumbnail.png
13+
alt: Image generated with DALL-E 3
14+
---
15+
16+
In this blog, I’m going to walk you through how to enrich your Ingress-Nginx Controller logs with valuable information about the users making request to your API and other important details, such as how long each request spends waiting, processing, and more. This helps you debug faster and get clearer insights into your traffic patterns all without needing expensive monitoring tools.
17+
18+
Since the Ingress acts as the main gateway to the cluster, logging those info here gives you a centralized view of all incoming requests.
19+
20+
## Add required info on response headers in your application
21+
22+
The first step is to have your application send essential user info like `X-User-ID`, `X-Org-ID`, and `X-User-Email` as response headers. This enables the ingress to include these details in the logs. Because the way to set these headers varies widely depending on the programming language and framework, I won’t go into those specifics here.
23+
24+
Besides these user headers, here are some additional headers I like to add to improve observability and make logs more meaningful. Feel free to include any of these in your app responses if they make sense for your use case:
25+
26+
- **X-Pod-Name:** The name of the pod handling the request. It usually comes from the `HOSTNAME` environment variable in the application pod.
27+
28+
- **X-Queue-Wait-Time:** This is the time a request spends waiting in the queue. For this, we need to send a header (for example, `X-Request-Start`) to the app that shows when the request first arrived at the ingress. The app can then subtract this time from when it starts processing the request to figure out how long the request waited. I’ll explain how to send this header to the upstream application in the [next](#sending-x-request-start-header-to-the-upstream) step.
29+
30+
- **X-Process-Time:** The actual time took to process the request without any queue time.
31+
32+
- **X-Original-Route:** The original route pattern of the endpoint, like `api/folder/<folder_id>`, instead of the full resolved path with IDs or params like `api/folder/25b95bea0d5a43919f36ac428c15f04f?page=2&limit=20`. This helps to make the logs easier to analyze and aggregate.
33+
34+
## Sending "X-Request-Start" header to the upstream
35+
36+
To send the `X-Request-Start` header to the upstream for calculating the queue wait time, create a ConfigMap:
37+
38+
```yaml
39+
apiVersion: v1
40+
kind: ConfigMap
41+
metadata:
42+
name: custom-headers
43+
namespace: ingress-nginx
44+
data:
45+
X-Request-Start: $msec
46+
```
47+
48+
Then, in the Ingress NGINX ConfigMap, set the `proxy-set-headers` field to reference the above ConfigMap:
49+
50+
```yaml
51+
data:
52+
proxy-set-headers: ingress-nginx/custom-headers
53+
```
54+
55+
This sets the `X-Request-Start` header to the current timestamp and send to the upstream application.
56+
57+
## Configure Ingress to to log the headers
58+
59+
Next, update the controller configMap to log your custom headers so they appear in the ingress logs.
60+
61+
To reference a response header in the log format, use the variable `$upstream_<header_name>`, where `<header_name>` is the lowercase request header name with dashes `(-)` replaced by underscores `(_)`. For example, the response header `X-User-ID` becomes `$http_x_user_id`.
62+
63+
> See the NGINX Ingress log-format [documentation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/log-format/) for the full list of available variables and examples.
64+
{: .prompt-tip }
65+
66+
```yaml
67+
apiVersion: v1
68+
kind: ConfigMap
69+
metadata:
70+
name: nginx-ingress-controller
71+
namespace: ingress-nginx
72+
data:
73+
log-format-escape-json: "true"
74+
log-format-upstream: '{<others>, "request_id":"$req_id", "remote_addr":"$remote_addr", "user_id":"$upstream_http_x_user_id","org_id":"$upstream_http_x_org_id"}'
75+
```
76+
77+
## Hide the headers from client responses
78+
79+
To prevent these headers from being sent to clients, list them under `hide-headers` in the Ingress ConfigMap.
80+
81+
```yaml
82+
data:
83+
hide-headers: X-User-Id, X-Org-Id, X-User-Email, X-Original-Route, X-Queue-Wait-Time, X-Process-Time, X-Pod-Name
84+
```
85+
86+
## Wrapping up
87+
88+
🎉 Now the ingress logs should contain information like user identity and request details. You can also create custom metrics and dashboards using tools like Google Cloud Metrics and Dashboards.
89+
90+
![Controller log](https://assets.hemantapkh.com/blog/enriching-controller-logs/controller-log.png)

0 commit comments

Comments
 (0)