Introduction
Je pars du principe que vous utilisez Portainer, que vous savez vous servir d’un éditeur de texte et que vous connaissez vos machines.
Quelques notions
Loki est un système d’agrégation de logs horizontalement évolutif, hautement disponible et multi-tenant inspiré de Prometheus. Il est conçu pour être très rentable et facile à utiliser. Il n’indexe pas le contenu des journaux, mais plutôt un ensemble d’étiquettes pour chaque flux de journaux.Le projet Loki a été lancé à Grafana Labs en 2018, et annoncé à la KubeCon de Seattle. Loki est publié sous la licence AGPLv3.Grafana Labs est fier de diriger le développement du projet Loki, en construisant un support de première classe pour Loki dans Grafana, et en s’assurant que les clients de Grafana Labs reçoivent le support de Loki et les fonctionnalités dont ils ont besoin.
Promtail est un agent qui envoie le contenu des journaux locaux vers une instance privée de Grafana Loki ou Grafana Cloud. Il est généralement déployé sur chaque machine qui a des applications à surveiller.Il permet principalement de :- Découvrir des cibles- Attache des étiquettes aux flux de journaux- Les pousse vers l’instance Loki.Actuellement, Promtail peut suivre les journaux provenant de deux sources : les fichiers journaux locaux et le journal systemd (sur les machines AMD64 uniquement).
Prérequis
Vous avez déjà installé un stack avec Grafana et Prometheus.
Fichiers requis
docker-compose.yml
[Fichier]
version: "3.0"
#
# updated: 2023-05-24
# stack: loki
#
x-logging: &x-logging
logging:
driver: loki
options:
loki-url: "http://loki:3100/loki/api/v1/push"
loki-retries: "5"
loki-batch-size: "400"
x-common: &x-common
<<: *x-logging
restart: "no"
stop_grace_period: 5s
stdin_open: true
tty: true
privileged: false
security_opt:
- no-new-privileges=true
cap_drop:
- ALL
cap_add:
- KILL
dns:
- 1.1.1.1
- 8.8.8.8
- 1.0.0.1
- 8.8.4.4
ipc: "shareable"
extra_hosts:
- "template.home:192.168.0.0"
environment:
TZ: "Europe/Paris"
PUID: 1000
PGID: 1000
user: 1000:1000
labels:
com.centurylinklabs.watchtower.enable: true
logging: "promtail"
com.stack.name: "common"
com.stack.service.name: "common"
devices:
- /dev/kmsg:/dev/kmsg
deploy:
resources:
limits:
cpus: "0.50"
memory: 256M
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
tmpfs:
- /tmp:rw,noexec,nosuid,size=64k
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
x-volume-timezone: &x-volume-timezone "/etc/timezone:/etc/timezone:ro"
x-volume-localtime: &x-volume-localtime "/etc/localtime:/etc/localtime:ro"
x-volume-docker-socket: &x-volume-docker-socket "/var/run/docker.sock:/var/run/docker.sock:rw"
x-volume-cgroups: &x-volume-cgroups "/proc/cgroups:/cgroup:rw"
x-volume-ssl: &x-volume-ssl "/opt/docker/ssl:/ssl:ro"
services:
loki:
<<: *x-common
logging:
driver: json-file
options:
max-size: 32m
max-file: "7"
compress: "true"
stop_grace_period: 60s
cap_add:
- DAC_OVERRIDE
container_name: loki
hostname: loki
image: grafana/loki:latest
restart: always
ports:
- "3100:3100"
expose:
- "3100"
command: -config.file=/etc/loki/loki.yml
labels:
com.stack.name: "loki"
com.stack.service.name: "loki"
deploy:
resources:
limits:
cpus: "4.0"
memory: 1G
tmpfs:
- /tmp:rw,noexec,nosuid,size=512M
volumes:
- *x-volume-timezone
- *x-volume-localtime
- *x-volume-docker-socket
- *x-volume-cgroups
- /opt/docker/loki/conf:/etc/loki
- /opt/docker/loki/datas/loki:/datas
promtail:
<<: *x-common
user: 0:0
cap_add:
- DAC_OVERRIDE
container_name: promtail
hostname: promtail
image: grafana/promtail:latest
restart: always
depends_on:
- loki
ports:
- "1514:1514"
expose:
- "1514"
command: -config.file=/etc/promtail/promtail.yml
labels:
com.stack.name: "loki"
com.stack.service.name: "promtail"
tmpfs:
- /tmp:rw,noexec,nosuid,size=512M
volumes:
- *x-volume-timezone
- *x-volume-localtime
- *x-volume-docker-socket
- *x-volume-cgroups
- /var/log:/var/log:ro
- /opt/docker/loki/conf:/etc/promtail
- /opt/docker/loki/datas/promtail:/datas
loki.yml
[Fichier]
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
path_prefix: /datas
storage:
filesystem:
chunks_directory: /datas/chunks
rules_directory: /datas/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
schema_config:
configs:
- from: 2023-05-01
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb:
directory: /datas/index
filesystem:
directory: /datas/chunks
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
split_queries_by_interval: 24h
chunk_store_config:
max_look_back_period: 0s
table_manager:
chunk_tables_provisioning:
inactive_read_throughput: 0
inactive_write_throughput: 0
provisioned_read_throughput: 0
provisioned_write_throughput: 0
index_tables_provisioning:
inactive_read_throughput: 0
inactive_write_throughput: 0
provisioned_read_throughput: 0
provisioned_write_throughput: 0
retention_deletes_enabled: false
retention_period: 0s
querier:
max_concurrent: 100
frontend:
max_outstanding_per_tenant: 10000
scheduler_worker_concurrency: 20
query_scheduler:
max_outstanding_requests_per_tenant: 10000
ruler:
alertmanager_url: http://alerts:9093
promtail.yml
[Fichier]
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /datas/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
# local machine logs
- job_name: local
static_configs:
- targets:
- localhost
labels:
host: "template"
job: "varlogs"
__path__: /var/log/*log
# docker logs
- job_name: docker
pipeline_stages:
- docker: {}
static_configs:
- labels:
host: "template"
job: "docker"
__path__: /var/lib/docker/containers/*/*-json.log
# syslog target
- job_name: syslog
syslog:
listen_address: 0.0.0.0:1514
idle_timeout: 60s
label_structured_data: yes
labels:
host: "template"
job: "syslog"
relabel_configs:
- source_labels: ["__syslog_message_hostname"]
target_label: "host"
# log containers with label: logging=promtail
- job_name: scrape
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
filters:
- name: label
values: ["logging=promtail"]
relabel_configs:
- source_labels: ["__meta_docker_container_log_stream"]
target_label: "stream"
- source_labels: ["__meta_docker_container_name"]
regex: "/(.*)"
target_label: "container"
- source_labels: ["__meta_docker_container_id"]
regex: "(.*)"
target_label: "id"
- source_labels: ["__meta_docker_container_label_logging_jobname"]
target_label: "job"
parser.json
[Fichier]
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "",
"editable": true,
"fiscalYearStartMonth": 0,
"gnetId": 13198,
"graphTooltip": 0,
"id": 18,
"links": [
{
"asDropdown": true,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"Zogg"
],
"targetBlank": false,
"title": "Dashboards",
"tooltip": "",
"type": "dashboards",
"url": ""
}
],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "$datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "normal"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 24,
"x": 0,
"y": 0
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "table",
"placement": "right",
"showLegend": true
},
"tooltip": {
"mode": "multi",
"sort": "desc"
}
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"uid": "$datasource"
},
"editorMode": "code",
\"expr\": \"count\_over\_time\({host=~\"\$host\", container\_name=~\"\$job\"} |~ \"\$search\"\[1m])\",
"legendFormat": "",
"queryType": "range",
"refId": "A"
}
],
"title": "Metric Rate",
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"gridPos": {
"h": 14,
"w": 24,
"x": 0,
"y": 8
},
"id": 2,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": true,
"sortOrder": "Descending",
"wrapLogMessage": true
},
"pluginVersion": "7.1.3",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", container\_name=~\"\$job\"} |~ \"\$search\"\",
"legendFormat": "",
"queryType": "range",
"refId": "A"
}
],
"title": "Loki Search",
"type": "logs"
}
],
"refresh": "5m",
"schemaVersion": 38,
"style": "dark",
"tags": [
"Zogg",
"Loki"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "Loki",
"value": "Loki"
},
"hide": 0,
"includeAll": false,
"label": "Datasource",
"multi": false,
"name": "datasource",
"options": [],
"query": "loki",
"queryValue": "",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"type": "datasource"
},
{
"current": {
"selected": false,
"text": "All",
"value": "$__all"
},
"datasource": {
"type": "loki",
"uid": "${datasource}"
},
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Host",
"multi": false,
"name": "host",
"options": [],
"query": {
"label": "host",
"refId": "LokiVariableQueryEditor-VariableQuery",
"stream": "",
"type": 1
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"type": "query"
},
{
"allValue": "",
"current": {
"selected": false,
"text": "All",
"value": "$__all"
},
"datasource": {
"type": "loki",
"uid": "$datasource"
},
"definition": "label_values(container_name)",
"hide": 0,
"includeAll": true,
"label": "Job",
"multi": false,
"name": "job",
"options": [],
"query": {
"label": "container_name",
"refId": "LokiVariableQueryEditor-VariableQuery",
"stream": "{host=\"$host\"}",
"type": 1
},
"refresh": 2,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"selected": false,
"text": "",
"value": ""
},
"hide": 0,
"label": "Search",
"name": "search",
"options": [
{
"selected": true,
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Parser",
"uid": "ZOGG0012",
"version": 11,
"weekStart": ""
}
logs.json
[Fichier]
{
"annotations": {
"list": [
{
"$$hashKey": "object:75",
"builtIn": 1,
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "Log Viewer Dashboard for Loki",
"editable": true,
"fiscalYearStartMonth": 0,
"gnetId": 13639,
"graphTooltip": 0,
"id": 14,
"links": [
{
"asDropdown": true,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"Zogg"
],
"targetBlank": false,
"title": "Dashboards",
"tooltip": "",
"type": "dashboards",
"url": ""
}
],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "hidden",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 100,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"links": [],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 3,
"w": 24,
"x": 0,
"y": 0
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": false
},
"tooltip": {
"mode": "multi",
"sort": "none"
}
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"expr": "sum(count_over_time({job=\"$app\"} |= \"$search\" [$__interval]))",
"legendFormat": "",
"refId": "A"
}
],
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"gridPos": {
"h": 25,
"w": 24,
"x": 0,
"y": 3
},
"id": 2,
"maxDataPoints": "",
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": true,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{job=\"\$app\"} |= \"\$search\" | logfmt\",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "A"
}
],
"transparent": true,
"type": "logs"
}
],
"refresh": "5m",
"schemaVersion": 38,
"style": "dark",
"tags": [
"Zogg",
"Loki"
],
"templating": {
"list": [
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Host",
"multi": true,
"name": "host",
"options": [],
"query": {
"label": "host",
"refId": "LokiVariableQueryEditor-VariableQuery",
"stream": "",
"type": 1
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"type": "query"
},
{
"current": {
"selected": false,
"text": "varlogs",
"value": "varlogs"
},
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"definition": "label_values(job)",
"hide": 0,
"includeAll": false,
"label": "Job",
"multi": false,
"name": "app",
"options": [],
"query": "label_values(job)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"selected": false,
"text": "",
"value": ""
},
"hide": 0,
"label": "Search",
"name": "search",
"options": [
{
"selected": true,
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"hidden": false,
"refresh_intervals": [
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Logs",
"uid": "ZOGG0011",
"version": 14,
"weekStart": ""
}
ssh.json
[Fichier]
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"description": "",
"editable": true,
"fiscalYearStartMonth": 0,
"gnetId": 17514,
"graphTooltip": 0,
"id": 24,
"links": [
{
"asDropdown": true,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"Zogg"
],
"targetBlank": false,
"title": "Dashboards",
"tooltip": "",
"type": "dashboards",
"url": ""
}
],
"liveNow": false,
"panels": [
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 5,
"panels": [],
"title": "SSH - Total Stats",
"type": "row"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"index": 0,
"text": "0"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "purple",
"value": null
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 6,
"x": 0,
"y": 1
},
"id": 2,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "center",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"sum"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "sum by(instance) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |=\": session opened for\" | __error__=\"\" [$__interval]))",
"queryType": "range",
"refId": "A"
}
],
"title": "Total Opened Connection",
"type": "stat"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"index": 0,
"text": "0"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "purple",
"value": null
},
{
"color": "red",
"value": 1
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 6,
"y": 1
},
"id": 3,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "center",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"sum"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "sum by(instance) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |~\": Failed|: Invalid|: Connection closed by authenticating user\" | __error__=\"\" [$__interval]))",
"hide": false,
"queryType": "range",
"refId": "A"
}
],
"title": "Total Failed Connection",
"transformations": [
{
"id": "merge",
"options": {}
}
],
"type": "stat"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"mappings": [
{
"options": {
"match": "null",
"result": {
"index": 0,
"text": "0"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "purple",
"value": null
},
{
"color": "red",
"value": 1
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 9,
"y": 1
},
"id": 21,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"count"
],
"fields": "/^IP$/",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "count by (ip) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |~\": Invalid|: Connection closed by authenticating user|: Failed\" |~\".* from .*\" | pattern `<_> from <ip> port` | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "A",
"resolution": 1
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "count by (ip) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |~\": Invalid|: Connection closed by authenticating user|: Failed\" !~\".* from .*\" | pattern `<_> user <_> <ip> port` | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "B"
}
],
"title": "Total Failed - Unique IP",
"transformations": [
{
"id": "labelsToFields",
"options": {
"mode": "rows",
"valueLabel": "ip"
}
},
{
"id": "merge",
"options": {}
},
{
"id": "organize",
"options": {
"excludeByName": {
"178.40.119.51": false,
"194.154.240.221": false,
"label": true
},
"indexByName": {},
"renameByName": {
"value": "IP"
}
}
}
],
"type": "stat"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"index": 0,
"text": "0"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "orange",
"value": null
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 12,
"y": 1
},
"id": 6,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"sum"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" | __error__=\"\" [$__interval])",
"queryType": "range",
"refId": "A"
}
],
"title": "SSH Log Lines",
"type": "stat"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"index": 0,
"text": "0"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "orange",
"value": null
}
]
},
"unit": "decbytes"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 15,
"y": 1
},
"id": 7,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"sum"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "bytes_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" | __error__=\"\" [$__interval])",
"queryType": "range",
"refId": "A"
}
],
"title": "SSH Log in bytes",
"type": "stat"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 6,
"x": 0,
"y": 5
},
"id": 15,
"options": {
"displayLabels": [],
"legend": {
"displayMode": "table",
"placement": "right",
"showLegend": true,
"values": [
"value",
"percent"
]
},
"pieType": "donut",
"reduceOptions": {
"calcs": [
"sum"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "multi",
"sort": "none"
}
},
"pluginVersion": "9.2.5",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "sum by (username) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |=\": session opened for\" | pattern `<_> session opened for user <username>(` | username !~\".* by \" | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "A"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "sum by (username) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |=\": session opened for\" | pattern `<_> session opened for user <username> <_>` | username !~\".*(uid=.*)\" | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "B"
}
],
"title": "Session Opened by User",
"transformations": [],
"type": "piechart"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 6,
"x": 6,
"y": 5
},
"id": 16,
"options": {
"displayLabels": [],
"legend": {
"displayMode": "table",
"placement": "right",
"showLegend": true,
"values": [
"value",
"percent"
]
},
"pieType": "donut",
"reduceOptions": {
"calcs": [
"sum"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "multi",
"sort": "none"
}
},
"pluginVersion": "9.2.5",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "sum by (username) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |~\": Invalid|: Connection closed by authenticating user|: Failed .* user\" | pattern `<_> user <username> <_> port` | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "A"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "sum by (username) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |=\": Failed\" !~\"invalid user\" | pattern `<_> for <username> from <_> port` | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "B"
}
],
"title": "Failed Attempt by User",
"transformations": [
{
"id": "joinByLabels",
"options": {
"value": "username"
}
}
],
"type": "piechart"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"gridPos": {
"h": 16,
"w": 12,
"x": 12,
"y": 5
},
"id": 9,
"options": {
"dedupStrategy": "signature",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" \",
"queryType": "range",
"refId": "A"
}
],
"title": "SSH Recent Log",
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"filterable": true,
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 6,
"x": 0,
"y": 14
},
"id": 22,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"frameIndex": 0,
"showHeader": true
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "count by (ip) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |=\": Accepted\" | pattern `<_> Accepted <_> for <_> from <ip> port <_>` | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "A",
"resolution": 1
}
],
"title": "Session Opened by Unique IP",
"transformations": [
{
"id": "labelsToFields",
"options": {
"mode": "rows"
}
},
{
"id": "merge",
"options": {}
},
{
"id": "organize",
"options": {
"excludeByName": {
"label": true
},
"indexByName": {},
"renameByName": {
"value": "IP"
}
}
}
],
"type": "table"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"filterable": true,
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 6,
"x": 6,
"y": 14
},
"id": 19,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"frameIndex": 0,
"showHeader": true
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "count by (ip) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |~\": Invalid|: Connection closed by authenticating user|: Failed\" |~\".* from .*\" | pattern `<_> from <ip> port` | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "A",
"resolution": 1
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "count by (ip) (count_over_time({host=~\"$host\", $filename=~\"$source\"} |=\"sshd[\" |~\": Invalid|: Connection closed by authenticating user|: Failed\" !~\".* from .*\" | pattern `<_> user <_> <ip> port` | __error__=\"\" [$__interval]))",
"hide": false,
"legendFormat": "",
"queryType": "range",
"refId": "B"
}
],
"title": "Failed by Unique IP",
"transformations": [
{
"id": "labelsToFields",
"options": {
"mode": "rows"
}
},
{
"id": "merge",
"options": {}
},
{
"id": "organize",
"options": {
"excludeByName": {
"label": true
},
"indexByName": {},
"renameByName": {
"value": "IP"
}
}
}
],
"type": "table"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 21
},
"id": 11,
"panels": [],
"title": "Detailed Stats",
"type": "row"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"filterable": true,
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 22
},
"id": 20,
"maxDataPoints": 1,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" |=\": Accepted\" | pattern `<_> Accepted <_> for <username> from <ip> port <_>` | \_\_error\_\_=\"\"\",
"hide": false,
"legendFormat": " ",
"queryType": "range",
"refId": "A",
"resolution": 1
}
],
"title": "Session Opened by User and IP",
"transformations": [
{
"id": "merge",
"options": {}
},
{
"id": "extractFields",
"options": {
"format": "auto",
"replace": false,
"source": "labels"
}
},
{
"id": "organize",
"options": {
"excludeByName": {
"Line": true,
"Time": false,
"env": true,
"filename": true,
"id": true,
"job": true,
"label": true,
"labels": true,
"tsNs": true
},
"indexByName": {},
"renameByName": {
"label": "",
"value": ""
}
}
},
{
"id": "sortBy",
"options": {
"fields": {},
"sort": [
{
"desc": true,
"field": "Time"
}
]
}
}
],
"type": "table"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"filterable": true,
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 22
},
"id": 23,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" |~\": Invalid|: Failed .\* user\" | pattern `<_> user <username> from <ip> <_> port` | \_\_error\_\_=\"\"\",
"hide": false,
"queryType": "range",
"refId": "A"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" |=\": Failed\" !~\"invalid user\" | pattern `<_> for <username> from <ip> port` | \_\_error\_\_=\"\"\",
"hide": false,
"queryType": "range",
"refId": "B"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" |=\": Connection closed by authenticating user\" | pattern `<_> user <username> <ip> port` | \_\_error\_\_=\"\"\",
"hide": false,
"queryType": "range",
"refId": "C"
}
],
"title": "SSH Failure by User and IP",
"transformations": [
{
"id": "merge",
"options": {}
},
{
"id": "extractFields",
"options": {
"format": "auto",
"replace": false,
"source": "labels"
}
},
{
"id": "organize",
"options": {
"excludeByName": {
"Line": true,
"env": true,
"filename": true,
"id": true,
"job": true,
"labels": true,
"tsNs": true
},
"indexByName": {},
"renameByName": {
"Time": "",
"env": "",
"instance": "",
"job": "",
"tsNs": ""
}
}
},
{
"id": "sortBy",
"options": {
"fields": {},
"sort": [
{
"desc": true,
"field": "Time"
}
]
}
}
],
"type": "table"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"filterable": true,
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 32
},
"id": 13,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" |=\": session opened for\" | pattern `<_> session opened for user <username>(` | username !~\".\* by \" | \_\_error\_\_=\"\"\",
"hide": false,
"queryType": "range",
"refId": "A"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" |=\": session opened for\" | pattern `<_> session opened for user <username> <_>` | username !~\".\*\(uid=.\*)\" | \_\_error\_\_=\"\"\",
"hide": false,
"queryType": "range",
"refId": "B"
}
],
"title": "SSH Session Opened by User",
"transformations": [
{
"id": "merge",
"options": {}
},
{
"id": "extractFields",
"options": {
"format": "auto",
"replace": false,
"source": "labels"
}
},
{
"id": "organize",
"options": {
"excludeByName": {
"Line": true,
"env": true,
"filename": true,
"id": true,
"job": true,
"labels": true,
"tsNs": true
},
"indexByName": {},
"renameByName": {
"Time": "",
"env": "",
"instance": "",
"job": "",
"tsNs": ""
}
}
},
{
"id": "sortBy",
"options": {
"fields": {},
"sort": [
{
"desc": true,
"field": "Time"
}
]
}
}
],
"type": "table"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"filterable": true,
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 32
},
"id": 14,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "9.5.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" |~\": Invalid|: Connection closed by authenticating user|: Failed .\* user\" | pattern `<_> user <username> <_> port` | \_\_error\_\_=\"\"\",
"hide": false,
"queryType": "range",
"refId": "A"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
\"expr\": \"{host=~\"\$host\", \$filename=~\"\$source\"} |=\"sshd\[\" |=\": Failed\" !~\"invalid user\" | pattern `<_> for <username> from <_> port` | \_\_error\_\_=\"\"\",
"hide": false,
"queryType": "range",
"refId": "B"
}
],
"title": "SSH Failure by User",
"transformations": [
{
"id": "merge",
"options": {}
},
{
"id": "extractFields",
"options": {
"format": "auto",
"replace": false,
"source": "labels"
}
},
{
"id": "organize",
"options": {
"excludeByName": {
"Line": true,
"env": true,
"filename": true,
"id": true,
"job": true,
"labels": true,
"tsNs": true
},
"indexByName": {},
"renameByName": {
"Time": "",
"env": "",
"instance": "",
"job": "",
"tsNs": ""
}
}
},
{
"id": "sortBy",
"options": {
"fields": {},
"sort": [
{
"desc": true,
"field": "Time"
}
]
}
}
],
"type": "table"
}
],
"refresh": "5m",
"revision": 2,
"schemaVersion": 38,
"style": "dark",
"tags": [
"Zogg",
"Loki"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "Loki",
"value": "Loki"
},
"hide": 0,
"includeAll": false,
"label": "Datasource",
"multi": false,
"name": "datasource",
"options": [],
"query": "loki",
"queryValue": "",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"type": "datasource"
},
{
"current": {
"selected": true,
"text": "services",
"value": "services"
},
"datasource": {
"type": "loki",
"uid": "${datasource}"
},
"definition": "label_names()",
"hide": 0,
"includeAll": false,
"label": "Host",
"multi": false,
"name": "host",
"options": [],
"query": {
"label": "host",
"refId": "LokiVariableQueryEditor-VariableQuery",
"stream": "",
"type": 1
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query"
},
{
"current": {
"selected": false,
"text": "filename",
"value": "filename"
},
"hide": 0,
"includeAll": false,
"label": "Filename",
"multi": false,
"name": "filename",
"options": [
{
"selected": true,
"text": "filename",
"value": "filename"
}
],
"query": "filename",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": false,
"text": "/var/log/auth.log",
"value": "/var/log/auth.log"
},
"description": "",
"hide": 0,
"includeAll": false,
"label": "Source",
"multi": false,
"name": "source",
"options": [
{
"selected": true,
"text": "/var/log/auth.log",
"value": "/var/log/auth.log"
}
],
"query": "/var/log/auth.log",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "SSH",
"uid": "ZOGG0013",
"version": 8,
"weekStart": ""
}
Mise en place
Je partirai du principe que vous utilisez Portainer pour gérer vos stack Docker.
Il vous faudra créer les répertoires suivants (ou adapter au besoin) :
- /opt/docker/loki/conf/
- /opt/docker/loki/datas/loki/
- /opt/docker/loki/datas/promtail/
Et une fois ceci fait, vous copiez les fichiers présentés ci-dessus dans les chemins tels qu’indiqué dans le docker-compose.yml.
Ces informations doivent refléter votre propre besoin.
Lorsque c’est fait, vous créez une nouvelle stack sous Portainer et copier/coller le contenu du fichier docker-compose.yml dans l’éditeur et vous lancez sa création.
Précisions
Il s’agit ici d’une configuration complète incluant Loki et Promtail.
Sur vos autres machines, il vous suffit de jouer le stack suivant sous Portainer :
loki-light.yml
[Fichier]
version: "3.0"
#
# updated: 2023-05-24
# stack: loki (light only for other VMs)
#
x-logging: &x-logging
logging:
driver: loki
options:
loki-url: "http://loki:3100/loki/api/v1/push"
loki-retries: "5"
loki-batch-size: "400"
x-common: &x-common
<<: *x-logging
restart: "no"
stop_grace_period: 5s
stdin_open: true
tty: true
privileged: false
security_opt:
- no-new-privileges=true
cap_drop:
- ALL
cap_add:
- KILL
dns:
- 1.1.1.1
- 8.8.8.8
- 1.0.0.1
- 8.8.4.4
ipc: "shareable"
extra_hosts:
- "template.home:192.168.0.0"
environment:
TZ: "Europe/Paris"
PUID: 1000
PGID: 1000
user: 1000:1000
labels:
com.centurylinklabs.watchtower.enable: true
logging: "promtail"
com.stack.name: "common"
com.stack.service.name: "common"
devices:
- /dev/kmsg:/dev/kmsg
deploy:
resources:
limits:
cpus: "0.50"
memory: 256M
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
tmpfs:
- /tmp:rw,noexec,nosuid,size=64k
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
x-volume-timezone: &x-volume-timezone "/etc/timezone:/etc/timezone:ro"
x-volume-localtime: &x-volume-localtime "/etc/localtime:/etc/localtime:ro"
x-volume-docker-socket: &x-volume-docker-socket "/var/run/docker.sock:/var/run/docker.sock:rw"
x-volume-cgroups: &x-volume-cgroups "/proc/cgroups:/cgroup:rw"
x-volume-ssl: &x-volume-ssl "/opt/docker/ssl:/ssl:ro"
services:
promtail:
<<: *x-common
user: 0:0
cap_add:
- DAC_OVERRIDE
container_name: promtail
hostname: promtail
image: grafana/promtail:latest
restart: always
ports:
- "1514:1514"
expose:
- "1514"
command: -config.file=/etc/promtail/promtail.yml
labels:
com.stack.name: "loki"
com.stack.service.name: "promtail"
tmpfs:
- /tmp:rw,noexec,nosuid,size=512M
volumes:
- *x-volume-timezone
- *x-volume-localtime
- *x-volume-docker-socket
- *x-volume-cgroups
- /var/log:/var/log:ro
- /opt/docker/loki/conf:/etc/promtail
- /opt/docker/loki/datas/promtail:/datas
Exploitation
Loki en soit n’est qu’un backend permettant de récupérer et stocker les logs tel que configurés.
Vous pouvez utiliser les dashboards que j’ai mis dans la section fichiers requis comme base pour consulter vos logs depuis Grafana :
- parser.json
- logs.json
- ssh.json
Dashboards
Voici quelques captures des dashboards que j’utilise au quotidien :
Conclusion
Vous avez maintenant les bases pour centraliser vos différents logs, les visualiser et les manipuler.
Il est donc possible, sur la base de règles d’alertes, d’utiliser Alertmanager ou Grafana directement pour vous envoyer automatiquement des alertes :)