Хорошо, много оглядевся, я не смог найти решение моей проблемы, так как это "должно" работать, но, очевидно, нет. Я использую на компьютере Ubuntu 14.04 LTS Logstash 1.4.2-1-2-2c0f5a1, и я получаю такие сообщения, как следующий:
2014-08-05 10:21:13,618 [17] INFO Class.Type - This is a log message from the class:
BTW, I am also multiline
В конфигурации ввода у меня есть кодек multiline
, и это событие правильно разбирается. Я также разделяю текст события несколькими частями, чтобы его было легче читать.
В конце я получаю, как видно в Kibana, что-то вроде следующего (вид JSON):
{
"_index": "logstash-2014.08.06",
"_type": "customType",
"_id": "PRtj-EiUTZK3HWAm5RiMwA",
"_score": null,
"_source": {
"@timestamp": "2014-08-06T08:51:21.160Z",
"@version": "1",
"tags": [
"multiline"
],
"type": "utg-su",
"host": "ubuntu-14",
"path": "/mnt/folder/thisIsTheLogFile.log",
"logTimestamp": "2014-08-05;10:21:13.618",
"logThreadId": "17",
"logLevel": "INFO",
"logMessage": "Class.Type - This is a log message from the class:\r\n BTW, I am also multiline\r"
},
"sort": [
"21",
1407315081160
]
}
Возможно, вы заметили, что я положил ";" в метке времени. Причина в том, что я хочу иметь возможность сортировать журналы с помощью строки timestamp, и, видимо, logstash не так хорош в этом (например: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/multi-fields.html).
Я безуспешно пытался использовать фильтр date
несколькими способами, и, похоже, это не сработало.
date {
locale => "en"
match => ["logTimestamp", "YYYY-MM-dd;HH:mm:ss.SSS", "ISO8601"]
timezone => "Europe/Vienna"
target => "@timestamp"
add_field => { "debug" => "timestampMatched"}
}
Поскольку я читал, что библиотека Joda может иметь проблемы, если строка не является строго совместимой с ISO 8601 (очень разборчива и ожидает T, см. https://logstash.jira.com/browse/LOGSTASH-180), я также попытался использовать mutate
для преобразования строки в нечто вроде 2014-08-05T10:21:13.618
, а затем использовать "YYYY-MM-dd'T'HH:mm:ss.SSS"
. Это также не сработало.
Я не хочу, чтобы вручную вводить +02: 00 в то время, потому что это создаст проблемы с летней экономией.
В любом из этих случаев событие переходит в поиск elasticsearch, но date
, по-видимому, ничего не имеет, поскольку @timestamp
и logTimestamp
являются разными, а поле debug
не добавляется.
Любая идея, как я мог бы корректно сортировать строки logTime? Я сосредоточился на преобразовании их в подходящую временную метку, но любое другое решение также будет приветствоваться.
Как вы можете видеть ниже:
При сортировке по @timestamp
, elasticsearch может сделать это правильно, но поскольку это не "реальная" временная метка журнала, а, скорее, когда было прочитано событие в журнале, мне нужно (очевидно), чтобы иметь возможность сортировать и над logTimestamp
. Это то, что затем выводится. Очевидно, что это не полезно:
Любая помощь приветствуется! Просто дайте мне знать, если я забуду какую-то информацию, которая может быть полезной.
Update:
Вот конфигурационный файл фильтра, который в итоге работал:
# Filters messages like this:
# 2014-08-05 10:21:13,618 [17] INFO Class.Type - This is a log message from the class:
# BTW, I am also multiline
# Take only type- events (type-componentA, type-componentB, etc)
filter {
# You cannot write an "if" outside of the filter!
if "type-" in [type] {
grok {
# Parse timestamp data. We need the "(?m)" so that grok (Oniguruma internally) correctly parses multi-line events
patterns_dir => "./patterns"
match => [ "message", "(?m)%{TIMESTAMP_ISO8601:logTimestampString}[ ;]\[%{DATA:logThreadId}\][ ;]%{LOGLEVEL:logLevel}[ ;]*%{GREEDYDATA:logMessage}" ]
}
# The timestamp may have commas instead of dots. Convert so as to store everything in the same way
mutate {
gsub => [
# replace all commas with dots
"logTimestampString", ",", "."
]
}
mutate {
gsub => [
# make the logTimestamp sortable. With a space, it is not! This does not work that well, in the end
# but somehow apparently makes things easier for the date filter
"logTimestampString", " ", ";"
]
}
date {
locale => "en"
match => ["logTimestampString", "YYYY-MM-dd;HH:mm:ss.SSS"]
timezone => "Europe/Vienna"
target => "logTimestamp"
}
}
}
filter {
if "type-" in [type] {
# Remove already-parsed data
mutate {
remove_field => [ "message" ]
}
}
}