Monitoring
Π ΡΡΠΎΠΌ ΡΠ°Π·Π΄Π΅Π»Π΅ ΠΌΡ Π½Π°ΡΡΡΠΎΠΈΠΌ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ Ρ Prometheus, Grafana, loki, Promtail
ΠΡΠ°ΡΠΊΠΎΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
- Prometheus β ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠ±ΠΎΡΠ° ΠΈ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΌΠ΅ΡΡΠΈΠΊ.
- Grafana β Π²ΠΈΠ·ΡΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΌΠ΅ΡΡΠΈΠΊ ΠΈ Π»ΠΎΠ³ΠΎΠ².
- Loki β ΡΠΈΡΡΠ΅ΠΌΠ° Ρ ΡΠ°Π½Π΅Π½ΠΈΡ Π»ΠΎΠ³ΠΎΠ² ΠΎΡ Grafana.
- Promtail β Π°Π³Π΅Π½Ρ, ΡΠΎΠ±ΠΈΡΠ°ΡΡΠΈΠΉ Π»ΠΎΠ³ΠΈ Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΠΈΠΉ ΠΈΡ Π² Loki.
ΠΠ°ΡΠ½Π΅ΠΌ Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ Π΄Π»Ρ Π½Π°ΡΠΈΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π½ΠΎΠ²ΡΡ ΠΏΠ°ΠΏΠΊΡ Π² monitoring Π² ΠΏΠ°ΠΏΠΊΠ΅ Ρ Π½Π°ΡΠΈΠΌ docker-compose.yaml
mkdir monitoringΠ‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ°ΠΉΠ» loki-config.yaml
sudo nano loki-config.yamlπ loki-config.yaml
auth_enabled: false
server:
http_listen_port: 3100
common:
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
replication_factor: 1
path_prefix: /tmp/loki
schema_config:
configs:
- from: 2020-05-15
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
storage_config:
filesystem:
directory: /tmp/loki/chunksΠ‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ°ΠΉΠ» prometheus.yml
sudo nano prometheus.ymlπ prometheus.yml
global:
scrape_interval: 15s # ΠΊΠ°ΠΊ ΡΠ°ΡΡΠΎ ΠΎΠΏΡΠ°ΡΠΈΠ²Π°ΡΡ ΠΌΠ΅ΡΡΠΈΠΊΠΈ
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'backend'
metrics_path: '/api/metrics'
static_configs:
- targets: ['backend:3001'] # Π°Π΄ΡΠ΅Ρ Π²Π½ΡΡΡΠΈ docker-ΡΠ΅ΡΠΈΠ‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ°ΠΉΠ» promtail-config.yaml
sudo nano promtail-config.yamlπ promtail-config.yaml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: docker
pipeline_stages:
- docker: {}
docker_sd_configs:
- host: unix:///var/run/docker.sock
relabel_configs:
- source_labels: [__meta_docker_container_name]
target_label: container
regex: "/(.*)" # ΡΠ±ΠΈΡΠ°Π΅ΠΌ ΡΠ»ΡΡ Π² Π½Π°ΡΠ°Π»Π΅ ΠΈΠΌΠ΅Π½ΠΈ
- source_labels: [__meta_docker_container_id]
target_label: container_id
- source_labels: [__meta_docker_container_image]
target_label: image
- source_labels: [__meta_docker_container_labels_com_docker_compose_service]
target_label: service
- source_labels: [__meta_docker_container_log_path]
target_label: __path__Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ°ΠΉΠ» datasources.yml
sudo nano datasources.ymlπ datasources.yml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
- name: Loki
type: loki
access: proxy
url: http://loki:3100
editable: trueΠΠ°Π»Π΅Π΅ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ docker-compose.yml ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΡΠ΄Π° Π½Π°ΡΠΈ ΡΠ΅ΡΠ²ΠΈΡΡ ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ
Π ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ΅ΡΠ²ΠΈΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ container_name ΡΡΠΎ Π½Π°ΠΌ ΠΏΡΠΈΠ³ΠΎΠ΄ΠΈΡΡΡ Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² Grafana
π docker-compose.yml
container_name: db
container_name: backend
container_name: frontendΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΠ΅ΡΠ²ΠΈΡ prometheus
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΠ΅ΡΠ²ΠΈΡ grafana
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana-storage:/var/lib/grafana
- ./monitoring/datasources.yml:/etc/grafana/provisioning/datasources/datasources.yaml
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
depends_on:
- prometheusΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΠ΅ΡΠ²ΠΈΡ loki
loki:
image: grafana/loki:latest
container_name: loki
volumes:
- ./monitoring/loki-config.yaml:/etc/loki/local-config.yamlΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΠ΅ΡΠ²ΠΈΡ promtail
promtail:
image: grafana/promtail:latest
container_name: promtail
volumes:
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./monitoring/promtail-config.yaml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
privileged: trueΠ’Π°ΠΆΠ΅ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠ±Π°Π²ΡΡ volumes Π΄Π»Ρ grafana
volumes:
pgdata:
grafana-storage:ΠΡΠΎΠ³ΠΎΠ²ΡΠΉ docker-compose.yml Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΡΠ°ΠΊΠΈΠΌ
services:
db:
image: postgres:16
container_name: db
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "${DB_USER}"]
interval: 10s
timeout: 5s
retries: 5
backend:
image: ${BACKEND_IMAGE}
container_name: backend
depends_on:
db:
condition: service_healthy
environment:
DB_HOST: db
DB_PORT: 5432
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
ports:
- "4545:3001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/api/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 5s
frontend:
image: ${FRONTEND_IMAGE}
container_name: frontend
ports:
- "4546:80"
depends_on:
backend:
condition: service_healthy
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana-storage:/var/lib/grafana
- ./monitoring/grafana/provisioning/datasources.yml:/etc/grafana/provisioning/datasources/datasources.yaml
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
depends_on:
- prometheus
loki:
image: grafana/loki:latest
container_name: loki
volumes:
- ./monitoring/loki-config.yaml:/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:latest
container_name: promtail
volumes:
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./monitoring/promtail-config.yaml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
privileged: true
volumes:
pgdata:
grafana-storage:ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Dashboards Grafana
ΠΠ°ΠΌ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π΄Π²Π° Π΄Π°ΡΠ±ΠΎΡΠ΄Π°
- Express.js Node Application Application Performance Dashboard β ΠΠ°ΡΠ±ΠΎΡΠ΄ Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ Π½Π°ΡΠ΅Π³ΠΎ Π±Π΅ΠΊΠ΅Π½Π΄ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Node JSβ
- Simple Loki Log Dashboard β ΠΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π»ΠΎΠ³ΠΎΠ² ΠΈΠ· Π½Π°ΡΠΈΡ ΠΊΠΎΠ½ΡΠ΅Π½Π΅ΠΉΡΠΎΠ² docker Loki logsβ
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° nginx Π΄Π»Ρ Grafana ΡΠ΅ΡΠ²ΠΈΡΠ°
βοΈ ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΏΡΠΎΠΊΡΠΈ
Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³:
sudo nano /etc/nginx/sites-available/devops-grafana.it-incubator.ioΠΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ
server {
listen 80; # Π‘Π»ΡΡΠ°Π΅ΠΌ HTTP-Π·Π°ΠΏΡΠΎΡΡ Π½Π° 80 ΠΏΠΎΡΡΡ
server_name devops-grafana.it-incubator.io; # Π£ΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ Π΄ΠΎΠΌΠ΅Π½ ΠΈΠ»ΠΈ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ IP ΡΠ΅ΡΠ²Π΅ΡΠ°
location / {
proxy_pass http://localhost:3000; # ΠΡΠΎΠΊΡΠΈΡΡΠ΅ΠΌ Π·Π°ΠΏΡΠΎΡΡ Π½Π° Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠΉ Node.js-ΡΠ΅ΡΠ²Π΅Ρ (Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅)
proxy_http_version 1.1; # ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ HTTP/1.1 Π΄Π»Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ Π²Π΅Π±-ΡΠΎΠΊΠ΅ΡΠΎΠ² ΠΈ keep-alive
proxy_set_header Host $host; # ΠΠ΅ΡΠ΅Π΄Π°ΡΠΌ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΠΉ Host-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ
}
}Π‘ΠΎΡ ΡΠ°Π½ΠΈΡΠ΅ ΡΠ°ΠΉΠ» ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΠ΅:
# Π‘ΠΎΠ·Π΄Π°ΡΠΌ ΡΠΈΠΌΠ²ΠΎΠ»ΠΈΡΠ΅ΡΠΊΡΡ ΡΡΡΠ»ΠΊΡ ΠΈΠ· ΡΠ°ΠΉΠ»Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π² sites-available Π² ΠΏΠ°ΠΏΠΊΡ sites-enabled,
# ΡΡΠΎΠ±Ρ NGINX Π½Π°ΡΠ°Π» ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΠΊΠΎΠ½ΡΠΈΠ³ (Π°ΠΊΡΠΈΠ²ΠΈΡΡΠ΅ΠΌ ΡΠ°ΠΉΡ)
sudo ln -s /etc/nginx/sites-available/devops-grafana.it-incubator.io /etc/nginx/sites-enabled/
# ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ NGINX ΠΈ ΠΈΡΠ΅ΠΌ ΠΎΡΠΈΠ±ΠΊΠΈ
sudo nginx -t
# ΠΠ΅ΡΠ΅Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌ NGINX, ΡΡΠΎΠ±Ρ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ Π½ΠΎΠ²ΡΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ (Π±Π΅Π· ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ°)
sudo systemctl reload nginxΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π΄ΠΎΠΌΠ΅Π½Π° ΠΈ HTTPS ΡΠ΅ΡΠ΅Π· Letβs Encrypt
sudo certbot --nginx -d devops-grafana.it-incubator.io