Добавить в корзинуПозвонить
Найти в Дзене

Парсим стандартный nginx access log vector-ом и раскладываем по ECS

Парсим стандартный nginx access log vector-ом и раскладываем по ECS ECS (Elastic Common Schema) - это стандарт для унификации структурированных данных. Он определяет, как должны выглядеть поля логов, что упрощает их обработку, анализ и визуализацию. Более подробно тут. Конфиг парсинга: observer.product = "<Product name>" .observer.vendor = "<Vendor name>" .event.kind = "event" .event.category = ["web"] .event.type = ["access", "info structured, json_err = parse_json(.message) if json_err == null && is_object(structured) { . = merge!(., structured) } else { .parsed, re_err = parse_regex( .message, pattern: r'(?P<source_ip>[\d\.]+) - - \[(?P<time>.+?)\] "(?P<method>[A-Z]+) (?P<path>[^ ]+) HTTP/(?P<http_version>[0-9\.]+)" (?P<status_code>\d+) (?P<bytes_sent>\d+|-) "(?P<referrer>[^"]*)" "(?P<user_agent>[^"]*)" "(?P<extra>[^"]*)"' ) if re_err == null && is_object(.parsed) { .source.ip = .parsed.source_ip .http.request.method = .parsed.method .url.path = .parsed.path .http.version = .parse

Парсим стандартный nginx access log vector-ом и раскладываем по ECS

ECS (Elastic Common Schema) - это стандарт для унификации структурированных данных. Он определяет, как должны выглядеть поля логов, что упрощает их обработку, анализ и визуализацию. Более подробно тут.

Конфиг парсинга:

observer.product = "<Product name>"

.observer.vendor = "<Vendor name>"

.event.kind = "event"

.event.category = ["web"]

.event.type = ["access", "info

structured, json_err = parse_json(.message)

if json_err == null && is_object(structured) {

. = merge!(., structured)

} else {

.parsed, re_err = parse_regex(

.message,

pattern: r'(?P<source_ip>[\d\.]+) - - \[(?P<time>.+?)\] "(?P<method>[A-Z]+) (?P<path>[^ ]+) HTTP/(?P<http_version>[0-9\.]+)" (?P<status_code>\d+) (?P<bytes_sent>\d+|-) "(?P<referrer>[^"]*)" "(?P<user_agent>[^"]*)" "(?P<extra>[^"]*)"'

)

if re_err == null && is_object(.parsed) {

.source.ip = .parsed.source_ip

.http.request.method = .parsed.method

.url.path = .parsed.path

.http.version = .parsed.http_versi

if exists(.parsed.status_code) {

code, parse_err = parse_int(.parsed.status_code)

if parse_err != null {

code = -1

}

.http.response.status_code = code

} else {

.http.response.status_code = -1

if .http.response.status_code >= 200 && .http.response.status_code <= 299 {

.event.outcome = "success"

} else if .http.response.status_code >= 400 && .http.response.status_code <= 499 {

.event.outcome = "failure"

} else if .http.response.status_code >= 500 && .http.response.status_code <= 599 {

.event.outcome = "failure"

} else {

.event.outcome = "unknown"

.user_agent.original = .parsed.user_agent

.event.created, ts_err = parse_timestamp(

to_string(.parsed.time),

format: "%d/%b/%Y:%H:%M:%S %z"

)

if ts_err != null {

.event.created = null

}

del(.parsed.extra)

del(.parsed)

}

}

del(.message)

Сначала пробуем распапрсить .message как JSON. Если парсинг JSON не удался, то применяем regexp для разбиения строки на поля. Далее полученные данные приводим к формату ECS + небольшая логика, чтобы выставить правильно .event.outcome поле.

#vector