[^\]]+)\]\s+(?PBan|Unban)\s+(?P\d+\.\d+\.\d+\.\d+) | action="Ban" ``"> Query Patterns - Solti Documentation
Skip to content

Query Patterns

Common Loki Query Patterns

Parsing journald logs

# Extract fields from log message using regexp
{service_type="fail2ban"}
| regexp `\[(?P<jail>[^\]]+)\]\s+(?P<action>Ban|Unban)\s+(?P<banned_ip>\d+\.\d+\.\d+\.\d+)`
| action="Ban"

Instant vs Range queries

  • Instant (/api/v1/query): Single value per metric, good for tables
  • Range (/api/v1/query_range): Time series, good for graphs

Aggregations

# Count by label over time window
sum by(jail) (count_over_time({service_type="fail2ban"} [24h]))

# Top N results
topk(20, sum by(banned_ip) (count_over_time(...)))

Loki LogQL Examples

Instant Query:

sum by(label) (count_over_time({service="myservice"} [24h]))

Range Query:

rate({service="myservice"} |= "error" [5m])

InfluxDB Flux Query Patterns

Counter Metrics

from(bucket: "telegraf")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["service"] == "alloy")
  |> filter(fn: (r) => r["host"] == "${hostname}")
  |> filter(fn: (r) => r["_field"] == "metric_total")
  |> derivative(unit: 1s, nonNegative: true)
  |> aggregateWindow(every: v.windowPeriod, fn: mean)

Gauge Metrics

from(bucket: "telegraf")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_field"] == "current_value")
  |> aggregateWindow(every: v.windowPeriod, fn: mean)

Multi-Metric Calculation

# Calculate percentage from two metrics
hits = from(bucket: "telegraf")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_field"] == "cache_hits")
  |> set(key: "_field", value: "hits")

misses = from(bucket: "telegraf")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_field"] == "cache_misses")
  |> set(key: "_field", value: "misses")

union(tables: [hits, misses])
  |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => ({
      _time: r._time,
      _value: (r.hits / (r.hits + r.misses)) * 100.0
    }))

Panel Type Examples

Stat Panel (single value)

{
    "type": "stat",
    "title": "Current Value",
    "datasource": {"type": "influxdb", "uid": "${datasource}"},
    "targets": [{"query": "...", "refId": "A"}],
    "fieldConfig": {
        "defaults": {
            "unit": "short",
            "thresholds": {
                "mode": "absolute",
                "steps": [
                    {"value": None, "color": "green"},
                    {"value": 80, "color": "yellow"},
                    {"value": 100, "color": "red"}
                ]
            }
        }
    }
}

Gauge Panel (visual meter)

{
    "type": "gauge",
    "title": "Usage Meter",
    "datasource": {"type": "influxdb", "uid": "${datasource}"},
    "fieldConfig": {
        "defaults": {
            "unit": "percent",
            "min": 0,
            "max": 100,
            "thresholds": {
                "steps": [
                    {"value": None, "color": "green"},
                    {"value": 70, "color": "yellow"},
                    {"value": 90, "color": "red"}
                ]
            }
        }
    }
}

Time Series Graph

{
    "type": "timeseries",
    "title": "Metric Over Time",
    "datasource": {"type": "influxdb", "uid": "${datasource}"},
    "fieldConfig": {
        "defaults": {
            "unit": "ops",
            "custom": {
                "drawStyle": "line",
                "lineInterpolation": "linear",
                "fillOpacity": 10,
                "showPoints": "never"
            }
        }
    },
    "options": {
        "tooltip": {"mode": "multi", "sort": "desc"},
        "legend": {
            "showLegend": True,
            "displayMode": "table",
            "placement": "bottom",
            "calcs": ["lastNotNull", "max", "mean"]
        }
    }
}

Fail2ban Journald Migration (2026-01-01)

Important: Fail2ban logs migrated from direct file monitoring to journald.

OLD source (deprecated): - Labels: {job="fail2ban", action_type="Ban", jail="sshd"} - Pre-parsed by log shipper - Last data: 2026-01-01 04:18 UTC

NEW source (current): - Labels: {service_type="fail2ban", hostname="ispconfig3-server.example.com"} - Log format: [jail] Ban/Unban IP - Requires regex parsing in queries - Started: 2026-01-01 04:41 UTC

Query migration example:

# OLD (don't use)
{job="fail2ban", action_type="Ban", jail="sshd"}

# NEW (current)
{service_type="fail2ban"}
| regexp `\[(?P<jail>[^\]]+)\]\s+(?P<action>Ban|Unban)\s+(?P<banned_ip>\d+\.\d+\.\d+\.\d+)`
| action="Ban"
| jail="sshd"