Skip to main content
Version: 3.19.0

Log with Elasticsearch

Elasticsearch is a popular JSON-based datastore for storing and indexing large volumes of data. It is often used to store logs from various sources and works with tools like Logstash and Kibana to form an entire observability stack known as the Elastic (ELK) Stack.

APISIX supports forwarding its logs directly to Elasticsearch through the elasticsearch-logger plugin. These logs can then be searched, filtered, and visualized through Kibana to gather insights to manage applications.

This guide will show you how to enable the elasticsearch-logger plugin to integrate APISIX with the ELK stack for observability.

Prerequisite(s)​

  • Install Docker.
  • Install cURL to send requests to the services for validation.
  • Follow the Getting Started tutorial to start a new APISIX instance in Docker.
  • If you use the Admin API examples and authentication is enabled, export an admin-role key as ADMIN_API_KEY. Configure the key under deployment.admin.admin_key. The Docker quickstart disables authentication for local evaluation; keep it enabled in production.

Start Elasticsearch and Kibana​

Set passwords for the built-in Elasticsearch users used in this local example:

export ELASTIC_PASSWORD="apisix-elastic-pass"
export KIBANA_SYSTEM_PASSWORD="apisix-kibana-pass"

Create a data volume and start Elasticsearch with authentication enabled:

docker volume create apisix-quickstart-elasticsearch-data

docker run -d --name apisix-quickstart-elasticsearch \
--network apisix-quickstart-net \
-p 9200:9200 \
-e discovery.type=single-node \
-e xpack.security.enabled=true \
-e xpack.security.http.ssl.enabled=false \
-e ELASTIC_PASSWORD="${ELASTIC_PASSWORD}" \
-e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
-v apisix-quickstart-elasticsearch-data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:9.4.2

❶ Attach Elasticsearch to the APISIX quickstart network so that APISIX and Kibana can reach it by container name.

❷ Disable HTTP TLS only for this isolated local example. In production, use HTTPS endpoints and keep the plugin's ssl_verify option enabled so that APISIX verifies the Elasticsearch certificate.

❸ Persist Elasticsearch data in the named Docker volume created above.

Wait up to two minutes for Elasticsearch to start, then verify that authentication succeeds:

curl --fail --silent --show-error \
--user "elastic:${ELASTIC_PASSWORD}" \
--retry 24 \
--retry-delay 5 \
--retry-connrefused \
--retry-max-time 120 \
--max-time 5 \
--output /dev/null \
"http://127.0.0.1:9200"

Set the password Kibana uses to connect to Elasticsearch:

curl -fsS -u "elastic:${ELASTIC_PASSWORD}" \
"http://127.0.0.1:9200/_security/user/kibana_system/_password" \
-X POST \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"password": "${KIBANA_SYSTEM_PASSWORD}"
}
EOF

Create a data volume and start the matching Kibana version:

docker volume create apisix-quickstart-kibana-data

docker run -d --name apisix-quickstart-kibana \
--network apisix-quickstart-net \
-p 5601:5601 \
-e ELASTICSEARCH_HOSTS="http://apisix-quickstart-elasticsearch:9200" \
-e ELASTICSEARCH_USERNAME="kibana_system" \
-e ELASTICSEARCH_PASSWORD="${KIBANA_SYSTEM_PASSWORD}" \
-v apisix-quickstart-kibana-data:/usr/share/kibana/data \
docker.elastic.co/kibana/kibana:9.4.2

Enable elasticsearch-logger Plugin​

Enable elasticsearch-logger globally and create a sample route to generate logs. Alternatively, you can enable the plugin on a route.

Enable the elasticsearch-logger plugin on all routes:

curl "http://127.0.0.1:9180/apisix/admin/global_rules/elasticsearch" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"plugins": {
"elasticsearch-logger": {
"endpoint_addrs": [
"http://apisix-quickstart-elasticsearch:9200"
],
"field": {
"index": "gateway-{%Y.%m.%d}"
},
"auth": {
"username": "elastic",
"password": "${ELASTIC_PASSWORD}"
},
"timeout": 60,
"retry_delay": 1,
"buffer_duration": 60,
"max_retry_count": 0,
"batch_max_size": 5,
"inactive_timeout": 5
}
}
}
EOF

❶ Create a daily index by resolving the date expression, for example, to gateway-2026.07.21.

Create a sample route. Setting pass_host to node sends the upstream hostname in the Host header:

curl "http://127.0.0.1:9180/apisix/admin/routes/observability-logs" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"uri": "/get",
"upstream": {
"type": "roundrobin",
"pass_host": "node",
"nodes": {
"postman-echo.com:80": 1
}
}
}'

Customize Log Format​

Customize the log format for elasticsearch-logger before generating traffic. The log format of most APISIX logging plugins can be customized locally on the plugin (e.g. bound to a route) and/or globally with plugin metadata.

Add host address, timestamp, and client IP address to the logs with built-in variables:

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/elasticsearch-logger" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"log_format": {
"host": "$host",
"timestamp": "$time_iso8601",
"client_ip": "$remote_addr"
}
}
EOF

Configure Kibana​

Send ten requests, then allow the inactive buffer to flush to Elasticsearch:

for i in {1..10}; do
curl -sS "http://127.0.0.1:9080/get" > /dev/null
done

sleep 6

List the date-based indices:

curl -u "elastic:${ELASTIC_PASSWORD}" \
"http://127.0.0.1:9200/_cat/indices/gateway-*?v"

You should see a gateway-YYYY.MM.DD index with documents. Inspect one indexed document:

curl -u "elastic:${ELASTIC_PASSWORD}" \
"http://127.0.0.1:9200/gateway-*/_search?pretty&size=1"

The document _source should contain host, timestamp, and client_ip fields.

View Logs in Kibana​

Open Kibana and sign in as elastic with the password stored in ELASTIC_PASSWORD.

Go to Stack Management > Data Views, select Create data view, and configure these values:

  • Name: APISIX logs
  • Index pattern: gateway-*
  • Timestamp field: timestamp
Kibana data view form configured for APISIX gateway indices

Select Save data view to Kibana, then go to Discover and select the APISIX logs data view. The indexed gateway requests should be available for searching and filtering.

Kibana Discover showing APISIX log documents from Elasticsearch

Next Steps​

See elasticsearch-logger plugin reference to learn more about the plugin configuration options.