Database-Based Observability
Introduction
Section titled “Introduction”Source Repositories:
- Plugin + Collector source code: https://github.com/higress-group/db-log-pusher
- Higress integration: You need to manually clone the source code and integrate it into the
plugins/wasm-go/extensionsdirectory of the Higress repository
This solution is based on db-log-pusher (WASM plugin) + db-log-collector (log collection service) + MySQL, providing fully open-source observability capabilities. It is suitable for small-to-medium traffic scenarios where you are not using Alibaba Cloud and prefer to store log data in your own database.
If you are using Alibaba Cloud, we recommend the Alibaba Cloud SLS solution.
Architecture Overview
Section titled “Architecture Overview”Higress Gateway └─ db-log-pusher (WASM Plugin) ──HTTP POST──▶ db-log-collector (Go Service) ──▶ MySQL (access_logs table) ▲ HiMarket Backend QueriesComponent descriptions:
db-log-pusher: A Higress WASM plugin that asynchronously collects request/response logs and pushes them to the collector service without blocking the main business flowdb-log-collector: A log collection service written in Go that receives logs and batch-writes them to MySQL (by default, every 50 records or once per second)access_logstable: Stores all access logs; the HiMarket backend queries this table directly to power the observability dashboard
Configuration Steps
Section titled “Configuration Steps”Step 1: Prepare the MySQL Database
Section titled “Step 1: Prepare the MySQL Database”Create the database and the access_logs table.
CREATE DATABASE IF NOT EXISTS higress_poc DEFAULT CHARACTER SET utf8mb4;
USE higress_poc;
CREATE TABLE access_logs ( id BIGINT AUTO_INCREMENT PRIMARY KEY, start_time DATETIME NOT NULL COMMENT 'Request start time', trace_id VARCHAR(255) COMMENT 'X-B3-TraceID', authority VARCHAR(255) COMMENT 'Host/Authority', method VARCHAR(10) COMMENT 'HTTP method', path TEXT COMMENT 'Request path', protocol VARCHAR(20) COMMENT 'HTTP protocol version', request_id VARCHAR(255) COMMENT 'X-Request-ID', user_agent TEXT COMMENT 'User-Agent', x_forwarded_for TEXT COMMENT 'X-Forwarded-For', response_code INT COMMENT 'Response status code', response_flags VARCHAR(100) COMMENT 'Envoy response flags', response_code_details TEXT COMMENT 'Response code details', bytes_received BIGINT COMMENT 'Bytes received', bytes_sent BIGINT COMMENT 'Bytes sent', duration BIGINT COMMENT 'Total request duration (ms)', upstream_cluster VARCHAR(255) COMMENT 'Upstream cluster name', upstream_host VARCHAR(255) COMMENT 'Upstream host', upstream_service_time VARCHAR(50) COMMENT 'Upstream service time', upstream_transport_failure_reason TEXT COMMENT 'Upstream transport failure reason', upstream_local_address VARCHAR(255) COMMENT 'Upstream local address', downstream_local_address VARCHAR(255) COMMENT 'Downstream local address', downstream_remote_address VARCHAR(255) COMMENT 'Downstream remote address', route_name VARCHAR(255) COMMENT 'Route name', requested_server_name VARCHAR(255) COMMENT 'SNI', istio_policy_status VARCHAR(100) COMMENT 'Istio policy status', ai_log JSON COMMENT 'AI log (model, token, MCP, etc.)', instance_id VARCHAR(255) COMMENT 'Instance ID', api VARCHAR(255) COMMENT 'API name', model VARCHAR(255) COMMENT 'Model name', consumer VARCHAR(255) COMMENT 'Consumer info', route VARCHAR(255) COMMENT 'Route name', service VARCHAR(255) COMMENT 'Service name', mcp_server VARCHAR(255) COMMENT 'MCP Server', mcp_tool VARCHAR(255) COMMENT 'MCP Tool', input_tokens BIGINT COMMENT 'Input token count', output_tokens BIGINT COMMENT 'Output token count', total_tokens BIGINT COMMENT 'Total token count', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_start_time (start_time), INDEX idx_trace_id (trace_id), INDEX idx_authority (authority), INDEX idx_method (method), INDEX idx_response_code (response_code), INDEX idx_instance_id (instance_id), INDEX idx_api (api), INDEX idx_model (model), INDEX idx_consumer (consumer), INDEX idx_mcp_server (mcp_server)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Higress Access Logs';Step 2: Deploy the db-log-collector Service
Section titled “Step 2: Deploy the db-log-collector Service”db-log-collector is an HTTP service written in Go that receives logs pushed by db-log-pusher and batch-writes them to MySQL. Choose a deployment method below:
Option 1: Kubernetes Deployment (Recommended)
Section titled “Option 1: Kubernetes Deployment (Recommended)”Save the following YAML as log-collector.yaml and apply it:
apiVersion: apps/v1kind: Deploymentmetadata: name: log-collector namespace: higress-system labels: app: log-collectorspec: replicas: 1 selector: matchLabels: app: log-collector template: metadata: labels: app: log-collector spec: containers: - name: collector image: registry.cn-shanghai.aliyuncs.com/daofeng/log-collector:latest imagePullPolicy: Always ports: - containerPort: 8080 env: - name: MYSQL_DSN value: "user:password@tcp(mysql-host:3306)/higress_poc?charset=utf8mb4&parseTime=True&loc=Local" resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "100m" memory: "128Mi" livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 5
---apiVersion: v1kind: Servicemetadata: name: log-collector namespace: higress-systemspec: selector: app: log-collector ports: - port: 80 targetPort: 8080 protocol: TCP type: ClusterIPDeploy and verify:
kubectl apply -f log-collector.yamlkubectl get pods -n higress-system -l app=log-collectorkubectl exec -n higress-system deployment/log-collector -- wget -qO- http://localhost:8080/healthOption 2: Docker Standalone Deployment
Section titled “Option 2: Docker Standalone Deployment”If you want to quickly deploy on a local machine or a single server, you can run the log collection service using Docker.
Deployment command:
docker run -d \ --name log-collector \ -p 8080:8080 \ -e MYSQL_DSN="user:password@tcp(mysql-host:3306)/higress_poc?charset=utf8mb4&parseTime=True&loc=Local" \ --restart unless-stopped \ registry.cn-shanghai.aliyuncs.com/daofeng/log-collector:latestParameter descriptions:
-d: Run the container in the background--name log-collector: Specify the container name-p 8080:8080: Map the container’s port 8080 to the host-e MYSQL_DSN: Set the MySQL database connection string; modify according to your environment--restart unless-stopped: Automatically restart the container on exit (unless manually stopped)
Verify the deployment:
Check the container status:
docker ps | grep log-collectorView container logs:
docker logs -f log-collectorTest the health check endpoint:
curl http://localhost:8080/healthStop and remove the container:
# Stop the containerdocker stop log-collector
# Remove the containerdocker rm log-collectorStep 3: Configure the db-log-pusher Plugin
Section titled “Step 3: Configure the db-log-pusher Plugin”Configure the db-log-pusher WASM plugin in Higress to push gateway logs to the collector service.
Option 1: Configure via Higress Console (Recommended)
Section titled “Option 1: Configure via Higress Console (Recommended)”This is the simplest and most straightforward approach — you can complete the plugin installation and configuration through the Higress Console’s graphical interface.
-
Access the Higress Console
- Log in to the Higress Console management page
- Navigate to Plugin Configuration -> Add Plugin
-
Fill in the plugin information
- Plugin Name:
db-log-pusher-plugin - Plugin Description:
Collect HTTP request logs to database - Image URL:
https://pysrc-test.oss-cn-beijing.aliyuncs.com/higress-plugin/plugin-20260323-101235.wasm - Plugin Execution Phase: Select Authentication Phase (AUTHN)
- Plugin Execution Priority:
1010(range 1~1000, higher values mean higher priority) - Plugin Pull Policy: Select Always Pull (Always)
- Plugin Name:
-
Configure routes and policies
- On the plugin configuration page, click “Add Match Rule”
- In the ingress list, select or enter the service names to which this plugin should be applied, for example:
model-api-qwen3-plus-0travel-assistant
-
Configure plugin parameters
- In the Custom Plugin Configuration area, select the
db-log-pusherplugin you just created - In the parameter configuration form, enter the following parameters one per line (format:
key: value):
log_level: infocollector_service_name: log-collector.higress-system.svc.cluster.localcollector_port: 80collector_path: /ingest- Ensure configDisable is set to
false(enable configuration)
- In the Custom Plugin Configuration area, select the
-
Save the configuration
- Click the “Save” button to complete the configuration
- Higress will automatically deploy the plugin to the gateway
Configuration notes:
- Execution Phase: Select the Authentication Phase (AUTHN) for statistics and log collection
- Priority: Set to 1010 to ensure it is higher than the
ai-statisticsplugin’s priority - Pull Policy: Always pull the latest version to ensure you are using the newest plugin features
Option 2: Configure via Kubernetes YAML
Section titled “Option 2: Configure via Kubernetes YAML”If you prefer using Kubernetes-native configuration, you can deploy the plugin by creating a WasmPlugin resource:
apiVersion: extensions.higress.io/v1alpha1kind: WasmPluginmetadata: name: db-log-pusher-plugin namespace: higress-system labels: higress.io/wasm-plugin-name: db-log-pusher higress.io/wasm-plugin-category: loggingspec: url: https://pysrc-test.oss-cn-beijing.aliyuncs.com/higress-plugin/plugin-20260323-101235.wasm sha256: "" # Recommended: fill in the SHA256 checksum of the WASM file defaultConfigDisable: true failStrategy: FAIL_OPEN imagePullPolicy: Always phase: AUTHN priority: 1010 matchRules: - configDisable: false ingress: - model-api-qwen3-plus-0 # Replace with your route names - travel-assistant config: log_level: info collector_service_name: "log-collector.higress-system.svc.cluster.local" collector_port: 80 collector_path: "/ingest"Apply the configuration:
kubectl apply -f db-log-pusher.yamlPlugin configuration parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
collector_service_name | string | Yes | - | Collector service address (K8s FQDN or IP) |
collector_port | int | Yes | - | Collector port |
collector_path | string | No | / | API path for receiving logs |
Plugin Execution Order
Section titled “Plugin Execution Order”If you need to read AI logs written by the ai-statistics plugin, ensure that db-log-pusher executes after ai-statistics:
- When in different phases, the phase of
db-log-pushershould be later than that ofai-statistics - When in the same phase, the priority of
db-log-pushershould be higher than that ofai-statistics(higher numbers execute first)
Step 4: Configure HiMarket
Section titled “Step 4: Configure HiMarket”Switch HiMarket’s log datasource to DB:
export OBSERVABILITY_LOG_SOURCE="DB"Or edit himarket-bootstrap/src/main/resources/application.yml:
observability: log-source: DBStep 5: Start and Verify
Section titled “Step 5: Start and Verify”After starting HiMarket, check the logs to confirm the datasource switch was successful:
INFO c.a.h.config.ObservabilityConfig - Observability log source: DBINFO c.a.h.config.ObservabilityConfig - DB datasource URL: jdbc:mysql://..., table: access_logsVerify the data pipeline:
- Send a few requests through the Higress gateway to generate access logs
- Check whether data has been written to the
access_logstable:SELECT COUNT(*) FROM access_logs; - Log in to the HiMarket admin console and check whether the observability dashboard shows data
Custom Development
Section titled “Custom Development”If you need to customize db-log-pusher or db-log-collector, refer to the source code:
Source repository relationships:
- Standalone repository: https://github.com/higress-group/db-log-pusher - Contains the complete plugin and collector source code
- Higress integration: https://github.com/alibaba/higress/tree/main/plugins/wasm-go/extensions - The plugin directory in the official Higress repository
Source code structure:
db-log-pusher/├── main.go # Pusher plugin main program└── log-collector/ # Collector server ├── main.go # Collector main program ├── Dockerfile # Docker image build file └── ... # Other dependency filesdb-log-collector main interfaces:
POST /ingest: Receive logsGET /query: Query logsGET /health: Health check
Build the image:
# Clone the db-log-pusher repositorygit clone git@github.com:higress-group/db-log-pusher.git
# Clone the higress repositorygit clone git@github.com:alibaba/higress.git
# Copy the db-log-collector directory to the higress plugin directorycp -r db-log-pusher/log-collector higress/plugins/wasm-go/extensions/db-log-pusher/
# Enter the directory and build the imagecd higress/plugins/wasm-go/extensions/db-log-pusher/log-collectordocker build -t your-registry/log-collector:latest .Important Notes
Section titled “Important Notes”- Performance: Deployed as a single instance by default, suitable for small-to-medium traffic. For high-concurrency scenarios, consider increasing replicas or introducing a message queue as a buffer.
- Data Security: It is recommended to use a dedicated database account with restricted permissions. Use TLS-encrypted connections in production environments.
- Resource Limits: Adjust the container’s CPU and memory limits based on actual traffic.
- Plugin Characteristics: Logs are sent asynchronously in a non-blocking manner. Send failures do not affect the main business flow. A built-in 5-second timeout prevents blocking.
Troubleshooting
Section titled “Troubleshooting”Logs Not Written to the Database
Section titled “Logs Not Written to the Database”- Check whether db-log-collector is running properly (
curl http://<collector-host>:<port>/health) - Verify that the
MYSQL_DSNconfiguration is correct and the collector can connect to MySQL - Review the db-log-collector logs for errors
- Confirm that the
collector_service_nameandcollector_portin the db-log-pusher plugin configuration are correct
No Data on the HiMarket Dashboard
Section titled “No Data on the HiMarket Dashboard”- Confirm that
OBSERVABILITY_LOG_SOURCEis set toDB - Confirm that the
access_logstable contains data:SELECT COUNT(*) FROM access_logs; - Confirm that HiMarket’s database connection points to the MySQL instance containing the
access_logstable - Review the HiMarket application logs for query errors