diff --git a/README.md b/README.md index e2641b6..31e6500 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ # ESP32 ESP-IDF component for Syslog UDP client -## Wiki - -[EN](WIKI_EN.md) | [RU](WIKI_RU.md) - -## Tested on - -1. [ESP-IDF v6.0.0](https://docs.espressif.com/projects/esp-idf/en/v6.0/esp32/index.html) - ## SAST Tools [PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) — static analyzer for C, C++, C#, and Java code. @@ -24,7 +16,7 @@ In an existing project, run the following command to install the components: -```text +```bash cd ../your_project/components git clone https://github.com/aZholtikov/zh_syslog ``` @@ -35,10 +27,121 @@ In the application, add the component: #include "zh_syslog.h" ``` -## Examples - -See Wiki [EN](WIKI_EN.md#usage-examples) | [RU](WIKI_RU.md#примеры-использования) - ## Note Messages are built using the format defined in [RFC 5424](https://datatracker.ietf.org/doc/html/rfc5424). + +## Example + +```c +#include "nvs_flash.h" +#include "esp_netif.h" +#include "esp_wifi.h" +#include "esp_timer.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_MAXIMUM_RETRY 5 +#define WIFI_RECONNECT_TIME 5 +#define WIFI_CONNECT_SUCCESS BIT0 + +#define SYSLOG_IP "8.8.8.8" + +esp_timer_handle_t wifi_reconnect_timer = {0}; +uint8_t wifi_reconnect_retry_num = 0; +EventGroupHandle_t event_group_handle = {0}; + +bool flag = false; + +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 wifi_init_sta_config = WIFI_INIT_CONFIG_DEFAULT(); + esp_wifi_init(&wifi_init_sta_config); + wifi_config_t wifi_config = { + .sta.ssid = WIFI_SSID, + .sta.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(); + event_group_handle = xEventGroupCreate(); + xEventGroupWaitBits(event_group_handle, WIFI_CONNECT_SUCCESS, pdTRUE, pdTRUE, portMAX_DELAY); + zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT(); + strcpy(config.syslog_ip, SYSLOG_IP); + zh_syslog_init(&config); + for (;;) + { + if (flag == true) + { + zh_syslog_send(ZH_USER, ZH_INFO, "my_device", "my_application", "Message"); + vTaskDelay(500 / portTICK_PERIOD_MS); + zh_syslog_send(ZH_USER, ZH_CRIT, "my_device", "my_application", "Message"); + vTaskDelay(500 / portTICK_PERIOD_MS); + zh_syslog_send(ZH_KERN, ZH_ERR, "my_device", "my_application", "Message"); + vTaskDelay(500 / portTICK_PERIOD_MS); + zh_syslog_send(ZH_KERN, ZH_WARNING, "my_device", "my_application", "Message"); + } + vTaskDelay(5000 / portTICK_PERIOD_MS); + } +} + +void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) +{ + switch (event_id) + { + case WIFI_EVENT_STA_START: + esp_wifi_connect(); + break; + case WIFI_EVENT_STA_DISCONNECTED: + if (flag == true) + { + flag = false; + } + if (wifi_reconnect_retry_num < WIFI_MAXIMUM_RETRY) + { + esp_wifi_connect(); + ++wifi_reconnect_retry_num; + } + else + { + wifi_reconnect_retry_num = 0; + if (wifi_reconnect_timer != NULL) + { + esp_timer_stop(wifi_reconnect_timer); + esp_timer_delete(wifi_reconnect_timer); + } + esp_timer_create_args_t wifi_reconnect_timer_args = { + .callback = (void *)esp_wifi_connect, + .name = "wifi_reconnect"}; + esp_timer_create(&wifi_reconnect_timer_args, &wifi_reconnect_timer); + esp_timer_start_once(wifi_reconnect_timer, WIFI_RECONNECT_TIME * 1000); + } + break; + case IP_EVENT_STA_GOT_IP: + flag = true; + wifi_reconnect_retry_num = 0; + if (wifi_reconnect_timer != NULL) + { + esp_timer_stop(wifi_reconnect_timer); + esp_timer_delete(wifi_reconnect_timer); + wifi_reconnect_timer = NULL; + } + xEventGroupSetBits(event_group_handle, WIFI_CONNECT_SUCCESS); + break; + default: + break; + } +} +``` diff --git a/WIKI_EN.md b/WIKI_EN.md deleted file mode 100644 index 2cf4801..0000000 --- a/WIKI_EN.md +++ /dev/null @@ -1,398 +0,0 @@ -# zh_syslog — Syslog UDP Client Component for ESP-IDF - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Installation](#installation) -- [API Reference](#api-reference) -- [Usage Examples](#usage-examples) -- [Technical Specifications](#technical-specifications) -- [Error Codes](#error-codes) -- [Contributing](#contributing) -- [License](#license) - ---- - -## Overview - -`zh_syslog` is a lightweight syslog UDP client library for ESP-IDF (Espressif IoT Development Framework). It provides an implementation of RFC 5424-compatible syslog message formatting and transmission over UDP datagrams. The library is designed specifically for ESP32/ESP-IDF platforms and integrates seamlessly with FreeRTOS-based applications. - -The library enables ESP32 devices to send structured log messages to a remote syslog server, facilitating centralized log management and monitoring in IoT deployments. Messages are formatted according to the RFC 5424 standard, supporting facility codes (0-23) and severity levels (0-7) for precise log categorization. - ---- - -## Features - -1. **RFC 5424 Compliance**: Messages are formatted according to the RFC 5424 syslog standard -2. **Standard Facility Codes**: Support for all 24 standard syslog facility codes (KERN, USER, DAEMON, LOCAL0-LOCAL7, etc.) -3. **Severity Levels**: Support for all 8 standard syslog severity levels (EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO, DEBUG) -4. **UDP Transport**: Uses datagram sockets for efficient log transmission -5. **DMA-Compatible Memory**: Utilizes MALLOC_CAP_8BIT allocations for potential DMA usage -6. **Structured Logging**: Includes hostname, app name, and message fields per RFC 5424 - ---- - -## Installation - -Navigate to your project's components directory: - -```bash -cd ../your_project/components -``` - -Clone the repository: - -```bash -git clone https://github.com/aZholtikov/zh_syslog -``` - -In your application, include the header: - -```c -#include "zh_syslog.h" -``` - -The component will be automatically built with your project. - ---- - -## API Reference - -### zh_syslog_init_config_t Structure - -Configuration structure for syslog client initialization. - -**Fields (internal):** - -| Field | Type | Description | -| ------ | ------ | ---------- | -| `syslog_ip` | `char[16]` | Syslog server IPv4 address as a null-terminated string (e.g., "192.168.1.1"). Maximum 15 characters plus null terminator. | -| `syslog_port` | `uint32_t` | Syslog server UDP port number (typically 514). | - -**Note:** IP address must be a valid IPv4 string. Port should be within valid range (standard syslog port is 514). - ---- - -### zh_syslog_facility_code_t Enum - -Standard syslog facility codes per RFC 5424 (0-23). - -**Values:** - -| Value | Enum | Description | -| ------- | ------ | ------------- | -| 0 | `ZH_KERN` | Kernel messages | -| 1 | `ZH_USER` | User-level messages | -| 2 | `ZH_MAIL` | Mail system | -| 3 | `ZH_DAEMON` | System daemons | -| 4 | `ZH_AUTH` | Security/authorization messages | -| 5 | `ZH_SYSLOG` | Messages from syslogd internally | -| 6 | `ZH_LPR` | Line printer subsystem | -| 7 | `ZH_NEWS` | Network news subsystem | -| 8 | `ZH_UUCP` | UUCP subsystem | -| 9 | `ZH_CRON` | Cron subsystem | -| 10 | `ZH_AUTHPRIV` | Security/authorization messages (private) | -| 11 | `ZH_FTP` | FTP daemon | -| 12 | `ZH_NTP` | NTP subsystem | -| 13 | `ZH_SECURITY` | Log audit | -| 14 | `ZH_CONSOLE` | Log alert | -| 15 | `ZH_SOLARIS_CRON` | Scheduling daemon | -| 16-23 | `ZH_LOCAL0`-`ZH_LOCAL7` | Local/custom use facilities | - ---- - -### zh_syslog_severity_code_t Enum - -Standard syslog severity codes per RFC 5424 (0-7). - -**Values:** - -| Value | Enum | Description | -| ------- | ------ | ------------- | -| 0 | `ZH_EMERG` | System is unusable | -| 1 | `ZH_ALERT` | Action must be taken immediately | -| 2 | `ZH_CRIT` | Critical conditions | -| 3 | `ZH_ERR` | Error conditions | -| 4 | `ZH_WARNING` | Warning conditions | -| 5 | `ZH_NOTICE` | Normal but significant condition | -| 6 | `ZH_INFO` | Informational messages | -| 7 | `ZH_DEBUG` | Debug-level messages | - ---- - -### zh_syslog_init() - -Initializes the syslog client by creating a UDP socket and configuring the destination server address. - -**Parameters:** - -- `config` - Pointer to `zh_syslog_init_config_t` with syslog server address and port. Can point to a temporary variable. Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - Config pointer is NULL -- `ESP_FAIL` - Socket creation failed - -**Example:** - -```c -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) { - // Handle initialization error -} -``` - -**Note:** Network connection must be established before calling this function. The config pointer can be temporary. Must not be NULL - ---- - -### zh_syslog_deinit() - -Deinitializes the syslog client and releases resources. - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_STATE` - Client was not initialized - -**Note:** After calling this function, `zh_syslog_init()` must be called again before any subsequent `zh_syslog_send()` calls. - ---- - -### zh_syslog_send() - -Sends a formatted syslog message to the configured server. - -**Parameters:** - -- `facility` - Syslog facility code (0-23) from `zh_syslog_facility_code_t` -- `severity` - Syslog severity code (0-7) from `zh_syslog_severity_code_t` -- `hostname` - Pointer to device hostname (alphanumeric characters only, no spaces). Must not be NULL -- `app_name` - Pointer to application name (alphanumeric characters only, no spaces). Must not be NULL -- `message` - Pointer to the message payload string. Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - hostname, app_name, or message is NULL -- `ESP_ERR_INVALID_STATE` - Client was not initialized -- `ESP_ERR_NO_MEM` - Memory allocation failed (1024 bytes payload buffer) -- `ESP_FAIL` - UDP send operation failed - -**Example:** - -```c -zh_syslog_send(ZH_USER, ZH_INFO, "esp32_device", "my_app", "System started"); -``` - -**Note:** This function is not thread-safe. Caller must ensure mutual exclusion if multiple tasks may call this function concurrently. Message format follows RFC 5424: `1 timestamp hostname app-name procid msgid - message`. - ---- - -## Usage Examples - -### Basic Example: Initialize and Send Messages - -```c -#include "zh_syslog.h" - -void app_main(void) -{ - esp_log_level_set("zh_syslog", ESP_LOG_ERROR); - // Initialize configuration with defaults - zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT(); - strcpy(config.syslog_ip, "192.168.1.100"); // Set syslog server IP - // Initialize syslog client - esp_err_t ret = zh_syslog_init(&config); - if (ret != ESP_OK) - { - printf("Syslog initialization failed: %s\n", esp_err_to_name(ret)); - return; - } - // Send informational message - zh_syslog_send(ZH_USER, ZH_INFO, "my_device", "my_app", "Application started"); - // Send warning message - zh_syslog_send(ZH_USER, ZH_WARNING, "my_device", "my_app", "Low battery"); - // Send error message - zh_syslog_send(ZH_KERN, ZH_ERR, "my_device", "kernel", "Disk read error"); - // Deinitialize when done - zh_syslog_deinit(); -} -``` - ---- - -### Example: Wi-Fi Integration with Periodic Logging - -```c -#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 "your_ssid" -#define WIFI_PASS "your_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); - // Initialize syslog after Wi-Fi connection - zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT(); - strcpy(config.syslog_ip, "192.168.1.100"); - zh_syslog_init(&config); - // Send periodic log messages - for (int i = 0; i < 10; i++) { - char msg[64]; - snprintf(msg, sizeof(msg), "Heartbeat #%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); - } -} -``` - ---- - -### Example: Using Facility and Severity Codes - -```c -#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); - // Kernel critical error - zh_syslog_send(ZH_KERN, ZH_CRIT, "esp32", "kernel", "Out of memory"); - // User application warning - zh_syslog_send(ZH_USER, ZH_WARNING, "esp32", "app", "Sensor reading timeout"); - // Auth subsystem notice - zh_syslog_send(ZH_AUTH, ZH_NOTICE, "esp32", "auth", "User login successful"); - // Local facility for custom logging - zh_syslog_send(ZH_LOCAL0, ZH_DEBUG, "esp32", "debugger", "Variable state: 0x1234"); - zh_syslog_deinit(); -} -``` - ---- - -## Technical Specifications - -| Parameter | Value | -| ----------- | ------- | -| **Message Size** | 1024 bytes (fixed buffer) | -| **Transport Protocol** | UDP (SOCK_DGRAM) | -| **Default Port** | 514 | -| **Format Standard** | RFC 5424 | -| **Memory Allocation** | heap_caps_calloc (MALLOC_CAP_8BIT) | -| **Thread Safety** | Not thread-safe (caller responsibility) | -| **ESP-IDF Version** | >= 5.0 | -| **Platform** | ESP32 series | -| **Language** | C (C99) | - ---- - -## Error Codes - -| Error Code | Description | -| ------------ | ------------- | -| `ESP_OK` | Operation successful | -| `ESP_ERR_INVALID_ARG` | Invalid argument (NULL config pointer, NULL hostname/app_name/message) | -| `ESP_ERR_INVALID_STATE` | Client not initialized (zh_syslog_init not called) | -| `ESP_ERR_NO_MEM` | Memory allocation failed (out of memory for 1024-byte buffer) | -| `ESP_FAIL` | Socket creation failed or UDP send operation failed | - ---- - -## Contributing - -Contributions are welcome! To contribute: - -1. Fork the repository -2. Create a feature branch (`git checkout -b feature/AmazingFeature`) -3. Commit your changes (`git commit -m 'Add some AmazingFeature'`) -4. Push to the branch (`git push origin feature/AmazingFeature`) -5. Open a Pull Request - -Please ensure your code follows the existing style and includes appropriate documentation. - ---- - -## License - -This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file for details. - -### Apache License, Version 2.0 - -Copyright (c) 2026 Alexey Zholtikov - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - ---- - -## Additional Notes - -- **UDP Reliability**: This library uses UDP which does not guarantee message delivery. For reliable delivery, implement application-level acknowledgment -- **Performance**: O(n) for message formatting (n = message length). Send operation is blocking -- **Best Practices**: - - Always check return values from zh_syslog_init() and zh_syslog_send() - - Call zh_syslog_deinit() before application exit or module unload - - Use facility codes to categorize log sources (KERN for OS, USER for app, LOCAL0-7 for custom) - - Keep hostname and app_name alphanumeric (no spaces) per RFC 5424 - - Set appropriate log level filtering on the syslog server to avoid excessive traffic - ---- - -*Generated for zh_syslog v1.0.0* diff --git a/WIKI_RU.md b/WIKI_RU.md deleted file mode 100644 index 81d84c0..0000000 --- a/WIKI_RU.md +++ /dev/null @@ -1,398 +0,0 @@ -# zh_syslog — Компонент syslog UDP клиента для ESP-IDF - -## Содержание - -- [Обзор](#обзор) -- [Возможности](#возможности) -- [Установка](#установка) -- [Справочник API](#справочник-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) для точной категоризации журналов. - ---- - -## Возможности - -1. **Соответствие RFC 5424**: Сообщения форматируются в соответствии со стандартом syslog RFC 5424 -2. **Стандартные коды Facility**: Поддержка всех 24 стандартных кодов facility syslog (KERN, USER, DAEMON, LOCAL0-LOCAL7 и т.д.) -3. **Уровни важности**: Поддержка всех 8 стандартных уровней severity syslog (EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO, DEBUG) -4. **UDP транспорт**: Использует дейтаграммные сокеты для эффективной передачи журналов -5. **Память совместимая с DMA**: Использует выделения MALLOC_CAP_8BIT для потенциального использования DMA -6. **Структурированное логирование**: Включает поля hostname, app name и message в соответствии с RFC 5424 - ---- - -## Установка - -Перейдите в каталог компонентов вашего проекта: - -```bash -cd ../ваш_проект/components -``` - -Клонируйте репозиторий: - -```bash -git clone https://github.com/aZholtikov/zh_syslog -``` - -В вашем приложении подключите заголовочный файл: - -```c -#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 равен NULL -- `ESP_FAIL` — Создание сокета не удалось - -**Пример:** - -```c -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_t` -- `severity` — Код severity syslog (0-7) из `zh_syslog_severity_code_t` -- `hostname` — Указатель на имя устройства (только алфавитно-цифровые символы, без пробелов). Не должен быть NULL -- `app_name` — Указатель на имя приложения (только алфавитно-цифровые символы, без пробелов). Не должен быть NULL -- `message` — Указатель на строку содержимого сообщения. Не должен быть NULL - -**Возвращает:** - -- `ESP_OK` — Успех -- `ESP_ERR_INVALID_ARG` — hostname, app_name или message равен NULL -- `ESP_ERR_INVALID_STATE` — Клиент не инициализирован -- `ESP_ERR_NO_MEM` — Ошибка выделения памяти (буфер 1024 байта) -- `ESP_FAIL` — Операция отправки UDP не удалась - -**Пример:** - -```c -zh_syslog_send(ZH_USER, ZH_INFO, "esp32_device", "my_app", "Приложение запущено"); -``` - -**Примечание:** Эта функция не является потокобезопасной. Вызывающий должен обеспечить взаимное исключение, если несколько задач могут вызывать эту функцию одновременно. Формат сообщения соответствует RFC 5424: `1 timestamp hostname app-name procid msgid - message`. - ---- - -## Примеры использования - -### Базовый пример: Инициализация и отправка сообщений - -```c -#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 и периодическая отправка журналов - -```c -#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 - -```c -#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 не удалась | - ---- - -## Вклад в проект - -Вклад приветствуется! Чтобы внести свой вклад: - -1. Сделайте форк репозитория -2. Создайте ветку функции (`git checkout -b feature/AmazingFeature`) -3. Закоммитьте ваши изменения (`git commit -m 'Add some AmazingFeature'`) -4. Отправьте в ветку (`git push origin feature/AmazingFeature`) -5. Откройте Pull Request - -Пожалуйста, убедитесь, что ваш код следует существующему стилю и включает соответствующую документацию. - ---- - -## Лицензия - -Этот проект лицензирован по лицензии Apache, версия 2.0 - см. файл [LICENSE](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*