Eh bien, après avoir beaucoup regardé autour de moi, je ne trouvais pas de solution à mon problème, car cela "devrait" fonctionner, mais cela ne fonctionne évidemment pas . J'utilise une machine Ubuntu 14.04 LTS Logstash 1.4.2- 1-2-2c0f5a1, et je reçois des messages tels que le suivant:
2014-08-05 10:21:13,618 [17] INFO Class.Type - This is a log message from the class:
BTW, I am also multiline
Dans la configuration d'entrée, j'ai un codec multiline
et l'événement est analysé correctement. Je sépare également le texte de l'événement en plusieurs parties afin qu'il soit plus facile à lire.
En fin de compte, j'obtiens, comme vu dans Kibana, quelque chose comme ceci (vue 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
]
}
Vous avez peut-être remarqué que je mets un ";" dans l'horodatage. La raison en est que je veux pouvoir trier les journaux en utilisant la chaîne timestamp, et apparemment, logstash n’est pas si bon que ça (par exemple: http://www.elasticsearch.org/guide/en/elasticsearch/guide/ current/multi-fields.html ).
J'ai échoué à essayer d'utiliser le filtre date
de plusieurs façons et cela n'a apparemment pas fonctionné.
date {
locale => "en"
match => ["logTimestamp", "YYYY-MM-dd;HH:mm:ss.SSS", "ISO8601"]
timezone => "Europe/Vienna"
target => "@timestamp"
add_field => { "debug" => "timestampMatched"}
}
Depuis que j'ai lu que la bibliothèque Joda peut a des problèmes si la chaîne n'est pas strictement conforme à ISO 8601 (très pointilleux et attend un T, voir https://logstash.jira.com/browse/LOGSTASH -180 ), j'ai aussi essayé d'utiliser mutate
pour convertir la chaîne en quelque chose comme 2014-08-05T10:21:13.618
, puis utiliser "YYYY-MM-dd'T'HH:mm:ss.SSS"
. Cela aussi n'a pas fonctionné.
Je ne veux pas avoir à mettre manuellement l'heure +02: 00 car cela donnerait des problèmes avec l'heure d'été.
Dans tous les cas, l'événement passe par elasticsearch, mais date
ne fait apparemment rien, car @timestamp
et logTimestamp
sont différents et aucun champ debug
n'est ajouté.
Toute idée de comment rendre les chaînes de logTime correctement triables Je me suis attaché à les convertir en un horodatage correct, mais toute autre solution serait également la bienvenue.
Comme vous pouvez le voir ci-dessous:
Lors du tri sur @timestamp
, elasticsearch peut le faire correctement, mais comme il ne s'agit pas du "vrai" horodatage du journal, mais plutôt lorsque l'événement logstash a été lu, j'ai besoin (évidemment) de pouvoir également effectuer un tri sur logTimestamp
. C'est ce qui est ensuite produit. Évidemment pas utile:
Toute aide est la bienvenue! Dites-moi si j'ai oublié des informations qui pourraient être utiles.
Mettre à jour:
Voici le fichier de configuration du filtre qui a finalement fonctionné:
# 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" ]
}
}
}
J'ai testé votre filtre date
. ça marche sur moi!
Voici ma configuration
input {
stdin{}
}
filter {
date {
locale => "en"
match => ["message", "YYYY-MM-dd;HH:mm:ss.SSS"]
timezone => "Europe/Vienna"
target => "@timestamp"
add_field => { "debug" => "timestampMatched"}
}
}
output {
stdout {
codec => "rubydebug"
}
}
Et j'utilise cette entrée:
2014-08-01;11:00:22.123
La sortie est:
{
"message" => "2014-08-01;11:00:22.123",
"@version" => "1",
"@timestamp" => "2014-08-01T09:00:22.123Z",
"Host" => "ABCDE",
"debug" => "timestampMatched"
}
Assurez-vous donc que votre logTimestamp
a la valeur correcte. C'est probablement un autre problème. Ou pouvez-vous fournir votre événement de journal et votre configuration logstash pour plus de discussion Je vous remercie.
Cela a fonctionné pour moi - avec un format de date/heure légèrement différent:
# 2017-11-22 13:00:01,621 INFO [AtlassianEvent::0-BAM::EVENTS:pool-2-thread-2] [BuildQueueManagerImpl] Sent ExecutableQueueUpdate: addToQueue, agents known to be affected: []
input {
file {
path => "/data/atlassian-bamboo.log"
start_position => "beginning"
type => "logs"
codec => multiline {
pattern => "^%{TIMESTAMP_ISO8601} "
charset => "ISO-8859-1"
negate => true
what => "previous"
}
}
}
filter {
grok {
match => [ "message", "(?m)^%{TIMESTAMP_ISO8601:logtime}%{SPACE}%{LOGLEVEL:loglevel}%{SPACE}\[%{DATA:thread_id}\]%{SPACE}\[%{Word:classname}\]%{SPACE}%{GREEDYDATA:logmessage}" ]
}
date {
match => ["logtime", "yyyy-MM-dd HH:mm:ss,SSS", "yyyy-MM-dd HH:mm:ss,SSS Z", "MMM dd, yyyy HH:mm:ss a" ]
timezone => "Europe/Berlin"
}
}
output {
elasticsearch { hosts => ["localhost:9200"] }
stdout { codec => rubydebug }
}