Централизованный сбор и анализ логово с помощью syslog-ng,td-agent,elasticsearch,kibana,grafana,elasticalert

В этой статье я задался целью раз и навсегда разрешить все вопросы по централизованному сбору логов, их визуализации, отправки уведомление по наступившим событиям, настройке форматов логов и предоставление докер контейнер, которые облегчат эти задачи для всех кто с этим столкнется.

Содержание

 

  • 1. Настраиваем кластер для сбора логов на основе syslog-ng,elasticsearch,kibana,graphana,elasticalert
  • 2. Настраиваем агенты на клиентах и форматы логов для отправки в агрегатор
  • 3. Различные сниппеты по логам
  • 4. Исправление ошибок
  • 5. Syslog-ng module incubator
  • 6. Запросы в kibana
  • 7. Syslog-ng alerts на события

 

Настраиваем кластер для сбора логов на основе syslog-ng,elasticsearch,kibana,graphana,elasticalert

Наш кластер будет состоять из 4 нод.

10.9.3.210 	elasticsearch-node1 elasticnode1
10.9.3.211      elasticsearch-node2 elasticnode2
10.9.3.212      elasticsearch-node3 elasticnode3
10.9.3.213      elasticsearch-node3 elasticnode4

1 нода – elasticsearch master нода, syslog-ng агрегатор логов, kibana и graphana для визуализации логов, elasticalert для реагирования на события по логам(например большого количества 500 ошибок nginx в определенный период времени).
2 нода – elasticsearch data нода
3 нода – elasticsearch data нода
4 нода – elasticsearch data нода(это уже как хотите)
На всех нодах установлена debian 8 с ядром 4.9.0. Как показала практика одна из стабильных связок.

Установка syslog-ng

Удаляем rsyslog

sudo systemctl disable rsyslog
sudo systemctl stop rsyslog

Ставим необхдимые системные пакеты

apt-get install apt-transport-https -y

Ставим java на debian 8

apt-get update && apt-get install -t jessie-backports openjdk-8-jre-headless  -y
 apt-get install -t jessie-backports openjdk-8-jre-headless  -y
update-java-alternatives --set java-1.8.0-openjdk-amd64

Ставим java на ubuntu

 sudo apt-get install openjdk-8-jre-headless -y

Устанавливаем переменную окружения

Правим файл

/etc/default/syslog-ng

Добавляем

LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server:$LD_LIBRARY_PATH

Делаем Export – для того чтобы дебажить через запуска без демона

export LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server:$LD_LIBRARY_PATH

Ставим syslog-ng последней версии на debian 8. Можем собрать из исходников

wget http://ftp.ru.debian.org/debian/pool/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb && dpkg -i libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb
wget http://ftp.ru.debian.org/debian/pool/main/j/json-c/libjson-c2_0.11-4_amd64.deb && dpkg -i libjson-c2_0.11-4_amd64.deb
wget -qO - http://download.opensuse.org/repositories/home:/laszlo_budai:/syslog-ng/Debian_8.0/Release.key | sudo apt-key add -
echo "deb http://download.opensuse.org/repositories/home:/laszlo_budai:/syslog-ng/Debian_8.0 ./" >> /etc/apt/sources.list.d/syslog-ng-obs.list
apt-get update
apt-get install -y syslog-ng-core syslog-ng-mod-pgsql libdbd-pgsql syslog-ng-mod-elastic

Ставим syslog-ng последней версии на ubuntu 16.04

sudo su
wget http://nl.archive.ubuntu.com/ubuntu/pool/main/j/json-c/libjson-c3_0.12.1-1.1_amd64.deb && dpkg -i libjson-c3_0.12.1-1.1_amd64.de
wget -qO - http://download.opensuse.org/repositories/home:/laszlo_budai:/syslog-ng/Debian_8.0/Release.key | sudo apt-key add -
echo "deb http://download.opensuse.org/repositories/home:/laszlo_budai:/syslog-ng/xUbuntu_16.10 ./" >> /etc/apt/sources.list.d/syslog-ng-obs.list
apt-get update
apt-get install syslog-ng-core syslog-ng-mod-pgsql libdbd-pgsql syslog-ng-mod-elastic

Ставим последний elasticsearch и kibana на все ноды

wget http://ftp.ru.debian.org/debian/pool/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb && dpkg -i libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb
 wget http://ftp.ru.debian.org/debian/pool/main/j/json-c/libjson-c2_0.11-4_amd64.deb && dpkg -i libjson-c2_0.11-4_amd64.deb
 echo "deb http://http.debian.net/debian jessie-backports main" >> /etc/apt/sources.list.d/jessie-backports.list
 apt-get update && apt-get install -t jessie-backports openjdk-8-jre-headless  -y
 update-java-alternatives --set java-1.8.0-openjdk-amd64
 wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
 echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" >> /etc/apt/sources.list.d/elastic-5.x.list
 apt-get update &&  apt-get install elasticsearch  kibana -y
 echo "LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server:$LD_LIBRARY_PATH" >> /root/.profile
 echo "LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server:$LD_LIBRARY_PATH" >> ~/.bash_profile
 mkdir /elasticsearchdata/ && chown -R elasticsearch:elasticsearch /elasticsearchdata/
update-rc.d elasticsearch defaults 95 10
sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable elasticsearch.service

Правим системные файлы.

Правим limits.conf

nano /etc/security/limits.conf
        *          hard  memlock   unlimited
        *          soft  memlock   unlimited
        root       soft  nproc     unlimited
        root       soft  nofile    65536
        root       hard  nofile    65536
        *          soft  nofile    65536
        *          hard  nofile    65536
        *          -     nofile    999999
elasticsearch    soft    nofile          65535
elasticsearch    hard    nofile          65535
elasticsearch    soft    memlock         unlimited
elasticsearch    hard    memlock         unlimited

Правим sysctl.conf

nano /etc/sysctl.conf
vm.swappiness=1
vm.max_map_count=262144
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_wmem = 4096 262144 4194304
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_tw_reuse  =  1
net.ipv4.tcp_tw_recycle  =  1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_rmem = 4096 262144 4194304
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_mem = 50576   64768   98152
net.ipv4.tcp_max_syn_backlog = 65536
net.ipv4.tcp_max_orphans = 65536
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 20
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_congestion_control = htcp
net.ipv4.tcp_adv_win_scale = 2
net.ipv4.route.flush = 1
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.ip_forward = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_echo_ignore_all = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.core.wmem_default = 65536
net.core.somaxconn = 65535
net.core.rmem_default = 65536
net.core.netdev_max_bacтlog = 100000
kernel.sem = 350 358400 64 1024
fs.inotify.max_user_watches = 67108864
fs.file-max = 518144

настраиваем kibana и elasticsearch

НАстроим на макимальное использование памяти
в /usr/lib/systemd/system/elasticsearch.service

[Service]
LimitMEMLOCK=infinityy

И

systemctl daemon-reload

Отредактируем файл на всех нодах

 nano /etc/elasticsearch/jvm.options

Блок – делаем половину озу – у меня 12 – поставил 6

# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space
-Xms6g
-Xmx6g

Конфиг master ноды elasticsearch

nano /etc/elasticsearch/elasticsearch.yml
## Default Elasticsearch configuration from elasticsearch-docker.
## from https://github.com/elastic/elasticsearch-docker/blob/master/build/elasticsearch/elasticsearch.yml
#
network.host: 0.0.0.0
cluster.name: "production"
node.name: elasticnode1
discovery.zen.ping.unicast.hosts: ["elasticnode1", "elasticnode2", "elasticnode3"]
# avoid swapping the Elasticsearch
bootstrap.memory_lock: true
###Make node master - non data
node.master: true
node.data: false
# minimum_master_nodes need to be explicitly set when bound on a public IP
discovery.zen.minimum_master_nodes: 1
path.data: /elasticsearchdata/
#
# Path to log files:
#
#path.logs: /path/to/logs
## Use single node discovery in order to disable production mode and avoid bootstrap checks
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
#
#discovery.type: single-node
## Disable X-Pack
## see https://www.elastic.co/guide/en/x-pack/current/xpack-settings.html
##     https://www.elastic.co/guide/en/x-pack/current/installing-xpack.html#xpack-enabling
#
#xpack.security.enabled: false
#xpack.monitoring.enabled: false
#xpack.ml.enabled: false
#xpack.graph.enabled: false
#xpack.watcher.enabled: false
rm -rf /var/lib/elasticsearch/*
/etc/init.d/elasticsearch restart

Смотрим здоровье и статус кластера

curl -XGET 'http://elastinode1:9200/_cluster/state?pretty'
curl http://elastinode:9200/_nodes/process?pretty
Следующая команда должна показать
curl -XGET 'http://localhost:9200/_cluster/health'

Такой вывод

{"cluster_name":"production","status":"green","timed_out":false,"number_of_nodes":4,"number_of_data_nodes":3,"active_primary_shards":41,"active_shards":82,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":0,"delayed_unassigned_shards":0,"number_of_pending_tasks":0,"number_of_in_flight_fetch":0,"task_max_waiting_in_queue_millis":0,"active_shards_percent_as_number":100.0}

Конфиг dataноды elasticsearch elasticnode2

nano /etc/elasticsearch/elasticsearch.yml
---
## Default Elasticsearch configuration from elasticsearch-docker.
## from https://github.com/elastic/elasticsearch-docker/blob/master/build/elasticsearch/elasticsearch.yml
#
network.host: 0.0.0.0
cluster.name: "production"
node.name: elasticnode2
discovery.zen.ping.unicast.hosts: ["elasticnode1", "elasticnode2", "elasticnode3"]
# avoid swapping the Elasticsearch
bootstrap.memory_lock: true
###Make node master - non data
node.master: false
node.data: true
# minimum_master_nodes need to be explicitly set when bound on a public IP
discovery.zen.minimum_master_nodes: 1
path.data: /elasticsearchdata/
#
# Path to log files:
#
#path.logs: /path/to/logs
## Use single node discovery in order to disable production mode and avoid bootstrap checks
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
#
#discovery.type: single-node
## Disable X-Pack
## see https://www.elastic.co/guide/en/x-pack/current/xpack-settings.html
##     https://www.elastic.co/guide/en/x-pack/current/installing-xpack.html#xpack-enabling
#
#xpack.security.enabled: false
#xpack.monitoring.enabled: false
#xpack.ml.enabled: false
#xpack.graph.enabled: false
#xpack.watcher.enabled: false

Конфиг dataноды elasticsearch elasticnode3

nano /etc/elasticsearch/elasticsearch.yml
---
## Default Elasticsearch configuration from elasticsearch-docker.
## from https://github.com/elastic/elasticsearch-docker/blob/master/build/elasticsearch/elasticsearch.yml
#
network.host: 0.0.0.0
cluster.name: "production"
node.name: elasticnode3
discovery.zen.ping.unicast.hosts: ["elasticnode1", "elasticnode2", "elasticnode3"]
# avoid swapping the Elasticsearch
bootstrap.memory_lock: true
###Make node master - non data
node.master: false
node.data: true
# minimum_master_nodes need to be explicitly set when bound on a public IP
discovery.zen.minimum_master_nodes: 1
path.data: /elasticsearchdata/
#
# Path to log files:
#
#path.logs: /path/to/logs
## Use single node discovery in order to disable production mode and avoid bootstrap checks
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
#
#discovery.type: single-node
## Disable X-Pack
## see https://www.elastic.co/guide/en/x-pack/current/xpack-settings.html
##     https://www.elastic.co/guide/en/x-pack/current/installing-xpack.html#xpack-enabling
#
#xpack.security.enabled: false
#xpack.monitoring.enabled: false
#xpack.ml.enabled: false
#xpack.graph.enabled: false
#xpack.watcher.enabled: false

Конфиг kibana

 nano /etc/kibana/kibana.yml
---
---
## Default Kibana configuration from kibana-docker.
## from https://github.com/elastic/kibana-docker/blob/master/build/kibana/config/kibana.yml
#
server.name: kibana.local
server.host: "0"
elasticsearch.url: http://elasticnode1:9200
## Disable X-Pack
## see https://www.elastic.co/guide/en/x-pack/current/xpack-settings.html
##     https://www.elastic.co/guide/en/x-pack/current/installing-xpack.html#xpack-enabling
#
xpack.security.enabled: false
xpack.security.enabled: false
xpack.monitoring.enabled: false
xpack.ml.enabled: false
xpack.graph.enabled: false
xpack.reporting.enabled: false

Рестартуес сервисы

/etc/init.d/elasticsearch restart
/etc/init.d/kibana restart

Подготовка формата логов nginx,php и nodejs

Настройка формата логов в nginx

Ставим nginx mainline с GEOIP или собираем из исходников. Проблем не будет.

wget http://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key
echo "deb http://nginx.org/packages/mainline/debian/ jessie nginx" >> /etc/apt/sources.list.d/nginx.list
echo "deb-src http://nginx.org/packages/mainline/debian/ jessie nginx" >> /etc/apt/sources.list.d/nginx.list
apt-get update
apt install -y nginx-module-geoip nginx -y

Скачиваем бызы geoip и рапаковываем

mkdir -p /etc/nginx/GEO
cd /etc/nginx/GEO
wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoIP.dat.gz
gunzip GeoLiteCity.dat.gz
nano /etc/nginx/nginx.conf

Добавляем формат логов и включаем запись их в файлы

###В самую верхнюю секцию
load_module /usr/lib/nginx/modules/ngx_http_geoip_module.so;
load_module /usr/lib/nginx/modules/ngx_stream_geoip_module.so;
##В секцию http {
geoip_country /etc/nginx/GEO/GeoIP.dat;
geoip_city    /etc/nginx/GEO/GeoLiteCity.dat
proxy_set_header GEOIP_COUNTRY_CODE $geoip_country_code;
proxy_set_header GEOIP_COUNTRY_CODE3 $geoip_country_code3;
proxy_set_header GEOIP_COUNTRY_NAME $geoip_city_country_name;
proxy_set_header GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code;
proxy_set_header GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3;
proxy_set_header GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name;
proxy_set_header GEOIP_REGION $geoip_region;
proxy_set_header GEOIP_CITY $geoip_city;
proxy_set_header GEOIP_POSTAL_CODE $geoip_postal_code;
proxy_set_header GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code;
proxy_set_header GEOIP_LATITUDE $geoip_latitude;
proxy_set_header GEOIP_LONGITUDE $geoip_longitude;
log_format logtodb '"$time_iso8601"|"$http_host"|"$remote_addr"|"$http_x_forwarded_for"|"$request_method"|"$request"|"$status"|"$body_bytes_sent"|"$http_referer"|"$request_time"|"$upstream_http_x_cache"|"$uri"|"$upstream_addr"|"$host"|"$upstream_response_length"|"$upstream_status"|"$server_name"|"$http_host"|"$upstream_response_time"|"$upstream_cache_status"|"$http_user_agent"';
log_format full_format '"$time_iso8601"|"$http_host"|"$remote_addr"|"$http_x_forwarded_for"|"$request_method"|"$request"|"$status"|"$body_bytes_sent"|"$http_referer"|"$request_time"|"$upstream_http_x_cache"|"$uri"|"$upstream_addr"|"$host"|"$upstream_response_length"|"$upstream_status"|"$server_name"|"$http_host"|"$upstream_response_time"|"$upstream_cache_status"|"$http_user_agent"|"$geoip_city"|"$geoip_country_name"|"$geoip_region"|"$cookie_COOKIE"';
access_log /var/log/nginx/access_logtodb.log logtodb;
access_log /var/log/nginx/access_main.log full_format;
error_log /var/log/nginx/error.log;

Настройка логов php – отправка их в nginxerror.log

Добаляем в конфиг, например у мея это

nano /php/7.0/fpm/pool.d/itc-life.ru.conf
 catch_workers_output = yes
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/fpm-php.www.log
php_admin_flag[log_errors] = on

Таким образом логи ошибок будут php будут попадать в nginx error log.
Идем далее.

Настройка формата логов nodejs, запускаемой через pm2

Делаем запуск с такими параметрами

pm2 start server.js --merge-logs --log-type=json --log-date-format="YYYY-MM-DD HH:mm Z" -i 4 --watch --max-memory-restart 1200M

Логи будет писаться в одну строку в json формате. Хотя это г. все равно не пишет логи как надо – выскакивает из json.

На этом подготовка формата логов окончена
Настраиваем syslog-ng на отправку логов nginx,php и nodejs через udp или tcp на сервер логов

Приведем syslog-ng к определенному виду. У нас на текущий момент версия 3.12

nano/etc/syslog-ng/syslog-ng.conf
@version: 3.12
@include "scl.conf"
#@module mod-java
# Настраиваем глобальные параметры
options {
chain_hostnames(off);
log_fifo_size(1000);
use_dns(no);
use_fqdn(no);
owner("root");
group("adm");
perm(0640);
stats_freq(0);
bad_hostname("^gconfd$");
};
@include "/etc/syslog-ng/conf.d/*.conf"

Все конфиги будем инклудить для удобства через conf.d. Конфиг для парсинга созданных нами логов и отправки их на сервер. Шлем по udp и tcp – кому как нравиться – tcp с флагом flow-control – контроль очереди на приемнике.

 nano /etc/syslog-ng/conf.d/output.conf
#####################################################################################################################
####Отправка логов на сервер
destination tcp_server_nginx_access {
 tcp("elasticnode1" port(25214));
 };
destination tcp_server_nginx_error {
 tcp("elasticnode1" port(25215));
 };
destination tcp_server_nodejs {
 tcp("elasticnode1" port(25216));
 };
####Отправка логов на сервер
destination udp_server_nginx_access {
 udp("elasticnode1" port(25214));
 };
destination udp_server_nginx_error {
 udp("elasticnode1" port(25215));
 };
destination udp_server_nodejs {
 udp("elasticnode1" port(25216));
 };
#########################################################################
###### Источник с логами nginx access##################
source s_tail_nginx_access_log { file( "/var/log/nginx/access_logtodb.log"
                    follow_freq(1)
                    flags(no-parse)
     );
};
###########################################################################################################
###### Источник с логами nginx error##################
source s_tail_nginx_error  { file( "/var/log/nginx/error.log"
                    follow_freq(1)
                    flags(no-parse)
     );
};
###########################################################################################################
####Источник с логами nodejs
source s_tail_node  { file( "/root/.pm2/logs/server-error.log"
                    follow_freq(1)
                    flags(no-parse)
     );
};
###Отпарвляем все источники на сервер - там их будем парсить и писать в нужные базы.
log {source(s_tail_nginx_access_log);  destination(udp_server_nginx_access); };
log {source(s_tail_nginx_error ); destination(udp_server_nginx_error);};
log {source(s_tail_node); destination(udp_server_nodejs);};
log {source(s_tail_nginx_access_log);  destination(tcp_server_nginx_access); flags(flow-control);};
log {source(s_tail_nginx_error ); destination(tcp_server_nginx_error);flags(flow-control);};
log {source(s_tail_node); destination(tcp_server_nodejs);flags(flow-control);};

Далее отдельным файлом выделим файл access с geoip. В принципе можете оставить только его.

 nano /etc/syslog-ng/conf.dudp_remote_log_host_nginx_main.conf
#####################################################################################################################
#####################################################################################################################
####Отправка логов на сервер
destination udp_remote_log_host_nginx_main {
 udp("elasticnode1" port(25230));
 };
#########################################################################
###### Источник с логами nginx access##################
source s_tail_log_host_nginx_main { file( "/var/log/nginx/access_main.log"
                    follow_freq(1)
                    flags(no-parse)
     );
};
###Отпарвляем все источники на сервер - там их будем парсить и писать в нужные базы.
log {source(s_tail_log_host_nginx_main); destination(udp_remote_log_host_nginx_main);};

Далее отдельным файлом выделим стандартные системные логи

nano /etc/syslog-ng/conf.d/system.logs.conf

Вставляем содержимое

########################
# Sources
########################
# This is the default behavior of sysklogd package
# Logs may come from unix stream, but not from another machine.
#
source s_src {
       system();
       internal();
};
# If you wish to get logs from remote machine you should uncomment
# this and comment the above source line.
#
#source s_net { tcp(ip(127.0.0.1) port(1000)); };
########################
# Destinations
########################
# First some standard logfile
#
destination d_auth { file("/var/log/auth.log"); };
destination d_cron { file("/var/log/cron.log"); };
destination d_daemon { file("/var/log/daemon.log"); };
destination d_kern { file("/var/log/kern.log"); };
destination d_lpr { file("/var/log/lpr.log"); };
destination d_mail { file("/var/log/mail.log"); };
destination d_syslog { file("/var/log/syslog"); };
destination d_user { file("/var/log/user.log"); };
destination d_uucp { file("/var/log/uucp.log"); };
# This files are the log come from the mail subsystem.
#
destination d_mailinfo { file("/var/log/mail.info"); };
destination d_mailwarn { file("/var/log/mail.warn"); };
destination d_mailerr { file("/var/log/mail.err"); };
# Logging for INN news system
#
destination d_newscrit { file("/var/log/news/news.crit"); };
destination d_newserr { file("/var/log/news/news.err"); };
destination d_newsnotice { file("/var/log/news/news.notice"); };
# Some 'catch-all' logfiles.
#
destination d_debug { file("/var/log/debug"); };
destination d_error { file("/var/log/error"); };
destination d_messages { file("/var/log/messages"); };
# The root's console.
#
destination d_console { usertty("root"); };
# Virtual console.
#
destination d_console_all { file(`tty10`); };
# The named pipe /dev/xconsole is for the nsole' utility.  To use it,
# you must invoke nsole' with the -file' option:
#
#    $ xconsole -file /dev/xconsole [...]
#
destination d_xconsole { pipe("/dev/xconsole"); };
# Send the messages to an other host
#
#destination d_net { tcp("127.0.0.1" port(1000) log_fifo_size(1000)); };
# Debian only
destination d_ppp { file("/var/log/ppp.log"); };
########################
# Filters
########################
# Here's come the filter options. With this rules, we can set which
# message go where.
filter f_dbg { level(debug); };
filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_err { level(err); };
filter f_crit { level(crit .. emerg); };
filter f_debug { level(debug) and not facility(auth, authpriv, news, mail); };
filter f_error { level(err .. emerg) ; };
filter f_messages { level(info,notice,warn) and
                    not facility(auth,authpriv,cron,daemon,mail,news); };
filter f_auth { facility(auth, authpriv) and not filter(f_debug); };
filter f_cron { facility(cron) and not filter(f_debug); };
filter f_daemon { facility(daemon) and not filter(f_debug); };
filter f_kern { facility(kern) and not filter(f_debug); };
filter f_lpr { facility(lpr) and not filter(f_debug); };
filter f_local { facility(local0, local1, local3, local4, local5,
                        local6, local7) and not filter(f_debug); };
filter f_mail { facility(mail) and not filter(f_debug); };
filter f_news { facility(news) and not filter(f_debug); };
filter f_syslog3 { not facility(auth, authpriv, mail) and not filter(f_debug); };
filter f_user { facility(user) and not filter(f_debug); };
filter f_uucp { facility(uucp) and not filter(f_debug); };
filter f_cnews { level(notice, err, crit) and facility(news); };
filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); };
filter f_ppp { facility(local2) and not filter(f_debug); };
filter f_console { level(warn .. emerg); };
########################
# Log paths
########################
########################
# SSh logins logs
########################
destination tcp_remote_log_host_ssh {
 tcp("elasticnode1" port(40514));
 };
destination udp_remote_log_host_ssh {
 udp("elasticnode1" port(40514));
 };
log { source(s_src); filter(f_auth); destination(d_auth); };
log { source(s_src); filter(f_auth); destination(udp_remote_log_host_ssh); };
########################
# crons logs
########################
destination tcp_remote_log_host_crons {
 tcp("elasticnode1" port(40515));
 };
destination udp_remote_log_host_crons  {
 udp("elasticnode1" port(40515));
 };
log { source(s_src); filter(f_cron); destination(udp_remote_log_host_crons); };
########################
# daemon logs
########################
destination tcp_remote_log_host_daemon {
 tcp("elasticnode1" port(40516));
 };
destination udp_remote_log_host_daemon  {
 udp("elasticnode1" port(40516));
 };
log { source(s_src); filter(f_daemon); destination(udp_remote_log_host_daemon); };
########################
# kern logs
########################
destination tcp_remote_log_host_kern {
 tcp("elasticnode1" port(40517));
 };
destination udp_remote_log_host_kern  {
 udp("elasticnode1" port(40517));
 };
log { source(s_src); filter(f_kern); destination(udp_remote_log_host_kern); };
########################
# user logs
########################
destination tcp_remote_log_host_user {
 tcp("elasticnode1" port(40518));
 };
destination udp_remote_log_host_user  {
 udp("elasticnode1" port(40518));
 };
log { source(s_src); filter(f_user); destination(udp_remote_log_host_user); };
########################
#  lpr logs
########################
destination tcp_remote_log_host_lpr {
 tcp("elasticnode1" port(40519));
 };
destination udp_remote_log_host_lpr {
 udp("elasticnode1" port(40519));
 };
log { source(s_src); filter(f_lpr); destination(udp_remote_log_host_lpr); };
########################
#  syslog logs
########################
destination tcp_remote_log_host_syslog {
 tcp("elasticnode1" port(40520));
 };
destination udp_remote_log_host_syslog {
 udp("elasticnode1" port(40520));
 };
log { source(s_src); filter(f_syslog3); destination(udp_remote_log_host_syslog ); };
########################
#  uucp logs
########################
destination tcp_remote_log_host_uucp {
 tcp("elasticnode1" port(40521));
 };
destination udp_remote_log_host_uucp {
 udp("elasticnode1" port(40521));
 };
log { source(s_src); filter(f_uucp); destination(udp_remote_log_host_uucp ); };
########################
#  mail logs
########################
destination tcp_remote_log_host_mail {
 tcp("elasticnode1" port(40522));
 };
destination udp_remote_log_host_mail {
 udp("elasticnode1" port(40522));
 };
log { source(s_src); filter(f_mail); destination(udp_remote_log_host_mail); };
########################
#  messages logs
########################
destination tcp_remote_log_host_messages {
 tcp("elasticnode1" port(40523));
 };
destination udp_remote_log_host_messages{
 udp("elasticnode1" port(40523));
 };
log { source(s_src); filter(f_messages); destination(udp_remote_log_host_messages); };
########################
#  debug logs
########################
destination tcp_remote_log_host_debug {
 tcp("elasticnode1" port(40524));
 };
destination udp_remote_log_host_debug {
 udp("elasticnode1" port(40524));
 };
log { source(s_src); filter(f_debug); destination(udp_remote_log_host_debug); };
log { source(s_src); filter(f_debug); destination(d_debug); };
########################
#  error logs
########################
destination tcp_remote_log_host_error {
 tcp("elasticnode1" port(40525));
 };
destination udp_remote_log_host_error {
 udp("elasticnode1" port(40525));
 };
log { source(s_src); filter(f_error); destination(udp_remote_log_host_error); };
###Неактивные за отсутствием
log { source(s_src); filter(f_ppp); destination(d_ppp); };
log { source(s_src); filter(f_news); filter(f_crit); destination(d_newscrit); };
log { source(s_src); filter(f_news); filter(f_err); destination(d_newserr); };
log { source(s_src); filter(f_news); filter(f_notice); destination(d_newsnotice); };
log { source(s_src); filter(f_error); destination(d_error); };
### Системные
log { source(s_src); filter(f_console); destination(d_console_all); destination(d_xconsole); };
log { source(s_src); filter(f_crit); destination(d_console); };
Проверяем – запускаем с выводом и дебагом
sudo /usr/sbin/syslog-ng -Fvde

Если всё ок – стартуем syslog-ng, но только после того как настроим прием логов на сервере.

sudo /etc/init.d/syslog-ng start

Настраиваем syslog-ng сервер на прием логов nginx,php и nodejs через udp и отправку их в elasticsearch и postgresql. Так же настроим прием системных логов и отправку их в elasticsearch

Приведем syslog-ng к определенному виду. У нас на текущий момент версия 3.12

nano/etc/syslog-ng/syslog-ng.conf
@version: 3.12
@include "scl.conf"
@module mod-java
# Настраиваем глобальные параметры
options {
chain_hostnames(off);
log_fifo_size(1000000);
use_dns(no);
use_fqdn(no);
owner("root");
group("adm");
perm(0640);
stats_freq(0);
bad_hostname("^gconfd$");
};
@include "/etc/syslog-ng/conf.d/*.conf"

Так же как и на клиентах, все конфиги будем инклудить для удобства через conf.d.

Примечание. Также включаем прием по tcp – как показала практика, udp иногда падает – решения с форумов и от разработчиков не помогло.

 nano /etc/syslog-ng/conf.d/input.conf
#####################################################################################################################
#####################################################################################################################
##Прием логов nginx access  с удаленных машин  на порт udp
source remote_log_host_nginx_access_udp  {
 udp(port(25214)so_rcvbuf(16777216) log_iw_size(10000) log_fetch_limit(1000000));
};
##Прием логов nginx access  с удаленных машин  на порт tcp
source remote_log_host_nginx_access_tcp {
 tcp(port(25214) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200));
};
#####################################################################################################################
#####################################################################################################################
###Парсим логи nginx access по столбцам из csv
parser p_remote_log_host_nginx_access {
    csv-parser(columns("NGINX_TIME", "NGINX_http_host", "NGINX_remote_addr", "NGINX_http_x_forwarded_for", "NGINX_request", "NGINX_request_method","NGINX_status", "NGINX_body_bytes_sent", "NGINX_http_referer", "NGINX_request_time", "NGINX_upstream_http_x_cache", "NGINX_uri", "NGINX_upstream_addr", "NGINX_host", "NGINX_upstream_response_length", "NGINX_upstream_status", "NGINX_server_name", "NGINX_newurl", "NGINX_upstream_response_time", "NGINX_user_agent")
         flags(escape-double-char,strip-whitespace)
         delimiters("|")
         quote-pairs('""[]')
         );
};
#####################################################################################################################
#####################################################################################################################
###Направляем nginx_acess в elasticsearch
destination d_elastic_nginx_access {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("nginxaccess-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
#Направляем в postgres
destination d_postgres_nginx_access {
  sql(type(pgsql)
  host("elasticnode1")  port("15432") username("postgres") password("mysecretpassword")
  database("nginx_access")
  table("DATE_${R_YEAR}_${R_MONTH}_nginx_access")
  columns("HOST text", "NGINX_TIME text", "NGINX_http_host text", "NGINX_remote_addr text", "NGINX_http_x_forwarded_for text", "NGINX_request_method text", "NGINX_request text", "NGINX_status text",  "NGINX_body_bytes_sent text",  "NGINX_http_referer text", "NGINX_request_time text", "NGINX_upstream_http_x_cache text", "NGINX_uri text", "NGINX_upstream_addr text",  "NGINX_host  text", "NGINX_upstream_response_length text", "NGINX_upstream_status text", "NGINX_server_name text", "NGINX_newurl text", "NGINX_upstream_response_time text", "NGINX_user_agent text")
  values("$HOST", "${NGINX_TIME}", "${NGINX_http_host}", "${NGINX_remote_addr}", "${NGINX_http_x_forwarded_for}", "${NGINX_request_method}", "${NGINX_request}", "${NGINX_status}", "${NGINX_body_bytes_sent}", "${NGINX_http_referer}", "${NGINX_request_time}", "${NGINX_upstream_http_x_cache}", "${NGINX_uri}", "${NGINX_upstream_addr}", "${NGINX_host }", "${NGINX_upstream_response_length}", "${NGINX_upstream_status}", "${NGINX_server_name}", "${NGINX_newurl}", "${NGINX_upstream_response_time}", "${NGINX_user_agent}")
  indexes("NGINX_server_name", "NGINX_newurl"));
};
#####Логи nginx access через tcp
#log {source(remote_log_host_nginx_access_tcp);  parser(p_remote_log_host_nginx_access); destination(d_elastic_nginx_access); };
log {source(remote_log_host_nginx_access_udp);  parser(p_remote_log_host_nginx_access); destination(d_elastic_nginx_access); };
log {source(remote_log_host_nginx_access);  parser(p_remote_log_host_nginx_access); destination(d_postgres_nginx_access); };
##Прием логов nginx error  с удаленных машин  на порт udp
source remote_log_host_nginx_error_udp  {
 udp(port(25215)so_rcvbuf(16777216) log_iw_size(10000) log_fetch_limit(1000000));
};
##Прием логов nginx error  с удаленных машин  на порт tcp
source remote_log_host_nginx_error_tcp {
 tcp(port(25215) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200));
};
 ###Направляем nginx_error  в elasticsearch
destination d_elastic_nginx_error {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("nginxerror-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log {source(remote_log_host_nginx_error_udp); destination(d_elastic_nginx_error); };
#log {source(remote_log_host_nginx_error_tcp); destination(d_elastic_nginx_error); };
##Прием логов nodejs  с удаленных машин  на порт на порт udp
source remote_log_host_nodejs_udp {
 udp(port(25216) so_rcvbuf(16777216) log_iw_size(10000) log_fetch_limit(1000000));
};
##Прием логов nodejs  с удаленных машин  на порт на порт tcp
source remote_log_host_nodejs_tcp {
 tcp(port(25216) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200));
};
 ###Направляем nodejs логи  в elasticsearch
destination d_elastic_nodejs {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("nodejs-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log {source(remote_log_host_nodejs_udp); destination(d_elastic_nodejs); };
#log {source(remote_log_host_nodejs_tcp); destination(d_elastic_nodejs); };
source udp_remote_log_host_nginx_main {
 udp(port(25230) log_iw_size(1000) log_fetch_limit(1000000)) ;
};
#source tcp_remote_log_host_nginx_main   {
 #tcp(port(25230) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(100)) ;
#};
###Парсим логи nginx access по столбцам  - разделитель "|"
#  log_format full_format '"$time_iso8601"|"$http_host"|"$remote_addr"|"$http_x_forwarded_for"|"$request_method"|"$request"|"$status"|"$body_bytes_sent"|"$http_referer"|"$request_time"|"$upstream_http_x_cache"|"$uri"|"$upstream_addr"|"$host"|"$upstream_response_length"|"$upstream_status"|"$server_name"|"$http_host"|"$upstream_response_time"|"$upstream_cache_status"|"$http_user_agent"|"$geoip_city"|"$geoip_country_name"|"$geoip_region"|"$http_cookie"';
parser p_remote_log_host_nginxaccessfull  {
    csv-parser(columns("NGINX_TIME", "NGINX_http_host", "NGINX_remote_addr", "NGINX_http_x_forwarded_for", "NGINX_request", "NGINX_request_method","NGINX_status", "NGINX_body_bytes_sent", "NGINX_http_referer", "NGINX_request_time", "NGINX_upstream_http_x_cache", "NGINX_uri", "NGINX_upstream_addr", "NGINX_host", "NGINX_upstream_response_length", "NGINX_upstream_status", "NGINX_server_name", "NGINX_newurl", "NGINX_upstream_response_time", "NGINX_upstream_cache_status", "NGINX_user_agent" , "geoip.city_name", "geoip.country_name", "geoip.region_name", "http_cookie" )
         flags(escape-double-char,strip-whitespace)
         delimiters("|")
         quote-pairs('""[]')
         );
};
###Направляем nginx_acess в elasticsearch
destination d_elastic_nginxaccessfull {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("nginxaccessfull-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log {source (udp_remote_log_host_nginx_main); parser(p_remote_log_host_nginxaccessfull );destination(d_elastic_nginxaccessfull);};

Здесь мы настроили парсинг входящего лога nginx acceess для отпраки его в elasticsearch и postgres, а также прием логов nginx error и nodejs и отправку их в elasticsearch.
Настраиваем прием системных логов c удаленных хостов через syslog-ng.

nano /etc/syslog-ng/conf.d/input.system.logs.conf

Вставляем содержимое

########################
# auth logs
########################
source tcp_remote_log_auth {
tcp(port(40514) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_auth {
udp(port(40514) log_iw_size(1000) log_fetch_limit(1000000));};
#parser p_geoip { geoip( "${HOST}", prefix( "geoip." ) database( "/etc/syslog-ng/GEOIP/GeoLiteCity.dat" ) ); };
###Направляем  в elasticsearch
destination d_elastic_auth {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("auth-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_auth); destination(d_elastic_auth); };
########################
# crons logs
########################
source tcp_remote_log_host_crons  {
tcp(port(40515) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_crons  {
udp(port(40515) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_crons {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("crons-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_crons); destination(d_elastic_crons); };
########################
# kern logs
########################
source tcp_remote_log_host_kern  {
tcp(port(40516) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_kern {
udp(port(40516) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_kern {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("kern-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_kern ); destination(d_elastic_kern); };
########################
# daemon logs
########################
source tcp_remote_log_host_daemon {
tcp(port(40517) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_daemon {
udp(port(40517) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_daemon {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("daemon-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_daemon); destination(d_elastic_daemon); };
########################
# user logs
########################
source tcp_remote_log_host_user  {
tcp(port(40518) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_user {
udp(port(40518) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_user {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("user-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_user); destination(d_elastic_user); };
########################
# lpr logs
########################
source tcp_remote_log_host_lpr  {
tcp(port(40519) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_lpr {
udp(port(40519) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_lpr {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("lpr-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_lpr); destination(d_elastic_lpr); };
########################
# syslog logs
########################
source tcp_remote_log_host_syslog  {
tcp(port(40520) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_syslog {
udp(port(40520) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_syslog {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("syslog-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_syslog); destination(d_elastic_syslog); };
########################
# uucp logs
########################
source tcp_remote_log_host_uucp  {
tcp(port(40521) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_uucp {
udp(port(40521) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_uucp {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("uucp-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_uucp); destination(d_elastic_uucp); };
########################
# mail logs
########################
source tcp_remote_log_host_mail {
tcp(port(40522) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_mail {
udp(port(40522) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_mail {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("mail-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_mail); destination(d_elastic_mail); };
########################
# messages logs
########################
source tcp_remote_log_host_messages  {
tcp(port(40523) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_messages {
udp(port(40523) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_messages {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("messages-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_messages); destination(d_elastic_messages); };
########################
# debug logs
########################
source tcp_remote_log_host_debug  {
tcp(port(40524) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_debug {
udp(port(40524) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_debug {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("debug-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_debug); destination(d_elastic_debug); };
########################
# error logs
########################
source tcp_remote_log_host_error  {
tcp(port(40525) so_rcvbuf(67108864) log_iw_size(100000)   log_fetch_limit(1000000) max-connections(200)); };
source udp_remote_log_host_error {
udp(port(40525) log_iw_size(1000) log_fetch_limit(1000000));};
###Направляем в elasticsearch
destination d_elastic_error {
  elasticsearch2(
    #client-lib-dir("/usr/share/elasticsearch/lib/")
    index("error-${YEAR}.${MONTH}.${DAY}")
    type("test")
    time-zone("UTC")
    client_mode("http")
    flush-limit("10000")
    cluster_url("http://elasticnode1:9200")
    custom_id("${UNIQID}")
    template("$(format_json --scope nv_pairs --key ISODATE @timestamp=${ISODATE})")
  );
};
log { source(udp_remote_log_host_error); destination(d_elastic_error); };

Индексы созданные в elasticsearch соответственно буду иметь следующие названия:

nginxaccess-*
nginxerror-*
nodejs-*

И т.д.- смотрим на имена индексов.
Чтобы логи писались в postgresql создадим базу nginx_access на любой ноде и настроим подключения по вашим данным

su postgres -c "psql"
create database nginx_access;

В ней будут создаваться таблицы вида

Все рестартуем агенты на сервере и отправителе.
sudo /etc/init.d/syslog-ng restart

Заходим в kibana на

https://127.0.0.1:5601

Добавляем индекс

lasticsearch-*

В поле timestamp выбираем

@timestamp

Смотрим в discover наши логи


Все разложено как и надо по парам!!!
Теперь перейдем к постройке графиков, например по статусам nginx. У нас передается поле с именем

3. Различные сниппеты по логам

3.1 Обработчик лога – сырого формата json

source s_tcp_json { tcp(port(10514) flags(no-parse)); };
parser p_json { json-parser(prefix(“.json.”)); };
destination d_file { file(“/var/log/remote.log”
template(“${.json.timestamp} ${.json.source} ${.json.app}[${.json.id}]: ${.json.msg}\n”)); };
destination d_mongodb { mongodb(collection(“remote_log”)
value-pairs(
pair(“PROGRAM” “${.json.app}”)
pair(“HOST” “${.json.source}”)
pair(“PID” “${.json.id}”)
pair(“MESSAGE” “${.json.msg}”)
pair(“DATE” “${.json.timestamp}”)
pair(“PRIORITY” “${.json.prio}”)
pair(“FACILITY” “auth”)
)); };
log {
source(s_tcp_json);
parser(p_json);
destination(d_file);
destination(d_mongodb);
};

3.2 Обработчик лога – syslog над json

source s_tcp_json_payload { tcp(); };
parser p_json { json-parser(); };
destination d_file { file("/var/log/remote.log"); };
destination d_mongodb { mongodb(collection("remote_log")); };
log {
 source(s_tcp_json_payload);
 parser(p_json);
 destination(d_file);
 destination(d_mongodb);
};

3.3 Обработчик лога – mixed syslog json

block parser mixed-json-parser() {
 channel {
  junction {
   channel {
    parser { json-parser(marker("@json:")); };
    rewrite { set-tag(".json"); };
    flags(final);
   };
   channel {
    flags(final);
   };
  };
 };
};
source s_mixed {
 tcp();
 parser { mixed-json-parser(); };
};

3.4 Скрипт очистки логов nginx чтобы не засирать систему.

#!/bin/bash
echo "Вычищаю логи nginx"
rm -rf /var/log/nginx/*
/bin/sleep 1;
echo "Переинициализация логов nginx"
[ ! -f /var/run/nginx.pid ] || /bin/kill -USR1 `/bin/cat /var/run/nginx.pid`
echo "Смотрим процессы"
/bin/ps aux | grep nginx
/bin/ps aux | grep syslog-ng

Добавляем его по крону каждые 2 часа

3.5 Обработчик лога – mapping geoip в elasticsearch для визуализации mapheat

curl -X PUT "http://127.0.0.1:9200/nginx-access4/" -d '{
   "mappings" : {
      "_default_" : {
         "properties" : {
            "geoip" : {
               "properties" : {
                  "geoip.country.code" : {
                     "index" : "not_analyzed",
                     "type" : "string",
                     "doc_values" : true
                  },
                  "geoip.latitude" : {
                     "index" : "not_analyzed",
                     "type" : "string",
                     "doc_values" : true
                  },
                  "geoip.longitude" : {
                     "type" : "string",
                     "doc_values" : true,
                     "index" : "not_analyzed"
                  },
                  "location" : {
                     "type" : "geo_point"
                  }
               }
            }
         }
      }
   }
}';

где
$ES_HOST – elastic host
$INDEX– имя индекса

4. Исправление ошибок

High disk watermark [90%] exceeded on

Ошибка связана с исчерпанием ресурса диска – решается уменьшением минимального размера доступного места

curl -XPUT http://elasticnodehost:9200/_cluster/settings -d '{
  "transient": {
    "cluster.routing.allocation.disk.watermark.low": "99%",
    "cluster.routing.allocation.disk.watermark.high": "10gb",
    "cluster.info.update.interval": "1m"
  }
}'
Фикс ошибки Kibana

Courier Fetch: 5 of 10 shards failed.
Одним из вариантов решения является обновление полей индекса в elasticsearch

Courier Fetch: 5 of 10 shards failed.
Фикс ошибки при запуске syslog-ng

Error parsing destination, destination plugin java not found in destination block elasticsearch2
Решение

export LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server:$LD_LIBRARY_PATH

5. Syslog-ng module incubator

Syslog-ng module incubator представляет собой набор инструментов и модулей для syslog-ng, которые по той или иной причине не являются частью официального репозитория. Syslog-ng module incubator служит как в качестве промежуточной площадки для экспериментальных модулей, так и в качестве хранилища плагинов.
Установка Syslog-ng module incubator
Требуемые зависимости

syslog-ng, bison, flex, libmongo-client, lua, perl, rdkafka; of which the latter six

Установка

git clone https://github.com/balabit/syslog-ng-incubator.git
cd syslog-ng-incubator
autoreconf -i
./configure && make && sudo make install

После установки регистрируемся

syslog-ng --module-registry

Что мы интересного в данном складе модулей?
Парсеры
grok parser

parser p_grok {
  grok(
       pattern_directory("/etc/syslog-ng/grok.d")
       match("%{STRING:field}" tags("matched" "string") )
       match("%{NUMBER:field}" tags("matched" "number") )
  );
};

Syslog-ng journald send logs

source s_journald {
	systemd-journal(prefix(".SDATA.journald."));
};
destination d_network {
	syslog("server.host");
};
log {
	source(s_journald);
	destination(d_network);
};

Триггеры

source s_trigger {
 trigger(
  program-override("trigger")
  tags("trigger-happy")
  trigger-freq(5)
  trigger-message("Beep.")
 );
};

Дополнительная целевая база для отправки логов.
Riemann

destination d_riemann {
 riemann(
  ttl("120")
  description("syslog-ng internal errors")
  metric(int("${SEQNUM}"))
 );
};
log {
  source { internal(); };
  filter { level(err..emerg); };
  destination(d_riemann);
};

Rss канал

destination d_rss {
 rss(
  port(8192)
  feed-title("Critical errors in the system")
  entry-title("Error from ${PROGRAM} @ ${HOST_FROM} at ${ISODATE}")
  entry-description("${MESSAGE}")
 );
};

Мониторинг с помощью syslog-ng и lua скриптов

source s_mark {
  monitor (
     monitor-freq(5)  # 5 seconds period
     monitor-script("/etc/syslog-ng/mark.lua")
     monitor-func("mark")
  );
};
destination d_tcp {
   tcp("" port() );
};
log {
  source(s_mark);
  destination(d_tcp);
};

Скрипт /etc/syslog-ng/mark.lua

values = { "wait_for_run", "sleep", "swapped", "free", "buffers",
"cache", "swapped_in", "swapped_out", "io_in", "io_out", "interrupts",
            "context_switches", "user_time", "kernel_time", "idle",
"wait_for_io" }
-- source
function vmstat()
  local result = {}
  local f = assert(io.popen("vmstat -n 1 1 | tail -n 1", 'r'))
  line = f:read("*all")
  f:close()
  local i = 1
  local send = -1
  local sstart = 0
  while i < #values do
    sstart, send = line:find("[^%s]+", send + 1)
    result["vmstat."..values[i]] = line:sub(sstart, send)
    i = i + 1
  end
  return result
end

6. Запросы в kibana

Найти время ответа сервера в промежутке между 10 и 11 сек(длительность)

NGINX_request_time: ["10.000" TO "11.000"]

Syslog-ng alerts на события

Пример конфгига для alets. Отправка уведомления на почту

filter f_linkdown {
    match("eth0: link down" value("MESSAGE"));
};
destination d_alert {
    smtp(
        host("localhost") port(25)
        from("syslog-ng alert service" "syslog@localhost")
        reply-to("Admins" "root@localhost")
        to("Ennekem" "me@localhost")
        subject("[SYSLOG ALERT]: eth0 link down")
        body("Syslog received an alert:\n$MSG")
        );
};
log {
    source(s_local);
    filter(f_linkdown);
    destination(d_alert);
};

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

 

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.