Skip to content

Grafana Loki

Grafana Loki - легковесный сервис централизованного логирования. Open source решение, которое без проблем может быть развернуто на личном linux-сервере.

Отличительной особенностью является то, в поступающих в сервис логах индексируются только метаданные, само тело лога не индексируется, за счет этого достигается легковестость

Loki стэк состоит из 3 компонентов:

  • Агент - сущность которая собирает логи, помещает их в поток, при этом помечая метками. Затем отправляет (push) эти потоки на Loki-сервер через HTTP API.
  • Loki-сервер - отвечает за прием и хранение логов, а также за обработку запросов на их просмотр.
  • Grafana - предоставляет интерфейс для создания запросов и просмотр логов.

Loki хранит данные в двух типах файлов

  • Index - хранит информацию о том где искать логи с определенными наборами меток. Индексы хранятся в TSDB базе данных.

  • Chunk - контейнер, в котором хранятся "тела" логов, в соответсвии со специфическим набором меток и за определенный промежуток времени.

Loki components

Loki-сервер представляет собой модульную систему, которая состоит из многих компонентов. Эти компоненты могут быть запущены вместе в режиме single binary; в режиме simple scalable deployment разделения по группам ответственности: read, write, backend; или в режиме microservice, когда каждый компонент работает, как микросервис.

Component individual all read write backend
Distributor x x x
Ingester x x x
Query Frontend x x x
Query Scheduler x x x
Querier x x x
Index Gateway x x
Compactor x x x
Ruler x x x
Bloom Planner (Experimental) x x
Bloom Builder (Experimental) x x
Bloom Gateway (Experimental) x x

Distributor

Distributor - сервис, который отвечает за прием входящих push запросов от клиентов. Дистриб.ютер принимает набор входящих HTTP-потоков, каждый поток проверяется на корректность в соответствии с заданными ограничениями. Затем каждый валидированный поток параллельно пересылается на n-ое количество ingesters, где n - это replication factor для данных. Дистрибьютер определяет определяет какому ingester слать поток логов, использую consistent hashing.

Перед Дистрибьютером должен находиться балансировщик нагрузки, что бы правильно распределять входящий трафик. Дисрибьютер является stateless компонентом, что делает его легко масштабируемым и позволяет максимально разгрузить ingesters - наиболее критичные компоненты на этапе write. Возможность отдельно масштабировать операции валидирования говорит о том, что Loki может самостоятельно защищать себя от атак типа "отказ в обслуживании", которые могут легко "положить" ingresters. Это также позволяет нам распределять операции записи в соответствии с replication factor.

  • Validation. На этапе валидации Дистрибьютер удостоверяется в том, что все входящие данные соответствуют спецификации. Сюда входит валидация лейблов логов, временных отметок логов, размера логов.
  • Preprocessing. В каком то смысле, главной задачей дистрибьютера является - нормализация лейблов, приведение их к определенному стандарту; сортировка, которая в дальнейшем позволит Loki кэшировать и хэшировать их предопределенным образом.
  • Rate limiting. Дистрибьютер также умеет ограничивать скорость входящих логов, на основании ограничений заданных на одного "поставщика" логов.
  • Forwarding. Как только Дистрибьютер произвел все свои валидационные действия, он переправляет данные на компонент ingester, который в конечном итоге отвечает за подтверждение операции записи.
  • Replication factor. Для того, чтобы убавить вероятность потери данных на каждом ingester, можно их реплицировать. Если ingester-ов будет несколько (3 и более), они будут одновременно писать одинаковые данные в разные реплики, что позволит, в случае ЧП, перезагрузить ingester без потери входящих данных. У ingester компонента есть еще один способ предотвратить потерю данных - write ahead log (WAL)

Ingester

Query Frontend

Query Scheduler

Подробнее про компоненты Loki-сервера


Loki Labels

Метки - ключевая часть Loki, они позволяют организовывать и группировать лог-сообщения в лог-потоки. Каждый поток должен иметь хотя бы одну Метку, чтобы быть сохраненным и "запрошенным" в Loki.

Loki не индексирует содержимое каждого лог-сообщения, вместо этого, логи групируется в потоки, которые индексируются с помощью меток.

Метка - это пара key-value. Например:

  • container_name = prometheus
  • service_name = nginx

Набор лог-сообщений, объединенный общими метками, называется stream (лог-потоком). Когда Loki осуществляет поиск, он сначала находит все сообщения в вабранном потоке, а затем итерирует по логом в этом потоке, чтобы выполнить запрос.

Правильная разметка логов улучшит результаты поисковых запросов, которые, в свою очередь, улучшат наглядность дашбордов. Очень важно хорошенько продумать стратегию разметки своих логов, прежде чем отправлять их в Loki.

Loki самостоятельно не парсит входящие логи. Но, в замисимости от клиента, который отправляет логи, к ним могут быть добавлены некоторые метки.

Метка service_name, добавляется ко всем входящим логам. Присваивает себе значение на основе анализа таких меток как: service_name, service, app, application, name, app_kubernetes_io_name, container, container_name, component, workload, job. Если ни одна из перечисленных меток не будет найдена, service_name примет значение unknown_service. Список данных меток может быть изменен в конфигурационном файле, строка discover_service_name в блоке limits_config.

Еще пример автоматичекого добавления меток - логи полученные от поставщика Grafana Alloy.

Подробнее про Labels в Loki

Loki install

Самый простой способ установить Loki у себя на сервере - запустить его в контейнере.

networks:
  monitoring:
    driver: bridge

volumes:
  loki_data: {}

services:
  loki:
    image: grafana/loki:latest
    container_name: loki
    pull_policy: always
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"
    volumes:
      - ./loki:/etc/loki # через docker bind пробрасываем файл конфигурации
      - loki_data:/loki # подключаем docker volume для хранения базы с логами
    ports:
      - "127.0.0.1:3100:3100" # Пробрасываем порт к которому потом подключится графана
    command: -config.file=/etc/loki/config.yml # указываем где находится конфигурация
    networks:
      - monitoring

Loki configure

Настройка Loki с помощью файла конфигурации /etc/loki/config.yml.

/etc/loki/config.yml
auth_enabled: false

server:
  http_listen_port: 3100

common:
  instance_addr: 127.0.0.1
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

schema_config:
  configs:
    - from: 2025-12-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

ruler:
  alertmanager_url: alertmanager:9093

limits_config:
  retention_period: 720h
  reject_old_samples: true
  reject_old_samples_max_age: 720h

table_manager:
  retention_deletes_enabled: true
  retention_period: 720h

analytics:
  reporting_enabled: false

Grafana Alloy

Grafana Alloy - универсальный сборшик наблюдаемых данных, который умеет принимать логи в различных форматах, а затем пересылать их на Loki-сервер.

Alloy состоит из компонентов, которые выполняют специфические функции, их условно можно разделить на следующие группы:

  • Collector. Компоненты этой группы собирают/получают логи из различных источников. Они могут забирать логи из файлов, получать по HTTP, gRPC или из очереди сообщений.

  • Trasformer. Компоненты этой группы могут быть использованы для манипулирования логами перед тем как они будут отправлены на Writer. К логам можно добавить метаданные, отфильтровать, сгрупировать.

  • Writer. Эти компоненты отправляют логи в различные направления. Например, в Alloy

Подробнее про компоненты Alloy

Alloy service in docker-compose
  alloy:
    image: grafana/alloy:latest
    container_name: alloy
    pull_policy: always
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"
    command: run /etc/alloy/config.alloy
    volumes:
      - ./alloy:/etc/alloy # Пробрасываем в контейнер файлы конфигурации
      - /var/log/fail2ban.log:/var/log/fail2ban.log:ro # Пробрасываем в контейнер файлы с логами
    depends_on:
      - loki
    networks:
      - monitoring

Grafana Alloy умеет мониторить различные источники логов.

Monitor log files

С помощью данного компонента Alloy мониторит указанные файлы, при появлении новых журнальных записей отправляет из на Loki-сервер. Конфигурация хранится в файле /etc/alloy/config.alloy

Какие компоненты необходимо настроить для успешной передачи лог файлов в Loki

  • local.file_match находит файлы в локальной ФС.
local.file_match
local.file_match "local_files" {
    path_targets = [{"__path__" = "/temp/logs/*.log", "job" = "python", "hostname" = constants.hostname}]
    sync_period  = "5s"
}
  • loki.source.file читает конкретные логи и переправляет в другие компоненты Loki.
loki.source.file
loki.source.file "log_scrape" {
    targets    = local.file_match.local_files.targets
    forward_to = [loki.write.local.receiver]
    tail_from_end = true
}
  • loki.write отправляет логи на конкретный Loki-сервер.
loki.write
loki.write "local" {
  endpoint {
    url = "http://loki:3100/loki/api/v1/push"
  }
}