Using Grafana Loki to parse specific Docker container logs

I have 5 servers used for the following purposes:

  1. edge1
  2. edge2
  3. services
  4. security
  5. media

Each server uses a Promtail docker container to push logs to a Loki instance hosted on the services server. All servers send docker logs and journal entries.

The promtail configuration looks like this:

server:
  http_listen_address: 0.0.0.0
  http_listen_port: 9080

positions:
  filename: /etc/promtail/positions.yaml

clients:
  - url: http://[services-ip]:3100/loki/api/v1/push

scrape_configs:

  - job_name: edge1-docker-sock 
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
        refresh_interval: 15s
    relabel_configs:
      - source_labels: ['__meta_docker_container_name']
        regex: '/(.*)'
        target_label: 'docker_container_name'
      - source_labels: ['__meta_docker_container_log_stream']
        target_label: 'docker_log_stream'
      - source_labels: ['__meta_docker_container_label_logging_jobname']
        target_label: 'docker_logging_job'
      - source_labels: ['__meta_docker_network_ip']
        target_label: 'docker_network_ip'
      - source_labels: ['__meta_docker_network_name']
        target_label: 'docker_network_name'

  - job_name: edge1-journal
    journal:
      json: false
      max_age: 12h
      labels:
        job: journal
        host: edge1
    relabel_configs:
      - source_labels: ['__journal__systemd_unit']
        target_label: journal_systemd_unit
      - source_labels: ['__journal__systemd_user_unit']
        target_label: journal_systemd_user_unit
      - source_labels: ['__journal__hostname']
        target_label: journal_hostname
      - source_labels: ['__journal_syslog_identifier']
        target_label: journal_syslog_identifier
      - source_labels: ['__journal__transport']
        target_label: journal_transport
      - source_labels: ['__journal_priority_keyword']
        target_label: journal_severity

The services server runs Loki in a container. This instance is added as a datasource to a Grafana where I can use the Explore function to validate my queries:

My crowdsec container is hosted on the same server as my traefik container, and the traefik logs folder is shared with the crowdsec container. I added specific Loki instances to my crowdsec aquisitions file for everything else:

source: file
filenames:
  - /logs/web/*.log
log_level: warn
labels:
  type: traefik
---
source: loki
url: http://192.168.1.93:3100/
query: |
  {job="journal"}
limit: 1000
log_level: warn
labels:
  type: syslog
---
source: loki
url: http://192.168.1.93:3100/
query: |
  {docker_container_name="homeassistant"}
limit: 1000
log_level: warn
labels:
  type: home-assistant
---
source: loki
url: http://192.168.1.93:3100/
query: |
  {docker_container_name="immich_server"}
limit: 1000
log_level: warn
labels:
  type: immich
---
source: loki
url: http://192.168.1.93:3100/
query: |
  {docker_container_name="joplin-server"}
limit: 1000
log_level: warn
labels:
  type: joplin-server

I added the various parsers to my crowdsec container:

# cscli parsers list
INFO Ignoring file /etc/crowdsec/parsers/s02-enrich/whitelists.yaml of type parsers
INFO Ignoring file /etc/crowdsec/hub/parsers/s02-enrich/crowdsecurity/whitelists.yaml of type parsers

PARSERS
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Name                               📦 Status          Version  Local Path
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 crowdsecurity/appsec-logs          ✔️  enabled        0.5      /etc/crowdsec/parsers/s01-parse/appsec-logs.yaml
 crowdsecurity/cri-logs             ✔️  enabled        0.1      /etc/crowdsec/parsers/s00-raw/cri-logs.yaml
 crowdsecurity/dateparse-enrich     ✔️  enabled        0.2      /etc/crowdsec/parsers/s02-enrich/dateparse-enrich.yaml
 crowdsecurity/docker-logs          ✔️  enabled        0.1      /etc/crowdsec/parsers/s00-raw/docker-logs.yaml
 crowdsecurity/geoip-enrich         ✔️  enabled        0.5      /etc/crowdsec/parsers/s02-enrich/geoip-enrich.yaml
 crowdsecurity/home-assistant-logs  ✔️  enabled        0.5      /etc/crowdsec/parsers/s01-parse/home-assistant-logs.yaml
 crowdsecurity/http-logs            ✔️  enabled        1.3      /etc/crowdsec/parsers/s02-enrich/http-logs.yaml
 crowdsecurity/sshd-logs            ✔️  enabled        2.8      /etc/crowdsec/parsers/s01-parse/sshd-logs.yaml
 crowdsecurity/syslog-logs          ✔️  enabled        0.8      /etc/crowdsec/parsers/s00-raw/syslog-logs.yaml
 crowdsecurity/traefik-logs         ✔️  enabled        0.9      /etc/crowdsec/parsers/s01-parse/traefik-logs.yaml
 crowdsecurity/whitelists           🏠  enabled,local           /etc/crowdsec/parsers/s02-enrich/custom-whitelists.yaml
 gauth-fr/immich-logs               ✔️  enabled        0.2      /etc/crowdsec/parsers/s01-parse/immich-logs.yaml
 instantdreams/local-addresses      🏠  enabled,local           /etc/crowdsec/parsers/s02-enrich/local-addresses.yaml
 instantdreams/zscaler-addresses    🏠  enabled,local           /etc/crowdsec/parsers/s02-enrich/zscaler-addresses.yaml
 xs539/joplin-server-logs           ✔️  enabled        0.1      /etc/crowdsec/parsers/s01-parse/joplin-server-logs.yaml
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

My issue is that the Loki parser doesn’t seem to separate by job:

# cscli metrics
Acquisition Metrics:
╭────────────────────────────────┬────────────┬──────────────┬────────────────┬────────────────────────┬───────────────────╮
│ Source                         │ Lines read │ Lines parsed │ Lines unparsed │ Lines poured to bucket │ Lines whitelisted │
├────────────────────────────────┼────────────┼──────────────┼────────────────┼────────────────────────┼───────────────────┤
│ file:/logs/web/access.log      │ 23.51k     │ 23.51k       │ 1              │ 5.51k                  │ 41.29k            │
│ loki:http://[services-ip]:3100/│ 23.98k     │ -            │ 23.98k         │ -                      │ -                 │
╰────────────────────────────────┴────────────┴──────────────┴────────────────┴────────────────────────┴───────────────────╯

How can I confirm that my docker logs for specific services are being parsed correctly, and that it isn’t just the last aquis.yaml file entry?

Is there a way to add additional labels to the aquisition entries such as job: immich and job: home-assistant?

Hopefully this is a useful use case that no one has yet delved into so we can document some examples.

I’ve found that if I use cscli parsers list to list all intalled parsers I can then inspect each one for the specific metrics.

Here’s traefik:

crowdsec:/# cscli parsers inspect crowdsecurity/traefik-logs
[removed details]
Current metrics:

 - (Parser) crowdsecurity/traefik-logs:
╭───────────────────────────┬──────┬────────┬──────────╮
│ Parsers                   │ Hits │ Parsed │ Unparsed │
├───────────────────────────┼──────┼────────┼──────────┤
│ file:/logs/web/access.log │ 424  │ 424    │ 0        │
╰───────────────────────────┴──────┴────────┴──────────╯

And home-assistant:

crowdsec:/# cscli parsers inspect crowdsecurity/home-assistant-logs
[removed details]
Current metrics:

 - (Parser) crowdsecurity/home-assistant-logs:
╭────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers                        │ Hits │ Parsed │ Unparsed │
├────────────────────────────────┼──────┼────────┼──────────┤
│ loki:http://[services-ip]:3100/│ 764  │ 0      │ 764      │
╰────────────────────────────────┴──────┴────────┴──────────╯

And immich for good measure:

crowdsec:/# cscli parsers inspect gauth-fr/immich-logs
[removed details]
Current metrics:

 - (Parser) gauth-fr/immich-logs:
╭────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers                        │ Hits │ Parsed │ Unparsed │
├────────────────────────────────┼──────┼────────┼──────────┤
│ loki:http://[services-ip]:3100/│ 10   │ 0      │ 10       │
╰────────────────────────────────┴──────┴────────┴──────────╯

First question, is there a way to show the parser details in a summary form for all active parsers? Ideally a table in the format:

Parser Source Hits Parsed Unparsed
crowdsecurity/home-assistant-logs loki:http://[services-ip]:3100/ 764 0 764
crowdsecurity/http-logs file:/logs/web/access.log 1751 1751 0

Second question, why are all my Loki sources showing unparsed? Is it because althought a data source of Loki is supported, each individual parser has to be configured to support the Loki format?

The docker logs in Loki are indeed docker logs, so according to the docker-logs parser details I adjusted my acquis.yaml file. Here’s a snippet:

source: loki
url: http://[services-ip]:3100/
query: |
  {docker_container_name="homeassistant"}
limit: 1000
log_level: warn
labels:
  type: docker
  program: home-assistant
---
source: loki
url: http://[services-ip]:3100/
query: |
  {docker_container_name="immich_server"}
limit: 1000
log_level: warn
labels:
  type: docker
  program: immich
---
source: loki
url: http://[services-ip]:3100/
query: |
  {docker_container_name="audiobookshelf"}
limit: 1000
log_level: warn
labels:
  type: docker
  program: audiobookshelf

When I inspect the parsers I can see that the initial injesting into docker-logs worked:

crowdsec:/# cscli parsers inspect crowdsecurity/docker-logs
[details removed]
Current metrics:

 - (Parser) crowdsecurity/docker-logs:
╭────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers                        │ Hits │ Parsed │ Unparsed │
├────────────────────────────────┼──────┼────────┼──────────┤
│ loki:http://[services-ip]:3100/│ 831  │ 831    │ 0        │
╰────────────────────────────────┴──────┴────────┴──────────╯

But each subsequent parser did not.

Home Assistant

crowdsec:/# cscli parsers inspect crowdsecurity/home-assistant-logs
Current metrics:

 - (Parser) crowdsecurity/home-assistant-logs:
╭────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers                        │ Hits │ Parsed │ Unparsed │
├────────────────────────────────┼──────┼────────┼──────────┤
│ loki:http://[services-ip]:3100/│ 402  │ 0      │ 402      │
╰────────────────────────────────┴──────┴────────┴──────────╯

Immich

crowdsec:/# cscli parsers inspect gauth-fr/immich-logs
Current metrics:

 - (Parser) gauth-fr/immich-logs:
╭────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers                        │ Hits │ Parsed │ Unparsed │
├────────────────────────────────┼──────┼────────┼──────────┤
│ loki:http://[services-ip]:3100/│ 2    │ 0      │ 2        │
╰────────────────────────────────┴──────┴────────┴──────────╯

Audiobookshelf

crowdsec:/# cscli parsers inspect plague-doctor/audiobookshelf-logs
Current metrics:

 - (Parser) plague-doctor/audiobookshelf-logs:
╭────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers                        │ Hits │ Parsed │ Unparsed │
├────────────────────────────────┼──────┼────────┼──────────┤
│ loki:http://[services-ip]:3100/│ 3    │ 0      │ 3        │
╰────────────────────────────────┴──────┴────────┴──────────╯

How can I best debug or resolve this issue?

Can you try running an explain command since it takes a DSN you should be able to do something like:

cscli explain --dsn 'loki://login:password@[services-ip]:3100/?query={docker_container_name="immich_server"}&since=1d' --labels program:immich --type docker

However, please note all your applications only parse failed authentication attempts, if you have not had a failed authentication since crowdsec is running all logs will be unparsed. So before attempting the above, try to generate a failed authentication and see if the parsed column goes up.

Using 1d wasn’t working: invalid since in dsn: time: unknown unit \"d\" in duration \"1d\""

Adjusted it and snipped out the lines that weren’t relevant.

Home Assistant

crowdsec:/# cscli explain --dsn 'loki://[services-ip]:3100/?query={docker_container_name="homeassistant"}&since=1h' --type docker --labels program:home-assistant
WARN Line 0/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 1/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 2/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 3/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 4/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 5/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 6/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 7/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 8/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 9/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 10/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 11/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 12/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 13/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 14/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 15/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 16/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 17/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 18/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 19/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 20/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 21/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 22/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 23/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 24/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 25/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 26/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 27/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 28/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 29/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 30/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 31/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 32/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 33/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 34/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 35/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 36/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 37/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 38/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 39/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 40/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 41/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 42/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 43/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 44/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 45/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 46/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 47/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 48/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 49/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 50/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 51/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 52/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 53/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 54/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 55/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 56/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 57/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 58/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 59/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 60/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 61/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 62/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 63/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 64/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 65/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 66/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 67/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 68/69 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
line: 2025-01-22 12:04:43.476 WARNING (MainThread) [homeassistant.components.http.ban] Login attempt or request with invalid authentication from 192.168.1.106 (192.168.1.106). Requested URL: '/auth/login_flow/[token]'. (Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0)
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       └ 🟢 crowdsecurity/docker-logs (+3 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🔴 plague-doctor/audiobookshelf-logs
        |       ├ 🔴 LePresidente/grafana-logs
        |       ├ 🔴 crowdsecurity/home-assistant-logs
        |       ├ 🔴 gauth-fr/immich-logs
        |       ├ 🔴 xs539/joplin-server-logs
        |       ├ 🔴 crowdsecurity/mariadb-logs
        |       ├ 🔴 crowdsecurity/mysql-logs
        |       ├ 🔴 LePresidente/overseerr-logs
        |       ├ 🔴 schiz0phr3ne/prowlarr-logs
        |       ├ 🔴 schiz0phr3ne/radarr-logs
        |       ├ 🔴 schiz0phr3ne/sonarr-logs
        |       ├ 🔴 crowdsecurity/sshd-logs
        |       ├ 🔴 crowdsecurity/traefik-logs
        |       ├ 🔴 timokoessler/uptime-kuma-logs
        |       └ 🔴 Dominic-Wagner/vaultwarden-logs
        └-------- parser failure 🔴

Immich

crowdsec:/# cscli explain --dsn 'loki://[services-ip]:3100/?query={docker_container_name="immich_server"}&since=1h' --type docker --labels program:immich
WARN Line 0/2 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 1/2 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
line: [Nest] 25  - 01/22/2025, 11:42:15 AM    WARN [Api:AuthService~5nuqfxq4] Failed login attempt for user admin@example.com from ip address ::ffff:192.168.1.106
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       └ 🟢 crowdsecurity/docker-logs (+3 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🔴 plague-doctor/audiobookshelf-logs
        |       ├ 🔴 LePresidente/grafana-logs
        |       ├ 🔴 crowdsecurity/home-assistant-logs
        |       ├ 🔴 gauth-fr/immich-logs
        |       ├ 🔴 xs539/joplin-server-logs
        |       ├ 🔴 crowdsecurity/mariadb-logs
        |       ├ 🔴 crowdsecurity/mysql-logs
        |       ├ 🔴 LePresidente/overseerr-logs
        |       ├ 🔴 schiz0phr3ne/prowlarr-logs
        |       ├ 🔴 schiz0phr3ne/radarr-logs
        |       ├ 🔴 schiz0phr3ne/sonarr-logs
        |       ├ 🔴 crowdsecurity/sshd-logs
        |       ├ 🔴 crowdsecurity/traefik-logs
        |       ├ 🔴 timokoessler/uptime-kuma-logs
        |       └ 🔴 Dominic-Wagner/vaultwarden-logs
        └-------- parser failure 🔴

line: [Nest] 25  - 01/22/2025, 12:10:19 PM    WARN [Api:AuthService~nype3jfq] Failed login attempt for user admin@example.com from ip address ::ffff:192.168.1.106
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       └ 🟢 crowdsecurity/docker-logs (+3 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🔴 plague-doctor/audiobookshelf-logs
        |       ├ 🔴 LePresidente/grafana-logs
        |       ├ 🔴 crowdsecurity/home-assistant-logs
        |       ├ 🔴 gauth-fr/immich-logs
        |       ├ 🔴 xs539/joplin-server-logs
        |       ├ 🔴 crowdsecurity/mariadb-logs
        |       ├ 🔴 crowdsecurity/mysql-logs
        |       ├ 🔴 LePresidente/overseerr-logs
        |       ├ 🔴 schiz0phr3ne/prowlarr-logs
        |       ├ 🔴 schiz0phr3ne/radarr-logs
        |       ├ 🔴 schiz0phr3ne/sonarr-logs
        |       ├ 🔴 crowdsecurity/sshd-logs
        |       ├ 🔴 crowdsecurity/traefik-logs
        |       ├ 🔴 timokoessler/uptime-kuma-logs
        |       └ 🔴 Dominic-Wagner/vaultwarden-logs
        └-------- parser failure 🔴

Audiobookshelf

crowdsec:/# cscli explain --dsn 'loki://[services-ip]:3100/?query={docker_container_name="audiobookshelf"}&since=1h' --type docker --labels program:audiobookshelf
WARN Line 0/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 1/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 2/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 3/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 4/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 5/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 6/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 7/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 8/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 9/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 10/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 11/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 12/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 13/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 14/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 15/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 16/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 17/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 18/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 19/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 20/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 21/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
line: [2025-01-22 11:41:24.907] ERROR: [Auth] Failed login attempt for username "admin" from ip ::ffff:192.168.1.106 (User not found)
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       └ 🟢 crowdsecurity/docker-logs (+3 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🔴 plague-doctor/audiobookshelf-logs
        |       ├ 🔴 LePresidente/grafana-logs
        |       ├ 🔴 crowdsecurity/home-assistant-logs
        |       ├ 🔴 gauth-fr/immich-logs
        |       ├ 🔴 xs539/joplin-server-logs
        |       ├ 🔴 crowdsecurity/mariadb-logs
        |       ├ 🔴 crowdsecurity/mysql-logs
        |       ├ 🔴 LePresidente/overseerr-logs
        |       ├ 🔴 schiz0phr3ne/prowlarr-logs
        |       ├ 🔴 schiz0phr3ne/radarr-logs
        |       ├ 🔴 schiz0phr3ne/sonarr-logs
        |       ├ 🔴 crowdsecurity/sshd-logs
        |       ├ 🔴 crowdsecurity/traefik-logs
        |       ├ 🔴 timokoessler/uptime-kuma-logs
        |       └ 🔴 Dominic-Wagner/vaultwarden-logs
        └-------- parser failure 🔴

Radarr

crowdsec:/# cscli explain --dsn 'loki://[services-ip]:3100/?query={docker_container_name="radarr"}&since=1h' --type docker --labels program:Radarr
WARN Line 0/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 1/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 2/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 3/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 4/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 5/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 6/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 7/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 8/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 9/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 10/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 11/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 12/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 13/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 14/15 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
line: [Warn] Auth: Auth-Failure ip 192.168.1.106 username 'admin'
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       └ 🟢 crowdsecurity/docker-logs (+3 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🔴 plague-doctor/audiobookshelf-logs
        |       ├ 🔴 LePresidente/grafana-logs
        |       ├ 🔴 crowdsecurity/home-assistant-logs
        |       ├ 🔴 gauth-fr/immich-logs
        |       ├ 🔴 xs539/joplin-server-logs
        |       ├ 🔴 crowdsecurity/mariadb-logs
        |       ├ 🔴 crowdsecurity/mysql-logs
        |       ├ 🔴 LePresidente/overseerr-logs
        |       ├ 🔴 schiz0phr3ne/prowlarr-logs
        |       ├ 🔴 schiz0phr3ne/radarr-logs
        |       ├ 🔴 schiz0phr3ne/sonarr-logs
        |       ├ 🔴 crowdsecurity/sshd-logs
        |       ├ 🔴 crowdsecurity/traefik-logs
        |       ├ 🔴 timokoessler/uptime-kuma-logs
        |       └ 🔴 Dominic-Wagner/vaultwarden-logs
        └-------- parser failure 🔴

Looks like the logs are being parsed by the docker parser but not being dealt with by the subsequent parser.

I turned on verbose mode as well, just in case it’s useful:

crowdsec:/# cscli explain --dsn 'loki://[services-ip]:3100/?query={docker_container_name="audiobookshelf"}&since=1h' --type docker --labels program:audiobookshelf,type:docker --verbose
WARN Line 0/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 1/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 2/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 3/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 4/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 5/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 6/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 7/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 8/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 9/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 10/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 11/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 12/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 13/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 14/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 15/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 16/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 17/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 18/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 19/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 20/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
WARN Line 21/22 is missing evt.StrTime. It is most likely a mistake as it will prevent your logs to be processed in time-machine/forensic mode.
line: [2025-01-22 12:03:57.922] ERROR: [Auth] Failed login attempt for username "admin" from ip ::ffff:192.168.1.106 (User not found)
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       └ 🟢 crowdsecurity/docker-logs (+3 ~7)
        |               └ update evt.Stage :  -> s01-parse
        |               └ update evt.Line.Raw :  -> [2025-01-22 12:03:57.922] ERROR: [Auth] Failed login attempt for username "admin" from ip ::ffff:192.168.1.106 (User not found)
        |               └ update evt.Line.Src :  -> http://192.168.1.93:3100
        |               └ update evt.Line.Time : 0001-01-01 00:00:00 +0000 UTC -> 2025-01-22 12:03:57.923032315 -0700 MST
        |               └ create evt.Line.Labels.program : audiobookshelf
        |               └ create evt.Line.Labels.type : docker
        |               └ update evt.Line.Process : %!s(bool=false) -> true
        |               └ update evt.Line.Module :  -> loki
        |               └ create evt.Parsed.program : audiobookshelf
        |               └ update evt.Time : 0001-01-01 00:00:00 +0000 UTC -> 2025-01-22 19:36:37.596540275 +0000 UTC
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🔴 plague-doctor/audiobookshelf-logs
        |       ├ 🔴 LePresidente/grafana-logs
        |       ├ 🔴 crowdsecurity/home-assistant-logs
        |       ├ 🔴 gauth-fr/immich-logs
        |       ├ 🔴 xs539/joplin-server-logs
        |       ├ 🔴 crowdsecurity/mariadb-logs
        |       ├ 🔴 crowdsecurity/mysql-logs
        |       ├ 🔴 LePresidente/overseerr-logs
        |       ├ 🔴 schiz0phr3ne/prowlarr-logs
        |       ├ 🔴 schiz0phr3ne/radarr-logs
        |       ├ 🔴 schiz0phr3ne/sonarr-logs
        |       ├ 🔴 crowdsecurity/sshd-logs
        |       ├ 🔴 crowdsecurity/traefik-logs
        |       ├ 🔴 timokoessler/uptime-kuma-logs
        |       └ 🔴 Dominic-Wagner/vaultwarden-logs
        └-------- parser failure 🔴

The logs dont seem to be in docker format, as typically docker logs as JSON lines

https://raw.githubusercontent.com/crowdsecurity/hub/refs/heads/master/.tests/docker-logs/docker-logs.log

we seem to be missing crowdsecurity/syslog-logs could you install this parser and try running explain again but just with --type audiobookshelf and no labels

line: [2025-01-22 12:03:57.922] ERROR: [Auth] Failed login attempt for username "admin" from ip ::ffff:192.168.1.106 (User not found)
	├ s00-raw
	|	├ 🔴 crowdsecurity/syslog-logs
	|	└ 🟢 crowdsecurity/non-syslog (+5 ~8)
	|		└ update evt.ExpectMode : %!s(int=0) -> 1
	|		└ update evt.Stage :  -> s01-parse
	|		└ update evt.Line.Raw :  -> [2025-01-22 12:03:57.922] ERROR: [Auth] Failed login attempt for username "admin" from ip ::ffff:192.168.1.106 (User not found)
	|		└ update evt.Line.Src :  -> /tmp/cscli_explain90663620/cscli_test_tmp.log
	|		└ update evt.Line.Time : 0001-01-01 00:00:00 +0000 UTC -> 2025-01-22 19:59:37.633943484 +0000 UTC
	|		└ create evt.Line.Labels.type : audiobookshelf
	|		└ update evt.Line.Process : %!s(bool=false) -> true
	|		└ update evt.Line.Module :  -> file
	|		└ create evt.Parsed.message : [2025-01-22 12:03:57.922] ERROR: [Auth] Failed login attempt for username "admin" from ip ::ffff:192.168.1.106 (User not found)
	|		└ create evt.Parsed.program : audiobookshelf
	|		└ update evt.Time : 0001-01-01 00:00:00 +0000 UTC -> 2025-01-22 19:59:37.633971445 +0000 UTC
	|		└ create evt.Meta.datasource_path : /tmp/cscli_explain90663620/cscli_test_tmp.log
	|		└ create evt.Meta.datasource_type : file
	├ s01-parse
	|	├ 🔴 LePresidente/adguardhome-logs
	|	├ 🔴 crowdsecurity/amavis-logs
	|	├ 🔴 corvese/apache-guacamole-logs
	|	├ 🔴 crowdsecurity/apache2-logs
	|	├ 🔴 jusabatier/apereo-cas-audit-logs
	|	├ 🔴 crowdsecurity/appsec-logs
	|	├ 🔴 crowdsecurity/asterisk-logs
	|	└ 🟢 plague-doctor/audiobookshelf-logs (+8 ~2)
	|		└ update evt.Stage : s01-parse -> s02-enrich
	|		└ create evt.Parsed.reason : User not found
	|		└ create evt.Parsed.source_ip : ::ffff:192.168.1.106
	|		└ create evt.Parsed.timestamp : 2025-01-22 12:03:57.922
	|		└ create evt.Parsed.username : admin
	|		└ update evt.StrTime :  -> 2025-01-22 12:03:57.922
	|		└ create evt.Meta.log_type : abs_failed_auth
	|		└ create evt.Meta.service : audiobookshelf
	|		└ create evt.Meta.source_ip : ::ffff:192.168.1.106
	|		└ create evt.Meta.username : admin
	├ s02-enrich
	|	├ 🟢 crowdsecurity/dateparse-enrich (+2 ~2)
	|		├ create evt.Enriched.MarshaledTime : 2025-01-22T12:03:57.922Z
	|		├ update evt.Time : 2025-01-22 19:59:37.633971445 +0000 UTC -> 2025-01-22 12:03:57.922 +0000 UTC
	|		├ update evt.MarshaledTime :  -> 2025-01-22T12:03:57.922Z
	|		├ create evt.Meta.timestamp : 2025-01-22T12:03:57.922Z
	|	├ 🔴 crowdsecurity/geoip-enrich
	|	├ 🔴 crowdsecurity/http-logs
	|	├ 🔴 crowdsecurity/jellyfin-whitelist
	|	├ 🔴 crowdsecurity/naxsi-logs
	|	├ 🔴 crowdsecurity/nextcloud-whitelist
	|	├ 🔴 selfhosted/whitelist
	|	└ 🟢 my/us-east-1-ranges (unchanged)
	├-------- parser success 🟢
	├ Scenarios
		└ 🟢 plague-doctor/audiobookshelf-bf

However, I see an issue in the parser ::ffff: should not be included in the source IP

I have docker configured to produce json log files across all servers:

$ cat /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts":
  {
    "max-file": "8",
    "max-size": "16m"
  },
  "metrics-addr" : "0.0.0.0:9323"
}

A quick inspect of a container will show the log location:

$ docker container inspect audiobookshelf | grep LogPath
        "LogPath": "/var/lib/docker/containers/ec77c5f8cfbaa7489e9fbd97eb0a8b02612c047af086b27b544e46cbbcccdfa1/ec77c5f8cfbaa7489e9fbd97eb0a8b02612c047af086b27b544e46cbbcccdfa1-json.log",

Confirming the docker log is in json format:

$ sudo tail /var/lib/docker/containers/ec77c5f8cfbaa7489e9fbd97eb0a8b02612c047af086b27b544e46cbbcccdfa1/ec77c5f8cfbaa7489e
9fbd97eb0a8b02612c047af086b27b544e46cbbcccdfa1-json.log
{"log":"[2025-01-22 13:48:53.403] ERROR: [Auth] Failed login attempt for username \"admin\" from ip ::ffff:192.168.1.106 (User not found)\n","stream":"stderr","time":"2025-01-22T20:48:53.40560825Z"}
{"log":"[2025-01-22 13:48:58.263] ERROR: [Auth] Failed login attempt for username \"root\" from ip ::ffff:192.168.1.106 (Invalid password)\n","stream":"stderr","time":"2025-01-22T20:48:58.263236085Z"}

Each server promtail instance is as defined in my original post and uses the docker.sock to access the logs directly. I added a pipeline_stages entry into promtail to preserve the json format:

  - job_name: id-media-docker-sock
    pipeline_stages:
      - docker: {}
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
        refresh_interval: 15s
    relabel_configs:
      - source_labels: ['__meta_docker_container_name']
        regex: '/(.*)'
        target_label: 'docker_container_name'
      - source_labels: ['__meta_docker_container_log_stream']
        target_label: 'docker_log_stream'
      - source_labels: ['__meta_docker_container_label_logging_jobname']
        target_label: 'docker_logging_job'
      - source_labels: ['__meta_docker_network_ip']
        target_label: 'docker_network_ip'
      - source_labels: ['__meta_docker_network_name']
        target_label: 'docker_network_name'

Now, following the troubleshooting guide for promtail, I can see what gets sent.

promtail-5:/# cat /etc/promtail/audiobookshelf.log | promtail --stdin --dry-run --client.url http://[services-ip]:3100/loki/api/v1/push
Clients configured:
----------------------
url: http://[services-ip]:3100/loki/api/v1/push
batchwait: 1s
batchsize: 1048576
follow_redirects: false
enable_http2: false
backoff_config:
  min_period: 500ms
  max_period: 5m0s
  max_retries: 10
timeout: 10s
tenant_id: ""
drop_rate_limited_batches: false

2025-01-22T14:05:52.936216603-0700      {hostname="promtail-5", job="stdin"}    {"log":"[2025-01-22 13:48:53.403] ERROR: [Auth] Failed login attempt for username \"admin\" from ip ::ffff:192.168.1.106 (User not found)\n","stream":"stderr","time":"2025-01-22T20:48:53.40560825Z"}
2025-01-22T14:05:52.936218367-0700      {hostname="promtail-5", job="stdin"}    {"log":"[2025-01-22 13:48:58.263] ERROR: [Auth] Failed login attempt for username \"root\" from ip ::ffff:192.168.1.106 (Invalid password)\n","stream":"stderr","time":"2025-01-22T20:48:58.263236085Z"}

It does appear that Loki - and therefore Promtail - is not JSONifying the log entries.

I’ve installed crowdsecurity/syslog-logs and will restart the crowdsec container then generate some failed auths for audiobookshelf.

cscli parsers list
crowdsec:/# cscli parsers list
INFO Ignoring file /etc/crowdsec/parsers/s02-enrich/whitelists.yaml of type parsers
INFO Ignoring file /etc/crowdsec/hub/parsers/s02-enrich/crowdsecurity/whitelists.yaml of type parsers

PARSERS
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Name                               📦 Status          Version  Local Path
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 crowdsecurity/appsec-logs          ✔️  enabled        0.5      /etc/crowdsec/parsers/s01-parse/appsec-logs.yaml
 crowdsecurity/cri-logs             ✔️  enabled        0.1      /etc/crowdsec/parsers/s00-raw/cri-logs.yaml
 crowdsecurity/dateparse-enrich     ✔️  enabled        0.2      /etc/crowdsec/parsers/s02-enrich/dateparse-enrich.yaml
 crowdsecurity/docker-logs          ✔️  enabled        0.1      /etc/crowdsec/parsers/s00-raw/docker-logs.yaml
 crowdsecurity/geoip-enrich         ✔️  enabled        0.5      /etc/crowdsec/parsers/s02-enrich/geoip-enrich.yaml
 crowdsecurity/home-assistant-logs  ✔️  enabled        0.5      /etc/crowdsec/parsers/s01-parse/home-assistant-logs.yaml
 crowdsecurity/http-logs            ✔️  enabled        1.3      /etc/crowdsec/parsers/s02-enrich/http-logs.yaml
 crowdsecurity/mariadb-logs         ✔️  enabled        0.4      /etc/crowdsec/parsers/s01-parse/mariadb-logs.yaml
 crowdsecurity/mysql-logs           ✔️  enabled        0.4      /etc/crowdsec/parsers/s01-parse/mysql-logs.yaml
 crowdsecurity/sshd-logs            ✔️  enabled        2.8      /etc/crowdsec/parsers/s01-parse/sshd-logs.yaml
 crowdsecurity/syslog-logs          ✔️  enabled        0.8      /etc/crowdsec/parsers/s00-raw/syslog-logs.yaml
 crowdsecurity/traefik-logs         ✔️  enabled        0.9      /etc/crowdsec/parsers/s01-parse/traefik-logs.yaml
 crowdsecurity/whitelists           🏠  enabled,local           /etc/crowdsec/parsers/s02-enrich/custom-whitelists.yaml
 Dominic-Wagner/vaultwarden-logs    ✔️  enabled        0.1      /etc/crowdsec/parsers/s01-parse/vaultwarden-logs.yaml
 gauth-fr/immich-logs               ✔️  enabled        0.2      /etc/crowdsec/parsers/s01-parse/immich-logs.yaml
 instantdreams/local-addresses      🏠  enabled,local           /etc/crowdsec/parsers/s02-enrich/local-addresses.yaml
 instantdreams/zscaler-addresses    🏠  enabled,local           /etc/crowdsec/parsers/s02-enrich/zscaler-addresses.yaml
 LePresidente/grafana-logs          ✔️  enabled        0.3      /etc/crowdsec/parsers/s01-parse/grafana-logs.yaml
 LePresidente/overseerr-logs        ✔️  enabled        0.1      /etc/crowdsec/parsers/s01-parse/overseerr-logs.yaml
 plague-doctor/audiobookshelf-logs  ✔️  enabled        0.1      /etc/crowdsec/parsers/s01-parse/audiobookshelf-logs.yaml
 schiz0phr3ne/prowlarr-logs         ✔️  enabled        0.2      /etc/crowdsec/parsers/s01-parse/prowlarr-logs.yaml
 schiz0phr3ne/radarr-logs           ✔️  enabled        0.2      /etc/crowdsec/parsers/s01-parse/radarr-logs.yaml
 schiz0phr3ne/sonarr-logs           ✔️  enabled        0.2      /etc/crowdsec/parsers/s01-parse/sonarr-logs.yaml
 timokoessler/uptime-kuma-logs      ✔️  enabled        0.2      /etc/crowdsec/parsers/s01-parse/uptime-kuma-logs.yaml
 xs539/joplin-server-logs           ✔️  enabled        0.1      /etc/crowdsec/parsers/s01-parse/joplin-server-logs.yaml
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Looks like that fixed it without needing to use the docker parser:

cscli parsers list
crowdsec:/# cscli explain --dsn 'loki://[services-ip]:3100/?query={docker_container_name="audiobookshelf"}&since=1h' --type audiobookshelf
line: [2025-01-22 13:48:58.263] ERROR: [Auth] Failed login attempt for username "root" from ip ::ffff:192.168.1.106 (Invalid password)
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       ├ 🔴 crowdsecurity/docker-logs
        |       ├ 🔴 crowdsecurity/syslog-logs
        |       └ 🟢 crowdsecurity/non-syslog (+5 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🟢 plague-doctor/audiobookshelf-logs (+8 ~2)
        |       ├ 🔴 LePresidente/grafana-logs
        |       ├ 🔴 crowdsecurity/home-assistant-logs
        |       ├ 🔴 gauth-fr/immich-logs
        |       ├ 🔴 xs539/joplin-server-logs
        |       ├ 🔴 crowdsecurity/mariadb-logs
        |       ├ 🔴 crowdsecurity/mysql-logs
        |       ├ 🔴 LePresidente/overseerr-logs
        |       ├ 🔴 schiz0phr3ne/prowlarr-logs
        |       ├ 🔴 schiz0phr3ne/radarr-logs
        |       ├ 🔴 schiz0phr3ne/sonarr-logs
        |       ├ 🔴 crowdsecurity/sshd-logs
        |       ├ 🔴 crowdsecurity/traefik-logs
        |       ├ 🔴 timokoessler/uptime-kuma-logs
        |       └ 🔴 Dominic-Wagner/vaultwarden-logs
        ├ s02-enrich
        |       ├ 🟢 crowdsecurity/whitelists (~2 [whitelisted])
        |       ├ 🟢 crowdsecurity/dateparse-enrich (+2 ~1)
        |       ├ 🔴 crowdsecurity/geoip-enrich
        |       ├ 🔴 crowdsecurity/http-logs
        |       ├ 🟢 instantdreams/local-addresses (unchanged)
        |       └ 🟢 instantdreams/zscaler-addresses (unchanged)
        └-------- parser success, ignored by whitelist (my ip ranges) 🟢

line: [2025-01-22 14:38:04.759] ERROR: [Auth] Failed login attempt for username "admin" from ip ::ffff:192.168.1.106 (User not found)
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       ├ 🔴 crowdsecurity/docker-logs
        |       ├ 🔴 crowdsecurity/syslog-logs
        |       └ 🟢 crowdsecurity/non-syslog (+5 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🟢 plague-doctor/audiobookshelf-logs (+8 ~2)
        |       ├ 🔴 LePresidente/grafana-logs
        |       ├ 🔴 crowdsecurity/home-assistant-logs
        |       ├ 🔴 gauth-fr/immich-logs
        |       ├ 🔴 xs539/joplin-server-logs
        |       ├ 🔴 crowdsecurity/mariadb-logs
        |       ├ 🔴 crowdsecurity/mysql-logs
        |       ├ 🔴 LePresidente/overseerr-logs
        |       ├ 🔴 schiz0phr3ne/prowlarr-logs
        |       ├ 🔴 schiz0phr3ne/radarr-logs
        |       ├ 🔴 schiz0phr3ne/sonarr-logs
        |       ├ 🔴 crowdsecurity/sshd-logs
        |       ├ 🔴 crowdsecurity/traefik-logs
        |       ├ 🔴 timokoessler/uptime-kuma-logs
        |       └ 🔴 Dominic-Wagner/vaultwarden-logs
        ├ s02-enrich
        |       ├ 🟢 crowdsecurity/whitelists (~2 [whitelisted])
        |       ├ 🟢 crowdsecurity/dateparse-enrich (+2 ~1)
        |       ├ 🔴 crowdsecurity/geoip-enrich
        |       ├ 🔴 crowdsecurity/http-logs
        |       ├ 🟢 instantdreams/local-addresses (unchanged)
        |       └ 🟢 instantdreams/zscaler-addresses (unchanged)
        └-------- parser success, ignored by whitelist (my ip ranges) 🟢

Fantastic stuff! Once I’ve stabilised this, I’ll write up the end to end configuration.

On reviewing this, I did have crowdsecurity/syslog-logs installed originally, so it might just be hitting my servers with enough auth failures got things to work. In fact, re-installing syslog made a difference.

Original inspection:

crowdsec:/# cscli explain --dsn 'loki://[services-ip]:3100/?query={docker_container_name="audiobookshelf"}&since=1h' --type docker --labels program:audiobookshelf
line: [2025-01-22 11:41:24.907] ERROR: [Auth] Failed login attempt for username "admin" from ip ::ffff:192.168.1.106 (User not found)
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       └ 🟢 crowdsecurity/docker-logs (+3 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🔴 plague-doctor/audiobookshelf-logs

New inspection:

crowdsec:/# cscli explain --dsn 'loki://[services-ip]:3100/?query={docker_container_name="audiobookshelf"}&since=1h' --type audiobookshelf

line: [2025-01-22 13:48:58.263] ERROR: [Auth] Failed login attempt for username "root" from ip ::ffff:192.168.1.106 (Invalid password)
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/cri-logs
        |       ├ 🔴 crowdsecurity/docker-logs
        |       ├ 🔴 crowdsecurity/syslog-logs
        |       └ 🟢 crowdsecurity/non-syslog (+5 ~7)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/appsec-logs
        |       ├ 🟢 plague-doctor/audiobookshelf-logs (+8 ~2)

It wasn’t using syslogs-logs or non-syslog - perhaps because the type was docker. Either way, things are looking good!

Oh and of course I just found the command that shows me what I need to see:

crowdsec:/# cscli metrics show parsers
Parser Metrics:
╭─────────────────────────────────────────┬───────┬────────┬──────────╮
│ Parsers                                 │ Hits  │ Parsed │ Unparsed │
├─────────────────────────────────────────┼───────┼────────┼──────────┤
│ Dominic-Wagner/vaultwarden-logs         │ 4     │ -      │ 4        │
│ LePresidente/overseerr-logs             │ 134   │ -      │ 134      │
│ child-Dominic-Wagner/vaultwarden-logs   │ 12    │ -      │ 12       │
│ child-LePresidente/overseerr-logs       │ 536   │ -      │ 536      │
│ child-crowdsecurity/home-assistant-logs │ 2     │ 1      │ 1        │
│ child-crowdsecurity/http-logs           │ 3.30k │ 2.43k  │ 866      │
│ child-crowdsecurity/traefik-logs        │ 2.20k │ 1.10k  │ 1.10k    │
│ child-gauth-fr/immich-logs              │ 1     │ 1      │ -        │
│ child-plague-doctor/audiobookshelf-logs │ 21    │ 1      │ 20       │
│ child-schiz0phr3ne/prowlarr-logs        │ 189   │ 1      │ 188      │
│ child-schiz0phr3ne/radarr-logs          │ 11    │ 1      │ 10       │
│ child-schiz0phr3ne/sonarr-logs          │ 47    │ 1      │ 46       │
│ child-timokoessler/uptime-kuma-logs     │ 52    │ 2      │ 50       │
│ child-xs539/joplin-server-logs          │ 683   │ -      │ 683      │
│ crowdsecurity/dateparse-enrich          │ 1.10k │ 1.10k  │ -        │
│ crowdsecurity/geoip-enrich              │ 273   │ 273    │ -        │
│ crowdsecurity/home-assistant-logs       │ 1     │ 1      │ -        │
│ crowdsecurity/http-logs                 │ 1.10k │ 1.10k  │ -        │
│ crowdsecurity/non-syslog                │ 2.12k │ 2.12k  │ -        │
│ crowdsecurity/traefik-logs              │ 1.10k │ 1.10k  │ -        │
│ crowdsecurity/whitelists                │ 1.11k │ 1.11k  │ -        │
│ gauth-fr/immich-logs                    │ 1     │ 1      │ -        │
│ instantdreams/local-addresses           │ 1.11k │ 1.11k  │ -        │
│ instantdreams/zscaler-addresses         │ 1.11k │ 1.11k  │ -        │
│ plague-doctor/audiobookshelf-logs       │ 21    │ 1      │ 20       │
│ schiz0phr3ne/prowlarr-logs              │ 95    │ 1      │ 94       │
│ schiz0phr3ne/radarr-logs                │ 6     │ 1      │ 5        │
│ schiz0phr3ne/sonarr-logs                │ 24    │ 1      │ 23       │
│ timokoessler/uptime-kuma-logs           │ 27    │ 2      │ 25       │
│ xs539/joplin-server-logs                │ 683   │ -      │ 683      │
╰─────────────────────────────────────────┴───────┴────────┴──────────╯

Apologies yes, I should have said cscli metrics is the command your looking for to print all details.

The only thing is I dont know how CrowdSec will handle ::ffff: infront of ipv4, if you have a decision on the address and do cscli decisions list it should normalize it