Filtern von OpenTelemetry-Protokollen
Der OpenTelemetry -Collector ermöglicht es, die erfassten Protokolldaten auf viele verschiedene Arten zu filtern. Dieses Dokument enthält Beispiele für das Filtern von Protokollen in bestimmten allgemeinen Szenarios. Diese Funktionen sind nur im Contrib-Repository des OpenTelemetry -Collectors enthalten, sodass diese Beispiele diese Version erfordern. Weitere Informationen finden Sie in der Dokumentation zum „ OpenTelemetry -Collector“.
Protokolle nach ihrem Inhalt filtern
Der Filterprozessor akzeptiert reguläre Ausdrücke, die auf den Inhalt von Protokollnachrichten angewendet werden. Alle Protokollnachrichten, die dem angegebenen regulären Ausdruck entsprechen, werden gelöscht und nie an den Empfänger am anderen Ende weitergeleitet.
Beispiele
Alle diese Beispiele folgen einem ähnlichen Muster. Der Konfigurationsdatei des Opentelemetry-Collectors muss ein Abschnitt filter hinzugefügt werden, und dieser Filter muss in derselben Datei in die logs/processors -Pipeline eingeschlossen werden. Wenn Sie Helm für die Installation des Kollektors verwenden, wird die Konfiguration im Abschnitt config: der Datei values.yaml bei der Installation ausgeführt.
Protokollmeldungen ausschließen, die eine bestimmte Teilzeichenfolge enthalten
Betrachten Sie eine Protokolldatei, die eine Zeitmarke, eine Protokollebene und eine Nachricht wie im folgenden Beispiel enthält:
2024-02-09 13:00:51 ERROR This is a test error message
2024-02-09 13:02:49 ERROR This is a test error message containing a secret
Diese Protokolle können mit einer Dateiprotokoll-Empfängerkonfiguration wie der folgenden allgemeiner abgeglichen werden:
receivers:
filelog/simple:
include: [ /tmp/foo.log ]
operators:
- type: regex_parser
regex: '^(?P<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (?P<sev>[A-Z]*) (?P<msg>.*)$'
timestamp:
parse_from: attributes.time
layout: '%Y-%m-%d %H:%M:%S'
severity:
parse_from: attributes.sev
Der angegebene reguläre Ausdruck ordnet die Zeitmarke und den Schweregrad den benannten Erfassungsgruppen zu. Die Zeitmarke layout ist so definiert, dass der Collector das Format versteht, das es ermöglicht, die richtige Zeitmarke aus der Protokollnachricht als Zeitmarke des Datensatzes zu verwenden, den der Collector an den Server sendet. Die Wertigkeit wird unverändert gesendet.
Dieser Empfänger muss der logs/receivers -Pipeline hinzugefügt werden:
pipelines:
logs:
receivers:
- filelog/simple
Diese Konfiguration meldet alle ordnungsgemäß formatierten Nachrichten aus dem Protokoll an den Server zurück.
Eine der Protokollmeldungen enthält jedoch ein Geheimnis. Um Nachrichten auszuschließen, die geheime Schlüssel enthalten, fügen Sie einen Filter zum Abschnitt processors der Konfiguration hinzu. Der Filter muss einen regulären Ausdruck enthalten, der mit jeder Zeichenfolge übereinstimmt, die das Wort enthält secret. Im folgenden Beispiel wird die OTTL-Funktion „ IsMatch(...)“ verwendet, um nach einer beliebigen Zeichenfolge zu suchen, die das Wort „ secret.“ enthält.
processors:
filter/remove_secret:
error_mode: ignore
logs:
log_record:
- 'IsMatch(body, ".*secret.*")'
Fügen Sie den folgenden Filter zur processors -Pipeline hinzu:
pipelines:
logs:
receivers:
- filelog/simple
processors:
- filter/remove_secret
Bei dieser Konfiguration wird nur die erste Nachricht aus den Beispielprotokollzeilen gemeldet, aber die zweite Nachricht, die das Wort "secret" enthält, wird gelöscht.
Syslog-Meldungen eines bestimmten Dienstes ausschließen
Betrachten Sie ein Syslog auf einem Linux® -System. Wenn jemand den Gnome-Desktop auf diesem System verwendet, kann dies zu lauten Protokollen führen:
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 31 with keysym 31 (keycode a).
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 32 with keysym 32 (keycode b).
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 33 with keysym 33 (keycode c).
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 34 with keysym 34 (keycode d).
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 35 with keysym 35 (keycode e).
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 36 with keysym 36 (keycode f).
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 37 with keysym 37 (keycode 10).
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 38 with keysym 38 (keycode 11).
Feb 9 09:10:00 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b org.gnome.Shell.desktop[4771]: Window manager warning: Overwriting existing binding of keysym 39 with keysym 39 (keycode 12).
Feb 9 09:10:26 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b systemd[1]: fprintd.service: Succeeded.
Wie im ersten Beispiel kann der filelog -Empfänger dieses Protokoll überwachen und die Zeitmarke mithilfe eines regulären Ausdrucks zuordnen:
receivers:
filelog/syslog:
include: [ /var/log/syslog ]
operators:
- type: regex_parser
regex: '^(?P<time>[A-Za-z]{3}[ ]+\d{1,2} \d{2}:\d{2}:\d{2}) (?P<msg>.*)$'
timestamp:
parse_from: attributes.time
layout: '%b %e %H:%M:%S'
Der Zeitstempel sieht anders aus als im ersten Beispiel, lässt sich aber mit dem richtigen regulären Ausdruck und der richtigen Layoutdefinition verstehen. Dieses Protokoll enthält keinen Schweregrad. Der Empfänger muss wie immer in die logs/receivers -Pipeline eingeschlossen werden:
pipelines:
logs:
receivers:
- filelog/simple
- filelog/syslog
Auf einem Serversystem kann es sinnvoll sein, die Systemprozesse zu überwachen, aber Protokolle auszuschließen, die von der Desktopumgebung generiert werden. Ein Filter für reguläre Ausdrücke kann alle Nachrichten eines bestimmten Service blockieren:
processors:
filter/remove_gnomeshell:
error_mode: ignore
logs:
log_record:
# message body will have the timestamp stripped off by the regex_parser, so it looks like:
# "hostname service[pid]: message"
# Regex matches this as:
# [^ ]+ <hostname> One or more non-whitespace characters, followed by
# A space, followed by
# org.gnome.Shell.desktop <service name> followed by
# [ followed by
# [0-9]+ <pid> one or more numeric digits, followed by
# ]: followed by
# .* <message> the rest of the log message
- 'IsMatch(body, "[^ ]+ org.gnome.Shell.desktop\\[[0-9]+\\]:.*")'
Fügen Sie den Filter zur logs/processors -Pipeline hinzu:
logs:
receivers:
- filelog/simple
- filelog/syslog
processors:
- filter/remove_secret
- filter/remove_gnomeshell
Jetzt werden alle Protokollsätze, bei denen das Servicefeld org.gnome.Shell.desktop ist, gelöscht.
Protokollfilterung anhand von Infrastrukturdaten
Der Filterprozessor kann anhand der Informationen filtern, die im resource attributes Abschnitt der Nutzlast bereitgestellt werden. Dieser Prozessor ermöglicht es, alle Nachrichten beispielsweise von einem bestimmten Pod unter Kubernetes, einem gesamten Namespace unter Kubernetes oder einem bestimmten Host auszuschließen. Weitere Informationen zu den unterstützten Infrastrukturdaten finden Sie unter „Infrastrukturdaten “.
Protokolle nach Schweregrad filtern
Es kann Fälle geben, in denen Container so konfiguriert sind, dass sie Protokolle mit unterschiedlichen Schweregraden erstellen. In solchen Fällen empfiehlt es sich, alle Meldungen außer ERROR- und FATAL-Meldungen herauszufiltern, um zu vermeiden, dass der Collector mit unnötigen Daten überflutet wird.
Betrachten Sie die folgenden Beispielprotokolle:
[15:52:30 DEBUG] Some debug message.
[15:52:30 INFO] Some info message.
[15:52:30 ERROR] Some error message.
[15:52:30 FATAL] Some fatal message.
Um die DEBUG- und INFO-Protokolle nach Schweregrad zu filtern, müssen Sie zunächst das severity_text Feld für jeden Protokolleintrag festlegen. Dies lässt sich mithilfe des folgenden transform Beispielprozessors bewerkstelligen:
transform/set_log_severity:
log_statements:
- context: log
statements:
- set(severity_text, "Debug") where IsMatch(body.string, "\\[[0-9]{2}:[0-9]{2}:[0-9]{2} DEBUG\\]")
- set(severity_text, "Info") where IsMatch(body.string, "\\[[0-9]{2}:[0-9]{2}:[0-9]{2} INFO\\]")
- set(severity_text, "Error") where IsMatch(body.string, "\\[[0-9]{2}:[0-9]{2}:[0-9]{2} ERROR\\]")
- set(severity_text, "Fatal") where IsMatch(body.string, "\\[[0-9]{2}:[0-9]{2}:[0-9]{2} FATAL\\]")
severity_text auf eine leere Zeichenkette gesetzt, was von Instana als NoneSchweregrad interpretiert wird.Wenn die severity_text Einstellung im Protokollsatz festgelegt ist, können Sie den folgenden filter Beispielprozessor verwenden, um Protokolle mit einem Schweregrad unterhalb von „ERROR“ sowie Protokolle ohne Schweregrad zu ignorieren.
filter/remove_unnecessary_logs:
logs:
log_record:
- IsMatch(severity_text, "^(|Debug|Info)$")
In diesem Beispiel wird die Funktion `OTTL IsMatch(...)` verwendet, um Protokolle auszuschließen, bei denen der angegebene reguläre Ausdruck mit dem leeren Zeichenfolgenwert, dem DebugKomma sowie den Info Protokollschweregraden übereinstimmt.
Alternativ können Sie mithilfe des Schlüsselworts „not“ anhand des Schweregrads der Protokolle angeben, welche Protokolle einbezogen statt ausgeschlossen werden sollen. Auf diese Weise filtern Sie nun Protokolle heraus, die nicht den Schweregraden Error oder entsprechen Fatal.
filter/remove_unnecessary_logs:
logs:
log_record:
- not IsMatch(severity_text, "^(Error|Fatal)$")
Fügen Sie in diesem service/pipelines/logs/processors Abschnitt den neuen Filter ein:
processors:
- resourcedetection
- transform/set_log_severity
- filter/remove_unnecessary_logs
- batch
Protokolle nach Ressourcenattributen filtern
Im Folgenden finden Sie eine nicht erschöpfende Liste von Beispielattributen für Ressourcen, die für die Protokollfilterung verwendet werden können:
Beispiele für Attribute, die vom Prozessor „ k8sattributes “ und vom Prozessor „resourcedetection“ erfasst werden:
resource.attributes["k8s.pod.name"]: Der Name des „ Kubernetes “-Pods, der die Protokollmeldung generiert hatresource.attributes["k8s.container.name"]: Der Name des zugrunde liegenden Containers, der die Protokollmeldung generiert hatresource.attributes["k8s.namespace.name"]: Der Name des Namespace, der den Pod enthält, der die Protokollmeldung generiert hatresource.attributes["k8s.deployment.name"]: Der Name des „ Kubernetes “-Bereitstellungsobjekts, das den Pod steuert, der die Protokollmeldung generiert hatresource.attributes["k8s.node.name"]: Der Name des „ Kubernetes “-Knotens, auf dem der Pod läuft, der die Protokollmeldung erzeugt hatresource.attributes["k8s.pod.hostname"]: Der Name des Hosts, auf dem der Prozess läuft, der die Protokollmeldung erzeugt hat. Wenn der Collector in einem Container ausgeführt wird, ist der Hostname in der Regel der Name des Containers und nicht der Name des eigentlichen zugrunde liegenden Hostsresource.attributes["os.type"]: Der Betriebssystemtyp des Hosts, auf dem der Prozess läuft, der die Protokollmeldung erzeugt hat
Durch den Einsatz desk8sattributes -Prozessors, des Ressourcenprozessors und des Transformationsprozessors können benutzerdefinierte Attribute im resource.attributes Mapping dynamisch festgelegt und für eine anpassbare Protokollfilterung verwendet werden.
Beispiele
Alle diese Beispiele folgen einem ähnlichen Muster. Der Konfigurationsdatei des Opentelemetry-Collectors muss ein Abschnitt filter hinzugefügt werden, und dieser Filter muss in derselben Datei in die logs/processors -Pipeline eingeschlossen werden. Wenn Sie Helm für die Installation des Kollektors verwenden, wird die Konfiguration im Abschnitt config: der Datei values.yaml bei der Installation ausgeführt.
Protokollmeldungen aus einem bestimmten „ Kubernetes “-Container ausschließen
Angenommen, Sie möchten alle Protokollnachrichten aus einem Kubernetes -Container mit dem Namen calico-nodeherausfiltern. Fügen Sie im Abschnitt processors der Konfiguration einen Block wie den folgenden hinzu:
filter/remove_calico:
error_mode: ignore
logs:
log_record:
- resource.attributes["k8s.container.name"] == "calico-node"
Schließen Sie dann im Abschnitt service/pipelines/logs/processors den neuen Filter ein:
processors:
- resourcedetection
- transform/set_log_severity
- filter/remove_calico
- batch
Der neue Filter wird zuletzt aufgelistet. Die anderen Prozessoren, die angezeigt werden, dienen nur dem Kontext und werden nicht benötigt, damit der Filterprozessor funktioniert.
Protokollmeldungen von allen „ Linux® “-Systemen ausschließen
Wenn Sie alle Protokollnachrichten von einem Linux®-basierten System blockieren möchten, können Sie im Abschnitt 'processors der Konfiguration Folgendes hinzufügen:
filter/remove_linux:
error_mode: ignore
logs:
log_record:
- resource.attributes["os.type"] == "linux"
Ebenso schließen Sie im Abschnitt service/pipelines/logs/processors auf der Basis des vorherigen Beispiels den neuen Filter ein:
processors:
- resourcedetection
- transform/set_log_severity
- filter/remove_calico
- filter/remove_linux
- batch
Ausschluss von Protokollmeldungen eines bestimmten „ Kubernetes “-Pods oder einer bestimmten „“-Bereitstellung mit bestimmten Labels oder Annotationen
Angenommen, Sie haben die folgende „ Kubernetes “-Bereitstellung mit den Labels und Annotationen, bei der Sie alle Protokollmeldungen herausfiltern möchten:
apiVersion: apps/v1
kind: Deployment
metadata:
[...]
spec:
[...]
template:
metadata:
labels:
some-keyword-label: "ABCD-label-substring-ABCD"
annotations:
some-keyword-annotation: "ABCD-annotation-substring-ABCD
Wenn Sie nach some-keyword-label oder filtern some-keyword-annotation möchten, können Sie den k8sattribute Prozessor wie im folgenden Beispiel gezeigt erweitern, um alle Pod-Labels und -Annotationen zu erfassen:
processors:
k8sattributes:
[...]
extract:
metadata:
[...]
## Note: The '$$1' is a placeholder for the label or annotation name and will be used in the 'resource.attributes' mapping.
labels:
- tag_name: $$1
key_regex: (.*)
from: pod
annotations:
- tag_name: $$1
key_regex: (.*)
from: pod
Verwenden Sie das folgende Beispiel, um die some-keyword-label Bezeichnung und some-keyword-annotation die Anmerkung zu extrahieren:
processors:
k8sattributes:
[...]
extract:
metadata:
[...]
## Note: In this example same label or annotation names are used as the ones to be extracted.
## The 'tag_name' corresponds to the key in the 'resource.attributes' mapping.
## The 'key' corresponds to the label or annotation you want to extract.
labels:
- tag_name: some-keyword-label
key: some-keyword-label
from: pod
annotations:
- tag_name: some-keyword-annotation
key: some-keyword-annotation
from: pod
Sobald Sie den k8sattributes Prozessor so konfiguriert haben, dass er die gewünschten Labels und Annotationen extrahiert, können Sie den filter Prozessor filter_by_keyword oder verwenden, um Log-Meldungen von Pods auszuschließen, die das some-keyword-label Label oder some-keyword-annotation die Annotation haben:
filter/keyword_filter:
logs:
log_record:
## Note: You can add as many filters as you would like if there are multiple labels/annotations.
- IsMatch(resource.attributes["some-keyword-label"], ".*(label-substring).*")
- IsMatch(resource.attributes["some-keyword-annotation"], ".*(annotation-substring).*")
Fügen Sie in diesem service/pipelines/logs/processors Abschnitt, aufbauend auf dem vorherigen Beispiel, den neuen Filter ein:
processors:
- resourcedetection
- filter/filter_by_keyword
- batch
Der neue Filter wird zuletzt aufgelistet. Die anderen Prozessoren, die angezeigt werden, dienen nur dem Kontext und werden nicht benötigt, damit der Filterprozessor funktioniert.
Schwärzen sensibler Informationen in Protokollen
Protokollnachrichten enthalten manchmal personenbezogene Daten oder andere sensible Daten, die privat gehalten und nicht an den Server gesendet oder gespeichert werden müssen. Zu diesen Informationen können Kennwörter, Kreditkartennummern oder eine beliebige Anzahl anderer Elemente gehören. Der transform -Prozessor kann solche Informationen mithilfe eines regulären Ausdrucks erkennen und durch einen anderen Ausdruck ersetzen.
Beispiele
Diese Beispiele folgen einem ähnlichen Muster. Der Konfigurationsdatei des Opentelemetry-Collectors muss ein Abschnitt transform hinzugefügt werden und diese Transformation muss in derselben Datei in die logs/processors -Pipeline eingeschlossen werden. Wenn Sie Helm für die Installation des Kollektors verwenden, wird die Konfiguration im Abschnitt config: der Datei values.yaml bei der Installation ausgeführt.
Passwörter aus Protokollmeldungen entfernen
Angenommen, eine Anwendung protokolliert das angegebene Kennwort, wenn ein Authentifizierungsfehler auftritt. Der Protokollsatz könnte wie folgt aussehen:
2024-02-14 19:40:31 WARNING failed login for user bob, password=bobo
Es ist wichtig zu wissen, dass ein fehlgeschlagener Anmeldeversuch aufgetreten ist, aber es ist ungeeignet, das verwendete Kennwort zu protokollieren.
Die Anwendung protokolliert das Kennwort in einem bekannten Format. Das Muster ist immer password=xyz. Ein regulärer Ausdruck kann dieses Muster erkennen und durch etwas anderes ersetzen:
transform/redact_password:
log_statements:
- context: log
statements:
# Any log messages containing "password=xxx" or "passwd=yyy" will be matched.
# Regex matches these as:
# passw The literal string 'passw', followed by
# (?:or)?? The literal string "or" 0 or 1 times (this allows either password or passwd)
# d= The literal string "d=", followed by
# [^\s]* Any non-whitespace characters (the password), followed by
# (\s?)* 0 or more whitespace characters, marking the end of the password.
- replace_pattern(body, "passw(?:or)??d\\=[^\\s]*(\\s?)", "password=REDACTED")
- replace_pattern(attributes["msg"], "passw(?:or)??d\\=[^\\s]*(\\s?)", "password=REDACTED")
Die Anweisung replace_pattern tritt einmal für die Nachricht body und einmal für das Attribut msg auf. Der geöffnete Telemetriekollektor stellt den Inhalt der Nachricht an beide Stellen, sodass beide aktualisiert werden müssen.
Fügen Sie die Transformation zur logs/processors -Pipeline hinzu:
logs:
receivers:
- otlp
- filelog/simple
processors:
- transform/redact_password
Die Transformation wandelt die ursprüngliche Protokollnachricht wie folgt um:
2024-02-15 15:45:37 WARNING failed login for user bob, password=REDACTED
Entfernen von Hostnamen aus Protokollmeldungen
Angenommen, eine andere Anwendung schreibt Hostnamen in das Systemprotokoll:
Feb 15 15:52:36 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b service[45568]: This is a test error message from where.ever.ibm.com
Wenn die Hostnamen als vertraulich betrachtet werden, ist es möglich, dass sie dem Protokoll hinzugefügt werden. Wenn sich alle Hosts in derselben Domäne befinden, in diesem Beispiel .ibm.com, kann ein regulärer Ausdruck das Muster erkennen und die Namen verschleiern:
transform/remove_hostnames:
log_statements:
- context: log
statements:
# Any log message containing a hostname ending in ".ibm.com" will have the hostname removed.
# Regex matches as:
# ([a-zA-Z0-9-_\.]+) One or more letters, digits, dashes, underscores, or dots, followed by
# \.ibm\.com The literal string ".ibm.com"
- replace_pattern(body, "([a-zA-Z0-9-_\\.]+)\\.ibm\\.com", "<hidden hostname>")
- replace_pattern(attributes["msg"], "([a-zA-Z0-9-_\\.]+)\\.ibm\\.com", "<hidden hostname>")
Auch hier werden das Attribut body und das Attribut msg neu geschrieben, da der Protokollnachrichtentext an beiden Stellen auftritt.
Fügen Sie erneut die Transformation zur Pipeline hinzu:
logs:
receivers:
- filelog/syslog
processors:
- transform/redact_password
- transform/remove_hostnames
Anschließend wird die Nachricht wie folgt neu geschrieben:
Feb 15 15:52:36 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b service[45568]: This is a test error message from <hidden hostname>