# Configure Centralized Logging

API7 Gateway produces several types of logs that are essential for debugging and operating the platform. For production environments, forward these logs to a centralized log management system such as Elasticsearch, Splunk, or AWS CloudWatch.

## Log Types and Locations[​](#log-types-and-locations "Direct link to Log Types and Locations")

Data plane and control plane components produce separate access and error logs, with destinations that depend on the deployment method.

### Data Plane Logs[​](#data-plane-logs "Direct link to Data Plane Logs")

The data plane produces an error log and an access log. The default configuration uses paths relative to the gateway's installation prefix:

| Log type   | Description                                                                | Default destination |
| ---------- | -------------------------------------------------------------------------- | ------------------- |
| Error log  | Gateway startup events, plugin errors, upstream failures, and core errors. | `logs/error.log`    |
| Access log | One line per request processed by the gateway.                             | `logs/access.log`   |

In a non-container installation, these destinations are regular files under the installation prefix. In the official container images, the resolved paths `/usr/local/apisix/logs/error.log` and `/usr/local/apisix/logs/access.log` are symbolic links to `/dev/stderr` and `/dev/stdout`, respectively. The gateway Helm chart writes to those device paths directly. Therefore, the default container deployment has no regular access or error log files to tail; collect its container output instead.

Both destinations are configurable. See [Configure Data Plane Logging](#configure-data-plane-logging) below and [Collect Gateway Logs on Kubernetes](https://docs.api7.ai/api7-gateway/observability/kubernetes-log-collection.md) for the volume, rotation, and collector requirements on Kubernetes.

### Control Plane Logs[​](#control-plane-logs "Direct link to Control Plane Logs")

Dashboard, DP Manager, and Developer Portal produce error and access logs. The official Docker Compose and Helm configurations use the following default destinations:

| Log type   | Description                                                                                                                            | Default destination |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| Error log  | Component events, warnings, and errors, including configuration processing, database access, and configuration synchronization issues. | `stderr`            |
| Access log | HTTP request summaries, including the request path, result, duration, and source.                                                      | `stdout`            |

In the official Docker Compose and Helm configurations, Dashboard, DP Manager, and Developer Portal write error logs directly to standard error (`stderr`) and access logs directly to standard output (`stdout`). These destinations are process output streams, not file paths or symbolic links. Therefore, the default container deployment has no regular access or error log files to tail; collect both streams from its container output instead.

For RPM installations from version 3.10.2, Dashboard writes to `/var/log/api7/dashboard.log` and `/var/log/api7/dashboard-access.log` by default, while DP Manager writes to `/var/log/api7/dp-manager.log` and `/var/log/api7/dp-manager-access.log`. Both components use `warn` as the default application log level.

Both destinations are configurable. See [Configure Control Plane Logging](#configure-control-plane-logging) below.

Use your container runtime to inspect the logs, for example:

```
docker logs <api7-ee-dashboard-container>

docker logs <api7-ee-dp-manager-container>

docker logs <api7-ee-developer-portal-container>
```

Requests to `/healthz` are excluded from access logs.

Access logs include the request path and query string. In versions 3.10.0 through 3.10.8, all query parameter values, including the credential in `key_value`, are logged unchanged. Starting in 3.10.9, its value is masked as `key_value=***`. Other query parameters remain unmasked, so avoid including sensitive data in query strings.

The optional File Server and API Usage services also produce error and access logs. In Helm, File Server defaults to `warn`; in Docker Compose, API Usage defaults to `debug`. Both write application logs to `stderr` and access logs to `stdout`. The configuration examples below focus on Dashboard, DP Manager, and Developer Portal.

#### Control Plane Log Contents[​](#control-plane-log-contents "Direct link to Control Plane Log Contents")

* **Application logs.** Entries from the main application logger include a timestamp, level, code location, message, and event-specific fields. Request-scoped entries can include `request_id`, which can correlate them with the access log for the same request.
* **Access logs.** Entries begin with `[HTTP]` and record the timestamp, request ID, method, path and query string, status code, duration, client IP, User-Agent, user ID, request and response body lengths, and any error message attached during request processing. A missing request ID or user ID appears as `-`. Values such as the path, User-Agent, and error message can contain spaces, so do not parse entries by splitting on spaces. Access logs record body lengths, not complete request or response bodies.

Covered administrative changes are recorded separately in the [audit log](https://docs.api7.ai/api7-gateway/security-and-compliance/audit-logs.md), which is viewable in the Dashboard. See that page for coverage limitations and sensitive-data handling.

## Configure Data Plane Logging[​](#configure-data-plane-logging "Direct link to Configure Data Plane Logging")

Data plane logging settings control log destinations, error-log verbosity, and access-log format.

### Set Log Destinations and Error Log Level[​](#set-log-destinations-and-error-log-level "Direct link to Set Log Destinations and Error Log Level")

Configure log destinations and error-log verbosity with the following keys in the gateway's `config.yaml`:

conf/config.yaml

```
nginx_config:

  error_log: logs/error.log

  error_log_level: warn  # debug, info, notice, warn, error, crit, alert, emerg

  http:

    enable_access_log: true

    access_log: logs/access.log

    access_log_format: '$remote_addr - $remote_user [$time_local] $http_host "$request_line" $status $body_bytes_sent $request_time "$http_referer" "$http_user_agent" $upstream_addr $upstream_status $upstream_response_time "$upstream_scheme://$upstream_host$upstream_uri" "$apisix_request_id"'

    access_log_format_escape: default  # default or json
```

The example shows the default destinations. Relative paths are resolved against the gateway's installation prefix. To write regular files in an official container image, choose paths outside `/usr/local/apisix/logs/`, such as `/var/log/apisix/access.log` and `/var/log/apisix/error.log`. Create the directory before starting the gateway, grant the gateway process write access, and mount a volume at that path.

After changing any of these values, reload or restart the gateway for the new configuration to take effect.

### Use a JSON Access Log Format[​](#use-a-json-access-log-format "Direct link to Use a JSON Access Log Format")

For easier parsing by log shippers, set a JSON access log format and switch escaping to `json`:

conf/config.yaml

```
nginx_config:

  http:

    access_log_format: '{"time_local":"$time_local","remote_addr":"$remote_addr","status":"$status","request_time":"$request_time","upstream_status":"$upstream_status","request":"$request"}'

    access_log_format_escape: json
```

To include consumer labels in each access log line, see [Include Consumer Labels in Access Logs](https://docs.api7.ai/api7-gateway/observability/consumer-label-based-logging.md).

## Configure Control Plane Logging[​](#configure-control-plane-logging "Direct link to Configure Control Plane Logging")

Dashboard, DP Manager, and Developer Portal use separate configurations with the same `log` settings. Update each component that you want to change.

### Configure Logging in Configuration Files[​](#configure-logging-in-configuration-files "Direct link to Configure Logging in Configuration Files")

Edit the `log` section in the configuration file used by the component, preserving the other settings:

| Deployment                                 | Component            | Configuration file                                |
| ------------------------------------------ | -------------------- | ------------------------------------------------- |
| Bundled control-plane Docker Compose stack | Dashboard            | `dashboard_conf/conf.yaml`                        |
| Bundled control-plane Docker Compose stack | DP Manager           | `dp_manager_conf/conf.yaml`                       |
| Bundled control-plane Docker Compose stack | Developer Portal API | `developer_portal_conf/conf.yaml`                 |
| Standalone Developer Portal Docker Compose | Developer Portal API | `backend_conf/conf.yaml`                          |
| RPM, version 3.10.2 or later               | Dashboard            | `/usr/local/api7/dashboard/conf/dashboard.yaml`   |
| RPM, version 3.10.2 or later               | DP Manager           | `/usr/local/api7/dp-manager/conf/dp-manager.yaml` |

The following example matches the logging defaults in the official Docker Compose and Helm configurations for Dashboard, DP Manager, and Developer Portal:

```
log:

  level: warn

  output: stderr

  access_log: stdout
```

| Setting          | Description                                                                                                                                                                      |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `log.level`      | The minimum application log level. Accepted values are `debug`, `info`, `warn`, `error`, `panic`, and `fatal`. At `warn`, warnings, errors, and more severe events are recorded. |
| `log.output`     | The application log destination: `stderr`, `stdout`, or a file path.                                                                                                             |
| `log.access_log` | The access log destination: `stdout`, `stderr`, or a file path.                                                                                                                  |

Access logs have no separate log level and are not filtered by `log.level`. Setting `log.access_log` to an empty string still writes access logs to `stdout`; it does not disable access logging. Changing `log.level` neither disables access logging nor adds fields to access log entries.

For file output, create the parent directory in advance and grant the running user write permission. Logs are appended to files. In containers, mount persistent storage for that directory and configure log collection, rotation, and retention.

When `log.output` is `stdout` or `stderr`, application log entries use colored console encoding and can contain ANSI color codes. When `log.output` is a file, application log entries use JSON, while database (GORM) and etcd-compatibility (kine) entries remain plain text in the same file. Configure the log collector to handle these formats.

Restart the corresponding component after changing its configuration.

### Configure Logging with Helm[​](#configure-logging-with-helm "Direct link to Configure Logging with Helm")

In your existing values file for the `api7/api7ee3` control plane chart, update `dashboard_configuration.log`, `dp_manager_configuration.log`, and `developer_portal_configuration.log` as needed. Preserve the other settings. The following example sets the error log level to `warn`, sends error logs to `stderr`, and sends access logs to `stdout` for all three components:

values.yaml

```
dashboard_configuration:

  log:

    level: warn

    output: stderr

    access_log: stdout



dp_manager_configuration:

  log:

    level: warn

    output: stderr

    access_log: stdout



developer_portal_configuration:

  log:

    level: warn

    output: stderr

    access_log: stdout
```

Update the deployment using the currently installed chart version and a values file containing your complete existing configuration:

```
helm upgrade <release-name> api7/api7ee3 \

  --namespace <namespace> \

  --version <installed-chart-version> \

  -f <values-file>
```

The chart triggers a rolling update of the corresponding Pods when their configuration changes. After the update completes, check the logs of the new Pods. For more deployment configuration details, see [Deploy API7 Enterprise on Kubernetes](https://docs.api7.ai/api7-gateway/install/deploy-on-kubernetes.md).

## Forward Logs to a Centralized System[​](#forward-logs-to-a-centralized-system "Direct link to Forward Logs to a Centralized System")

You have two complementary options:

* **Collect container output or ship configured log files.** This applies to both data plane and control plane logs. In container deployments, collect standard output and standard error unless you explicitly configure regular files. For file output, run a log forwarder such as Fluentd, Vector, Filebeat, or Logstash and tail the configured paths, such as `/var/log/apisix/access.log` and `/var/log/apisix/error.log` for the data plane. This works with any backend and decouples log delivery from the request path.
* **Stream data plane request logs directly from a route.** Use one of the gateway's logger plugins to send structured request logs over the network without writing them to disk first. These plugins do not forward control plane logs. Available logger plugins include [`http-logger`](https://docs.api7.ai/hub/http-logger.md), [`kafka-logger`](https://docs.api7.ai/hub/kafka-logger.md), [`syslog`](https://docs.api7.ai/hub/syslog.md), [`splunk-hec-logging`](https://docs.api7.ai/hub/splunk-hec-logging.md), [`google-cloud-logging`](https://docs.api7.ai/hub/google-cloud-logging.md), [`elasticsearch-logger`](https://docs.api7.ai/hub/elasticsearch-logger.md), [`rocketmq-logger`](https://docs.api7.ai/hub/rocketmq-logger.md), and [`clickhouse-logger`](https://docs.api7.ai/hub/clickhouse-logger.md). For a full Splunk HEC walkthrough, see [Send Access Logs to Splunk](https://docs.api7.ai/api7-gateway/observability/splunk-integration.md).

For data plane logs on Kubernetes, see [Collect Gateway Logs on Kubernetes](https://docs.api7.ai/api7-gateway/observability/kubernetes-log-collection.md) to choose between container output and files in the pod, and to configure the OpenTelemetry Collector or Filebeat. For a Splunk-specific gateway error-log workflow, see [Send Kubernetes Error Logs to Splunk](https://docs.api7.ai/api7-gateway/observability/kubernetes-error-log-forwarding.md).

## Next Steps[​](#next-steps "Direct link to Next Steps")

* [Include Consumer Labels in Access Logs](https://docs.api7.ai/api7-gateway/observability/consumer-label-based-logging.md) — include per-consumer metadata in every access log line.
* [Collect Gateway Logs on Kubernetes](https://docs.api7.ai/api7-gateway/observability/kubernetes-log-collection.md) — collect container output or files in the pod with the OpenTelemetry Collector or Filebeat.
* [Send Access Logs to Splunk](https://docs.api7.ai/api7-gateway/observability/splunk-integration.md) — stream logs to Splunk over HTTP.
* [Send Kubernetes Error Logs to Splunk](https://docs.api7.ai/api7-gateway/observability/kubernetes-error-log-forwarding.md) — collect Kubernetes gateway error logs with the Splunk OpenTelemetry Collector.
* [Configure Alerts](https://docs.api7.ai/api7-gateway/observability/alerts.md) — get notified when error rates breach a threshold.
* [Audit Logs](https://docs.api7.ai/api7-gateway/security-and-compliance/audit-logs.md) — track configuration changes made through the Dashboard or Admin API.
