2016-03-24 7 views
2

Ich habe 2 Protokolle, die ich zusammenfügen muss, um alle Informationen zu bekommen, die ich brauche. summary.log hat die meisten Felder, die ich brauche (es gibt eine gute Anzahl von ihnen) zusammen mit einem Indikator, ob dieses Ereignis für mich gilt. location.log hat genau 1 Feld, das ich brauche, zusammen mit einer eindeutigen Kennung, um die Logs zu verknüpfen.Splunk Karte ohne Felder zu verlieren

Zuerst dachte ich, einen Join-Befehl zu verwenden, wie der Name andeutet, aber die resultierenden Felder der ersten Suche können nicht in einem Subsarch verwendet werden (welcher Join verwendet). Dann entdeckte ich den Map-Befehl, der genau das erlaubt, aber die Map hat eine Nebenwirkung, alle Felder zu löschen, die gerade nicht von der Map gekommen sind. Später dachte ich, ich könnte Collect oder outputlookup verwenden, um die Felder vorübergehend zu speichern. Aber ich brauche mehrere Leute, um diese Abfrage ohne Race Conditions ausführen zu können, so dass ein Lookup nicht in Frage kommt. collect testmode = true könnte funktionieren (oder auch nicht), aber nur existierende Indizes können verwendet werden, und ich werde keinen leeren Index erstellen und sicherstellen, dass er leer bleibt. Nach ein wenig Online-Suche konnte ich keine anderen Befehle finden, die kein Unterverzeichnis verwendeten (daher hat set das gleiche Problem wie Join). So konnte ich mit nur drei Optionen kommen:

Option 1:

source=summary.log | xmlkv | search transactionFailed=true 
| join transactionId max=0 [search 
source=summary.log | xmlkv | search transactionFailed=true 
| map search="search source=location.log \"[$transactionId$]\" | eval transactionId=\"$transactionId$\"" 
| rex "(?<locationId>\w+)$" | fields transactionId locationId] 
| table * 

Option 2:

source=summary.log | xmlkv | search transactionFailed=true 
| map search="search source=location.log \"[$transactionId$]\" | eval transactionId=\"$transactionId$\" 
| eval every=\"$every$\" | eval single=\"$single$\" | eval field=\"$field$\" | eval I=\"$I$\" | eval need=\"$need$\"" 
| rex "(?<locationId>\w+)$" | table * 

Option 3:

source=location.log | rex "\[(?<transactionId>.+?)\]" | rex "(?<locationId>\w+)$" 
| map search="source=summary.log \"$transactionId$\" | eval locationId=\"$locationId$\"" 
maxsearches=2147483647 
| xmlkv | search transactionFailed=true | table * 

Option 1 macht genau das gleiche suche zweimal (deshalb habe ich untersucht, wie man seine Ergebnisse mit collect oder outputlookup speichert), aber ein Problem ist, dass dies einfach ist eine vereinfachte Scheinabfrage, die tatsächliche Abfrage ist kompliziert und die Wiederholung der großen Sache ist nicht-trocken und wahrscheinlich schlecht für die Leistung.

Option 2 erfordert eine Liste von jedem einzelnen Feld, das funktioniert, aber ist chaotisch (ich denke, es ist etwa 10 Felder). Es ist auch nicht flexibel, aber das ist keine Voraussetzung, da sich die Felder in absehbarer Zeit nicht ändern werden.

Option 3 wird nie enden, wie immer. Die überwiegende Mehrheit der Transaktionen sind keine Fehler und der Map-Befehl ist sehr langsam. Nein, ich brauche nicht mehr als ein paar Tausend, die obigen Max-Searches sollten nur das Problem des syntaktisch saubersten Ansatzes hervorheben.

Alle von ihnen sind schlecht. Option 3 ist keine Option. Optionen 1 ist langsam und unordentlich. Optionen 2 ist unordentlich, aber ansonsten gut, so dass es das Beste ist. Ich habe einige Zeit damit verbracht, durch Splunk-Dokumentation zu suchen, aber es könnte einen relevanten Befehl geben, den ich verpasst habe. Ich habe keine Fragen anderer Leute gefunden, die mit meinem Problem übereinstimmen.

Was mich verblüfft ist, dass dies ein recht normaler Anwendungsfall für den Map-Befehl ist, aber es gibt no option, um alle nicht-internen Felder zu behalten.

Fazit: Gibt es eine Möglichkeit, eine solche Suche auf eine saubere und vernünftige Art und Weise durchzuführen?

Ich bin gerade nicht bei der Arbeit, aber ich denke, die Version von Splunk ist 6.1.8 (es ist nicht Splunk Mint).

+1

Eigentlich (anstelle eines optionalen Arguments) würde es viel sinnvoller sein, wenn map alle Felder standardmäßig beibehalten würde und die Verwendung von "fields - *" erforderlich wäre, um sie zu entfernen. Aber so ist es nicht, und wenn man es ändert, wäre das nicht rückwärtskompatibel (dh vorhergehende Abfragen brechen). – SkySpiral7

+0

Hey, hast du jemals eine Lösung gefunden? Ich treffe das gleiche Problem. – dobbs

+0

@dobbs Nicht wirklich. Ich habe nie auf der Splunk-Website gefragt, so dass es einen Versuch wert sein könnte. Allerdings scheint Splunk schlecht konzipiert zu sein: Es gibt eine große Anzahl von Suchbefehlen, die sich überlappen und mit einem kleineren Satz von kleinen granularen Befehlen ohne Überlappung besser wären. Mehr auf den Punkt: Siehe meine Antwort. – SkySpiral7

Antwort

0

Splunk unterstützt nur Piping Dinge wie SQL, aber wir wollen etwas mehr wie PL/SQL, so dass wir ein Werkzeug in einer Weise verwenden, für die es nicht entwickelt wurde. Das bedeutet, dass es ohne eine Änderung von Splunk keine gute Möglichkeit gibt, dies zu tun.

Die beste Lösung ist derzeit, dass die App alles Interessante berechnet und protokolliert. In meinem Beispiel das sommerliche.log sollte die locationId enthalten. Nach einiger Zeit ist es nicht schwer, alle wichtigen Felder zu kennen und diese in jedes anwendbare Protokoll einzutragen (vor dem Start müssen Sie nur noch auf QA raten). Idealerweise sollten Sie für jeden Zweck ein Protokoll haben: performance.log, security.log, errors.log, businessMetrics.log (zB "wie viele Erfolge pro Tag in New York?") Jeweils mit allen benötigten Feldern in einem netten Schlüssel Wertpaar-Format. Es ist in Ordnung, wenn das gleiche Feld in mehreren Protokollen vorhanden ist und für ein einzelnes Ereignis mehr als 1 Protokoll ausgelöst wird. Wenn alles gut geht, könnten Sie Splunk für etwas billiger und besser wie Elasticsearch fallen lassen (Sie müssen möglicherweise ein Skript ausführen, um alte Protokolle in JSON zu konvertieren).

Also die "Lösung" zu diesem Splunk-Problem ist, Splunk nicht zu verwenden ... Yeah, das ist eine schlechte Indikation für Splunk. Damit Splunk wirklich glänzt, muss JavaScript (oder eine andere Sprache) mit vordefinierten Funktionen für den Zugriff auf die Protokolle unterstützt werden. Aber selbst dann: Warum brauchen Sie extrem komplexe Suchen? Wenn diese Felder alle in den Protokollen vorhanden sind, können Sie sie auch an leicht erreichbaren Orten platzieren. Daher wäre Splunk nur dann nützlich, um geschäftliche Fragen zu beantworten, die ein nicht standardmäßiges Feld betreffen, oder um ein Problem zu beheben, das mit den vorhandenen Feldern nicht gelöst werden kann (beide Beispiele verwenden rex, xmlkv oder spath zum Parsen).