Formale Trennungsmarkierung von Syslog-Ereignissen?

7

Ich habe mir RFC5424 angesehen , um den formal angegebenen Marker zu finden, der ein Syslog-Ereignis beendet.

Leider konnte ich es nicht finden. Wenn ich also einen kleinen Syslog-Server implementieren wollte, der auf bestimmte Nachrichten reagiert, was ist der Marker, der eine Nachricht beendet (ja, normalerweise ist ein Ereignis eine einzelne Zeile, aber ich konnte es in der Spezifikation einfach nicht finden).

Klarstellung :

Ich nenne es Ereignis, weil ich eine Nachricht einer einzelnen Zeile zuordne. Ein Ereignis könnte möglicherweise so etwas wie sein

Type: foo
Source: webservers

Eine Botschaft an mich lautet:

Type: foo Source: webservers

http://tools.ietf.org/html/rfc5424#section-6 definiert:

SYSLOG-MSG      = HEADER SP STRUCTURED-DATA [SP MSG]

weder STRUCTURED-DATAnoch MSGsagen Sie mir, wie diese Felder enden. Insbesondere MSGwird definiert, MSG-ANY / MSG-UTF8was sich auf praktisch alles ausdehnt. Es gibt nichts, was besagt, dass eine neue Zeile das Ende markiert (oder ein 8oder ein afür diese Angelegenheit). Anhand der Beispielnachrichten (Abschnitt 6.5):

Dies ist eine gültige Nachricht oder zwei gültige Nachrichten, je nachdem, ob Sie sagen, dass ein HEADERElement in keinem MSGElement vorkommen darf :

buchstäbliche Leerzeichen

<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - <34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47
                                                                |
                                                               is this an end marker?

\t steht für eine Registerkarte

<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 -\t<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47
                                                                |
                                                               is this an end marker?

\n steht für eine Newline

<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 -\n<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47
                                                                |
                                                               is this an end marker?

Entweder habe ich den RFC falsch verstanden oder es wird einfach nichts erwähnt. Die im RFC angegebenen Größen geben nur an, mit welcher Mindestlänge ich arbeiten kann ...

ANTWORTEN? : Anscheinend habe ich den falschen RFC gelesen. Man muss die spezifischen Transport-RFCs gehen und sich daran halten http://tools.ietf.org/html/rfc5426#section-3.1 alles für den UDP-Transport sagt.

@joechip: Da Ihre Kommentare und Antworten dazu führen, dass ich tatsächlich ein bisschen mehr in den Transport-RFCs lese, werde ich Ihre Antwort gerne akzeptieren, wenn Sie sie ein bisschen in diese Richtung aktualisieren :)

Martin M.
quelle
OK strukturierte Daten enden mit einem, ]aber ein \nkönnte innerhalb PARAM-VALUEeines seinSD-ELEMENT
Martin M.
1
Welches ist, was ich gesagt habe: Es kann Zeilenumbrüche enthalten. Ich denke, Sie können nicht davon ausgehen, dass eine Nachricht einer einzelnen Zeile entspricht. Und ich stimme zu, dass der RFC nicht anzugeben scheint, wie die Nachrichtenlänge bestimmt wird, daher denke ich, dass die Zeichenfolge NULL-terminiert sein sollte.
Joechip
OK, jetzt bin ich verwirrt. Wollen Sie im Wesentlichen sagen: "Es gibt keine Spezifikation für Endmarkierungen" oder "Vielleicht ist es ein ASCII-NULL". Da es sich bei der Spezifikation nicht um einen Transport handelt, ist sie transportunabhängig. Ich könnte mir leicht einen SMTP-Transport für Syslog einfallen lassen und perfekt mit diesem RFC kompatibel sein. Alles, was mir sagt, ist, wie man die Nachricht in Felder aufteilt, nur nicht, was der letzte Teil ist, damit ich weiß, ob ein UDP / TCP / Was auch immer das Paket enthält 1 oder mehr Nachrichten. Suche ich für diese Frage den falschen RFC?
Martin M.
Ich habe die Antwort bearbeitet, um das gesamte Problem mit der Beendigung von Zeichenfolgen zu klären. Die Beendigung von Zeichenfolgen wird im Speicher benötigt, jedoch nicht über das Netzwerk. Und es stellt sich heraus, dass die Syslog-Nachricht etwas anderes als eine Zeichenfolge (dh einen Oktett-Stream) enthalten kann, die nicht zum Nullterminieren geeignet wäre.
Joechip

Antworten:

2

Was meinst du mit "Syslog-Ereignis"? Wenn Sie sich auf Syslog-Nachrichten beziehen, definiert RFC5424 die Syslog-Nachrichtensyntax in Abschnitt 6 eindeutig so, wie sie von einer Syslog-Anwendung zu einer anderen übertragen werden soll.

Wenn Sie sich darauf beziehen, wie sie von der empfangenden Syslog-Anwendung in den Protokolldateien gespeichert werden, trennen typische Syslog-Implementierungen einfach einen Datensatz mit Zeilenumbrüchen von einem anderen, und dies ist normalerweise kein konfigurierbares Verhalten. Darüber hinaus kann das Textfeld eines Syslog-Datensatzes auch Zeilenumbrüche enthalten, was die korrekte Analyse der Protokolldatei erschwert. Es kann normalerweise trotzdem analysiert werden, da jeder Syslog-Datensatz mit der üblichen Reihenfolge von Datum, Uhrzeit, Host und Tag beginnt, während auf Zeilenumbrüche in einem Syslog-Datensatz normalerweise kein ähnlicher Text folgt.

Ich denke, dass die Möglichkeit, das Syslog-Trennzeichen für gespeicherte Datensätze zu ändern, eine nützliche Funktion wäre, aber das Auftreten eines solchen Trennzeichens im Datensatz selbst sollte vermieden werden, damit dies nützlich ist. Das Hinzufügen von so viel Struktur zu einer Nur-Text-Datei ist ein Kompromiss. Wenn Sie sich für dieses Problem interessieren, sollten Sie möglicherweise das Schreiben in Protokolldateien in einem genau definierten Binärformat unterstützen (z. B. könnte SQLite hier hilfreich sein).

Bearbeiten: Eine genauere Untersuchung von RFC5424 Abschnitt 6 zeigt, dass eine Syslog-Nachricht zwei Formen haben kann:

HEADER SP STRUCTURED-DATA

oder

HEADER SP STRUCTURED-DATA SP MSG

Durch Erweitern der ABNF-Spezifikation können wir leicht erkennen, dass die erste Form entweder mit "-" oder "]" endet. Vor diesem letzten Zeichen können andere "-" und "]" Zeichen stehen, sodass es nicht für einen Syslog-Nachrichtenterminator verwendet werden kann.

Das Ende der zweiten Form hängt davon ab, wie MSG endet. MSG kann entweder eine UTF-8-Zeichenfolge (wie in RFC 3629 angegeben, die keine Zeichenfolgenbeendigung enthält) oder ein beliebiger Oktettstrom sein, der mit einem beliebigen Wert endet. Offensichtlich ist auch für dieses Formular kein solches Beendigungssymbol angegeben.

Tatsache ist jedoch, dass kein Syslog-Nachrichtenterminator erforderlich ist, unabhängig davon, in welcher Form er vorliegt, da die Nachrichtenlänge von der Transportschicht außerhalb des Bandes übertragen wird. Wenn das UDP-Paket von der Anwendung gesendet wird, muss die Syslog-Nachricht bereits gemäß Spezifikation vorbereitet und in einem Puffer gespeichert sein. Dieser Puffer wird von der Anwendung an eine Funktion oder Methode übergeben, um ihn zu senden, und die Anzahl der zu sendenden Bytes wird ebenfalls übergeben. Zum Beispiel haben wir in C:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);

In diesem Beispiel ist len die Anzahl der Bytes, die aus dem Puffer-Puffer entnommen und an den Remote-Host gesendet werden sollen.

Ebenso wird auf dem Syslog-Server eine andere Funktion oder Methode aufgerufen, wie diese:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);

Diese Funktion gibt die Länge der im Puffer buf empfangenen UDP-Nutzdaten in Byte zurück . Wenn die Anwendung versucht, mehr als diese zurückgegebene Länge zu lesen, wird Müll (oder ein Segmentierungsfehler) ausgegeben. Um ein Überschreiten dieser Grenze zu vermeiden, wird normalerweise direkt nach dem Aufruf von siz = recvfrom (...) ein NULL-Wert an Position buf [siz] gesetzt . Auf diese Weise kann jeder spätere Funktionsaufruf, der buf verwendet als Zeichenfolge verwendet, ordnungsgemäß. Diese Nullterminierung gilt natürlich nur für Zeichenfolgen und nicht für Oktett-Streams. Und dieser Nullwert wird, wie gesagt, normalerweise nicht über das Netzwerk übertragen, sondern nur von der empfangenden Anwendung hinzugefügt.

Im Fall des Syslog-Servers als empfangende Anwendung fügen die meisten Syslog-Server diese Nullterminierung möglicherweise für ihre interne Behandlung der empfangenen Zeichenfolge hinzu (wenn sie diese überhaupt als Zeichenfolge behandeln). In jedem Fall bleibt dieser Nullwert jedoch erhalten out, wenn die Zeichenfolge an die Protokolldatei angehängt wird, um die Textverarbeitung der gesamten Protokolldatei nicht zu stören.

Joechip
quelle
Wie wäre es mit lokalen TLS-Nachrichten, die nicht über UDP übertragen werden?
Nils
Nur ein anderer RFC zum Lesen (natürlich habe ich die Nummer nicht zur Hand). Aber im Grunde ist es der Transport, der definiert, wie bestimmt wird, wann eine Nachricht endet und wann eine neue beginnt. Laut UDP wird nur eine Nachricht pro Datagramm entweder vollständig oder abgeschnitten zugestellt. Ich weiß nicht, was TLS sagt ...
Martin M.
@Nils Es ist dasselbe, nur die TLS-Kapselung wird von RFC5425 geregelt. In Abschnitt 4.3 wird gezeigt, wie die gesamte Länge der Syslog-Nachricht (die Anzahl der Bytes) bei der Kapselung verwendet wird, und es wird angegeben, dass die Syslog-Nachricht selbst von RFC5424 (der bereits besprochenen) regiert wird.
Joechip
0

In Abschnitt 6.1 definieren sie eine Nachrichtenlänge. Ich würde mir vorstellen, dass wenn Sie die vollständige Nachricht erhalten, Sie den Header und die Daten haben und sich diese Länge summieren würde.

Darüber hinaus sehe ich dort keine Möglichkeit für mehrere Nachrichten. Ich würde mir also vorstellen, dass jede Nachricht ein Ereignis ist. Es gibt keine Mehrnachrichtenverfolgung jeglicher Art und keine spezifizierte Codierung für Start-, Mittel- und Endnachrichten. Syslog verfolgt protokollierte Nachrichten und verfügt nicht über ein übergeordnetes Ereigniskonzept.

Kennzeichen
quelle