Je voulais faire une copie d'un champ imbriqué dans un filtre Logstash mais je n'arrive pas à trouver la syntaxe correcte. Voici ce que j'essaye:
syntaxe incorrecte:
mutate {
add_field => { "received_from" => %{beat.hostname} }
}
beat.hostname n'est pas remplacé
mutate {
add_field => { "received_from" => "%{beat.hostname}" }
}
beat.hostname n'est pas remplacé
mutate {
add_field => { "received_from" => "%{[beat][hostname]}" }
}
beat.hostname n'est pas remplacé
mutate {
add_field => { "received_from" => "%[beat][hostname]" }
}
En aucune façon. Si je donne un champ non imbriqué, cela fonctionne comme prévu.
La structure de données reçue par logstash est la suivante:
{
"@timestamp" => "2016-08-24T13:01:28.369Z",
"beat" => {
"hostname" => "etg-dbs-master-tmp",
"name" => "etg-dbs-master-tmp"
},
"count" => 1,
"fs" => {
"device_name" => "/dev/vdb",
"total" => 5150212096,
"used" => 99287040,
"used_p" => 0.02,
"free" => 5050925056,
"avail" => 4765712384,
"files" => 327680,
"free_files" => 326476,
"mount_point" => "/opt/ws-etg/datas"
},
"type" => "filesystem",
"@version" => "1",
"tags" => [
[0] "topbeat"
],
"received_at" => "2016-08-24T13:01:28.369Z",
"received_from" => "%[beat][hostname]"
}
ÉDITER:
Puisque vous n'avez pas montré votre message d'entrée, j'ai travaillé sur votre sortie. Dans votre sortie, le champ dans lequel vous essayez de copier existe déjà, c'est pourquoi vous devez utiliser replace. S'il n'existe pas, vous devez en effet utiliser add_field. J'ai mis à jour ma réponse pour les deux cas.
EDIT 2: J'ai réalisé que votre problème pourrait être d'accéder à la valeur imbriquée, j'ai donc ajouté cela également :)
vous utilisez le filtre muté mal/en arrière.
Première erreur:
Vous souhaitez remplacer un champ, pas en ajouter un. Dans les documents, il vous donne l'option "remplacer". Voir: https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-replace
Deuxième erreur, vous utilisez la syntaxe à l'envers. Il semble que vous pensiez que cela est vrai:
"text I want to write" => "Field I want to write it in"
Bien que cela soit vrai:
"myDestinationFieldName" => "My Value to be in the field"
Avec cette connaissance, nous pouvons maintenant faire ceci:
mutate {
replace => { "[test][a]" => "%{s}"}
}
ou si vous voulez réellement ajouter un NOUVEAU CHAMP NON EXISTANT:
mutate {
add_field => {"[test][myNewField]" => "%{s}"}
}
Ou ajoutez un nouveau champ existant avec la valeur d'un champ imbriqué:
mutate {
add_field => {"some" => "%{[test][a]}"}
}
Ou plus de détails, dans mon exemple:
input {
stdin {
}
}
filter {
json {
source => "message"
}
mutate {
replace => { "[test][a]" => "%{s}"}
add_field => {"[test][myNewField]" => "%{s}"}
add_field => {"some" => "%{[test][a]}"}
}
}
output {
stdout { codec => rubydebug }
}
Cet exemple prend stdin et les sorties vers stdout. Il utilise un filtre json pour analyser le message, puis le filtre mutate pour remplacer le champ imbriqué. J'ajoute également un champ complètement nouveau dans l'objet de test imbriqué. Et enfin crée un nouveau champ "certains" qui a la valeur de test.a
Donc pour ce message:
{"test" : { "a": "hello"}, "s" : "to_Repalce"}
Nous voulons remplacer test.a (valeur: "Hello") par s (Value: "to_Repalce"), et ajouter un champ test.myNewField avec la valeur de s.
Sur mon terminal:
artur@pandaadb:~/dev/logstash$ ./logstash-2.3.2/bin/logstash -f conf2/
Settings: Default pipeline workers: 8
Pipeline main started
{"test" : { "a": "hello"}, "s" : "to_Repalce"}
{
"message" => "{\"test\" : { \"a\": \"hello\"}, \"s\" : \"to_Repalce\"}",
"@version" => "1",
"@timestamp" => "2016-08-24T14:39:52.002Z",
"Host" => "pandaadb",
"test" => {
"a" => "to_Repalce",
"myNewField" => "to_Repalce"
},
"s" => "to_Repalce"
"some" => "to_Repalce"
}
La valeur a été remplacée avec succès.
Un champ "certains" avec la valeur de remplacement a été ajouté
Un nouveau champ dans le tableau imbriqué a été ajouté.
si vous utilisez add_field, il convertira a en tableau et y ajoutera votre valeur.
J'espère que cela résout votre problème,
Artur