Extrahieren von Werten aus dem CSV-Parser in Syslog-ng

Extrahieren von Werten aus dem CSV-Parser in Syslog-ng

Ich habe einen Syslog-Feed im CSV-Format, der von Syslog-ng mithilfe des CSV-Parsers aufgenommen und auf die Festplatte geschrieben wird.

So wie ich es verstehe, soll die Verwendung des CSV-Parsers Syslog-ng einen Kontext für die eingehenden Daten und die Bedeutung der Werte geben. Ich möchte diesen Kontext verwenden, damit Syslog-ng Filter basierend auf dieser Logik anwendet.

Ich möchte beispielsweise, dass ein Ereignis nur dann auf der Festplatte protokolliert wird, wenn eine der CSV-Spalten mit einem bestimmten Wert übereinstimmt.

Der CSV-ParserDokumentationscheint darauf hinzudeuten, dass dies möglich sein sollte.

Meine Konfiguration sieht ungefähr so ​​aus:

parser p_my_app {
    csv-parser(
        columns("MY_APP.COLOUR","MY_APP.SIZE","MY_APP.SERIAL_NUMBER")
        delimiters(",")
        flags(escape-double-char)
    );
};

source s_my_app {
    syslog(ip(0.0.0.0) port(6514)
        transport("tcp")
    );
}; 

filter f_my_app { 
    match("123456" value("MY_APP.SERIAL_NUMBER") );
};

destination d_my_app { 
    file("/var/log/my_app.log"
        create_dirs(yes)
    ); 
};

log { 
    source(s_my_app);
    filter(f_my_app);
    parser(p_my_app);
    destination(d_my_app); 
};

Es scheint jedoch, dass die Übereinstimmung nie übereinstimmt, egal wie sehr ich es versuche. Hier ist die Debug-Ausgabe von sylog-ng mit dieser Konfiguration:

Incoming log entry; line='<14>1 2017-01-18T17:46:38+11:00 hostname  - - - red,large,123456
'
Filter rule evaluation begins; rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'
Filter node evaluation result; result='not-match'
Filter rule evaluation result; result='not-match', rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'

Ich (hoffe?) ich übersehe etwas ganz Offensichtliches, aber ich kann nach stundenlangem Googeln keine vollständigen Beispiele online finden, nur Auszüge, die nie zu funktionieren scheinen. Kann jemand sehen, was ich falsch mache und/oder ein vollständiges funktionierendes Beispiel liefern?

Antwort1

Nun, wie es anscheinend immer so ist, verbringe ich eine Woche mit einem Problem, gebe auf, beschließe, mir Hilfe zu suchen – und finde eine Stunde später selbst die Lösung.

Mein Problem war die Reihenfolge der Elemente in der log()Anweisung. Insbesondere die parser()ZeileMUSSvor der filter()Aussage stehen.

Tatsächlich ist dieDokumentation(was ich bestimmt zehnmal gelesen und übersehen habe) besagt:

Notiz Die Reihenfolge der Filter, Umschreibregeln und Parser in der Protokollanweisung ist wichtig, da sie sequenziell verarbeitet werden.

Der funktionierende Code lautet also:

log { 
    source(s_my_app);
    parser(p_my_app);
    filter(f_my_app);
    destination(d_my_app); 
};

Außerdem ist noch etwas zu beachten: Es match()soll sich eigentlich um einen regulären Ausdruck handeln. Zur besseren Übersicht habe ich den Filter daher wie folgt aktualisiert:

filter f_my_app { 
    match("123456" value("MY_APP.SERIAL_NUMBER") type("string"));
};

Syslog-ng meldet jetzt:

Incoming log entry; line='<14>1 2017-01-18T17:46:38+11:00 hostname  - - - red,large,123456
'
Message parsing complete; result='1', rule='p_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:14:2'
Filter rule evaluation begins; rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'
Filter node evaluation result; result='match'
Filter rule evaluation result; result='match', rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'

verwandte Informationen