ESPHome 2026.10.2
Loading...
Searching...
No Matches
esphome_syslog.cpp
Go to the documentation of this file.
1#include "esphome_syslog.h"
2
5#include "esphome/core/time.h"
6
7namespace esphome::syslog {
8
9// Map log levels to syslog severity using an array, indexed by ESPHome log level (1-7)
11 3, // NONE
12 3, // ERROR
13 4, // WARN
14 5, // INFO
15 6, // CONFIG
16 7, // DEBUG
17 7, // VERBOSE
18 7 // VERY_VERBOSE
19};
20
23 this, [](void *self, uint8_t level, const char *tag, const char *message, size_t message_len) {
24 static_cast<Syslog *>(self)->on_log(level, tag, message, message_len);
25 });
26}
27
28void Syslog::on_log(uint8_t level, const char *tag, const char *message, size_t message_len) {
29 this->log_(level, tag, message, message_len);
30}
31
32void Syslog::log_(const int level, const char *tag, const char *message, size_t message_len) const {
33 if (level > this->log_level_)
34 return;
35 // Syslog PRI calculation: facility * 8 + severity
36 int severity = 7;
37 if ((unsigned) level <= 7) {
38 severity = LOG_LEVEL_TO_SYSLOG_SEVERITY[level];
39 }
40 int pri = this->facility_ * 8 + severity;
41
42 size_t len = message_len;
43 // remove color formatting
44 if (this->strip_ && message[0] == 0x1B && len > 11) {
45 message += 7;
46 len -= 11;
47 }
48
49 // Build syslog packet on stack (508 bytes chosen as practical limit for syslog over UDP)
50 char packet[508];
51 size_t offset = 0;
52 // Write PRI - abort if this fails as packet would be malformed
53 offset = buf_append_printf(packet, sizeof(packet), 0, "<%d>", pri);
54 if (offset == 0) {
55 return; // PRI always produces at least "<0>" (3 chars), so 0 means error
56 }
57 auto now = this->time_->now();
58 if (this->format_ == SYSLOG_FORMAT_RFC5424) {
59 offset = buf_append_str(packet, sizeof(packet), offset, "1 ");
60
61 char timestamp[32];
62 size_t timestamp_len = now.is_valid() ? now.strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S%z") : 0;
63 if (timestamp_len == 24) {
64 // ESPTime formats the numeric offset as +HHMM. RFC 3339 requires +HH:MM.
65 timestamp[25] = '\0';
66 timestamp[24] = timestamp[23];
67 timestamp[23] = timestamp[22];
68 timestamp[22] = ':';
69 offset = buf_append_printf(packet, sizeof(packet), offset, "%s", timestamp);
70 } else {
71 offset = buf_append_str(packet, sizeof(packet), offset, "-");
72 }
73 offset = buf_append_printf(packet, sizeof(packet), offset, " %s %s - - - %.*s", App.get_name().c_str(), tag,
74 (int) len, message);
75 } else {
76 // RFC 3164 has no NILVALUE. If the clock is invalid, omit TIMESTAMP so a relay can add it.
77 if (now.is_valid()) {
78 offset += now.strftime(packet + offset, sizeof(packet) - offset, "%b %e %H:%M:%S ");
79 }
80 offset = buf_append_printf(packet, sizeof(packet), offset, "%s %s: %.*s", App.get_name().c_str(), tag, (int) len,
81 message);
82 }
83 // Clamp to exclude null terminator position if buffer was filled
84 if (offset >= sizeof(packet)) {
85 offset = sizeof(packet) - 1;
86 }
87
88 if (offset > 0) {
89 this->parent_->send_packet(reinterpret_cast<const uint8_t *>(packet), offset);
90 }
91}
92
93} // namespace esphome::syslog
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
constexpr const char * c_str() const
Definition string_ref.h:77
void add_log_callback(void *instance, void(*fn)(void *, uint8_t, const char *, const char *, size_t))
Register a log callback to receive log messages.
Definition logger.h:192
time::RealTimeClock * time_
void log_(int level, const char *tag, const char *message, size_t message_len) const
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len)
ESPTime now()
Get the time in the currently defined timezone.
void send_packet(const uint8_t *data, size_t size)
const LogString * message
Definition component.cpp:35
Logger * global_logger
Definition logger.cpp:274
constexpr int LOG_LEVEL_TO_SYSLOG_SEVERITY[]
size_t buf_append_str(char *buf, size_t size, size_t pos, const char *str)
Safely append a string to buffer, returning new position (capped at size).
Definition helpers.h:1235
const void size_t len
Definition hal.h:64
Application App
Global storage of Application pointer - only one Application can exist.
uint16_t timestamp
Definition tt21100.cpp:2