> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bronto.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Nginx logs, metrics, and traces with OpenTelemetry

> Collect Nginx access logs, error logs, stub_status metrics, and request traces with the OpenTelemetry Collector and forward all three signals to Bronto.

Forward Nginx access and error logs, and optionally request traces, to Bronto through a single OpenTelemetry Collector. See [Connect OpenTelemetry Collector to Bronto](/agent-setup/open-telemetry) for Collector basics.

## Prerequisites

* A Bronto account and API key ([how to create one](/Account-Management/API-Keys#create-a-new-api-key))
* Nginx running and writing logs (default paths: `/var/log/nginx/access.log` and `/var/log/nginx/error.log`)
* An [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/installation/) (recommended) or [Fluent Bit](https://docs.fluentbit.io/manual/installation/getting-started-with-fluent-bit) installed on the same host
* For traces: Nginx 1.25.3+ with the [`ngx_otel_module`](https://nginx.org/en/docs/ngx_otel_module.html) (install the `nginx-module-otel` package)

## Logs, metrics, and traces

Nginx emits request traces over OTLP/gRPC through `ngx_otel_module` and exposes connection/request metrics through `stub_status`.

The example uses the standard same-host OTLP/gRPC endpoint, `localhost:4317`. Change the host, port, and TLS settings when the Collector is not local or its receiver configuration differs.

**1. Enable tracing in Nginx.** Add `load_module` to the top of `nginx.conf` and the `otel_*` directives inside the `http` block:

```nginx nginx.conf theme={"dark"}
load_module modules/ngx_otel_module.so;

http {
    otel_exporter {
        endpoint localhost:4317;
    }
    otel_service_name  nginx;
    otel_trace         on;
    otel_trace_context propagate;

    server {
        listen 127.0.0.1:8080;
        location /status {
            stub_status;
            allow 127.0.0.1;
            deny all;
        }
    }
}
```

**2. Configure the Collector** to tail the log files and accept traces, then export each signal to Bronto:

```yaml /etc/otel/config.yaml theme={"dark"}
receivers:
  filelog/nginx:
    include:
      - /var/log/nginx/access.log
      - /var/log/nginx/error.log
    resource:
      service.name: nginx
      service.namespace: <YOUR_COLLECTION_NAME>
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
  nginx:
    endpoint: http://localhost:8080/status
    collection_interval: 30s

processors:
  batch:

exporters:
  otlphttp/brontologs:
    logs_endpoint: "https://ingestion.<REGION>.bronto.io/v1/logs"
    compression: gzip
    headers:
      x-bronto-api-key: <YOUR_API_KEY>
  otlphttp/brontometrics:
    metrics_endpoint: "https://ingestion.<REGION>.bronto.io/v1/metrics"
    compression: gzip
    headers:
      x-bronto-api-key: <YOUR_API_KEY>
  otlphttp/brontotraces:
    traces_endpoint: "https://ingestion.<REGION>.bronto.io/v1/traces"
    compression: gzip
    headers:
      x-bronto-api-key: <YOUR_API_KEY>

service:
  pipelines:
    logs:
      receivers: [filelog/nginx]
      processors: [batch]
      exporters: [otlphttp/brontologs]
    metrics:
      receivers: [nginx]
      processors: [batch]
      exporters: [otlphttp/brontometrics]
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlphttp/brontotraces]
```

Set `<REGION>` to `eu` or `us`. The `service.name` / `service.namespace` attributes (and `otel_service_name`) route data to the Bronto dataset and collection.

You can remove any signal pipeline you do not need.

For receiver options and available measurements, see the [Collector Contrib NGINX receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/nginxreceiver).

## What you will see in Bronto

Open [Search](https://app.bronto.io/search) and filter by `service.name = nginx`. Access logs in the default `combined` format carry the client IP, request method and path, HTTP status code, response size, referrer, and user agent; error logs carry a timestamp, severity level (`error`, `warn`, `crit`), and the message. Bronto's [Custom Parser](/core-features/custom-parser) extracts these fields server-side — no parser operators needed in the Collector.

Traces appear in [Explore Traces](/tracing/explore-traces) — one span per request, with the method, route, status code, and duration. See [Send Traces to Bronto](/tracing/send-traces) for more.

## Troubleshooting

* **No logs?** Confirm the Collector's user can read `/var/log/nginx/`. Run `sudo chmod +r /var/log/nginx/*.log` or add the user to the `adm` group, then restart the Collector.
* **No traces?** Confirm `ngx_otel_module` is loaded (`nginx -V`), `otel_trace` is `on`, and the `otel_exporter` endpoint matches the Collector's configured OTLP/gRPC receiver address.
* **Want structured fields at the source?** Switch Nginx to a JSON `log_format` (see the [Nginx log\_format reference](https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format)) for direct field extraction.
* For general issues, see [OTel Collector troubleshooting](https://opentelemetry.io/docs/collector/troubleshooting/).

## Alternative: Fluent Bit

If your organization already runs Fluent Bit, forward the Nginx log files with its `tail` input and HTTP output. Fluent Bit handles logs only — for traces, use the OpenTelemetry Collector above.

```ini fluent-bit.conf theme={"dark"}
[INPUT]
    name  tail
    path  /var/log/nginx/access.log,/var/log/nginx/error.log
    tag   nginx

[OUTPUT]
    name        http
    match       nginx
    host        ingestion.<REGION>.bronto.io
    port        443
    tls         on
    format      json_lines
    compress    gzip
    header      x-bronto-api-key    <YOUR_API_KEY>
    header      x-bronto-dataset    nginx
    header      x-bronto-collection <YOUR_COLLECTION_NAME>
```

Set **Format** to `json_lines`, not `json` — `json` sends a single array and breaks ingestion. See [Connect Fluent Bit to Bronto](/agent-setup/fluent-bit) for installation and the full output reference.
