Skip to main content

VictoriaLogs + Alloy Docker Deployment

Before You Begin

If MongoDB log rotation is not configured, first see MongoDB Log Rotation. The Docker image includes Grafana and the slow query dashboard.

Prerequisites​

  • Installed docker
  • Installed docker-compose

Deploy VictoriaLogs + Grafana​

  1. Download the image

    docker pull registry.cn-hangzhou.aliyuncs.com/hap-mdy/hap-monitor-victorialogs-grafana-amd64:1.1.0
  2. Create configuration and data directories

    mkdir -p /usr/local/victoria-logs-linux
    mkdir -p /data/victorialogs
    mkdir -p /data/grafana
  3. Create the configuration file

    cat > /usr/local/victoria-logs-linux/hap-monitor-logs.yaml << 'EOF'
    services:
    hap-monitor-logs:
    image: registry.cn-hangzhou.aliyuncs.com/hap-mdy/hap-monitor-victorialogs-grafana-amd64:1.1.0
    container_name: hap-monitor-logs
    restart: always
    ports:
    # VictoriaLogs API
    - "9428:9428"
    # Grafana
    - "3000:3000"
    # Persistence
    volumes:
    # VictoriaLogs data directory
    - /data/victorialogs:/data/victorialogs
    # Grafana data directory
    - /data/grafana:/usr/local/grafana/data
    environment:
    # VictoriaLogs HTTP Basic Auth; use the same credentials for Alloy (change in production)
    MONITOR_AUTH_USERNAME: myuser
    MONITOR_AUTH_PASSWORD: mypassword
    # External URL (change for reverse proxy or subpath access)
    GRAFANA_SERVER_ROOT_URL: "%(protocol)s://%(domain)s:%(http_port)s/privatedeploy/mdy/monitor/victorialogs-grafana/"
    # Match GRAFANA_SERVER_ROOT_URL: true for a subpath, false for root access
    GRAFANA_SERVER_SERVE_FROM_SUB_PATH: "true"
    # Grafana administrator credentials (change in production)
    GRAFANA_ADMIN_USER: admin
    GRAFANA_ADMIN_PASSWORD: admin@123456
    # Resource limits
    mem_limit: 3g
    memswap_limit: 3g
    cpus: 2.0
    ulimits:
    nofile:
    soft: 102400
    hard: 102400
    # Logs
    logging:
    driver: json-file
    options:
    max-size: "100m"
    max-file: "3"
    EOF

Start and Stop​

# Start
docker-compose -f /usr/local/victoria-logs-linux/hap-monitor-logs.yaml up -d

# Stop
docker-compose -f /usr/local/victoria-logs-linux/hap-monitor-logs.yaml down

# Check status
docker-compose -f /usr/local/victoria-logs-linux/hap-monitor-logs.yaml ps

# View logs
docker-compose -f /usr/local/victoria-logs-linux/hap-monitor-logs.yaml logs

Variable Reference​

All variables can be overridden through Compose environment. Variables marked as omitted from Compose use startup script defaults and need explicit configuration only when changing the default behavior.

Authentication and Service Modes

VariableCompose StatusDefaultDescriptionSupported Version
MONITOR_AUTH_USERNAME / MONITOR_AUTH_PASSWORDIncluded; change in productionmyuser / mypasswordVictoriaLogs external Basic Auth credentials, also used by Alloy and the Grafana datasource.1.1.0+
MONITOR_SERVICESOmitted from Composeallall starts VictoriaLogs and Grafana; victorialogs or grafana starts one service. Unset or empty defaults to all.1.1.0+

Grafana

VariableCompose StatusDefaultDescriptionSupported Version
GRAFANA_ADMIN_USER / GRAFANA_ADMIN_PASSWORDIncluded; must changeadmin / admin@123456Grafana administrator credentials.1.0.0+
GRAFANA_SERVER_ROOT_URLIncluded; adjust for deployment%(protocol)s://%(domain)s:%(http_port)s/privatedeploy/mdy/monitor/victorialogs-grafana/External Grafana URL. Set the actual address for a reverse proxy or subpath.1.0.0+
GRAFANA_SERVER_SERVE_FROM_SUB_PATHIncluded; match ROOT_URLtrueSet to true when GRAFANA_SERVER_ROOT_URL has a subpath, or false for root access.1.0.0+
GRAFANA_ALLOW_UNSIGNED_PLUGINSOmitted from Composevictoriametrics-logs-datasourceThe startup script allows the current plugin by default; override if its name changes.1.0.0+
GRAFANA_VL_DATASOURCE_URLOmitted from Composehttp://127.0.0.1:9428VictoriaLogs URL used by Grafana. Set an external address when using MONITOR_SERVICES=grafana.1.0.0+

Runtime and Storage

VariableCompose StatusDefaultDescriptionSupported Version
TZOmitted from ComposeAsia/ShanghaiContainer time zone; override the startup script default when needed.1.0.0+
GOMEMLIMITOmitted from Compose2GiBGo runtime memory limit; do not exceed Compose mem_limit.1.0.0+
VL_STORAGE_DATA_PATHOmitted from Compose/data/victorialogsVictoriaLogs data directory. Update the Compose volumes mapping when changing it.1.0.0+
VL_HTTP_LISTEN_ADDROmitted from Compose:9428VictoriaLogs HTTP listen address. Update ports and the Alloy write address if the port changes.1.0.0+

Retention, Concurrency, and Queries

VariableCompose StatusDefaultDescriptionSupported Version
VL_RETENTION_PERIODOmitted from Compose30dMaximum log retention period; older data is removed.1.0.0+
VL_RETENTION_DISK_USAGEOmitted from Compose50GiBMaximum disk space for the VictoriaLogs data directory; applies alongside time-based retention.1.0.0+
VL_MEMORY_ALLOWED_PERCENTOmitted from Compose2VictoriaLogs memory usage percentage.1.0.0+
VL_MAX_CONCURRENT_INSERTSOmitted from Compose4Maximum concurrent ingestion requests; increasing it raises CPU, memory, and disk pressure.1.0.0+
VL_MAX_CONCURRENT_REQUESTSOmitted from Compose2Maximum concurrent query requests; excess requests enter a queue.1.0.0+
VL_SEARCH_MAX_QUERY_DURATIONOmitted from Compose30sMaximum execution time per query; queries terminate on timeout.1.0.0+
VL_SEARCH_MAX_QUERY_TIMERANGEOmitted from Compose24hMaximum allowed time range per query.1.0.0+
VL_SEARCH_MAX_QUEUE_DURATIONOmitted from Compose5sMaximum query wait time in the concurrency queue.1.0.0+
VL_SEARCH_LOG_SLOW_QUERY_DURATIONOmitted from Compose3sLog slow queries when execution reaches this duration.1.0.0+

Log Ingestion and Logging Level

VariableCompose StatusDefaultDescriptionSupported Version
VL_INSERT_MAX_LINE_SIZE_BYTESOmitted from Compose262144Maximum size per log entry, 256 KiB; larger entries are rejected.1.0.0+
VL_INSERT_MAX_FIELDS_PER_LINEOmitted from Compose300Maximum number of fields per log entry.1.0.0+
VL_SYSLOG_EXTRA_FIELDS_TCPOmitted from Compose{"job":"rsyslog"}JSON fields added to TCP Syslog ingestion.1.0.0+
VL_LOGGER_LEVELOmitted from ComposeINFOVictoriaLogs logging level. Common values: DEBUG, INFO, WARN, ERROR.1.0.0+

Service modes:

  • MONITOR_SERVICES=all: Start VictoriaLogs and Grafana for the default deployment.
  • MONITOR_SERVICES=grafana: Start only Grafana; set GRAFANA_VL_DATASOURCE_URL to the external VictoriaLogs address.
  • MONITOR_SERVICES=victorialogs: Start only VictoriaLogs, without Grafana.

Deploy the Alloy Log Collector​

Notes

Deploy Alloy on every MongoDB node to read its local mongodb.log and send slow query logs to VictoriaLogs. Each node collects its own logs.

Notes:

  • VICTORIALOGS_IP: VictoriaLogs service address; adjust for your environment.
  • MONITOR_AUTH_USERNAME: VictoriaLogs authentication username; adjust for your environment.
  • MONITOR_AUTH_PASSWORD: VictoriaLogs authentication password; adjust for your environment.
  • VICTORIALOGS_PORT: VictoriaLogs service port; default is 9428.
  • MONGODB_SERVER_IP: MongoDB server IP, used to generate the unique mongodb-<IP> identifier.
  • In /data/logs/mongodb/mongodb.log:/data/logs/mongodb/mongodb.log:ro, change the path before the colon to the actual MongoDB log file on the server.
  1. Download the Alloy image

    docker pull registry.cn-hangzhou.aliyuncs.com/hap-mdy/hap-alloy-vlogs-mongodb-amd64:1.0.0
  2. Create configuration and data directories

    mkdir -p /usr/local/alloy-vlogs/ /data/alloy-data
  3. Create the Alloy configuration file

    cat > /usr/local/alloy-vlogs/alloy-vlogs-mongodb.yaml << 'EOF'
    services:
    alloy-vlogs-mongodb:
    image: registry.cn-hangzhou.aliyuncs.com/hap-mdy/hap-alloy-vlogs-mongodb-amd64:1.0.0
    container_name: alloy-vlogs-mongodb
    restart: always
    environment:
    # VictoriaLogs address
    VICTORIALOGS_IP: 10.206.0.5
    # VictoriaLogs port
    VICTORIALOGS_PORT: 9428
    # Use VictoriaLogs credentials
    MONITOR_AUTH_USERNAME: myuser
    MONITOR_AUTH_PASSWORD: mypassword
    # MongoDB server IP, used to generate a unique mongodb-<IP> identifier
    MONGODB_SERVER_IP: 10.206.0.8
    volumes:
    - /data/logs/mongodb/mongodb.log:/data/logs/mongodb/mongodb.log:ro
    - /etc/hostname:/host/etc/hostname:ro
    - /etc/machine-id:/host/etc/machine-id:ro
    - /data/alloy-data:/usr/local/alloy-vlogs/data
    deploy:
    resources:
    limits:
    cpus: '1'
    memory: 1G
    EOF

Start and Stop​

# Start
docker-compose -f /usr/local/alloy-vlogs/alloy-vlogs-mongodb.yaml up -d

# Stop
docker-compose -f /usr/local/alloy-vlogs/alloy-vlogs-mongodb.yaml down

# Check status
docker-compose -f /usr/local/alloy-vlogs/alloy-vlogs-mongodb.yaml ps

# View logs
docker-compose -f /usr/local/alloy-vlogs/alloy-vlogs-mongodb.yaml logs

Variable Reference​

Confirm these five items during deployment:

VariableConfigurationDefaultExamplePurpose
VICTORIALOGS_IPCheckhap-monitor-logs10.206.0.5VictoriaLogs address; use the service name when in the same Compose project.
VICTORIALOGS_PORTCheck94289428VictoriaLogs HTTP port.
MONITOR_AUTH_USERNAMERequiredNonemyuserVictoriaLogs authentication username.
MONITOR_AUTH_PASSWORDRequiredNonemypasswordVictoriaLogs authentication password; change it in production.
MONGODB_SERVER_IPRecommendedGenerated using machine-id10.206.0.8Generates a unique job name, such as mongodb-10.206.0.8.
  • If MONGODB_SERVER_IP or MONGODB_INSTANCE_ID is not set, Compose mounts the host /etc/machine-id read-only and generates a name such as mongodb-a1b2c3d4e5f6. After cloning a VM or server, ensure its machine-id has been regenerated.

Optional variables and defaults:

VariableRequiredDefaultPurpose
MONGODB_LOG_PATHNo/data/logs/mongodb/mongodb.logMongoDB log path inside the container; must match the mount target.
MONGODB_JOB_NAMENoAutomatically generatedManually specify a unique job name; the mongodb- prefix is recommended.
MONGODB_INSTANCE_IDNoEmptyStable instance identifier when no server IP is available.
MONGODB_HOSTNAMENoAutomatically read host hostnameFor display only, not a unique identifier.
VICTORIALOGS_PUSH_URLDo not setAutomatically generatedAddress used by Alloy to write to VictoriaLogs.

Variable precedence: host environment > --env-file > Compose file > startup script defaults. When server IP, instance ID, and job name are unset, the startup script uses the first 12 characters of host /etc/machine-id to generate a unique job name.

Built-in Alloy settings:

ItemValueDescription
Configuration file/usr/local/alloy-vlogs/config.alloyReads MongoDB logs, filters slow queries, and writes to VictoriaLogs.
Executable path/usr/local/alloy-vlogs/bin/alloyAlloy executable path.
HTTP listen address0.0.0.0:9081Management and health-check port; not exposed by Compose by default.
State directory/usr/local/alloy-vlogs/dataStores file read positions; mount a host directory for persistence.

Generate Test Slow Query Logs​

Notes
  • These commands test the collection pipeline by appending 15 MongoDB slow query entries exceeding 1000 ms to /data/logs/mongodb/mongodb.log. Table IDs, database names, UUIDs, and signatures are sanitized examples; each entry uses the current UTC time.
  • Change /data/logs/mongodb/mongodb.log to the actual log path.

Uses Bash, date, and cat without Python. It generates three random table names and writes 15 entries, five per table, at one-second intervals so each ns has multiple timestamps.

Click to view the Linux test script
sudo bash <<'BASH'
set -eu

LOG_FILE=/data/logs/mongodb/mongodb.log
mkdir -p "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"

DURATIONS=(1250 2387 43146 1680 9021 1380 2670 5120 1940 8030 1560 3290 6840 2210 9470)
TABLE_IDS=(
"ws$(od -An -N12 -tx1 /dev/urandom | tr -d ' \n')"
"ws$(od -An -N12 -tx1 /dev/urandom | tr -d ' \n')"
"ws$(od -An -N12 -tx1 /dev/urandom | tr -d ' \n')"
)

for i in "${!DURATIONS[@]}"; do
now="$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)"
epoch="$(date +%s)"
uuid="$(cat /proc/sys/kernel/random/uuid)"
table_id="${TABLE_IDS[$((i % ${#TABLE_IDS[@]}))]}"
duration="${DURATIONS[$i]}"

cat >> "$LOG_FILE" <<EOF
{"t":{"\$date":"$now"},"s":"I","c":"COMMAND","id":51803,"ctx":"conn$((100+i+1))","msg":"Slow query","attr":{"command":{"\$clusterTime":{"clusterTime":{"\$timestamp":{"i":$((i+1)),"t":$epoch}},"signature":{"hash":{"\$binary":{"base64":"REDACTED","subType":"0"}},"keyId":1}},"\$db":"example_db","find":"$table_id","filter":{"status":1,"sys_lock":{"\$ne":true}},"limit":2000,"lsid":{"id":{"\$uuid":"$uuid"}},"sort":{"utime":-1}},"cursorExhausted":true,"docsExamined":1010000,"durationMillis":$duration,"keysExamined":1010000,"nreturned":0,"ns":"example_db.$table_id","numYields":4095,"planCacheKey":"demo$i","planSummary":"IXSCAN { utime: 1 }","protocol":"op_msg","queryHash":"demo_hash_$i","reslen":249,"type":"command"}}
EOF
sleep 1
done

echo "Wrote ${#DURATIONS[@]} test slow query entries: $LOG_FILE"
BASH

Verify the result:

tail -n 5 /data/logs/mongodb/mongodb.log | jq -r '[.t["$date"], .attr.ns, .attr.durationMillis] | @tsv'

Configure the Grafana Reverse Proxy​

Notes
  • Replace 192.168.1.10:3000 with the actual Grafana address and port.
  • Replace hap.domain.com:80 with the external domain and port, and update server_name.
  • The proxy subpath must match GRAFANA_SERVER_ROOT_URL.
upstream grafana {
server 192.168.1.10:3000;
}

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 80;
server_name hap.domain.com;
access_log /data/logs/weblogs/grafana.log main;
error_log /data/logs/weblogs/grafana.mingdao.net.error.log;

location /privatedeploy/mdy/monitor/victorialogs-grafana/ {
#allow 1.1.1.1;
#deny all;
proxy_hide_header X-Frame-Options;
proxy_set_header X-Frame-Options ALLOWALL;
proxy_set_header Host $http_host;
proxy_pass http://grafana;
proxy_redirect http://localhost:3000 http://hap.domain.com:80/privatedeploy/mdy/monitor/victorialogs-grafana;
}

location /privatedeploy/mdy/monitor/victorialogs-grafana/api/live {
rewrite ^/(.*) /$1 break;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_pass http://grafana;
}
}

Access Notes​

After configuring the proxy, access Grafana at:

http://hap.domain.com/privatedeploy/mdy/monitor/victorialogs-grafana
  • Use the GRAFANA_ADMIN_USER and GRAFANA_ADMIN_PASSWORD values from the configuration above.
  • Username: admin
  • Password: admin@123456