Apache2 logs send to elasticsearch and kibana with syslog-ng
Прости меня Игорь!!!)).
!!!!Читаем статью с первоначальной настройкой системы сборы логов здесь.!!!! Это дополнение.
1. Config server with apache2 and syslog-ng log forwarder
Tune log format in apache2.conf
nano /etc/apache2/apache2.conf
LogFormat '"%t"|"%a"|"%A"|"%V"|"%U"|"%m"|"%s"|"%{User-agent}i"|"%{Referer}i"|"%q"|"%B"|"%D"|"%I"|"%O"' full_format CustomLog /var/log/apache2/access_full.log full_format ErrorLogFormat '"%t"|"[C:%{c}L]"|"%l %7F: %E: "|"%A"|"%M% ,\"|"%{Referer}i"' ErrorLog ${APACHE_LOG_DIR}/error.log
And restart apache2
/etc/init.d/apache2 restart
Edit syslog-ng log forwarder. Add to config
nano /etc/syslog-ng/conf.d/web-logs.conf
##########APACHE2LOGS##################################### ########################################################## source s_tail_log_host_apache2_main { file( "/var/log/apache2/access_full.log" follow_freq(1) flags(no-parse) ); }; destination tcp-apache2 { tcp ( "syslogng-server" port(25002) disk-buffer( mem-buf-length(10000) disk-buf-size(2000000) reliable(no) ) ); }; log {source(s_tail_log_host_apache2_main); destination(tcp-apache2);}; ######################################################## ######################################################## source s_tail_apache2_error { file( "/var/log/apache2/error.log" follow_freq(1) flags(no-parse) ); }; destination d_server_apache2_error { tcp ( "syslogng-server" port(25003) disk-buffer( mem-buf-length(10000) disk-buf-size(2000000) reliable(no) ) ); }; log {source(s_tail_apache2_error ); destination(d_server_apache2_error);};
Add mapping to elasticsearch
curl -H "Content-Type: application/json" -XPUT 'http://127.0.0.1:29200/_template/apache2access_per_index' -d \ '{ "template" : "apache2access-*", "mappings" : { "_default_" : { "properties" : { "apache2" : { "properties" : { "response_size": {"type": "integer","ignore_malformed": true}, "response_time": {"type": "integer","ignore_malformed": true}, "remote_addr": {"type": "ip","ignore_malformed": true}, "local_addr": {"type": "ip","ignore_malformed": true}, "status": {"type": "integer","ignore_malformed": true}, "bytes_received": {"type": "integer","ignore_malformed": true}, "bytes_sent": {"type": "integer","ignore_malformed": true}, "request": {"type": "text","fields": {"keyword": {"type": "keyword"} } } } }, "geoip2" : { "properties" : { "location2" : {"type" : "geo_point"} } } } } } } }'
Restart syslog-ng
syslog-ng -s /etc/init.d/syslog-ng restart
2. Edit log agregator syslog-ng elasticsearch.
Edit log agregator config.
add to conf file
##Принимаем apache2 access logs на порт 25002 source tcp-apache2-accesslogs { tcp(port(25002) so_rcvbuf(67108864) log_iw_size(100000) log_fetch_limit(1000000) max-connections(200)); }; ###Парсим принятые логи nginx, здесь мы указываем имена полей, куда будут попадать данные, укажем также разделитель полей символ "|" parser p-apache2-acessfull-mapped { csv-parser(columns("apache2.time","apache2.remote_addr", "apache2.local_addr", "apache2.host", "apache2.request", "apache2.request_method", "apache2.status", "apache2.user_agent","apache2.referer", "apache2.query_string", "apache2.response_size", "apache2.response_time", "apache2.bytes_received","apache2.bytes_sent") flags(escape-double-char,strip-whitespace) delimiters("|") quote-pairs('""[]') ); }; ###Здесь мы сверяем прилетающий ip из логов nginx - в поле "nginx.remote_addr" с нашей базой данных maxmidn geoip2 parser p_geoip2apache { geoip2( "${apache2.remote_addr}", prefix( "geoip2." ) database( "/etc/syslog-ng/GeoLite2-City.mmdb" ) ); }; ##Rewrite необходим для того, чтобы информация о местоположении находилась в форме, ожидаемой Elasticsearch. Он выглядит несколько более сложным, чем для первой версии анализатора GeoIP, поскольку имеется больше информации и информация теперь структурирована. rewrite r_geoip2 { set( "${geoip2.location.latitude},${geoip2.location.longitude}", value( "geoip2.location2" ), condition(not "${geoip2.location.latitude}" == "") ); }; ###Направляем nginx_ destination d_elastic-apache2-acessfull { elasticsearch2( index("apache2access-${YEAR}.${MONTH}") type("test") time-zone("UTC") client_mode("http") flush-limit("100") cluster_url("http://elasticsearch:9200") custom_id("${UNIQID}") template("$(format-json --scope rfc5424 --scope nv-pairs --exclude DATE --key ISODATE)") type("apache2access") persist-name(elasticsearch-apache2access) ); }; log {source (tcp-apache2-accesslogs); parser(p-apache2-acessfull-mapped); rewrite(r_geoip2); parser(p_geoip2apache); destination(d_elastic-apache2-acessfull);}; ##Принимаем apache2 error logs на порт 25003 source tcp-apache2-errorlogs { tcp(port(25003) so_rcvbuf(67108864) log_iw_size(100000) log_fetch_limit(1000000) max-connections(200)); }; ###Парсим принятые логи nginx, здесь мы указываем имена полей, куда будут попадать данные, укажем также разделитель полей символ "|" parser p-apache2-error-mapped { csv-parser(columns("apache2.time","apache2.pid", "apache2.level", "apache2.host", "apache2.message", "apache2.refferer") flags(escape-double-char,strip-whitespace) delimiters("|") quote-pairs('""[]') ); }; ###Направляем nginx_ destination d_elastic-apache2-error { elasticsearch2( index("apache2error-${YEAR}.${MONTH}") type("test") time-zone("UTC") client_mode("http") flush-limit("100") cluster_url("http://elasticsearch:9200") custom_id("${UNIQID}") template("$(format-json --scope rfc5424 --scope nv-pairs --exclude DATE --key ISODATE)") type("apache2error") persist-name(elasticsearch-apache2error) ); }; log {source (tcp-apache2-errorlogs); parser(p-apache2-error-mapped); destination(d_elastic-apache2-error);};
Restart syslog-ng
syslog-ng -s /etc/init.d/syslog-ng restart