Продолжая тему ведения журналов событий и отладки, поговорим про Syslog. Это протокол передачи текстовых сообщений, прежде всего логов — сообщений о происходящих событиях, разработанный в 1980 году. Формат этого протокола очень прост и удобен, и практически не изменился за последние 35 лет.
Формат достаточно гибок, и предусматривает отправку как простых текстовых сообщений:
Use the BFG!
(но надо сказать что информативность в таких сообщениях практически отсутствует), так и более сложных, включающих в себя маркер уровня важности, метку времени и текстовый комментарий:
<13> Feb 5 17:32:18 10.0.0.9 Use the BFG!
Стандарт рассматривает также отправку ещё более сложных сообщений, в том числе со специальными указаниями для дальнейшей пересылки, но суть остаётся прежней — это всё то же текстовое сообщение не длиннее 1 килобайта, отправленное на порт 514 (UDP) / 6514 (UDP) или 601 (TCP) / 6514 (TCP).
Маркер важности
Очень важная фича, которая может помочь syslog-серверу правильно отреагировать на пришедшее сообщение — поместить его в нужную таблицу или запустить оповещение администратора системы, к примеру. Предусмотрены такие метки:
0 — Emergency, авария
1 — Alert, тревога
2 — Critical, критическая ошибка
3 — Error, ошибка
4 — Warning, предупреждение
5 — Notice, уведомление
6 — Info, информация
7 — Debug, отладка
Реализация
Таким образом, со стороны МК требуется лишь подключиться к Syslog-серверу (в случае TCP), нужным образом сформировать сообщение, и отправить его на сервер.
debug_socket.c:
char syslog_buffer[500] = { 0 };
extern struct in_addr ServerIP;
void SyslogSend(char* buf, int buf_len)
{
struct pbuf *p;
p = pbuf_alloc(PBUF_TRANSPORT, buf_len, PBUF_RAM);
if (p == NULL) return;
memcpy(p->payload, buf, buf_len);
struct ip_addr server;
//ServerIP
IP4_ADDR(&server,192,168,1,123);
udp_sendto(UDPSyslogSock, p, &server, 514);
pbuf_free(p);
}
void SyslogTransportInit()
{
UDPSyslogSock = udp_new();
udp_recv(UDPSyslogSock, NULL, NULL);
udp_bind(UDPSyslogSock, IP_ADDR_ANY, 514);
udp_connect(UDPSyslogSock, IP_ADDR_ANY, 514);
}
debug_socket.h:
extern char syslog_buffer[500];
extern int DebugBufLen;
extern char MACString[17];
extern unsigned long int dbg_msg_seq;
#define DEBUG_PRINTF(...) { \
if (fDebugConnected) { \
DebugBufLen += sprintf(&DebugBuffer[DebugBufLen], "
"); \
DebugBufLen += snprintf(&DebugBuffer[DebugBufLen], DEBUG_BUF_LEN - DebugBufLen - 1, __VA_ARGS__);\
} \
unsigned int len = sprintf(syslog_buffer, "%s:%lu:", MACString, dbg_msg_seq++); \
len += sprintf(&syslog_buffer[len], __VA_ARGS__); \
SyslogSend(syslog_buffer, len); \
}
На сервере я обычно использую syslog-ng, он умеет складывать пришедшие сообщения в текстовый файл или в базу данных, а также проставлять сообщениям временнУю метку (Timestamp), что избавляет МК от необходимости знать точное время, да и уменьшает трафик. Впрочем я думаю, это умеют все syslog-серверы.
И у вас всегда остаётся возможность обойтись стандартными средствами: линукс прямо из коробки умеет складывать syslog-сообщения, пришедшие по UDP на порт 514, в /var/log.
Пример применения
Мои устройства имеют отладочную telnet-консоль, и чтение информации с неё было неудобным — нет архива старых сообщений, для отладки требуется одновременная работа двух человек (один воспроизводит глюк, другой записывает лог), ну и просто putty не очень удобен для этого.
Telnet-консоль была сделана как в статье, и мне было достаточно просто переписать этот макрос немного иначе — теперь он вызывает функцию отправки данных в UDP/514. Также я добавляю к сообщению MAC-адрес устройства и номер сообщения (чтобы отследить ситуацию пропажи сообщений). На сервере работает скрипт на питоне, он разрезает сообщение и складывает принятое в БД.
На веб-интерфейсе сервера есть страница просмотра сообщений по приборам, с динамической подгрузкой AJAX-ом новых (в процессе появления) и более старых (при прокрутке списка) сообщений. Все отображаемые сообщения можно копировать для подробного анализа. Также есть разбиение по датам.
Объём записываемых данных достаточно велик — порядка 50 мегабайт/час с одного прибора, поэтому сделаны также средства logrotate: в конце дня данные за день архивируются, а архивы старше недели удаляются, потому что ошибки обычно принимаются в рассмотрение сразу после их появления.
В целом, можно подытожить что Syslog — простой и нетребовательный к ресурсам метод логирования событий, и если есть возможность — все события нужно не складировать на девайсе, а отправлять syslog-ом на компьютер, он большой и умный — разберётся
Свежие комментарии