diff --git a/README.md b/README.md index 5f27228..894547d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Grafana Clickhouse Docker Log Aggregation -This demo project can aggregate logs from Docker containers and store them in Clickhouse. In the `dashboards` directory you can find dashboard examples for specific log format. `Logs + Structured via Query` is recommended. +This demo project can aggregate logs from Docker containers and store them in Clickhouse. In the `dashboards` directory you can find dashboard examples for specific log format. `Logs + Structured via Query` is recommended because the other one is deprecated now. **Note**: dashboards are tuned for structured logging (JSON log records). @@ -8,8 +8,8 @@ This demo project can aggregate logs from Docker containers and store them in Cl Obviously, you'll need Docker: -1. `make migrate` (you can totally use `clickhouse-client` inside container if migrator hangs up). -2. Navigate to `http://localhost:3000`, use `admin:admin` as credentials. -3. Create your own dashboard or import those I provided (`dashboards/` directory). +1. `make migrate` (use `clickhouse-client` inside container and execute migration SQL directly if migrator doesn't work). +2. Navigate to `http://grafana.test` or `http://localhost:3000` (if you did not configure Traefik locally), use `admin:admin` as credentials. +3. Import [Logs + Structured via Query](dashboards/Logs + Structured via Query.json) dashboard. 4. Run any Docker project with structured JSON logs. 5. Done. \ No newline at end of file diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..04b3c6e --- /dev/null +++ b/compose.yml @@ -0,0 +1,53 @@ +services: + grafana: + image: grafana/grafana:latest + volumes: + - grafana_data:/var/lib/grafana + depends_on: + - clickhouse + ports: + - 3000:3000 + labels: + traefik.enable: "true" + traefik.http.routers.grafana.entrypoints: web + traefik.http.routers.grafana.rule: 'Host(`grafana.test`)' + traefik.http.services.grafana.loadbalancer.server.port: 3000 + clickhouse: + image: clickhouse/clickhouse-server:24 + environment: + - CLICKHOUSE_DB=default + - CLICKHOUSE_USER=default + - CLICKHOUSE_PASSWORD=default + - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 + ports: + - '8123:8123' + ulimits: + nofile: + soft: 262144 + hard: 262144 + cap_add: + - NET_ADMIN + - SYS_NICE + - IPC_LOCK + healthcheck: + test: wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1 + interval: 10s + timeout: 5s + retries: 5 + volumes: + - clickhouse_data:/var/lib/clickhouse + vector: + image: timberio/vector:latest-alpine + ports: + - '8686:8686' + depends_on: + - clickhouse + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./files/vector.yaml:/etc/vector/vector.yaml:ro + +volumes: + clickhouse_data: + driver: local + grafana_data: + driver: local \ No newline at end of file diff --git a/dashboards/Logs + Structured via Query.json b/dashboards/Logs + Structured via Query.json index 343d5d4..e7111cd 100644 --- a/dashboards/Logs + Structured via Query.json +++ b/dashboards/Logs + Structured via Query.json @@ -53,6 +53,7 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "hue", @@ -202,6 +203,7 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -338,6 +340,7 @@ }, { "datasource": { + "default": true, "type": "grafana-clickhouse-datasource", "uid": "c029a1fb-9305-40f9-ad75-bd648c3138b4" }, @@ -389,106 +392,6 @@ "unit": "string" }, "overrides": [ - { - "matcher": { - "id": "byName", - "options": "logdatetime" - }, - "properties": [ - { - "id": "custom.width", - "value": 196 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "host" - }, - "properties": [ - { - "id": "custom.width", - "value": 132 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "program" - }, - "properties": [ - { - "id": "custom.width", - "value": 210 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "priority" - }, - "properties": [ - { - "id": "custom.width", - "value": 71 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "time" - }, - "properties": [ - { - "id": "custom.width", - "value": 266 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "level" - }, - "properties": [ - { - "id": "custom.width", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "handler" - }, - "properties": [ - { - "id": "custom.width", - "value": 217 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "msg" - }, - "properties": [ - { - "id": "custom.width", - "value": 1307 - }, - { - "id": "custom.inspect", - "value": true - } - ] - }, { "matcher": { "id": "byName", @@ -498,6 +401,10 @@ { "id": "custom.width", "value": 658 + }, + { + "id": "custom.inspect", + "value": true } ] }, @@ -510,7 +417,7 @@ { "id": "custom.cellOptions", "value": { - "type": "color-text" + "type": "json-view" } }, { @@ -522,59 +429,43 @@ { "matcher": { "id": "byName", - "options": "connection" - }, - "properties": [ - { - "id": "custom.width", - "value": 220 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "account" - }, - "properties": [ - { - "id": "custom.width", - "value": 223 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Message" - }, - "properties": [ - { - "id": "custom.inspect", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Priority" + "options": "Handler" }, "properties": [ { "id": "custom.cellOptions", "value": { - "type": "color-text" + "type": "json-view" } + }, + { + "id": "custom.width", + "value": 272 } ] }, { "matcher": { "id": "byName", - "options": "Handler" + "options": "Account" }, "properties": [ + { + "id": "custom.width", + "value": 158 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Context" + }, + "properties": [ + { + "id": "custom.inspect", + "value": true + }, { "id": "custom.cellOptions", "value": { @@ -589,21 +480,101 @@ "options": "TS" }, "properties": [ + { + "id": "unit", + "value": "dateTimeAsIso" + }, { "id": "custom.width", - "value": 172 + "value": 176 } ] }, { "matcher": { "id": "byName", - "options": "Account" + "options": "Stream ID" }, "properties": [ { "id": "custom.width", - "value": 113 + "value": 234 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Priority" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + }, + { + "id": "mappings", + "value": [ + { + "options": { + "DEBUG": { + "color": "green", + "index": 0, + "text": "Debug" + }, + "ERROR": { + "color": "red", + "index": 2, + "text": "Error" + }, + "INFO": { + "color": "blue", + "index": 1, + "text": "Info" + }, + "WARN": { + "color": "yellow", + "index": 4, + "text": "Warning" + }, + "WARNING": { + "color": "yellow", + "index": 3, + "text": "Warning" + } + }, + "type": "value" + }, + { + "options": { + "match": "empty", + "result": { + "color": "transparent", + "index": 5, + "text": "(not set)" + } + }, + "type": "special" + } + ] + }, + { + "id": "custom.width", + "value": 118 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Connection" + }, + "properties": [ + { + "id": "custom.width", + "value": 250 } ] } @@ -630,7 +601,7 @@ "showHeader": true, "sortBy": [] }, - "pluginVersion": "10.4.1", + "pluginVersion": "11.2.0", "targets": [ { "builderOptions": { @@ -735,7 +706,7 @@ } }, "queryType": "sql", - "rawSql": "SELECT \n visitParamExtractString(message, 'datetime') as time,\n visitParamExtractString(message, 'level_name') as level,\n visitParamExtractString(message, 'connection') as connection,\n visitParamExtractString(message, 'account') as account,\n visitParamExtractString(message, 'handler') as handler,\n visitParamExtractString(message, 'message') as msg,\n visitParamExtractRaw(message, 'context') as ctx\nFROM \"default\".\"log_docker_raw\"\nWHERE ( logdatetime >= $__fromTime AND logdatetime <= $__toTime )\n AND IF('Any' IN (${priority}), 1 = 1, level IN (${priority}))\n AND ( program = ${program:singlequote} )\n AND ( message LIKE '%$filter1%' )\n AND ( message LIKE '%$filter2%' )\n AND ( message LIKE '%$filter3%' )\n AND ( msg <> '' )\nORDER BY logdatetime DESC LIMIT 5000", + "rawSql": "SELECT \n visitParamExtractString(message, 'datetime') as t,\n visitParamExtractString(message, 'level_name') as level,\n visitParamExtractString(message, 'connection') as connection,\n visitParamExtractString(message, 'account') as account,\n visitParamExtractString(message, 'handler') as handler,\n visitParamExtractString(message, 'streamId') as stream_id,\n visitParamExtractString(message, 'message') as msg,\n replaceAll(visitParamExtractRaw(message, 'context'), '\\\\\\\\', '\\\\') as context\nFROM \"default\".\"log_docker_raw\"\nWHERE ( logdatetime >= $__fromTime AND logdatetime <= $__toTime )\n AND IF('Any' IN (${priority}), 1 = 1, level IN (${priority}))\n AND ( program = ${program:singlequote} )\n AND ( message LIKE '%$filter1%' )\n AND ( message LIKE '%$filter2%' )\n AND ( message LIKE '%$filter3%' )\n AND ( msg <> '' )\nORDER BY logdatetime DESC LIMIT 5000", "refId": "A", "selectedFormat": 4 } @@ -751,11 +722,14 @@ "renameByName": { "account": "Account", "connection": "Connection", + "context": "Context", "ctx": "Context", "handler": "Handler", "level": "Priority", "msg": "Message", "raw": "Raw", + "stream_id": "Stream ID", + "t": "TS", "time": "TS" } } @@ -897,7 +871,7 @@ "showHeader": true, "sortBy": [] }, - "pluginVersion": "10.4.1", + "pluginVersion": "11.2.0", "targets": [ { "builderOptions": { @@ -977,9 +951,9 @@ "list": [ { "current": { - "selected": true, - "text": "telegram-mg_telegram-1", - "value": "telegram-mg_telegram-1" + "selected": false, + "text": "whatsapp-360-dialog-app-1", + "value": "whatsapp-360-dialog-app-1" }, "datasource": { "type": "grafana-clickhouse-datasource", @@ -1094,6 +1068,6 @@ "timezone": "", "title": "Logs + Structured via Query", "uid": "b445eb43-25d1-4112-b628-3b8acf037f10", - "version": 5, + "version": 8, "weekStart": "" } \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index b1a6dfe..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,31 +0,0 @@ -version: '3.8' - -services: - grafana: - image: grafana/grafana:latest - volumes: - - grafana_data:/var/lib/grafana - ports: - - '3000:3000' - clickhouse: - image: docker.io/bitnami/clickhouse:23 - environment: - - CLICKHOUSE_ADMIN_USER=default - - CLICKHOUSE_ADMIN_PASSWORD=default - ports: - - '8123:8123' - volumes: - - clickhouse_data:/bitnami/clickhouse - vector: - image: timberio/vector:latest-alpine - ports: - - '8686:8686' - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - ./files/vector.yaml:/etc/vector/vector.yaml:ro - -volumes: - clickhouse_data: - driver: local - grafana_data: - driver: local \ No newline at end of file