Здравствуйте,Коллеги!Имеется сервер мониторинга, на котором крутится в том числе Syslog-ng. Сетевое оборудование скидывает по Syslog события, на нем происходящие. И все хорошо, но вот есть несколько отечественных устройств (ФПСУ-IP), которые для описания события используют русский язык.
Syslog-сервер трактует эти сообщения в виде каракулей. Хочется, чтобы сообщения отображались в читаемом виде.1. К сожалению, не знаю какая должна быть использована кодировка для нормальной трактовки входящих сообщений. Знаю лишь то, что русские символы представлены однобайтовым кодом, и то, что в шестнадцатеричном виде слово "Изменение" имеет вид "88 a7 ac a5 ad a5 ad a8 a5" Можно ли как-то определить тип кодировки во входящем потоке?
2. Можно ли заставить syslog-ng корректно трактовать сообщения с кириллицей?
Большое спасибо!
> "88 a7 ac a5 ad a5 ad a8 a5" Можно ли
> как-то определить тип кодировки во входящем потоке?Можно. Я определил.
$ echo %88%a7%ac%a5%ad%a5%ad%a8%a5|sed 's/%/, 0x/g;s/^, //'|recode cp866/x..
> 2. Можно ли заставить syslog-ng корректно трактовать сообщения с кириллицей?
Какой фигни только не может случиться...
>> "88 a7 ac a5 ad a5 ad a8 a5" Можно ли
>> как-то определить тип кодировки во входящем потоке?
> Можно. Я определил.
> $ echo %88%a7%ac%a5%ad%a5%ad%a8%a5|sed 's/%/, 0x/g;s/^, //'|recode cp866/x..
>> 2. Можно ли заставить syslog-ng корректно трактовать сообщения с кириллицей?
> Какой фигни только не может случиться...iconv? Не, не слышал
>>> 2. Можно ли заставить syslog-ng корректно трактовать сообщения с кириллицей?
>> Какой фигни только не может случиться...
> iconv? Не, не слышалОн чем-то лучше recode?
А ты про перекодирование логов. А если там cp1251 в перемешку с 866? И utf8?... С разных хостов.
> 2. Можно ли заставить syslog-ng корректно трактовать сообщения с кириллицей?mkfifo /tmp/ififo;
while true;
do read line < /tmp/ififo;
echo $line | iconv -f cp866 -t utf8 >> /var/log/recoded.log;
done
source 866log { file("/var/log/russian_pribor.log"); };
destination iconv_pipe { pipe("/tmp/ififo"); };
log { source(866log); destination(iconv_pipe); };
>> 2. Можно ли заставить syslog-ng корректно трактовать сообщения с кириллицей?
> mkfifo /tmp/ififo;
> while true;
> do read line < /tmp/ififo;
> echo $line | iconv -f
> cp866 -t utf8 >> /var/log/recoded.log;
> done
> source 866log { file("/var/log/russian_pribor.log"); };
> destination iconv_pipe { pipe("/tmp/ififo"); };
> log { source(866log); destination(iconv_pipe); };Спасибо за советы. Всё попробовал - с переводом кодировки всё ок!
Насчет взаимодействия с syslog-ng - есть проблемы. Почему-то в recoded.log ничего не пишется. Модифицировал Ваш конфиг под свои нужды следующим образом:
source 866log { udp("0.0.0.0"); port(514) };
filter rus_host { host(10.10.10.10); };
destination iconv_pipe { pipe("/tmp/ififo"); };
log { source(866log); filter(rus_host); destination(iconv_pipe); };Пробовал вообще отключать фильтр
source 866log { udp("0.0.0.0"); port(514) };
destination iconv_pipe { pipe("/tmp/ififo"); };
log { source(866log); destination(iconv_pipe); };Безрезультатно.
Если же просто
echo "Test" > /tmp/ififo
то в recoded.log сообщение Test пишется, так что в целом pipe вроде как работает.
Права на pipe 666, на recoded.log тоже 666.Почему в оконечном логе recoded не оседают сообщения syslog.
Спасибо!
>[оверквотинг удален]
> destination iconv_pipe { pipe("/tmp/ififo"); };
> log { source(866log); destination(iconv_pipe); };
> Безрезультатно.
> Если же просто
> echo "Test" > /tmp/ififo
> то в recoded.log сообщение Test пишется, так что в целом pipe вроде
> как работает.
> Права на pipe 666, на recoded.log тоже 666.
> Почему в оконечном логе recoded не оседают сообщения syslog.
> Спасибо!Запустил службу в режиме отладки syslog-ng -Fevd и выяснил, что проблема с правами:
при попытке писать в пайп ругается
Error opening file for writing; filename ='/tmp/ififo', error='Permission denied(13)'Пробовал изменить права на 777, все равно та же ошибка...
>[оверквотинг удален]
>> то в recoded.log сообщение Test пишется, так что в целом pipe вроде
>> как работает.
>> Права на pipe 666, на recoded.log тоже 666.
>> Почему в оконечном логе recoded не оседают сообщения syslog.
>> Спасибо!
> Запустил службу в режиме отладки syslog-ng -Fevd и выяснил, что проблема с
> правами:
> при попытке писать в пайп ругается
> Error opening file for writing; filename ='/tmp/ififo', error='Permission denied(13)'
> Пробовал изменить права на 777, все равно та же ошибка...На тебе логгер с перекодировкой, и не мучайся.
Можно прикрутить чтоб он сам писал в свой файл, под UDP или через pipe,...
демона тоже можно.
/*
Висим на tcp/514 порту, пишем в stdout*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <error.h>
#include <netdb.h>
#include <wchar.h>
#include <iconv.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>int Cp866ToUTF8(int fd, char *outbuf) {
char inbuf[128] = {'0'};
char *wrptr = (char *) outbuf;
size_t nread;
iconv_t cd;
ssize_t avail;
char *inptr = inbuf;
cd = iconv_open("UTF-8", "CP866");
nread = read(fd, inbuf, sizeof (inbuf));
iconv(cd, &inptr, &nread, &wrptr, &avail);
iconv_close(cd);
return (char *) wrptr - outbuf;
}void *server_thread(void *ad) {
char out[128] = {0};
char time_buff[128] = {0};
struct tm tm;
time_t tme;
int fd = (int) (ssize_t) ad;Cp866ToUTF8(fd, out);
shutdown(fd, SHUT_RD);
(void) close(fd);tme = time(NULL);
localtime_r(&tme, &tm);
strftime(time_buff, sizeof (time_buff), "%d.%m.%Y %T", &tm);
printf("%s : ", time_buff);
printf("%s\n", out);return (NULL);
}int main(void) {
struct addrinfo hints;
struct addrinfo *addr_res;
pthread_attr_t pattr;
pthread_t pth;int res, fd;
ssize_t th_fd;hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_canonname = NULL;
hints.ai_addr = INADDR_ANY;
hints.ai_next = NULL;if ((fd = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol)) < 0) {
perror("socket()");
return (1);
}
if ((res = getaddrinfo(NULL, "syslog", &hints, &addr_res)) != 0) {
fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(res));
return (2);
}if (bind(fd, addr_res->ai_addr, addr_res->ai_addrlen) < 0) {
perror("bind()");
freeaddrinfo(addr_res);
return (3);
}
freeaddrinfo(addr_res);if (listen(fd, SOMAXCONN) < 0) {
perror("listen()");
return (4);
}if ((errno = pthread_attr_init(&pattr)) != 0) {
perror("pthread_attr_init()");
return (errno);
}pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
while (1) {
if ((th_fd = accept(fd, NULL, NULL)) < 0) {
perror("accept()");
return (6);
}
if ((errno =
pthread_create(&pth, &pattr, server_thread,
(void *) th_fd)) != 0) {
perror("pthread_create()");
return (errno);
}
}
return (0);
}