diff --git a/.env.example b/.env.example index 890b8ff..4b39d12 100644 --- a/.env.example +++ b/.env.example @@ -7,4 +7,5 @@ JWT_SECRET=wow POSTGRES_DB=chromacase API_URL=http://localhost:80/api SCORO_URL=ws://localhost:6543 +MINIO_ROOT_PASSWORD=12345678 diff --git a/config/grafana_dashboard.json b/config/grafana_dashboard.json new file mode 100644 index 0000000..05978fd --- /dev/null +++ b/config/grafana_dashboard.json @@ -0,0 +1,283 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 1, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "editorMode": "builder", + "expr": "{container=\"chromacase-back-1\"} | json | userId = `$userId`", + "key": "Q-a2f514d0-81a4-4c43-a260-bad7add20957-1", + "queryType": "range", + "refId": "B" + } + ], + "title": "Back logs by user id", + "type": "logs" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "editorMode": "builder", + "expr": "{container=\"chromacase-back-1\"} | json | username = `$username`", + "key": "Q-a2f514d0-81a4-4c43-a260-bad7add20957-1", + "queryType": "range", + "refId": "B" + } + ], + "title": "Back logs by username", + "type": "logs" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 4, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Ascending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "editorMode": "code", + "expr": "{container=\"chromacase-back-1\"}", + "key": "Q-a2f514d0-81a4-4c43-a260-bad7add20957-1", + "queryType": "range", + "refId": "B" + } + ], + "title": "Back logs", + "type": "logs" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 3, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "editorMode": "code", + "expr": "{container=\"chromacase-front-1\"} | json | userId = `$userId`", + "key": "Q-a2f514d0-81a4-4c43-a260-bad7add20957-1", + "queryType": "range", + "refId": "B" + } + ], + "title": "Front logs", + "type": "logs" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 5, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "editorMode": "code", + "expr": "{container=\"chromacase-scorometer-1\"}", + "key": "Q-a2f514d0-81a4-4c43-a260-bad7add20957-1", + "queryType": "range", + "refId": "B" + } + ], + "title": "Scorometer logs", + "type": "logs" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "2", + "value": "2" + }, + "hide": 0, + "name": "userId", + "options": [ + { + "selected": true, + "text": "2", + "value": "2" + } + ], + "query": "2", + "skipUrlSync": false, + "type": "textbox" + }, + { + "current": { + "selected": false, + "text": "lou", + "value": "lou" + }, + "hide": 0, + "name": "username", + "options": [ + { + "selected": true, + "text": "lou", + "value": "lou" + } + ], + "query": "lou", + "skipUrlSync": false, + "type": "textbox" + }, + { + "current": {}, + "description": "unique id of scorometer game", + "hide": 0, + "label": "game uuid", + "name": "game_uuid", + "options": [], + "query": "", + "skipUrlSync": false, + "type": "textbox" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Chromacase dashboard", + "uid": "c3d1eb51-85f6-43d3-b2fd-e0096b72cf67", + "version": 2, + "weekStart": "" + } \ No newline at end of file diff --git a/config/logs_nginx.conf b/config/logs_nginx.conf new file mode 100644 index 0000000..38472b1 --- /dev/null +++ b/config/logs_nginx.conf @@ -0,0 +1,37 @@ +user nginx; +worker_processes 5; ## Default: 1 +events { + worker_connections 1000; +} +http { + resolver 127.0.0.11; + server { + listen 3100; + location = / { + return 200 'OK'; + auth_basic off; + } + location = /api/prom/push { + proxy_pass http://write:3100\$$request_uri; + } + location = /api/prom/tail { + proxy_pass http://read:3100\$$request_uri; + proxy_set_header Upgrade \$$http_upgrade; + proxy_set_header Connection "upgrade"; + } + location ~ /api/prom/.* { + proxy_pass http://read:3100\$$request_uri; + } + location = /loki/api/v1/push { + proxy_pass http://write:3100\$$request_uri; + } + location = /loki/api/v1/tail { + proxy_pass http://read:3100\$$request_uri; + proxy_set_header Upgrade \$$http_upgrade; + proxy_set_header Connection "upgrade"; + } + location ~ /loki/api/.* { + proxy_pass http://read:3100\$$request_uri; + } + } +} \ No newline at end of file diff --git a/config/loki-config.yaml b/config/loki-config.yaml new file mode 100644 index 0000000..775db58 --- /dev/null +++ b/config/loki-config.yaml @@ -0,0 +1,33 @@ +--- +server: + http_listen_port: 3100 +memberlist: + join_members: + - loki:7946 +schema_config: + configs: + - from: 2021-08-01 + store: boltdb-shipper + object_store: s3 + schema: v11 + index: + prefix: index_ + period: 24h +common: + path_prefix: /loki + replication_factor: 1 + storage: + s3: + endpoint: minio:9000 + insecure: true + bucketnames: loki-data + access_key_id: loki + secret_access_key: supersecret + s3forcepathstyle: true + ring: + kvstore: + store: memberlist +ruler: + storage: + s3: + bucketnames: loki-ruler diff --git a/config/promtail-local-config.yaml b/config/promtail-local-config.yaml new file mode 100644 index 0000000..dcb2d3e --- /dev/null +++ b/config/promtail-local-config.yaml @@ -0,0 +1,22 @@ +--- +server: + http_listen_port: 9080 + grpc_listen_port: 0 + +positions: + filename: /tmp/positions.yaml + +clients: + - url: http://gateway:3100/loki/api/v1/push + tenant_id: tenant1 + +scrape_configs: + - job_name: flog_scrape + docker_sd_configs: + - host: unix:///var/run/docker.sock + refresh_interval: 5s + relabel_configs: + - source_labels: ['__meta_docker_container_name'] + regex: '/(.*)' + target_label: 'container' + diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index ac5ccc3..18c6255 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -1,7 +1,66 @@ networks: loki: + services: + back: + build: + context: ./back + dockerfile: Dockerfile.dev + privileged: true + ports: + - "3000:3000" + volumes: + - ./back:/app + - ./assets:/assets + depends_on: + db: + condition: service_healthy + env_file: + - .env + + scorometer: + build: + context: ./scorometer + dockerfile: Dockerfile.dev + ports: + - "6543:6543" + volumes: + - ./scorometer:/app + - ./assets:/assets + + db: + container_name: db + image: postgres:alpine3.14 + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 5s + timeout: 5s + retries: 5 + ports: + - "5432:5432" + front: + build: + context: ./front + dockerfile: Dockerfile.dev + environment: + - SCOROMETER_URL=http://scorometer:6543/ + - NGINX_PORT=80 + ports: + - "19006:19006" + volumes: + - ./front:/app + depends_on: + - "back" + env_file: + - .env + +# logs setup + read: image: grafana/loki:2.8.2 command: "-config.file=/etc/loki/config.yaml -target=read" @@ -10,7 +69,7 @@ services: - 7946 - 9095 volumes: - - ./loki-config.yaml:/etc/loki/config.yaml + - ./config/loki-config.yaml:/etc/loki/config.yaml depends_on: - minio healthcheck: @@ -31,7 +90,7 @@ services: - 7946 - 9095 volumes: - - ./loki-config.yaml:/etc/loki/config.yaml + - ./config/loki-config.yaml:/etc/loki/config.yaml healthcheck: test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1" ] interval: 10s @@ -45,7 +104,7 @@ services: promtail: image: grafana/promtail:2.8.2 volumes: - - ./promtail-local-config.yaml:/etc/promtail/config.yaml:ro + - ./config/promtail-local-config.yaml:/etc/promtail/config.yaml:ro - /var/run/docker.sock:/var/run/docker.sock command: -config.file=/etc/promtail/config.yaml depends_on: @@ -54,7 +113,7 @@ services: - loki minio: - image: minio/minio + image: minio/minio:RELEASE.2023-07-21T21-12-44Z entrypoint: - sh - -euc @@ -64,7 +123,7 @@ services: minio server /data environment: - MINIO_ROOT_USER=loki - - MINIO_ROOT_PASSWORD=supersecret + - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} - MINIO_PROMETHEUS_AUTH_TYPE=public - MINIO_UPDATE=off ports: @@ -80,7 +139,7 @@ services: - loki grafana: - image: grafana/grafana:latest + image: grafana/grafana:9.5.6 environment: - GF_PATHS_PROVISIONING=/etc/grafana/provisioning - GF_AUTH_ANONYMOUS_ENABLED=true @@ -116,7 +175,7 @@ services: - loki gateway: - image: nginx:latest + image: nginx:1.25.1 depends_on: - read - write @@ -183,59 +242,3 @@ services: retries: 5 networks: - loki - - back: - build: - context: ./back - dockerfile: Dockerfile.dev - privileged: true - ports: - - "3000:3000" - volumes: - - ./back:/app - - ./assets:/assets - depends_on: - db: - condition: service_healthy - env_file: - - .env - - scorometer: - build: - context: ./scorometer - dockerfile: Dockerfile.dev - ports: - - "6543:6543" - volumes: - - ./scorometer:/app - - ./assets:/assets - - db: - container_name: db - image: postgres:alpine3.14 - environment: - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_DB=${POSTGRES_DB} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] - interval: 5s - timeout: 5s - retries: 5 - ports: - - "5432:5432" - front: - build: - context: ./front - dockerfile: Dockerfile.dev - environment: - - SCOROMETER_URL=http://scorometer:6543/ - - NGINX_PORT=80 - ports: - - "19006:19006" - volumes: - - ./front:/app - depends_on: - - "back" - env_file: - - .env diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 64cca51..7c5ae80 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,3 +1,6 @@ +networks: + loki: + services: back: image: ghcr.io/chroma-case/back:main @@ -43,3 +46,188 @@ services: - "back" env_file: - .env + +# logs setup + + read: + image: grafana/loki:2.8.2 + command: "-config.file=/etc/loki/config.yaml -target=read" + ports: + - 3101:3100 + - 7946 + - 9095 + volumes: + - ./config/loki-config.yaml:/etc/loki/config.yaml + depends_on: + - minio + healthcheck: + test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1" ] + interval: 10s + timeout: 5s + retries: 5 + networks: &loki-dns + loki: + aliases: + - loki + + write: + image: grafana/loki:2.8.2 + command: "-config.file=/etc/loki/config.yaml -target=write" + ports: + - 3102:3100 + - 7946 + - 9095 + volumes: + - ./config/loki-config.yaml:/etc/loki/config.yaml + healthcheck: + test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1" ] + interval: 10s + timeout: 5s + retries: 5 + depends_on: + - minio + networks: + <<: *loki-dns + + promtail: + image: grafana/promtail:2.8.2 + volumes: + - ./config/promtail-local-config.yaml:/etc/promtail/config.yaml:ro + - /var/run/docker.sock:/var/run/docker.sock + command: -config.file=/etc/promtail/config.yaml + depends_on: + - gateway + networks: + - loki + + minio: + image: minio/minio:RELEASE.2023-07-21T21-12-44Z + entrypoint: + - sh + - -euc + - | + mkdir -p /data/loki-data && \ + mkdir -p /data/loki-ruler && \ + minio server /data + environment: + - MINIO_ROOT_USER=loki + - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} + - MINIO_PROMETHEUS_AUTH_TYPE=public + - MINIO_UPDATE=off + ports: + - 9000 + volumes: + - ./.data/minio:/data + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ] + interval: 15s + timeout: 20s + retries: 5 + networks: + - loki + + grafana: + image: grafana/grafana:9.5.6 + environment: + - GF_PATHS_PROVISIONING=/etc/grafana/provisioning + - GF_AUTH_ANONYMOUS_ENABLED=true + - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin + depends_on: + - gateway + entrypoint: + - sh + - -euc + - | + mkdir -p /etc/grafana/provisioning/datasources + cat < /etc/grafana/provisioning/datasources/ds.yaml + apiVersion: 1 + datasources: + - name: Loki + type: loki + access: proxy + url: http://gateway:3100 + jsonData: + httpHeaderName1: "X-Scope-OrgID" + secureJsonData: + httpHeaderValue1: "tenant1" + EOF + /run.sh + ports: + - "3001:3000" + healthcheck: + test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3001/api/health || exit 1" ] + interval: 10s + timeout: 5s + retries: 5 + networks: + - loki + + gateway: + image: nginx:1.25.1 + depends_on: + - read + - write + entrypoint: + - sh + - -euc + - | + cat < /etc/nginx/nginx.conf + user nginx; + worker_processes 5; ## Default: 1 + + events { + worker_connections 1000; + } + + http { + resolver 127.0.0.11; + + server { + listen 3100; + + location = / { + return 200 'OK'; + auth_basic off; + } + + location = /api/prom/push { + proxy_pass http://write:3100\$$request_uri; + } + + location = /api/prom/tail { + proxy_pass http://read:3100\$$request_uri; + proxy_set_header Upgrade \$$http_upgrade; + proxy_set_header Connection "upgrade"; + } + + location ~ /api/prom/.* { + proxy_pass http://read:3100\$$request_uri; + } + + location = /loki/api/v1/push { + proxy_pass http://write:3100\$$request_uri; + } + + location = /loki/api/v1/tail { + proxy_pass http://read:3100\$$request_uri; + proxy_set_header Upgrade \$$http_upgrade; + proxy_set_header Connection "upgrade"; + } + + location ~ /loki/api/.* { + proxy_pass http://read:3100\$$request_uri; + } + } + } + EOF + /docker-entrypoint.sh nginx -g "daemon off;" + ports: + - "3100:3100" + healthcheck: + test: ["CMD", "service", "nginx", "status"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - loki + diff --git a/docker-compose.yml b/docker-compose.yml index aefda37..e297fe7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,11 @@ +networks: + loki: + + +volumes: + db: + + services: back: build: ./back @@ -50,5 +58,186 @@ services: env_file: - .env -volumes: - db: +# logs setup + + read: + image: grafana/loki:2.8.2 + command: "-config.file=/etc/loki/config.yaml -target=read" + ports: + - 3101:3100 + - 7946 + - 9095 + volumes: + - ./config/loki-config.yaml:/etc/loki/config.yaml + depends_on: + - minio + healthcheck: + test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1" ] + interval: 10s + timeout: 5s + retries: 5 + networks: &loki-dns + loki: + aliases: + - loki + + write: + image: grafana/loki:2.8.2 + command: "-config.file=/etc/loki/config.yaml -target=write" + ports: + - 3102:3100 + - 7946 + - 9095 + volumes: + - ./config/loki-config.yaml:/etc/loki/config.yaml + healthcheck: + test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1" ] + interval: 10s + timeout: 5s + retries: 5 + depends_on: + - minio + networks: + <<: *loki-dns + + promtail: + image: grafana/promtail:2.8.2 + volumes: + - ./config/promtail-local-config.yaml:/etc/promtail/config.yaml:ro + - /var/run/docker.sock:/var/run/docker.sock + command: -config.file=/etc/promtail/config.yaml + depends_on: + - gateway + networks: + - loki + + minio: + image: minio/minio:RELEASE.2023-07-21T21-12-44Z + entrypoint: + - sh + - -euc + - | + mkdir -p /data/loki-data && \ + mkdir -p /data/loki-ruler && \ + minio server /data + environment: + - MINIO_ROOT_USER=loki + - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} + - MINIO_PROMETHEUS_AUTH_TYPE=public + - MINIO_UPDATE=off + ports: + - 9000 + volumes: + - ./.data/minio:/data + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ] + interval: 15s + timeout: 20s + retries: 5 + networks: + - loki + + grafana: + image: grafana/grafana:9.5.6 + environment: + - GF_PATHS_PROVISIONING=/etc/grafana/provisioning + - GF_AUTH_ANONYMOUS_ENABLED=true + - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin + depends_on: + - gateway + entrypoint: + - sh + - -euc + - | + mkdir -p /etc/grafana/provisioning/datasources + cat < /etc/grafana/provisioning/datasources/ds.yaml + apiVersion: 1 + datasources: + - name: Loki + type: loki + access: proxy + url: http://gateway:3100 + jsonData: + httpHeaderName1: "X-Scope-OrgID" + secureJsonData: + httpHeaderValue1: "tenant1" + EOF + /run.sh + ports: + - "3001:3000" + healthcheck: + test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3001/api/health || exit 1" ] + interval: 10s + timeout: 5s + retries: 5 + networks: + - loki + + gateway: + image: nginx:1.25.1 + depends_on: + - read + - write + entrypoint: + - sh + - -euc + - | + cat < /etc/nginx/nginx.conf + user nginx; + worker_processes 5; ## Default: 1 + + events { + worker_connections 1000; + } + + http { + resolver 127.0.0.11; + + server { + listen 3100; + + location = / { + return 200 'OK'; + auth_basic off; + } + + location = /api/prom/push { + proxy_pass http://write:3100\$$request_uri; + } + + location = /api/prom/tail { + proxy_pass http://read:3100\$$request_uri; + proxy_set_header Upgrade \$$http_upgrade; + proxy_set_header Connection "upgrade"; + } + + location ~ /api/prom/.* { + proxy_pass http://read:3100\$$request_uri; + } + + location = /loki/api/v1/push { + proxy_pass http://write:3100\$$request_uri; + } + + location = /loki/api/v1/tail { + proxy_pass http://read:3100\$$request_uri; + proxy_set_header Upgrade \$$http_upgrade; + proxy_set_header Connection "upgrade"; + } + + location ~ /loki/api/.* { + proxy_pass http://read:3100\$$request_uri; + } + } + } + EOF + /docker-entrypoint.sh nginx -g "daemon off;" + ports: + - "3100:3100" + healthcheck: + test: ["CMD", "service", "nginx", "status"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - loki