Объединить несколько файлов журналов в каталоге

Объединить несколько файлов журналов в каталоге

У меня есть кластер k3s single node, работающий на машине. У меня пока нет настроенной инфраструктуры журналирования, и я бы оставил это как будущий опыт обучения на данный момент.

На этом k3s я запускаю несколько заданий cron, которые создают журналы для каждого задания в отдельный файл. Я могу наблюдать за ними на /var/log/containers/cron-job-*хост-машине. Эти журналы исчезают через определенное время (successfulJobsHistoryLimit: 3). Новые экземпляры заданий создают новые файлы журналов.

Я не могу найти простой инструмент, который мог бы следить за каталогом журналов, желательно с шаблоном имени файла, и транслировать/объединять эти небольшие журналы заданий в один файл журнала, включая новые файлы, которые создаются. Я не против, если имя файла потеряется, я просто хочу, чтобы строки журнала оказались в одном файле, служащем архивом всех выполненных заданий.

Что я рассмотрел?

Я мог бы просто добавить скрипт для cat этих файлов и добавления в целевой файл с интервалом, но мне пришлось бы отслеживать, какие файлы уже были вставлены, в случае если задания выйдут из синхронизации или изменится интервал cron. Также я мог бы расширить эту функциональность для подов, которые "долго работают", и в этом случае мне пришлось бы начать отслеживать обновленные строки в журналах.

Все примеры, которые я нашел, имеют дело с отслеживанием в реальном времени на экране, что мне не нужно. Мне нужно многопоточное отслеживание в целевой файл журнала.

Есть идеи? (Я бы также принял какой-нибудь простой пример хука для ведения журналов Kubernetes)

решение1

Я предлагаю одно решение, которое я сейчас для себя выбрал. Это не тот ответ, который я искал, но тот, который, кажется, плывет по течению. Мне все еще интересно, можно ли это сделать с помощью какой-нибудь распространенной команды Unix.

В любом случае, вот что я сделал:

Распространенный способ, кажется, использует инструмент под названиемFluentd, который позволяет собирать журналы из различных источников и переносить их в любое удобное для вас место — своего рода ETL для журналов.

Я решил отправлять логи на сервер syslog, поскольку он у меня уже запущен, но вы можете выбрать любой из плагинов вывода отсюда:Выходные плагины. Также имеется большой набор дополнительных плагинов:Все плагины

Шаг 1

Получите настройку Fluentd с установленным плагином remote_syslog. Он не идет в комплекте с официальным образом docker, но вы можете настроить его самостоятельно.

FROM fluent/fluentd:v1.14.0-1.0
USER root

# https://github.com/fluent-plugins-nursery/fluent-plugin-remote_syslog
RUN fluent-gem install fluent-plugin-remote_syslog

USER fluent

Создайте образ и поместите его в свой реестр.

Шаг 2

Затем настройте манифест развертывания Fluentd с требованиями тома только для чтения для доступа к журналам pod. Фактические файлы находятся в /var/log/pods/*, а /var/log/containers содержит фактические символические ссылки. Нам нужны фактические файлы. Эти журналы принадлежат root на хост-машине, и простой пользователь Fluent не будет иметь доступа для их чтения. Нам нужно установить некоторые контексты безопасности. Чтобы все заработало, я использовал группу root для fsGroup. Не стесняйтесь копать глубже и находить/комментировать наиболее оптимальное решение для этого с точки зрения безопасности.

apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      securityContext:
        fsGroup: 0
      volumes:
        - name: varlogpods-pv
          persistentVolumeClaim:
            claimName: pvc-var-log-pods
            ...
      containers:
        - name: fluentd
          image: your/fluentd-image

См. мой полный манифест в этой статье:fluentd-развертывание

Шаг 3

Перед развертыванием вам также необходимо настроить fluent.confи описать некоторые правила.

У меня он настроен на соответствие такой строке журнала:

2022-04-26T20:05:00.847016854+03:00 stderr F time="2022-04-26 17:05:00" level=info msg="processing 3 records ..."

Подробнее о плагине tail:хвост

    <source>
      @type tail
      @id in_tail_container_logs
      path "/var/log/pods/default_cron-*/*/*.log"
      pos_file "/tmp/cron_.log.pos"
      read_from_head true
      tag cron
      <parse>
        @type regexp
        expression /^(?<logtime>[^ ]*) .* level=(?<level>[^ ]*) msg="(?<message>[^"]*)"$/ 
        time_key logtime
        time_format %FT%T.%N%:z
      </parse>
    </source>
    
    <match cron>
     @type remote_syslog
     host 172.16.3.10
     port 514
     protocol udp
     severity info
     program "fluentd"
     hostname "k3sserver"
     
     <buffer>
     </buffer>
     
     <format>
      @type single_value
      message_key message
     </format>
    </match>

Один важный атрибут конфигурации здесь — read_from_head truewhich читает файлы журнала сверху. Это необходимо для этого сценария, поскольку журналы пода вращаются, мы хотим, чтобы Fluentd читал полный журнал пода, а не только несколько строк обновления в конце. Для короткого задания cron файл журнала просто появляется, и tail не будет сообщать о каких-либо начальных строках в нем.

Шаг 4

Поиграйтесь с конфигурацией и попробуйте, попробуйте снова. Не забудьте перезапустить развертывание после обновления конфигурации в configMap.

Несколько фрагментов из поискового маршрута:

Связанный контент