We detected you are likely not from a Russian-speaking region. Would you like to switch to the international version of the site?

  Назад к списку статей

Управление системными журналами через journalctl в Termux: централизованный сбор, агрегация, хранение и поиск с Elastic Stack

Разбираем, как в Termux управлять журналами через journalctl, организовать централизованный сбор, агрегацию, хранение и поиск с помощью Elastic Stack (Elasticsearch, Logstash, Kibana). Подход подходит для лабораторий и полевых задач.

Termux стал удобной платформой для полевых работ: диагностика, автоматизация, сбор телеметрии и журналов. Однако, когда требуется аналитика по событиям на большом числе устройств или узлов, одного локального просмотра логов недостаточно. Решение — централизовать журналы и дать удобный поиск и визуализацию.

В этой статье Денис Евгеньевич, ведущий эксперт РыбинскЛАБ, покажет практический подход к управлению системными журналами через journalctl (systemd-journald) в контуре Termux и дальнейшему маршрутизированию событий в Elastic Stack: сбор/агрегацию (Logstash), хранение (Elasticsearch) и поиск/дешборды (Kibana).

Что именно будем собирать: model журнала и источники

Системные журналы обычно доступны через journalctl и содержат метаданные: единицу (unit), приоритет (priority), временную метку, hostname и PID. Наша цель — превратить события из journald в поток структурированных документов для индексации в Elasticsearch.

Возможные источники событий:

  • события systemd (службы и единицы): UNIT / unit;
  • ошибки приложений, которые пишут в journald;
  • события ядра (при наличии в journald);
  • системные сообщения в пределах узла, где работает Termux.

Условия и оговорки

Termux сам по себе не является полноценным systemd-контейнером на всех устройствах. Поэтому подход зависит от того, как именно у вас организован доступ к journalctl:

  • Если на устройстве/среде фактически запущен systemd-journald, то journalctl может быть доступен напрямую.
  • Если systemd-journald находится в другой среде (например, отдельный Linux-слой/контейнер/виртуальная машина), Termux может работать как клиент, передающий запросы и/или читающий выгрузки журналов.

Независимо от архитектуры, базовая идея одинакова: получать события в формате, пригодном для транспортировки, добавить метаданные (host, service, severity), отправить в Logstash/Elasticsearch.

Подготовка Termux: инструменты и доступ к journalctl

На стороне Termux подготавливаем базовые утилиты. В зависимости от окружения может потребоваться отдельная установка util-linux, coreutils, а также инструменты для сети.

pkg update
pkg upgrade
pkg install curl jq nano

Далее проверяем наличие journalctl:

command -v journalctl || which journalctl
journalctl --version || true

Если команда недоступна, это сигнал, что требуется другой путь: чтение экспорта журналов, доступ к journald из окружения, либо использование альтернативного источника логов (например, файлы, которые пишутся приложениями). В этой статье фокус — именно workflow вокруг journalctl.

Экспорт событий из journalctl: фильтрация и форматирование

Ключ к интеграции — получить данные из journald в предсказуемом формате. Практичный вариант — JSON-вывод.

Пример: чтение последних событий с ограничением по времени и выводом в JSON.

journalctl -u ssh --since "-1 hour" -o json-pretty

Для потоковой отправки лучше использовать не «pretty», а компактный JSON. Часто используют -o json.

journalctl -u ssh --since "-10 minutes" -o json

Добавим базовую фильтрацию по приоритету (например, ошибки). В journald priority обычно: 0..7, где 0 — emergency, 3 — error (в зависимости от конфигурации). На практике удобнее начинать с --priority и тестировать.

journalctl --since "-30 minutes" --priority=3 -o json

Добавление метаданных: hostname, environment, service

Elastic Stack лучше работает с унифицированной схемой. Мы добавим поля на этапе преобразования. Самый простой способ в Termux — через jq дописать/нормализовать структуру.

Пример преобразования одного JSON-события: извлекаем ключевые поля и приводим их к целевому формату.

journalctl -u ssh --since "-10 minutes" -o json \
| jq -c '{
    "@timestamp": .REALTIME_TIMESTAMP,
    "host": (.SYSLOG_HOST // "unknown"),
    "unit": (.SYSLOG_IDENTIFIER // ._SYSTEMD_UNIT // "unknown"),
    "priority": .PRIORITY,
    "message": (.MESSAGE // "")
}'

Важно: REALTIME_TIMESTAMP — это числовой timestamp в формате journald. Его обычно нужно конвертировать к ISO8601 или к формату, который понимает Elasticsearch. Ниже мы покажем практичный вариант отправки с нормализацией на стороне Logstash.

Схема централизованного контура: Termux → Logstash → Elasticsearch → Kibana

Рекомендуемая схема для централизации:

  • Termux: вычитывает события из journalctl, формирует события в JSON и отправляет их в Logstash (обычно по HTTP или TCP).
  • Logstash: принимает входящие события, нормализует поля, обогащает (например, service/level), определяет индекс и отправляет в Elasticsearch.
  • Elasticsearch: хранит документы и обеспечивает индексацию/поиск.
  • Kibana: строит запросы, визуализации, алерты (если настроены).

Такой подход удобен для лабораторий и эксплуатационных сценариев: вы контролируете схему данных и процесс агрегации.

Вариант транспорта: HTTP от Termux в Logstash

На стороне Termux проще отправлять JSON постом. Пример подготовки одного события (или итерации по событию) зависит от того, как вы хотите шить поток: батчами или поштучно. Для демонстрации используем поштучный формат и отправку через curl.

Ниже — пример «прослойки» (скриптовый подход) без претензии на идеальную производительность, с акцентом на корректность схемы.

LOGSTASH_URL="http://192.168.1.10:8080/event"

journalctl --since "-5 minutes" -o json \
| jq -c '{
    "@source": "termux-journalctl",
    "host": (.SYSLOG_HOST // "unknown"),
    "unit": (. _SYSTEMD_UNIT // .SYSLOG_IDENTIFIER // "unknown"),
    "priority": .PRIORITY,
    "message": (.MESSAGE // ""),
    "realtime_timestamp": .REALTIME_TIMESTAMP
}' \
| while read -r event; do
    curl -sS -X POST "$LOGSTASH_URL" \
      -H 'Content-Type: application/json' \
      -d "$event" >/dev/null
  done

Примечание: показан пример с while read. На проде стоит использовать батчирование и контроль ошибок/ретраев.

Если вы применяете VPN, то только для создания локальной сети и связности устройств в рамках инфраструктуры — не для обхода блокировок. В этом случае Logstash будет доступен по адресам локального сегмента.

Конфигурация Logstash: вход, нормализация, индексация

Далее зададим конфигурацию Logstash. Здесь показан пример входа по HTTP и сохранения в Elasticsearch.

Пример pipeline для logstash.conf:

input {
  http {
    port => 8080
    codec => json
    # Ожидаем: единичные JSON-события, отправляемые Termux
  }
}

filter {
  # realtime_timestamp из journald конвертируем.
  # REALTIME_TIMESTAMP обычно: микросекунды с эпохи.
  # Переведем в миллисекунды для @timestamp.
  ruby {
    code => '
      rt = event.get("realtime_timestamp")
      if rt
        # rt в микросекундах → миллисекунды
        event.set("@timestamp", (rt.to_f / 1000).to_i)
      end
    '
  }

  # Приводим @timestamp к формату, который понимает ES.
  date {
    match => [ "@timestamp", "UNIX_MS" ]
    target => "@timestamp"
  }

  mutate {
    # Нормализуем поля
    rename => { "unit" => "service" }
    remove_field => [ "realtime_timestamp" ]
  }

  # Пример маппинга priority в уровень (очень грубо, для иллюстрации)
  ruby {
    code => '
      p = event.get("priority")
      level = case p
        when 0..1 then "emergency"
        when 2 then "alert"
        when 3 then "error"
        when 4..6 then "warning"
        else "info"
      end
      event.set("level", level)
    '
  }
}

output {
  elasticsearch {
    hosts => ["http://192.168.1.20:9200"]
    index => "termux-journalctl-%{+YYYY.MM.dd}"
  }
}

Смысл: Logstash принимает JSON, нормализует timestamp, формирует индекс по дате и записывает документы в Elasticsearch.

Настройка Elasticsearch и индексов: mapping и шаблоны

Чтобы поиск и агрегации работали предсказуемо, заранее полезно задать mapping (или использовать шаблон индекса). Минимально:

  • @timestamp — date;
  • host, service, level — keyword;
  • message — text (и возможно keyword под точные совпадения);
  • priority — integer.

Если вы используете шаблоны через Index Template, вы управляете типами полей. В рамках статьи приведем пример логики, а конкретный curl зависит от версии Elastic.

Kibana: поиск, фильтры и готовые запросы

После поступления данных в индексы termux-journalctl-* в Kibana можно:

  • выбрать Data View по шаблону;
  • сделать Discover-поиск по service, host, level и тексту message;
  • создать Lens/Viz для распределений событий по времени.

Примеры запросов в Discover (KQL):

  • ошибки сервиса: service:"ssh" and level:"error"
  • события конкретного узла: host:"device-01"
  • за период (через Time Picker): last 15 minutes
  • по тексту: message:"Failed"

Потоковый сбор: journalctl -f и «живые» события

Для живого мониторинга можно использовать режим слежения:

journalctl -f -u ssh -o json \
| jq -c '{
    "@source": "termux-journalctl",
    "host": (.SYSLOG_HOST // "unknown"),
    "service": (. _SYSTEMD_UNIT // .SYSLOG_IDENTIFIER // "unknown"),
    "priority": .PRIORITY,
    "message": (.MESSAGE // ""),
    "realtime_timestamp": .__REALTIME_TIMESTAMP
}' \
| while read -r event; do
    curl -sS -X POST "$LOGSTASH_URL" \
      -H 'Content-Type: application/json' \
      -d "$event" >/dev/null
  done

При таком подходе важно учесть:

  • устойчивость сети и повторные попытки;
  • нагрузку на Logstash/Elasticsearch;
  • идемпотентность (если возможны повторы при реконнекте);
  • ротацию и backpressure (на уровне клиента — хотя бы логирование ошибок отправки).

Агрегация и хранение: что улучшает Elastic Stack

Централизация через Elastic дает:

  • Единый поиск по всем узлам и всем типам событий (в пределах вашей схемы).
  • Горизонтальную масштабируемость хранения и поисковых запросов.
  • Возможность агрегаций: по сервисам, хостам, уровням, временным окнам.
  • Дешборды и отчеты: динамика ошибок, пики, частотность сообщений.

Если вы расширите модель (добавите кореляцию по PID/TRANSACTION_ID, группировку по unit, обогащение гео/инвентаризацией узлов), ценность системы резко вырастет.

Безопасность и эксплуатация

В зависимости от требований:

  • используйте изоляцию сети (VLAN/локальный сегмент), а при необходимости — локальную сеть через VPN;
  • ограничивайте доступ к Logstash endpoint и Elasticsearch (firewall, правила;
  • по возможности включайте TLS для HTTP между Termux и Logstash;
  • ведёте мониторинг Logstash и Elasticsearch (очереди, latency, reject, pipeline failures).

Даже в лабораторной среде лучше сразу заложить контроль, чтобы система не «разрослась» и не потеряла стабильность.

Чек-лист внедрения

  • Проверьте наличие journalctl и доступность событий.
  • Определите фильтры: -u, --since, --priority.
  • Согласуйте схему полей документа: @timestamp, host, service, level, message.
  • Настройте Logstash input/filter/output и индексацию.
  • Создайте Data View в Kibana и валидируйте запросы.
  • Добавьте тестовый поток, затем включите мониторинг и алертинг (при необходимости).

Заключение

Мы рассмотрели практический workflow для управления системными журналами через journalctl в Termux и их централизованный сбор в Elastic Stack: от фильтрации и форматирования событий до нормализации в Logstash, индексации в Elasticsearch и поиска/аналитики в Kibana. Такой подход дает единый контур диагностики, ускоряет расследования и помогает строить прозрачные наблюдаемости.

Если вам нужна помощь с внедрением под вашу инфраструктуру (схема индексов, оптимизация pipeline Logstash, настройка надежной доставки, шаблоны и dashboards), команда РыбинскЛАБ поможет спроектировать и развернуть решение под ваши требования.

* Текст статьи подготовлен и структурирован с использованием технологий искусственного интеллекта. Проверен и доработан перед публикацией.

Нужна помощь с настройкой Termux, Linux и серверов?

Я оказываю ИТ-услуги: настройка серверов, автоматизация, безопасность, помощь с Linux и инфраструктурой. Материалы сайта — только в ознакомительных и образовательных целях.

Связаться со мной
Поддержать проект