Skip to content

Commit 8be8ec2

Browse files
authored
Merge pull request #4588 from ClickHouse/clickstack-nginx-guide
Initial Version of nginx guide
2 parents 377bcbf + caab560 commit 8be8ec2

File tree

17 files changed

+704
-3
lines changed

17 files changed

+704
-3
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
slug: /use-cases/observability/clickstack/integration-guides
3+
pagination_prev: null
4+
pagination_next: null
5+
description: 'Data ingestion for ClickStack - The ClickHouse Observability Stack'
6+
title: 'Integration Guides'
7+
doc_type: 'landing-page'
8+
keywords: ['ClickStack data ingestion', 'observability data ingestion', 'ClickStack integration guides']
9+
---
10+
11+
ClickStack provides multiple ways to ingest observability data into your ClickHouse instance. This section contains
12+
quick start guides for various log and trace sources.
13+
14+
| Section | Description |
15+
|------|-------------|
16+
| [Nginx Logs](./nginx-logs.md) | Introduction to data ingestion methods and architecture |
17+
| [Nginx Traces](./nginx-traces.md) | Introduction to data ingestion methods and architecture |
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
---
2+
slug: /use-cases/observability/clickstack/integrations/nginx
3+
title: 'Monitoring Nginx Logs with ClickStack'
4+
sidebar_label: 'Nginx Logs'
5+
pagination_prev: null
6+
pagination_next: null
7+
description: 'Monitoring Nginx with ClickStack'
8+
doc_type: 'guide'
9+
---
10+
11+
import Image from '@theme/IdealImage';
12+
import useBaseUrl from '@docusaurus/useBaseUrl';
13+
import import_dashboard from '@site/static/images/clickstack/import-dashboard.png';
14+
import finish_import from '@site/static/images/clickstack/finish-import.png';
15+
import example_dashboard from '@site/static/images/clickstack/example-logs-dashboard.png';
16+
import log_view from '@site/static/images/clickstack/log-view.png';
17+
import search_view from '@site/static/images/clickstack/nginx-logs-search-view.png';
18+
19+
# Monitoring Nginx Logs with ClickStack {#nginx-clickstack}
20+
21+
::::note[TL;DR]
22+
This guide shows you how to monitor nginx with ClickStack by configuring the OpenTelemetry collector to ingest nginx access logs. You'll learn how to:
23+
24+
- Configure nginx to output JSON-formatted logs
25+
- Create a custom OTel collector configuration for log ingestion
26+
- Deploy ClickStack with your custom configuration
27+
- Use a pre-built dashboard to visualize nginx metrics (requests, errors, latency)
28+
29+
A demo dataset with 10,000 sample logs is provided to test the integration before connecting your production nginx instances.
30+
31+
Time Required: 5-10 minutes.
32+
::::
33+
34+
## Prerequisites {#prerequisites}
35+
- ClickStack instance running
36+
- Existing nginx installation
37+
- Access to modify nginx configuration files
38+
39+
## Integration with existing nginx {#existing-nginx}
40+
41+
This section covers configuring your existing nginx installation to send logs to ClickStack by modifying the ClickStack OTel collector configuration.
42+
43+
<VerticalStepper>
44+
45+
## Configure nginx log format {#configure-nginx}
46+
First, configure nginx to output logs in JSON format for easier parsing. Add this log format definition to your nginx.conf:
47+
48+
The `nginx.conf` file is typically located at:
49+
- **Linux (apt/yum)**: `/etc/nginx/nginx.conf`
50+
- **macOS (Homebrew)**: `/usr/local/etc/nginx/nginx.conf` or `/opt/homebrew/etc/nginx/nginx.conf`
51+
- **Docker**: Configuration is usually mounted as a volume
52+
53+
Add this log format definition to the `http` block:
54+
55+
```nginx
56+
http {
57+
log_format json_combined escape=json
58+
'{'
59+
'"time_local":"$time_local",'
60+
'"remote_addr":"$remote_addr",'
61+
'"request_method":"$request_method",'
62+
'"request_uri":"$request_uri",'
63+
'"status":$status,'
64+
'"body_bytes_sent":$body_bytes_sent,'
65+
'"request_time":$request_time,'
66+
'"upstream_response_time":"$upstream_response_time",'
67+
'"http_referer":"$http_referer",'
68+
'"http_user_agent":"$http_user_agent"'
69+
'}';
70+
71+
access_log /var/log/nginx/access.log json_combined;
72+
error_log /var/log/nginx/error.log warn;
73+
}
74+
```
75+
76+
After making this change, reload nginx.
77+
78+
## Create custom otel collector configuration {#custom-otel}
79+
80+
ClickStack allows you to extend the base OpenTelemetry Collector configuration by mounting a custom configuration file and setting an environment variable. The custom configuration is merged with the base configuration managed by HyperDX via OpAMP.
81+
82+
Create a file named nginx-monitoring.yaml with the following configuration:
83+
84+
```yaml
85+
receivers:
86+
filelog:
87+
include:
88+
- /var/log/nginx/access.log
89+
- /var/log/nginx/error.log
90+
start_at: end
91+
operators:
92+
- type: json_parser
93+
parse_from: body
94+
parse_to: attributes
95+
- type: time_parser
96+
parse_from: attributes.time_local
97+
layout: '%d/%b/%Y:%H:%M:%S %z'
98+
- type: add
99+
field: attributes.source
100+
value: "nginx"
101+
102+
service:
103+
pipelines:
104+
logs/nginx:
105+
receivers: [filelog]
106+
processors:
107+
- memory_limiter
108+
- transform
109+
- batch
110+
exporters:
111+
- clickhouse
112+
```
113+
114+
This configuration:
115+
- Reads nginx logs from their standard locations
116+
- Parses JSON log entries
117+
- Extracts and preserves the original log timestamps
118+
- Adds source: nginx attribute for filtering in HyperDX
119+
- Routes logs to the ClickHouse exporter via a dedicated pipeline
120+
121+
::::note
122+
- You only define new receivers and pipelines in the custom config
123+
- The processors (memory_limiter, transform, batch) and exporters (clickhouse) are already defined in the base ClickStack configuration - you just reference them by name
124+
- The time_parser operator extracts timestamps from nginx's time_local field to preserve original log timing
125+
- The pipelines route data from your receivers to the ClickHouse exporter via the existing processors
126+
::::
127+
128+
## Configure ClickStack to load custom configuration {#load-custom}
129+
130+
To enable custom collector configuration in your existing ClickStack deployment, you must:
131+
132+
1. Mount the custom config file at /etc/otelcol-contrib/custom.config.yaml
133+
2. Set the environment variable CUSTOM_OTELCOL_CONFIG_FILE=/etc/otelcol-contrib/custom.config.yaml
134+
3. Mount your nginx log directories so the collector can read them
135+
136+
### Option 1: Docker Compose {#docker-compose}
137+
138+
Update your ClickStack deployment configuration:
139+
```yaml
140+
services:
141+
clickstack:
142+
# ... existing configuration ...
143+
environment:
144+
- CUSTOM_OTELCOL_CONFIG_FILE=/etc/otelcol-contrib/custom.config.yaml
145+
# ... other environment variables ...
146+
volumes:
147+
- ./nginx-monitoring.yaml:/etc/otelcol-contrib/custom.config.yaml:ro
148+
- /var/log/nginx:/var/log/nginx:ro
149+
# ... other volumes ...
150+
```
151+
152+
### Option 2: Docker Run (All-in-One Image) {#all-in-one}
153+
154+
If using the all-in-one image with docker run:
155+
```bash
156+
docker run --name clickstack \
157+
-p 8080:8080 -p 4317:4317 -p 4318:4318 \
158+
-e CUSTOM_OTELCOL_CONFIG_FILE=/etc/otelcol-contrib/custom.config.yaml \
159+
-v "$(pwd)/nginx-monitoring.yaml:/etc/otelcol-contrib/custom.config.yaml:ro" \
160+
-v /var/log/nginx:/var/log/nginx:ro \
161+
docker.hyperdx.io/hyperdx/hyperdx-all-in-one:latest
162+
```
163+
164+
::::note
165+
Ensure the ClickStack collector has appropriate permissions to read the nginx log files. In production, use read-only mounts (:ro) and follow the principle of least privilege.
166+
::::
167+
168+
## Verifying Logs in ClickStack {#verifying-logs}
169+
Once configured, log into HyperDX and verify logs are flowing:
170+
171+
1. Navigate to the Logs view
172+
2. Verify you see JSON-parsed log entries with fields like request, request_time, upstream_response_time, etc.
173+
174+
This is an example of what you should see:
175+
176+
<Image img={search_view} alt="Log view"/>
177+
178+
<Image img={log_view} alt="Log view"/>
179+
180+
</VerticalStepper>
181+
182+
## Demo dataset {#demo-dataset}
183+
184+
For users who want to test the nginx integration before configuring their production systems, we provide a sample dataset of pre-generated nginx access logs with realistic traffic patterns.
185+
186+
<VerticalStepper>
187+
188+
## Download the sample dataset {#download-sample}
189+
190+
Download the sample log file and update timestamps to the current time:
191+
192+
```bash
193+
# Download the logs
194+
curl -O https://datasets-documentation.s3.eu-west-3.amazonaws.com/clickstack-integrations/access.log
195+
```
196+
197+
The dataset includes:
198+
- 10,000 log entries with realistic traffic patterns
199+
- Various endpoints and HTTP methods
200+
- Mix of successful requests and errors
201+
- Realistic response times and byte counts
202+
- Timestamps now distributed over recent time
203+
204+
## Create test collector configuration {#test-config}
205+
206+
Create a file named `nginx-demo.yaml` with the following configuration:
207+
208+
```yaml
209+
cat > nginx-demo.yaml << 'EOF'
210+
receivers:
211+
filelog:
212+
include:
213+
- /tmp/nginx-demo/access.log
214+
start_at: beginning # Read from beginning for demo data
215+
operators:
216+
- type: json_parser
217+
parse_from: body
218+
parse_to: attributes
219+
- type: time_parser
220+
parse_from: attributes.time_local
221+
layout: '%d/%b/%Y:%H:%M:%S %z'
222+
- type: add
223+
field: attributes.source
224+
value: "nginx-demo"
225+
226+
service:
227+
pipelines:
228+
logs/nginx-demo:
229+
receivers: [filelog]
230+
processors:
231+
- memory_limiter
232+
- transform
233+
- batch
234+
exporters:
235+
- clickhouse
236+
EOF
237+
```
238+
239+
## Run ClickStack with demo configuration {#run-demo}
240+
241+
Run ClickStack with the demo logs and configuration:
242+
243+
```bash
244+
docker run --name clickstack-demo \
245+
-p 8080:8080 -p 4317:4317 -p 4318:4318 \
246+
-e CUSTOM_OTELCOL_CONFIG_FILE=/etc/otelcol-contrib/custom.config.yaml \
247+
-v "$(pwd)/nginx-demo.yaml:/etc/otelcol-contrib/custom.config.yaml:ro" \
248+
-v "$(pwd)/access.log:/tmp/nginx-demo/access.log:ro" \
249+
docker.hyperdx.io/hyperdx/hyperdx-all-in-one:latest
250+
```
251+
252+
## Verify logs in HyperDX {#verify-demo-logs}
253+
254+
Once ClickStack is running (you may have to create an account and login first):
255+
256+
1. Open [HyperDX](http://localhost:8080/search?from=1760976000000&to=1761062400000&isLive=false&source=690235c1a9b7fc5a7c0fffc7&select=Timestamp,ServiceName,SeverityText,Body&where=&whereLanguage=lucene&filters=[]&orderBy=)
257+
258+
::::note
259+
It is important to use the link above to get the correct time range, if you don't use this link set your time range to Oct 20 11:00:00 - Oct 21 11:00:00 to see proper results.
260+
::::
261+
262+
Here's what you should see in your search view:
263+
264+
<Image img={search_view} alt="Log view"/>
265+
266+
<Image img={log_view} alt="Log view"/>
267+
268+
</VerticalStepper>
269+
270+
## Dashboards and visualization {#dashboards}
271+
272+
To help you get started monitoring nginx with ClickStack, we provide essential visualizations for nginx logs.
273+
274+
<VerticalStepper>
275+
## <a href={useBaseUrl('/examples/example-logs-dashboard.json')} download="nginx-logs-dashboard.json">Download</a> the dashboard configuration.
276+
277+
## Import Pre-built Dashboard {#import-dashboard}
278+
1. Open HyperDX and navigate to the Dashboards section.
279+
2. Click "Import Dashboard" in the upper right corner under the ellipses.
280+
281+
<Image img={import_dashboard} alt="Import Dashboard"/>
282+
283+
3. Upload the nginx-logs-dashboard.json file and click finish import.
284+
285+
<Image img={finish_import} alt="Finish Import"/>
286+
287+
## The dashboard will be created with all visualizations pre-configured. {#created-dashboard}
288+
289+
<Image img={example_dashboard} alt="Example Dashboard"/>
290+
291+
</VerticalStepper>
292+
293+
## Troubleshooting {#troubleshooting}
294+
295+
### Custom config not loading {#troubleshooting-not-loading}
296+
297+
- Verify the environment variable CUSTOM_OTELCOL_CONFIG_FILE is set correctly
298+
299+
```bash
300+
docker exec <container-name> printenv CUSTOM_OTELCOL_CONFIG_FILE
301+
```
302+
303+
- Check that the custom config file is mounted at /etc/otelcol-contrib/custom.config.yaml
304+
305+
```bash
306+
docker exec <container-name> ls -lh /etc/otelcol-contrib/custom.config.yaml
307+
```
308+
309+
- View the custom config content to verify it's readable
310+
311+
```bash
312+
docker exec <container-name> cat /etc/otelcol-contrib/custom.config.yaml
313+
```
314+
315+
### No logs appearing in HyperDX {#no-logs}
316+
317+
- Ensure nginx is writing JSON logs
318+
```bash
319+
tail -f /var/log/nginx/access.log
320+
```
321+
- Check the collector can read the logs
322+
```bash
323+
docker exec `<container>` cat /var/log/nginx/access.log
324+
```
325+
326+
- Verify the effective config includes your filelog receiver
327+
```bash
328+
docker exec `<container>` cat /etc/otel/supervisor-data/effective.yaml | grep filelog
329+
```
330+
331+
- Check for errors in the collector logs
332+
```bash
333+
docker exec `<container>` cat /etc/otel/supervisor-data/agent.log
334+
```
335+
336+
## Next Steps {#next-steps}
337+
If you want to explore further, here are some next steps to experiment with your dashboard
338+
339+
- Set up alerts for critical metrics (error rates, latency thresholds)
340+
- Create additional dashboards for specific use cases (API monitoring, security events)

0 commit comments

Comments
 (0)