В статье https://habr.com/ru/articles/594805/ описаны основные системы для сбора и анализа логов. Сначала хотел настроить Graylog, но он у меня не поднялся у меня в Docker на VPS с 2 Гб памяти, поэтому остановился на Grafana Loki.

Стек Grafana Loki требует очень мало ресурсов по сравнению с другим стеками и работает быстро. Так же есть Grafana Cloud который предоставляет бесплатно 50 Гб под логи и этого достаточно на начальном этапе (что бы не занимать ресурсы своего VPS)

Сначала я поднял стек Grafana Loki (Loki + Promtail + Grafana) на своем VPS и настроил сбор логов приложения Go через slog с использованием библиотеки https://github.com/samber/slog-loki но столкнулся с проблемой аутентификации. Loki не предоставляет средства аутентификации и предлагает использовать обратные прокси. Обратный прокси легко делается на Go, но я решил использовать Grafana Cloud, т.к. подумал, что это будет быстрее.

Собирать логи будем через Grafana Docker driver client (а не через slog-loki). Это плагин Docker который берет стандартный вывод (stdout) контейнера и отправляет его в Loki. Учтите, что с данным вариантом может быть проблема Deadlocked Docker Daemon.

Ставим в терминале:

docker plugin install grafana/loki-docker-driver:2.9.1 --alias loki --grant-all-permissions

И подключаем к нашему контейнеру. Я использую docker-compose, другие варианты описаны в официальной инструкции

services:
  example:
    build: .
    logging:
      driver: loki
      options:
        loki-url: "https://<user_id>:<password>@<loki_url>/loki/api/v1/push"

И вот на этом этапе ничего не получалось, непонятно было где брать пароль, а информации в документации об этом практически нет. В итоге оказалось, что <password> это токен, создаваемый отдельно в админке Grafana Cloud (учтите, что когда поднимаете Loki у себя, логин и пароль не нужно прописывать если не настраивали аутентификацию)

Итак, смотрим сначала user_id и loki_url в Data sources:

Находим “источник” для логов:

Открываем и видим нужные данные:

Password при этом написан как “configured”, т.е. его здесь нет. Кнопка “Reset” не работает. Поэтому далее создаем токен:

В открывшемся окне прописываем название и выставляем права

Записываем и создаем токен:

Копируем созданный токен (иначе его потом не посмотреть!):

Этот токен и есть <password>.

Прописываем <user_id>,<password> и <loki_url> в файле compose, который указан выше и запускаем контейнеры (docker-compose up).

На этом настройка закончена, далее в Grafana создаем дашбоард либо просто смотрим данные из источника.

Настройка стека Loki локально

Привожу файл docker-compose для стека Loki:

version: "3"

services:
  loki:
    image: grafana/loki:2.9.2
    # ports:
    #   - "3100:3100"
    command: -config.file=/etc/loki/local-config.yaml
    networks:
      hds:
        ipv4_address: "172.20.0.10"

  promtail:
    image: grafana/promtail:2.9.2
    volumes:
      - /var/log:/var/log
    command: -config.file=/etc/promtail/config.yml
    networks:
      - hds

  grafana:
    environment:
      - GF_PATHS_PROVISIONING=/etc/grafana/provisioning
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
    entrypoint:
      - sh
      - -euc
      - |
        mkdir -p /etc/grafana/provisioning/datasources
        cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml
        apiVersion: 1
        datasources:
        - name: Loki
          type: loki
          access: proxy 
          orgId: 1
          url: http://loki:3100
          basicAuth: false
          isDefault: true
          version: 1
          editable: false
        EOF
        /run.sh
    image: grafana/grafana:latest
    logging:
      driver: loki
      options:
        loki-url: "http://172.20.0.10:3100/loki/api/v1/push"
    ports:
      - "3000:3000"
    networks:
      - hds

networks:
  hds:
    external: true

Перед запуском необходимо в Docker создать сеть, в моем случае ее название hds. Сеть делал внешнюю, т.к. обратный прокси у меня в отдельном файле docker-compose

Обратите внимание, что для Loki указан IP адрес вручную! Это необходимо для Docker driver client, т.к. он не может разрешать DNS потому, что находится вне сети Docker.

В приложении Go, для samber/slog-loki в качестве endpoint пишем: “http://127.0.0.1:3100/api/prom/push” т.к. она шлет логи через promtail, а не напрямую в Loki