2014-11-14 7 views
5

Ich habe eine Java-Anwendung, die in eine Protokolldatei im JSON-Format schreibt. Die Felder in den Protokollen sind variabel. Der Logstash liest diese Logdatei und sendet sie an Kibana.Logstash + Kibana Begriffe Panel ohne Wörter zu brechen

Ich habe die logstash mit folgenden Datei konfiguriert:

input { 
     file { 
       path => ["[log_path]"] 
       codec => "json" 
     } 
} 

filter{ 
     json { 
       source => "message" 
     } 

     date { 
       match => [ "data", "dd-MM-yyyy HH:mm:ss.SSS" ] 
       timezone => "America/Sao_Paulo" 
     } 
} 

output { 
     elasticsearch_http { 
       flush_size => 1 
       host => "[host]" 
       index => "application-%{+YYYY.MM.dd}" 
     } 
} 

Ich habe es geschaffen, ohne Zuordnung korrekt alles in Kibana zu zeigen. Aber wenn ich versuche, ein Terms Panel zu erstellen, um die Anzahl der Server anzuzeigen, die diese Nachrichten gesendet haben, habe ich ein Problem. Ich habe ein Feld namens Server in meinem JSON, die den Servernamen anzeigen (wie: a1-Name-Server1), aber die Begriffe Panel teilen den Servernamen wegen der "-". Auch ich möchte zählen, wie oft eine Fehlermeldung angezeigt wird, aber das gleiche Problem tritt auf, weil die Begriffe Panel die Fehlermeldung wegen der Leerzeichen aufgeteilt.

Ich benutze Kibana 3 und Logstash 1.4. Ich habe viel im Internet gesucht und konnte keine Lösung finden. Ich habe auch versucht, die .raw von Logstash, aber es hat nicht funktioniert.

Wie kann ich das schaffen?

Danke für die Hilfe.

Antwort

1

Da Sie in elasticsearch kein Mapping definiert haben, finden die Standardeinstellungen für jedes Feld in Ihrem Typ in Ihrem Index statt. Die Standardeinstellungen für Zeichenfolgenfelder (wie Ihr Serverfeld) lautet Analysieren Sie das Feld, was bedeutet, dass die elastische Suche den Feldinhalt tokenisiert. Deshalb teilt es Ihre Servernamen in Teile.

Sie können dieses Problem lösen, indem Sie ein Mapping definieren. Sie müssen nicht alle Felder definieren, sondern nur diejenigen, die nicht von elasticsearch analysiert werden sollen. In Ihrem speziellen Fall, wird der folgende Befehl put sendet den Trick:

http://[host]:9200/[index_name]/_mapping/[type] 

{ 
    "type" : { 
     "properties" : { 
      "server" : {"type" : "string", "index" : "not_analyzed"} 
     } 
    } 
} 

Sie das nicht auf einem bereits vorhandenen Index tun kann, weil von zu analysiere not_analyzed Schalt ist eine große Veränderung in der Abbildung.

4

Ihr Problem hier ist, dass Ihre Daten Tokenized sind. Dies ist hilfreich, um Ihre Daten zu durchsuchen. ES (standardmäßig) teilt Ihr Feld message in verschiedene Teile auf, um sie durchsuchen zu können. Zum Beispiel möchten Sie möglicherweise nach dem Wort in Ihren Protokollen suchen, also möchten Sie wahrscheinlich in den Ergebnissen Nachrichten wie "Es war ein Fehler in Ihrem Cluster" oder "Fehler Verarbeitung was auch immer" sehen möchten. Wenn Sie die Daten für dieses Feld nicht mit tokenizers analysieren, können Sie nicht so suchen.

Dieses analysiert Verhalten ist hilfreich, wenn Sie die Dinge suchen möchten, aber es nicht erlaubt, wenn verschiedene Nachrichten gruppieren, die den gleichen Inhalt haben. Dies ist dein Anwendungsfall. Die Lösung besteht darin, Ihr Mapping zu aktualisieren, indem Sie not_analyzed für das spezifische Feld eingeben, das nicht in Tokens aufgeteilt werden soll. Dies wird wahrscheinlich für Ihr host Feld funktionieren, wird aber wahrscheinlich die Suche unterbrechen.

Was ich normalerweise für diese Art von Situationen tue, ist die Verwendung von index templates und multifields. Die Indexvorlage erlaubt mir, eine Zuordnung für jeden Index festzulegen, die einer Regex entsprechen, und die Multifelder ermöglichen mir, das analyzed und not_analyzed Verhalten in einem gleichen Feld zu haben.

die folgende Abfrage verwenden würde die Arbeit für Ihr Problem tun:

curl -XPUT https://example.org/_template/name_of_index_template -d ' 
{ 
    "template": "indexname*", 
    "mappings": { 
     "type": { 
      "properties": { 
       "field_name": { 
        "type": "multi_field", 
        "fields": { 
        "field_name": { 
         "type": "string", 
         "index": "analyzed" 
        }, 
        "untouched": { 
         "type": "string", 
         "index": "not_analyzed" 
        }      
       } 
      } 
     } 
    } 
}' 

Und dann in Ihren Bedingungen Panel können Sie field.untouched verwenden, um den gesamten Inhalt des Feldes zu berücksichtigen, wenn Sie die Zählung der verschiedenen berechnen Elemente.

Wenn Sie keine Indexvorlagen verwenden möchten (möglicherweise liegen Ihre Daten in einem einzigen Index vor), würde auch das Festlegen der Zuordnung mit Put Mapping API die Aufgabe übernehmen. Wenn Sie mehrere Felder verwenden, müssen die Daten nicht erneut indiziert werden, da ab dem Zeitpunkt, an dem Sie das neue Mapping für den Index festlegen, die neuen Daten in diesen beiden Unterfeldern dupliziert werden (field_name und field_name.untouched). Wenn Sie nur die Zuordnung von analyzed zu not_analyzed ändern, können Sie keine Änderungen sehen, bis Sie alle Ihre Daten neu indiziert haben.

+0

Muss ich den genauen Feldnamen anstelle von "field_name" übergeben, oder funktioniert das nur für alle Felder? – brunodahora

+0

@brunodahora Sie müssen den Feldnamen angeben. – Pigueiras