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

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

Мониторинг и лог‑агрегация в Termux: Prometheus + Grafana + Loki для сбора метрик и журналов мобильных процессов

Termux — удобная среда для запуска утилит и скриптов на Android, но при эксплуатации возникает типичная потребность: понимать, что происходит с процессами «на телефоне» или на мобильном устройстве, где они работают и как долго, а также получать логи в структурированном виде. В этой статье описывается практичная схема мониторинга и лог‑агрегации для мобильных сценариев: сбор метрик в Prometheus, визуализация в Grafana и централизованный сбор журналов в Loki.

Концептуально решение строится вокруг локальной сети и сервисов, развернутых на отдельном устройстве (например, на домашнем ПК/мини‑сервере или на другом узле в той же сети). Это не про обход ограничений и не про какие‑либо «обходы», а про корректную инфраструктуру: телефон (Termux) отправляет телеметрию в локальные компоненты, а вы получаете единые дашборды и поиск по логам.

Архитектура: что за чем и где работает

Рассмотрим типовой поток данных:

  • Termux — источник телеметрии: метрики (например, по процессам/ресурсам) и логи приложений.
  • Prometheus — сервер метрик: скрапит endpoint’ы, собирает временные ряды и хранит их.
  • Grafana — интерфейс: дашборды, алерты, объединение данных из разных источников.
  • Loki — сервер логов: принимает логи по протоколу и предоставляет поиск/просмотр через Grafana.

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

  • Пуллинг (scrape) для метрик: Prometheus опрашивает HTTP‑endpoint на устройстве (или через gateway).
  • Пушинг для логов: Loki принимает логи из клиента (например, через promtail).

Выбор конкретного способа зависит от возможностей устройства, сети и того, как вы хотите организовать доступ по IP/порту.

Подготовка: сеть и адресация

Чтобы Prometheus и Loki были доступны от Termux, устройства должны «видеть» друг друга в локальной сети. Самый простой вариант — убедиться, что:

  • Телефон и сервер находятся в одной Wi‑Fi сети.
  • У сервера фиксирован адрес (или вы знаете, где его найти).
  • Порты сервиса открыты локально (на стороне сервера) и не блокируются брандмауэром.

Если вам нужно организовать локальную сеть между устройствами, используйте VPN только для создания локальной сети (как overlay сети), а не для обхода блокировок. Дальше конфигурации делаются так же, как для обычного LAN.

Установка базовых компонентов в Termux

В Termux установим инструменты, которые пригодятся для сбора метрик и отправки логов. В зависимости от выбранного подхода вы будете использовать либо экспортеры/скрипты, либо отправку через системные журналы приложений (а для приложений — через stdout/stderr и форвардинг).

Обновите пакеты и установите базовый набор:

pkg update -y
pkg upgrade -y
pkg install -y wget curl tar procps netcat-openbsd

Далее, если вы планируете собирать метрики через простой HTTP‑endpoint, понадобится интерпретатор/скриптовая среда (часто используют Python или Go). На практике Python быстрее подключить для прототипа:

pkg install -y python

Для работы с лог‑транспортом может потребоваться бинарь promtail или минимальный клиент. На Termux проще рассматривать вариант, когда вы отправляете логи в Loki через HTTP endpoint, если есть готовый инструмент/бинарь под вашу архитектуру. Далее мы покажем вариант с promtail (часто его используют на сервере/узле), а на Termux — либо прямую отправку, либо чтение и пересылку логов скриптом.

Сбор метрик: вариант через Prometheus scrape

Наиболее универсальная модель для мобильного сценария — дать Prometheus возможность собирать метрики с Termux по HTTP. Для примера ниже создадим простой метрик‑endpoint, который будет отдавать числа в формате Prometheus text exposition format.

Допустим, вы хотите собирать:

  • Оценку CPU в простом виде (например, из /proc/stat).
  • Количество процессов в системе (из ps).
  • Сводку по конкретным сервисам (если вы отслеживаете свои процессы).

Создадим демонстрационный HTTP сервер в Termux.

mkdir -p ~/monitoring
cat > ~/monitoring/metrics_exporter.py <<'PY'
import http.server
import socketserver
import subprocess
import time
from urllib.parse import urlparse

PORT = 9105  # пример порта для Prometheus

def get_process_count():
    try:
        # ps -e даёт список процессов
        out = subprocess.check_output(["sh", "-c", "ps -e | wc -l"]).decode().strip()
        return int(out)
    except Exception:
        return 0

def get_uptime_seconds():
    try:
        # /proc/uptime: <seconds> <idle_seconds>
        with open("/proc/uptime", "r") as f:
            return float(f.read().split()[0])
    except Exception:
        return 0.0

class Handler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        if urlparse(self.path).path != "/metrics":
            self.send_response(404)
            self.end_headers()
            self.wfile.write(b"Not Found")
            return

        process_count = get_process_count()
        uptime_seconds = get_uptime_seconds()

        # Формат Prometheus: метрика [labels] value
        body = "
".join([
            "# HELP termux_process_count Number of processes on device",
            "# TYPE termux_process_count gauge",
            f"termux_process_count {process_count}",
            "# HELP termux_uptime_seconds Uptime of device in seconds",
            "# TYPE termux_uptime_seconds gauge",
            f"termux_uptime_seconds {uptime_seconds}",
            ""
        ]).encode()

        self.send_response(200)
        self.send_header("Content-Type", "text/plain; version=0.0.4")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

if name == "main":
    with socketserver.TCPServer(("0.0.0.0", PORT), Handler) as httpd:
        print(f"Metrics exporter running on port {PORT}")
        httpd.serve_forever()
PY
python ~/monitoring/metrics_exporter.py

Запуск вручную подходит для теста. Для постоянного функционирования обычно применяют запуск в фоне (screen/tmux, сценарии при загрузке — с учётом особенностей Android). На уровне безопасности используйте доступ по сети минимально необходимый: ограничьте firewall на сервере так, чтобы Prometheus мог ходить на нужный порт.

Настройка Prometheus для скрапинга Termux

На сервере (где работает Prometheus) добавьте target в конфиг. Пример: Prometheus будет скрапить endpoint Termux по адресу TERMUX_IP и порту 9105.

cat > /etc/prometheus/targets.yml <<'YML'
scrape_configs:
  - job_name: "termux_device"
    metrics_path: /metrics
    scheme: http
    static_configs:
      - targets: ["TERMUX_IP:9105"]
YML

Дальше вставьте или подключите этот фрагмент в основной конфиг Prometheus (обычно prometheus.yml). Пример упрощённо:

grep -n "scrape_configs" -n /etc/prometheus/prometheus.yml
# Добавьте раздел scrape_configs или инклюдом подключайте targets.yml (если ваш setup поддерживает).

Если у вас нет инклюда, просто объедините содержимое scrape_configs в prometheus.yml.

Grafana: подключение Prometheus и базовый дашборд

В Grafana выполните добавление источника данных (Data Source): выберите Prometheus и укажите URL вашего Prometheus. Затем создайте панель с метриками.

Пример запросов (PromQL) для ваших метрик из экспортера:

  • termux_process_count
  • termux_uptime_seconds

Для удобства добавьте шаблонизацию (dashboard variables), если у вас несколько устройств Termux — например, через labels (в расширенной версии экспортера).

Логи в Loki: подход с promtail и структурирование

Для логов важно выбрать формат и источники. На практике лог‑потоки Termux бывают двух типов:

  • Логи ваших приложений/скриптов, которые вы запускаете и хотите централизованно хранить.
  • Системные логи Android — они более сложны к извлечению в Termux, и часто удобнее сосредоточиться на собственных логах сервисов.

Рекомендуемая стратегия: все важные скрипты/демоны в Termux запускайте так, чтобы они писали в файл или наружу (stdout/stderr), а затем этот поток отправлялся в Loki.

Практический вариант: отправка логов из Termux в Loki через HTTP (упрощённо)

Если у вас нет возможности удобно развернуть promtail прямо в Termux, можно пересылать лог‑файлы скриптом. Ниже — демонстрационный шаблон: он читает строки из файла и отправляет в Loki. Важно: Loki имеет конкретный формат запросов, поэтому перед внедрением проверьте совместимость с вашей версией Loki и используемым endpoint’ом.

Подготовим файл логов в Termux:

mkdir -p ~/monitoring/logs
touch ~/monitoring/logs/app.log

Пример «писателя» (ваше приложение/скрипт):

for i in $(seq 1 100000); do
  echo "$(date -Is) event_number=$i message='termux run'" >> ~/monitoring/logs/app.log
  sleep 1
done

Теперь пример форвардера (псевдо‑скелет). Перед использованием адаптируйте payload под ваш Loki и версию:

cat > ~/monitoring/loki_forwarder.py <<'PY'
import time
import requests

LOKI_URL = "http://LOKI_IP:3100"   # замените на адрес Loki
TENANT = None

# Пример: укажем labels для потока
LABELS = {
    "job": "termux",
    "device": "termux-phone-01"
}

LOG_FILE = "/data/data/com.termux/files/home/monitoring/logs/app.log"

def format_labels(labels: dict):
    # В зависимости от формата Loki labels должны быть строкой 'key="value",...'
    parts = [f'{k}="{v}"' for k, v in labels.items()]
    return ",".join(parts)

def tail_f(path):
    with open(path, "r", encoding="utf-8", errors="ignore") as f:
        f.seek(0, 2)
        while True:
            line = f.readline()
            if not line:
                time.sleep(0.2)
                continue
            yield line.rstrip("
")

def main():
    url = f"{LOKI_URL}/loki/api/v1/push"

    # Loki ingestion обычно ожидает batch, но для простоты делаем одиночные отправки.
    for line in tail_f(LOG_FILE):
        payload = {
            "streams": [
                {
                    "stream": LABELS,
                    "values": [
                        # values: [ [timestamp_ns, line], ... ]
                        [str(int(time.time() * 1e9)), line]
                    ]
                }
            ]
        }

        r = requests.post(url, json=payload, timeout=5)
        r.raise_for_status()

if name == "main":
    main()
PY

pkg install -y python
python ~/monitoring/loki_forwarder.py

Если этот метод вызывает трудности из‑за payload (формата labels/tenant/endpoint), используйте promtail на сервере или поднимите promtail на другом узле, который читает лог‑файлы. На практике это часто проще и надёжнее.

Настройка Loki (сервер)

Для Loki на сервере достаточно базовой конфигурации, где вы задаёте режим хранения (в зависимости от вашей инфраструктуры) и порты. Пример базового блока конфигурации (общая идея):

cat > /etc/loki/loki-config.yml <<'YML'
auth_enabled: false

server:
  http_listen_port: 3100

ingester:
  lifecycler:
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
  chunk_idle_period: 1h
  chunk_retain_period: 30s
  max_transfer_retries: 0

schema_config:
  configs:
    - from: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h

storage_config:
  boltdb_shipper:
    active_index_directory: /var/lib/loki/index
    cache_location: /var/lib/loki/cache
    shared_store: filesystem
  filesystem:
    directory: /var/lib/loki/chunks

limits_config:
  enforce_metric_name: false
YML

После настройки поднимите Loki как сервис. Убедитесь, что у сервера доступны записи /loki/api/v1/push из локальной сети Termux.

Grafana: лог‑панели и поиск в Loki

В Grafana добавьте Data Source типа Loki и укажите URL (например, http://LOKI_IP:3100). Далее в Explore/панелях используйте:

  • Тэги labels, которые вы передали из Termux (например, job, device).
  • Поиск по тексту (фильтры по содержимому строк).
  • Корреляцию по времени с графиками метрик (удобно анализировать всплески событий рядом с графиками CPU/нагрузки).

Для более точной наблюдаемости добавляйте в лог‑строки структурные поля (например, event_number, service, status) в едином формате. Это повышает ценность поиска и облегчает построение шаблонов фильтрации.

Практика эксплуатации: рекомендации по устойчивости

  • Ограничьте экспозицию: не делайте эндпоинты открытыми в интернет; ориентируйтесь на локальную сеть.
  • Следите за портами: keep it simple — один метрик‑порт и один путь для логов.
  • Логи — с ротацией: ваши файлы в Termux должны иметь разумный размер. Пересылка должна корректно переживать перезапуски.
  • Часовой пояс и timestamp: для Loki важны временные метки. Используйте ns timestamp при формировании payload.
  • Алерты: алерты строятся на Prometheus метриках (например, рост количества процессов, падение экспортера, отсутствие скрейпа). Для лог‑условий часто удобнее сначала визуализировать в Explore, затем формализовать алерт через метрики/правила.

Типовой чек‑лист отладки

  • В Termux проверьте, что endpoint метрик доступен: попробуйте с сервера открыть http://TERMUX_IP:9105/metrics.
  • В Prometheus проверьте статус target’а в UI: состояние UP, метрики появляются.
  • В Loki проверьте доступность push endpoint’а: тестовый POST (или временно включите логирование клиента).
  • В Grafana проверьте, что datasource подключается, и что поля labels совпадают с теми, что вы передали.

Заключение

Мониторинг и лог‑агрегация для Termux в связке Prometheus + Grafana + Loki позволяют превратить «мобильные» скрипты и процессы в управляемую наблюдаемую систему: метрики — на графиках и алертах, логи — в централизованном поиске с фильтрами по labels и временем. Ключ к успеху — корректная организация локальной сети между узлами, понятные endpoints и единый подход к форматированию логов.

Если вы хотите быстро и надёжно внедрить такую схему под ваши сценарии (количество устройств, формат логов, требования к хранению и алертам), обращайтесь в РыбинскЛАБ: поможем с проектированием, настройкой и эксплуатационными рекомендациями.

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

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

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

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