19 KiB
zh_syslog — Компонент syslog UDP клиента для ESP-IDF
Содержание
- Обзор
- Возможности
- Установка
- Справочник API
- Примеры использования
- Технические характеристики
- Коды ошибок
- Вклад в проект
- Лицензия
Обзор
zh_syslog — это легковесная библиотека syslog UDP клиента для ESP-IDF (Espressif IoT Development Framework). Она предоставляет реализацию формирования и передачи syslog-сообщений совместимых со стандартом RFC 5424 через UDP дейтаграммы. Библиотека разработана специально для платформ ESP32/ESP-IDF и бесшовно интегрируется с приложениями на базе FreeRTOS.
Библиотека позволяет устройствам ESP32 отправлять структурированные журнальные сообщения на удалённый syslog-сервер, что способствует централизованному управлению журналами и мониторингу в IoT-развертываниях. Сообщения форматируются в соответствии со стандартом RFC 5424, поддерживая коды facility (0-23) и уровни важности (0-7) для точной категоризации журналов.
Возможности
- Соответствие RFC 5424: Сообщения форматируются в соответствии со стандартом syslog RFC 5424
- Стандартные коды Facility: Поддержка всех 24 стандартных кодов facility syslog (KERN, USER, DAEMON, LOCAL0-LOCAL7 и т.д.)
- Уровни важности: Поддержка всех 8 стандартных уровней severity syslog (EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO, DEBUG)
- UDP транспорт: Использует дейтаграммные сокеты для эффективной передачи журналов
- Память совместимая с DMA: Использует выделения MALLOC_CAP_8BIT для потенциального использования DMA
- Структурированное логирование: Включает поля hostname, app name и message в соответствии с RFC 5424
Установка
Перейдите в каталог компонентов вашего проекта:
cd ../ваш_проект/components
Клонируйте репозиторий:
git clone https://github.com/aZholtikov/zh_syslog
В вашем приложении подключите заголовочный файл:
#include "zh_syslog.h"
Компонент будет автоматически собран вместе с вашим проектом.
Справочник API
Структура zh_syslog_init_config_t
Структура конфигурации для инициализации syslog клиента.
Поля (внутренние):
| Поле | Тип | Описание |
|---|---|---|
syslog_ip |
char[16] |
IPv4-адрес syslog сервера в виде нуль-терминированной строки (например, "192.168.1.1"). Максимум 15 символов плюс нуль-терминатор. |
syslog_port |
uint32_t |
UDP-порт syslog сервера (обычно 514). |
Примечание: IP-адрес должен быть валидной IPv4-строкой. Порт должен быть в допустимом диапазоне (стандартный порт syslog — 514).
Перечисление zh_syslog_facility_code_t
Стандартные коды facility syslog в соответствии с RFC 5424 (0-23).
Значения:
| Значение | Перечисление | Описание |
|---|---|---|
| 0 | ZH_KERN |
Сообщения ядра |
| 1 | ZH_USER |
Пользовательские сообщения |
| 2 | ZH_MAIL |
Почтовая система |
| 3 | ZH_DAEMON |
Системные демоны |
| 4 | ZH_AUTH |
Сообщения безопасности/авторизации |
| 5 | ZH_SYSLOG |
Сообщения от самого syslogd |
| 6 | ZH_LPR |
Подсистема принтеров |
| 7 | ZH_NEWS |
Сетевая подсистема новостей |
| 8 | ZH_UUCP |
Подсистема UUCP |
| 9 | ZH_CRON |
Подсистема cron |
| 10 | ZH_AUTHPRIV |
Сообщения безопасности (приватные) |
| 11 | ZH_FTP |
FTP демон |
| 12 | ZH_NTP |
Подсистема NTP |
| 13 | ZH_SECURITY |
Журнал аудита |
| 14 | ZH_CONSOLE |
Журнал уведомлений |
| 15 | ZH_SOLARIS_CRON |
Планировщик задач |
| 16-23 | ZH_LOCAL0-ZH_LOCAL7 |
Локальное/пользовательское использование |
Перечисление zh_syslog_severity_code_t
Стандартные коды severity syslog в соответствии с RFC 5424 (0-7).
Значения:
| Значение | Перечисление | Описание |
|---|---|---|
| 0 | ZH_EMERG |
Система неработоспособна |
| 1 | ZH_ALERT |
Необходимо немедленное действие |
| 2 | ZH_CRIT |
Критические условия |
| 3 | ZH_ERR |
Ошибки |
| 4 | ZH_WARNING |
Предупреждения |
| 5 | ZH_NOTICE |
Обычные, но значимые условия |
| 6 | ZH_INFO |
Информационные сообщения |
| 7 | ZH_DEBUG |
Сообщения отладки |
zh_syslog_init()
Инициализирует syslog клиент путём создания UDP сокета и настройки адреса целевого сервера.
Параметры:
config— Указатель наzh_syslog_init_config_tс адресом и портом syslog сервера. Может указывать на временную переменную. Не должен быть NULL
Возвращает:
ESP_OK— УспехESP_ERR_INVALID_ARG— Указатель config равен NULLESP_FAIL— Создание сокета не удалось
Пример:
zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT();
strcpy(config.syslog_ip, "192.168.1.100");
esp_err_t ret = zh_syslog_init(&config);
if (ret != ESP_OK) {
// Обработка ошибки инициализации
}
Примечание: Подключение к сети должно быть установлено перед вызовом этой функции. Указатель config может быть временным.
zh_syslog_deinit()
Деинициализирует syslog клиент и освобождает ресурсы.
Возвращает:
ESP_OK— УспехESP_ERR_INVALID_STATE— Клиент не был инициализирован
Примечание: После вызова этой функции zh_syslog_init() должна быть вызвана заново перед любыми последующими вызовами zh_syslog_send().
zh_syslog_send()
Отправляет отформатированное syslog-сообщение на настроенный сервер.
Параметры:
facility— Код facility syslog (0-23) изzh_syslog_facility_code_tseverity— Код severity syslog (0-7) изzh_syslog_severity_code_thostname— Указатель на имя устройства (только алфавитно-цифровые символы, без пробелов). Не должен быть NULLapp_name— Указатель на имя приложения (только алфавитно-цифровые символы, без пробелов). Не должен быть NULLmessage— Указатель на строку содержимого сообщения. Не должен быть NULL
Возвращает:
ESP_OK— УспехESP_ERR_INVALID_ARG— hostname, app_name или message равен NULLESP_ERR_INVALID_STATE— Клиент не инициализированESP_ERR_NO_MEM— Ошибка выделения памяти (буфер 1024 байта)ESP_FAIL— Операция отправки UDP не удалась
Пример:
zh_syslog_send(ZH_USER, ZH_INFO, "esp32_device", "my_app", "Приложение запущено");
Примечание: Эта функция не является потокобезопасной. Вызывающий должен обеспечить взаимное исключение, если несколько задач могут вызывать эту функцию одновременно. Формат сообщения соответствует RFC 5424: <priority>1 timestamp hostname app-name procid msgid - message.
Примеры использования
Базовый пример: Инициализация и отправка сообщений
#include "zh_syslog.h"
void app_main(void)
{
esp_log_level_set("zh_syslog", ESP_LOG_ERROR);
// Инициализация конфигурации со значениями по умолчанию
zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT();
strcpy(config.syslog_ip, "192.168.1.100"); // IP syslog сервера
// Инициализация syslog клиента
esp_err_t ret = zh_syslog_init(&config);
if (ret != ESP_OK)
{
printf("Ошибка инициализации syslog: %s\n", esp_err_to_name(ret));
return;
}
// Отправка информационного сообщения
zh_syslog_send(ZH_USER, ZH_INFO, "my_device", "my_app", "Приложение запущено");
// Отправка предупреждения
zh_syslog_send(ZH_USER, ZH_WARNING, "my_device", "my_app", "Низкий заряд батареи");
// Отправка сообщения об ошибке
zh_syslog_send(ZH_KERN, ZH_ERR, "my_device", "kernel", "Ошибка чтения диска");
// Деинициализация при завершении
zh_syslog_deinit();
}
Пример: Интеграция с Wi-Fi и периодическая отправка журналов
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "zh_syslog.h"
#define WIFI_SSID "ваш_ssid"
#define WIFI_PASS "ваш_password"
#define WIFI_CONNECT_SUCCESS BIT0
static EventGroupHandle_t s_event_group;
static const int WIFI_CONNECTED_BIT = BIT0;
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
void app_main(void)
{
esp_log_level_set("zh_syslog", ESP_LOG_ERROR);
nvs_flash_init();
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
},
};
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL);
esp_wifi_start();
s_event_group = xEventGroupCreate();
xEventGroupWaitBits(s_event_group, WIFI_CONNECTED_BIT, pdFALSE, pdTRUE, portMAX_DELAY);
// Инициализация syslog после подключения Wi-Fi
zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT();
strcpy(config.syslog_ip, "192.168.1.100");
zh_syslog_init(&config);
// Периодическая отправка журнальных сообщений
for (int i = 0; i < 10; i++) {
char msg[64];
snprintf(msg, sizeof(msg), "Сердцебитие #%d", i + 1);
zh_syslog_send(ZH_USER, ZH_INFO, "esp32_sensor", "logger", msg);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
zh_syslog_deinit();
}
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_id == IP_EVENT_STA_GOT_IP)
{
xEventGroupSetBits(s_event_group, WIFI_CONNECTED_BIT);
}
}
Пример: Использование кодов Facility и Severity
#include "zh_syslog.h"
void app_main(void)
{
esp_log_level_set("zh_syslog", ESP_LOG_ERROR);
zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT();
strcpy(config.syslog_ip, "192.168.1.100");
zh_syslog_init(&config);
// Критическая ошибка ядра
zh_syslog_send(ZH_KERN, ZH_CRIT, "esp32", "kernel", "Недостаточно памяти");
// Предупреждение пользовательского приложения
zh_syslog_send(ZH_USER, ZH_WARNING, "esp32", "app", "Таймаут чтения сенсора");
// Уведомление подсистемы аутентификации
zh_syslog_send(ZH_AUTH, ZH_NOTICE, "esp32", "auth", "Пользователь успешно вошёл");
// Локальный facility для пользовательского логирования
zh_syslog_send(ZH_LOCAL0, ZH_DEBUG, "esp32", "debugger", "Состояние переменной: 0x1234");
zh_syslog_deinit();
}
Технические характеристики
| Параметр | Значение |
|---|---|
| Размер сообщения | 1024 байта (фиксированный буфер) |
| Транспортный протокол | UDP (SOCK_DGRAM) |
| Порт по умолчанию | 514 |
| Стандарт форматирования | RFC 5424 |
| Выделение памяти | heap_caps_calloc (MALLOC_CAP_8BIT) |
| Потокобезопасность | Не потокобезопасна (ответственность вызывающего) |
| Версия ESP-IDF | >= 5.0 |
| Платформа | Серия ESP32 |
| Язык | C (C99) |
Коды ошибок
| Код ошибки | Описание |
|---|---|
ESP_OK |
Операция выполнена успешно |
ESP_ERR_INVALID_ARG |
Неверный аргумент (NULL config, NULL hostname/app_name/message) |
ESP_ERR_INVALID_STATE |
Клиент не инициализирован (zh_syslog_init не вызвана) |
ESP_ERR_NO_MEM |
Ошибка выделения памяти (не хватает памяти для буфера 1024 байта) |
ESP_FAIL |
Создание сокета не удалось или операция отправки UDP не удалась |
Вклад в проект
Вклад приветствуется! Чтобы внести свой вклад:
- Сделайте форк репозитория
- Создайте ветку функции (
git checkout -b feature/AmazingFeature) - Закоммитьте ваши изменения (
git commit -m 'Add some AmazingFeature') - Отправьте в ветку (
git push origin feature/AmazingFeature) - Откройте Pull Request
Пожалуйста, убедитесь, что ваш код следует существующему стилю и включает соответствующую документацию.
Лицензия
Этот проект лицензирован по лицензии Apache, версия 2.0 - см. файл LICENSE для подробной информации.
Apache License, Version 2.0
Авторское право (c) 2026 Алексей Жолтиков
Лицензировано по лицензии Apache License, Version 2.0 (далее — "Лицензия"); вы не можете использовать этот файл, кроме случаев, предусмотренных Лицензией. Копию Лицензии можно получить по адресу:
http://www.apache.org/licenses/LICENSE-2.0
Если иное не требуется действующим законодательством или не согласовано в письменном виде, программное обеспечение, распространяемое по Лицензии, распространяется на условиях "КАК ЕСТЬ", БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, явных или подразумеваемых, включая, но не ограничиваясь, гарантии ТОВАРНОГО СОСТОЯНИЯ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. Смотрите Лицензию для получения конкретных прав и ограничений.
Дополнительные заметки
- Надёжность UDP: Эта библиотека использует UDP, который не гарантирует доставку сообщений. Для надёжной доставки реализуйте приложение-уровень подтверждения
- Производительность: O(n) для форматирования сообщения (n = длина сообщения). Операция отправки блокирующая
- Лучшие практики:
- Всегда проверяйте возвращаемые значения от zh_syslog_init() и zh_syslog_send()
- Вызывайте zh_syslog_deinit() перед выходом из приложения или выгрузкой модуля
- Используйте коды facility для категоризации источников журналов (KERN для ОС, USER для приложения, LOCAL0-7 для пользовательских)
- Держите hostname и app_name алфавитно-цифровыми (без пробелов) в соответствии с RFC 5424
- Настройте соответствующий уровень фильтрации журналов на syslog-сервере, чтобы избежать избыточного трафика
Сгенерировано для zh_syslog v1.0.0