LogstashExample1
Материал из noname.com.ua
Пример
Это продолжение статьи https://noname.com.ua/mediawiki/index.php?title=Logstash
nginx
Отправка логов nginx в Elastic (один из вариантов)
Тут рассматривается самый простой случай - когда Filebeat не делает преобразований
Nginx умеет писать логи в Json
log_format nginxlog_json escape=json.
'{ "timestamp": "$time_iso8601", '
'"remote_addr": "$remote_addr", '
'"body_bytes_sent": $body_bytes_sent, '
'"request": "$request", '
'"request_method": "$request_method", '
'"request_time": $request_time, '
'"response_status": $status, '
'"upstream_status": $upstream_status,'
'"upstream_response_time": $upstream_response_time,'
'"upstream_connect_time": $upstream_connect_time,'
'"upstream_header_time": $upstream_header_time,'
'"upstream_addr": "$upstream_addr",'
'"host": "$host",'
'"http_x_forwarded_for": "$http_x_forwarded_for",'
'"http_referrer": "$http_referer", '
'"http_user_agent": "$http_user_agent", '
'"http_version": "$server_protocol", '
'"nginx_access": true }';
В лог попадает:
tail -1 /var/log/nginx/access.log.ssl | jq .
{
"timestamp": "2021-08-08T08:47:59+00:00",
"remote_addr": "159.224.49.4",
"body_bytes_sent": 361,
"request": "POST /internal/bsearch HTTP/1.1",
"request_method": "POST",
"request_time": 0.152,
"response_status": 200,
"upstream_status": 200,
"upstream_response_time": 0.028,
"upstream_connect_time": 0,
"upstream_header_time": 0.028,
"upstream_addr": "127.0.0.1:5601",
"host": "elk.domain.tld",
"http_x_forwarded_for": "",
"http_referrer": "https://elk.domain.tld/app/discover",
"http_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15",
"http_version": "HTTP/1.1",
"nginx_access": true
}
Filebeat
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/elk.domain.tld-access.log.ssl
exclude_files: ['\.gz$']
filebeat.config.modules:
reload.enabled: false
setup.template.settings:
index.number_of_shards: 1
setup.kibana:
output.logstash:
hosts: ["elk.domain.tld:5400"]
ssl.certificate_authorities: ["/etc/elk-certs/elk-ssl.crt"]
ssl.certificate: "/etc/elk-certs/elk-ssl.crt"
ssl.key: "/etc/elk-certs/elk-ssl.key"
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
logging.level: debug
logging.selectors: ["*"]
В примере мониторится всего один файл (исключение очевидно лишнее)
Результат пересылается на удаленный хост в Logstash
Важно Сертификат должен соответствовать хостнейму - тут нельзя указать IP адрес
hosts: ["elk.domain.tld:5400"]
Logstash
Базовый пример без преобразований
Минимальный конфиг - слушать Filebeat на порту 5400 (без сертификата - не будет работать)
Результат - писать в файл без всяких преобразований
input {
beats {
port => 5400
ssl => true
ssl_certificate_authorities => ["/etc/elk-certs/elk-ssl.crt"]
ssl_certificate => "/etc/elk-certs/elk-ssl.crt"
ssl_key => "/etc/elk-certs/elk-ssl.key"
ssl_verify_mode => "force_peer"
}
}
output {
file {
flush_interval => 5
gzip => false
path => "/var/log/logstash/logstash_debug.log"
}
}
Результат записи в файл не удовлетворительный
root@elk:/var/log/logstash# tail -1 logstash_debug.log | jq .
Сообщение не было разобрано на поля
{
"message": "{ \"timestamp\": \"2021-08-08T09:20:47+00:00\", \"remote_addr\": \"61.219.11.151\", \"body_bytes_sent\": 163, \"request\": \"GET / HTTP/1.1\", \"request_method\": \"GET\", \"request_time\": 0.213, \"response_status\": 400, \"upstream_status\": ,\"upstream_response_time\": ,\"upstream_connect_time\": ,\"upstream_header_time\": ,\"upstream_addr\": \"\",\"host\": \"elk.arturhaunt.ninja\",\"http_x_forwarded_for\": \"\",\"http_referrer\": \"\", \"http_user_agent\": \"\", \"http_version\": \"HTTP/1.1\", \"nginx_access\": true }",
"cloud": {
"availability_zone": "us-east-1f",
"region": "us-east-1",
"instance": {
"id": "i-075866580c26fd42c"
},
"service": {
"name": "EC2"
},
"machine": {
"type": "t3.large"
},
"image": {
"id": "ami-09e67e426f25ce0d7"
},
"account": {
"id": "543591064633"
},
"provider": "aws"
},
"@timestamp": "2021-08-08T09:20:52.684Z",
"agent": {
"hostname": "elk.domain.tld",
"id": "aef24fda-f14c-40cf-a388-fa0af443f5d7",
"type": "filebeat",
"version": "7.14.0",
"ephemeral_id": "c53f02a8-0b37-4dae-a3c7-cbf03eabca6a",
"name": "elk.arturhaunt.ninja"
},
"@version": "1",
"log": {
"offset": 4126,
"file": {
"path": "/var/log/nginx/elk.domain.tld-access.log.ssl"
}
},
"host": {
"hostname": "elk.domain.tld",
"id": "ec2385ad84aeea5eb425460c41a5b866",
"os": {
"type": "linux",
"codename": "focal",
"name": "Ubuntu",
"version": "20.04.2 LTS (Focal Fossa)",
"kernel": "5.4.0-1045-aws",
"platform": "ubuntu",
"family": "debian"
},
"ip": [
"172.31.91.220",
"fe80::14b5:eff:feac:ae79"
],
"name": "elk.domain.tld",
"mac": [
"16:b5:0e:ac:ae:79"
],
"architecture": "x86_64",
"containerized": false
},
"input": {
"type": "log"
},
"ecs": {
"version": "1.10.0"
},
"tags": [
"beats_input_codec_plain_applied"
]
}
Базовый пример с JSON
Для того что бы разобрать на поля JSON
filter {
json {
source => "message"
}
}