VictoriaLogs + Alloy Binary Deployment
If you have not rotated MongoDB logs yet, first read MongoDB Log Rotation.
This option does not include Grafana, so a usable Grafana environment must already be available. When installing the VictoriaLogs datasource plugin,
Grafana must meet the plugin requirements. The current reference VictoriaLogs datasource plugin version is 0.32.0,
Grafana must be >= 10.4.0. If this requirement is not met, first refer to Grafana Upgrade Steps Reference.
Deploy VictoriaLogs
-
Prepare the installation directory
mkdir -p /data/mdtempmkdir -p /usr/local/victorialogsmkdir -p /data/victorialogscd /data/mdtemp -
Download the VictoriaLogs package
wget https://pdpublic.mingdao.com/private-deployment/offline/common/victoria-logs-linux-amd64-v1.52.0.tar.gz -
Extract it to the installation directory
tar xzvf victoria-logs-linux-amd64-v1.52.0.tar.gz -C /usr/local/victorialogs/chmod +x /usr/local/victorialogs/victoria-logs-prodVerify the version:
/usr/local/victorialogs/victoria-logs-prod --versionThe expected version is
v1.52.0. -
Create the data directory
mkdir -p /data/victorialogs -
Write the environment file
cat > /usr/local/victorialogs/victorialogs.env <<'EOF'# Data directorySTORAGE_DATA_PATH=/data/victorialogs# HTTP listen portHTTP_LISTEN_ADDR=:9428# Basic Auth; change this in productionHTTP_AUTH_USERNAME=myuserHTTP_AUTH_PASSWORD=mypassword# Data retentionRETENTION_PERIOD=30dRETENTION_DISK_USAGE=50GiB# Memory and concurrencyMEMORY_ALLOWED_BYTES=1GiBMAX_CONCURRENT_INSERTS=4MAX_CONCURRENT_REQUESTS=2# Query limitsSEARCH_MAX_QUERY_DURATION=30sSEARCH_MAX_QUERY_TIMERANGE=24hSEARCH_MAX_QUEUE_DURATION=5sSEARCH_LOG_SLOW_QUERY_DURATION=3s# Write protectionINSERT_MAX_LINE_SIZE_BYTES=262144INSERT_MAX_FIELDS_PER_LINE=300# Log levelLOGGER_LEVEL=INFOEOFThe following parameters must be changed for the target environment:
HTTP_AUTH_USERNAMEHTTP_AUTH_PASSWORDRETENTION_PERIODRETENTION_DISK_USAGE -
Write the systemd service file
cat > /etc/systemd/system/victorialogs.service <<'EOF'[Unit]Description=VictoriaLogs Logging ServiceWants=network-online.targetAfter=network-online.target[Service]Type=simpleEnvironmentFile=/usr/local/victorialogs/victorialogs.envEnvironment="GOMEMLIMIT=2GiB"WorkingDirectory=/usr/local/victorialogsExecStart=/usr/local/victorialogs/victoria-logs-prod \-storageDataPath=${STORAGE_DATA_PATH} \-httpListenAddr=${HTTP_LISTEN_ADDR} \-retentionPeriod=${RETENTION_PERIOD} \-retention.maxDiskSpaceUsageBytes=${RETENTION_DISK_USAGE} \-memory.allowedBytes=${MEMORY_ALLOWED_BYTES} \-maxConcurrentInserts=${MAX_CONCURRENT_INSERTS} \-search.maxConcurrentRequests=${MAX_CONCURRENT_REQUESTS} \-search.maxQueryDuration=${SEARCH_MAX_QUERY_DURATION} \-search.maxQueryTimeRange=${SEARCH_MAX_QUERY_TIMERANGE} \-search.maxQueueDuration=${SEARCH_MAX_QUEUE_DURATION} \-search.logSlowQueryDuration=${SEARCH_LOG_SLOW_QUERY_DURATION} \-insert.maxLineSizeBytes=${INSERT_MAX_LINE_SIZE_BYTES} \-insert.maxFieldsPerLine=${INSERT_MAX_FIELDS_PER_LINE} \-httpAuth.username=${HTTP_AUTH_USERNAME} \-httpAuth.password=${HTTP_AUTH_PASSWORD} \-loggerLevel=${LOGGER_LEVEL}Restart=on-failureRestartSec=3sLimitNOFILE=65536TasksMax=2048CPUAccounting=trueCPUQuota=100%MemoryAccounting=trueMemoryMax=2GMemorySwapMax=0StandardOutput=journalStandardError=journal[Install]WantedBy=multi-user.targetEOF -
Start VictoriaLogs
systemctl daemon-reloadsystemctl enable --now victorialogssystemctl status victorialogs --no-pagerss -lnt | grep '9428'curl -s -u 'myuser:mypassword' http://localhost:9428/healthjournalctl -u victorialogs -n 100 --no-pager
Deploy Alloy
Deploy Alloy on every MongoDB node. It reads the local mongodb.log
and pushes slow-query logs to VictoriaLogs. Deploy one Alloy instance per node to collect its local logs,
so that each slow-query log can be associated with its source node.
Points to note:
- Change
VICTORIALOGS_PUSH_URLto the actual VictoriaLogs address. - Change
VICTORIALOGS_USERNAMEandVICTORIALOGS_PASSWORDto the actual authentication credentials. - Alloy automatically uses the local IPv4 address as the
jobidentifier; no manual node-name change is needed. - Set
MONGODB_LOG_PATHto the absolute path of the MongoDB log file on the current node. /data/alloy-vlogs-datastores the log read position. Do not delete it arbitrarily, or logs may be collected again.
-
Confirm the MongoDB log path
ls -lh /data/logs/mongodb/mongodb.logtail -n 3 /data/logs/mongodb/mongodb.log -
Create the Alloy installation directory
mkdir -p /data/mdtempmkdir -p /usr/local/alloy-vlogs/binmkdir -p /data/alloy-vlogs-datacd /data/mdtemp -
Download the Alloy package
wget https://pdpublic.mingdao.com/private-deployment/offline/common/alloy-linux-amd64-v1.19.2.zip -
Extract and install Alloy
unzip -o alloy-linux-amd64-v1.19.2.zip -d /data/mdtemp/mv -f /data/mdtemp/alloy-linux-amd64 /usr/local/alloy-vlogs/bin/alloychmod +x /usr/local/alloy-vlogs/bin/alloy/usr/local/alloy-vlogs/bin/alloy --versionThe expected version is
v1.19.2. -
Write the Alloy environment file
cat > /usr/local/alloy-vlogs/alloy.env <<'EOF'# VictoriaLogs address; change this to the actual IPVICTORIALOGS_PUSH_URL="http://VictoriaLogs_IP:9428/insert/loki/api/v1/push?preserve_json_keys=attr&_stream_fields=job,host&ignore_fields=filename"# VictoriaLogs Basic AuthVICTORIALOGS_USERNAME="myuser"VICTORIALOGS_PASSWORD="mypassword"# Absolute path to the MongoDB logMONGODB_LOG_PATH="/data/logs/mongodb/mongodb.log"EOFchmod 600 /usr/local/alloy-vlogs/alloy.envThe following parameters must be changed for the target environment:
VictoriaLogs_IPVICTORIALOGS_USERNAMEVICTORIALOGS_PASSWORDMONGODB_LOG_PATH -
Write the Alloy configuration file
cat > /usr/local/alloy-vlogs/config.alloy <<'EOF'// ============================================================// Grafana Alloy// MongoDB Slow Query -> VictoriaLogs// ============================================================logging {level = "info"format = "logfmt"}// ============================================================// 1. Read MongoDB logs// ============================================================loki.source.file "mongodb" {targets = [{__path__ = sys.env("MONGODB_LOG_PATH"),job = string.format("mongodb-%s", sys.env("HOST_IP")),host = constants.hostname,},]forward_to = [loki.process.mongodb.receiver,]}// ============================================================// 2. Process MongoDB slow queries// ============================================================loki.process "mongodb" {forward_to = [loki.write.victorialogs.receiver,]// Parse MongoDB JSON logsstage.json {expressions = {ts = "t.\"$date\"",severity = "s",c = "",msg = "",attr = "attr",durationMillis = "attr.durationMillis",ns = "attr.ns",planSummary = "attr.planSummary",docsExamined = "attr.docsExamined",reslen = "attr.reslen",}}// Use the original MongoDB log timestampstage.timestamp {source = "ts"format = "RFC3339"}// c / msg are used only for the filters belowstage.labels {values = {c = "",msg = "",}}// Keep only c=COMMANDstage.match {selector = "{c!=\"COMMAND\"}"action = "drop"drop_counter_reason = "not_command"}// Keep only msg=Slow querystage.match {selector = "{msg!=\"Slow query\"}"action = "drop"drop_counter_reason = "not_slow_query"}// Remove temporary labelsstage.label_drop {values = ["c","msg",]}// Convert the MongoDB log levelstage.template {source = "level"template = `{{ if eq .severity "I" }}info{{ else if eq .severity "W" }}warn{{ else if eq .severity "E" }}error{{ else if eq .severity "F" }}critical{{ else if eq .severity "D" }}debug{{ else }}info{{ end }}`}stage.labels {values = {level = "",}}// Keep common fields as Structured Metadatastage.structured_metadata {values = {durationMillis = "",ns = "",planSummary = "",docsExamined = "",reslen = "",}}// Content displayed in the Grafana Logs panelstage.template {source = "display_msg"template = `{"ns": {{ toJson .ns }},"durationMillis": {{ toJson (printf "%v" .durationMillis) }},"planSummary": {{ toJson .planSummary }},"docsExamined": {{ toJson (printf "%v" .docsExamined) }},"reslen": {{ toJson (printf "%v" .reslen) }},"attr": {{ toJson (fromJson .attr) }}}`}// Final JSON sent to VictoriaLogsstage.template {source = "vl_line"template = `{"_msg":{{ toJson .display_msg }},"ns":{{ toJson .ns }},"durationMillis":{{ toJson (printf "%v" .durationMillis) }},"planSummary":{{ toJson .planSummary }},"docsExamined":{{ toJson (printf "%v" .docsExamined) }},"reslen":{{ toJson (printf "%v" .reslen) }},"attr":{{ toJson (fromJson .attr) }}}`}stage.output {source = "vl_line"}}// ============================================================// 3. Send to VictoriaLogs// ============================================================loki.write "victorialogs" {endpoint {url = sys.env("VICTORIALOGS_PUSH_URL")batch_wait = "1s"batch_size = "100KiB"basic_auth {username = sys.env("VICTORIALOGS_USERNAME")password = sys.env("VICTORIALOGS_PASSWORD")}}}EOF -
Validate the Alloy configuration
Load the environment variables:
set -a. /usr/local/alloy-vlogs/alloy.envset +aTemporarily generate the local IP:
export HOST_IP="$(ip -4 route get 1.1.1.1 2>/dev/null \| sed -n 's/.* src \([^ ]*\).*/\1/p' \| head -n1)"Confirm the environment variables:
echo "$HOST_IP"echo "$MONGODB_LOG_PATH"Validate the configuration:
/usr/local/alloy-vlogs/bin/alloy validate \/usr/local/alloy-vlogs/config.alloyContinue only if no errors are reported.
-
Write the Alloy startup script
cat > /usr/local/alloy-vlogs/bin/start-alloy.sh <<'EOF'#!/bin/sh# Automatically obtain the server egress IP from the default IPv4 routeHOST_IP=$(ip -4 route get 1.1.1.1 2>/dev/null \| sed -n 's/.* src \([^ ]*\).*/\1/p' \| head -n1)if [ -z "$HOST_IP" ]; thenecho "ERROR: failed to detect local IPv4 address"exit 1fiif [ -z "$MONGODB_LOG_PATH" ]; thenecho "ERROR: MONGODB_LOG_PATH is empty"exit 1fiif [ ! -r "$MONGODB_LOG_PATH" ]; thenecho "ERROR: MongoDB log is not readable: $MONGODB_LOG_PATH"exit 1fiexport HOST_IPecho "Alloy HOST_IP=${HOST_IP}"echo "MongoDB LOG=${MONGODB_LOG_PATH}"/usr/local/alloy-vlogs/bin/alloy validate \/usr/local/alloy-vlogs/config.alloy || exit 1exec /usr/local/alloy-vlogs/bin/alloy run \--server.http.listen-addr=127.0.0.1:9081 \--storage.path=/data/alloy-vlogs-data \/usr/local/alloy-vlogs/config.alloyEOFGrant execute permission:
chmod +x /usr/local/alloy-vlogs/bin/start-alloy.shVerify the automatically detected IP:
ip -4 route get 1.1.1.1View only the IP:
ip -4 route get 1.1.1.1 \| sed -n 's/.* src \([^ ]*\).*/\1/p' -
Write the systemd service file
cat > /etc/systemd/system/alloy-vlogs.service <<'EOF'[Unit]Description=Grafana Alloy VictoriaLogs CollectorWants=network-online.targetAfter=network-online.target[Service]Type=simpleEnvironmentFile=/usr/local/alloy-vlogs/alloy.envEnvironment="GOMEMLIMIT=768MiB"ExecStart=/usr/local/alloy-vlogs/bin/start-alloy.shRestart=on-failureRestartSec=3sCPUAccounting=trueCPUQuota=100%MemoryAccounting=trueMemoryMax=1GMemorySwapMax=0LimitNOFILE=65536TasksMax=1024StandardOutput=journalStandardError=journal[Install]WantedBy=multi-user.targetEOF -
Start Alloy
systemctl daemon-reload
systemctl enable --now alloy-vlogs
View the status:
systemctl status alloy-vlogs --no-pager
View the logs:
journalctl -u alloy-vlogs -n 50 --no-pager
The output should include:
Alloy HOST_IP=<local_IP>
MongoDB LOG=/data/logs/mongodb/mongodb.log
- Alloy health checks
Port:
ss -lntp | grep ':9081'
Ready:
curl -s http://127.0.0.1:9081/-/ready
Expected response:
Alloy is ready.
Healthy:
curl -s http://127.0.0.1:9081/-/healthy
Expected response:
All Alloy components are healthy.
- Check Alloy collection and delivery
curl -s http://127.0.0.1:9081/-/healthy
journalctl -u alloy-vlogs -n 50 --no-pager
curl -s http://127.0.0.1:9081/metrics | egrep -i 'loki_.*(sent|dropped|error|retry|read)' | head -n 80
Configure Grafana
This option does not include Grafana, so a usable Grafana environment must already be available. If Grafana is not available, install or upgrade Grafana before continuing with the steps below. The current reference VictoriaLogs datasource plugin version is
0.32.0. Grafana must be>= 10.4.0during installation. If this requirement is not met, first refer to Grafana Upgrade Steps Reference.
-
Install the VictoriaLogs datasource plugin
cd /data/mdtemp# Grafana >= 10.4.0; upgrade Grafana first if this requirement is not metwget https://pdpublic.mingdao.com/private-deployment/offline/common/victoriametrics-logs-datasource-v0.32.0.tar.gztar xzvf victoriametrics-logs-datasource-v0.32.0.tar.gz -C /usr/local/grafana/data/plugins/systemctl restart grafana -
Configure the datasource
- Enter the VictoriaLogs address in
url, for examplehttp://127.0.0.1:9428. - Enable
Basic auth. - Enter
HTTP_AUTH_USERNAMEinUser. - Enter
HTTP_AUTH_PASSWORDinPassword. - Keep
Maximum linesat2000000unless the environment requires otherwise.
- Enter the VictoriaLogs address in
-
Import the slow-query dashboard
The dashboard file is ready. Download it and import it into Grafana.
View / download the dashboard JSON
- Dashboard file:
mongodb-VictoriaLogs-Slow-Query-v1.1.0.en.json - Import method: in Grafana, click
Import dashboardand upload this file. - After importing, confirm that the current VictoriaLogs datasource is selected.
- To preview the content, open this JSON file directly in a browser.
Open the JSON file in a browser - Dashboard file: