Filtragem de registros OpenTelemetry
O Coletor OpenTelemetry permite que os dados do log que ele coleta sejam filtrados de muitas maneiras diferentes Este documento fornece exemplos de como filtrar logs em determinados Cenários comuns. Esses recursos são incluídos apenas no repositório do OpenTelemetry Collector Contrib, portanto, esses exemplos requerem essa versão. Para obter mais informações, consulte a documentação de contribuições do OpenTelemetry Collector.
Filtrar registros por seu conteúdo
O processador de filtro aceita expressões regulares que são aplicadas ao conteúdo de mensagens de registro. Quaisquer mensagens de log que correspondam à expressão regular fornecida são descartados, e nunca encaminhados para o receptor na outra extremidade
Exemplos
Todos estes exemplos seguem um padrão similar. Uma seção filter deve ser incluída no arquivo de configuração do opentelemetry-collector e esse filtro deve ser incluído no pipeline logs/processors no mesmo arquivo. Se você estiver usando Helm para instalar o coletor, a configuração entrará na seção config: do arquivo values.yaml na instalação.
Excluindo mensagens de log que contenham uma determinada subseqüência
Considere um arquivo de log que contém um registro de data e hora, um nível de log e uma mensagem, como este exemplo:
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
Esses logs podem ser correspondidos de forma mais geral usando uma configuração de receptor de filelog como esta:
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
A expressão regular fornecida designa o registro de data e hora e a severidade para os grupos de captura nomeados O registro de data e hora layout é definido para que o coletor entenda o formato, o que permite que o registro de data e hora correto da mensagem de log seja usado como o registro de data e hora do registro que o coletor envia para o servidor A gravidade é enviada inalterada.
Este receptor deve ser incluído no pipeline logs/receivers :
pipelines:
logs:
receivers:
- filelog/simple
Essa configuração relata todas as mensagens formatadas corretamente do log de volta para o servidor
No entanto, uma das mensagens de log esconde um segredo. Para excluir quaisquer mensagens que contenham segredos, inclua um filtro na seção processors da configuração.. O filtro deve conter uma expressão regular que corresponda a qualquer sequência de caracteres que inclua a palavra secret. O exemplo a seguir utiliza a função OTTL IsMatch(...) para encontrar qualquer sequência de caracteres que inclua a palavra secret.
processors:
filter/remove_secret:
error_mode: ignore
logs:
log_record:
- 'IsMatch(body, ".*secret.*")'
Inclua este filtro no pipeline do processors :
pipelines:
logs:
receivers:
- filelog/simple
processors:
- filter/remove_secret
Com essa configuração em vigor, apenas a primeira mensagem das linhas do registro de exemplo é relatada, mas a segunda, que contém a palavra "secret", é descartada..
Excluir mensagens syslog de um serviço específico
Considere um syslog em um sistema Linux® .. Se alguém usa a área de trabalho do Gnome neste sistema, ele pode criar logs ruidosos:
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.
Como com o primeiro exemplo, o receptor filelog pode monitorar esse log e mapear o registro de data e hora usando uma expressão regular:
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'
O carimbo de data e hora parece diferente do primeiro exemplo, mas com a expressão regular e a definição de layout corretas, é possível compreendê-lo. Este log não contém nenhuma gravidade O receptor, como sempre, deve ser incluído no pipeline logs/receivers :
pipelines:
logs:
receivers:
- filelog/simple
- filelog/syslog
Em um sistema do servidor, pode-se desejar monitorar os processos do sistema, mas excluir logs que o ambiente de desktop gera. Um filtro regex pode bloquear todas as mensagens de um serviço específico:
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]+\\]:.*")'
Inclua o filtro no pipeline do logs/processors :
logs:
receivers:
- filelog/simple
- filelog/syslog
processors:
- filter/remove_secret
- filter/remove_gnomeshell
Agora, quaisquer registros de log nos quais o campo de serviço é org.gnome.Shell.desktop são eliminados.
Filtrar registros por dados de infraestrutura
O processador de filtro é capaz de filtrar com base nas informações fornecidas na resource attributes seção da carga útil. Este processador permite excluir todas as mensagens provenientes, por exemplo, de um determinado pod do Kubernetes, de todo um namespace do Kubernetes ou de um determinado host. Para obter mais informações sobre os dados de infraestrutura compatíveis, consulte dados de infraestrutura.
Filtrar registros por nível de gravidade
Pode haver situações em que os contêineres sejam configurados para gerar registros com vários níveis de gravidade. Nesses casos, pode ser recomendável filtrar todas as mensagens, exceto as de ERROR e FATAL, para evitar sobrecarregar o coletor com dados desnecessários.
Considere os seguintes exemplos de registros de log:
[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.
Para filtrar os registros de log DEBUG e INFO por gravidade, é necessário primeiro definir o severity_text campo para cada registro de log. Isso pode ser feito utilizando o seguinte processador transform de exemplo:
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 será definido como uma string vazia, o que Instana interpretará como um nível de gravidade de None.Com a configuração severity_text definida no registro de log, você pode usar o seguinte processador filter de exemplo para ignorar logs com nível de gravidade inferior a ERROR e logs sem nível de gravidade.
filter/remove_unnecessary_logs:
logs:
log_record:
- IsMatch(severity_text, "^(|Debug|Info)$")
Este exemplo utiliza a função OTTL IsMatch(...) para excluir registros em que a expressão regular especificada corresponda a uma string vazia, ao caractere Debug, e às gravidades Info de registro.
Como alternativa, você pode especificar os registros que deseja incluir, em vez de excluir, com base na gravidade do registro, utilizando a palavra-chave `not`. Dessa forma, você agora filtra os registros que não correspondem aos níveis de Error gravidade ou Fatal.
filter/remove_unnecessary_logs:
logs:
log_record:
- not IsMatch(severity_text, "^(Error|Fatal)$")
Na service/pipelines/logs/processors seção, inclua o novo filtro:
processors:
- resourcedetection
- transform/set_log_severity
- filter/remove_unnecessary_logs
- batch
Filtragem de registros por atributos de recurso
A seguir, apresentamos uma lista não exaustiva de exemplos de atributos de recursos que podem ser usados para filtrar registros:
Exemplos de atributos coletados pelo processador k8sattributes e pelo processador resourcedetection :
resource.attributes["k8s.pod.name"]: O nome do pod do serviço de armazenamento de dados ( Kubernetes ) que gerou a mensagem de logresource.attributes["k8s.container.name"]: O nome do contêiner subjacente que gerou a mensagem de logresource.attributes["k8s.namespace.name"]: O nome do namespace que contém o pod que gerou a mensagem de logresource.attributes["k8s.deployment.name"]: O nome do objeto de implantação do ` Kubernetes ` que controla o pod que gerou a mensagem de logresource.attributes["k8s.node.name"]: O nome do nó do ` Kubernetes ` no qual o pod que gerou a mensagem de log está em execuçãoresource.attributes["k8s.pod.hostname"]: O nome do host no qual está em execução o processo que gerou a mensagem de log. Se o coletor estiver sendo executado dentro de um contêiner, o nome do host geralmente é o nome do contêiner, e não o nome do host subjacente propriamente ditoresource.attributes["os.type"]: O tipo de sistema operacional do host no qual está em execução o processo que gerou a mensagem de log
Ao utilizar o processador de k8sattributes, o processador de recursos e o processador de transformação, os atributos definidos pelo usuário no resource.attributes mapeamento podem ser definidos dinamicamente e utilizados para a filtragem personalizável de logs.
Exemplos
Todos estes exemplos seguem um padrão similar. Uma seção filter deve ser incluída no arquivo de configuração do opentelemetry-collector e esse filtro deve ser incluído no pipeline logs/processors no mesmo arquivo. Se você estiver usando Helm para instalar o coletor, a configuração entrará na seção config: do arquivo values.yaml na instalação.
Excluir mensagens de log de um determinado contêiner do Kubernetes
Suponha que você deseja filtrar todas as mensagens de log de um contêiner Kubernetes chamado calico-node. Na seção processors da configuração, inclua um bloco como este:
filter/remove_calico:
error_mode: ignore
logs:
log_record:
- resource.attributes["k8s.container.name"] == "calico-node"
Em seguida, na seção service/pipelines/logs/processors , inclua o novo filtro:
processors:
- resourcedetection
- transform/set_log_severity
- filter/remove_calico
- batch
O novo filtro é listado por último.. Os outros processadores mostrados são apenas para contexto e não são necessários para que o processador de filtro funcione.
Excluir mensagens de log de todos os sistemas do Linux®
Se desejar bloquear todas as mensagens de log de qualquer sistema baseado em Linux®, na seção 'processors da configuração, será possível incluir:
filter/remove_linux:
error_mode: ignore
logs:
log_record:
- resource.attributes["os.type"] == "linux"
Da mesma forma, na seção service/pipelines/logs/processors , com base no exemplo anterior, inclua o novo filtro:
processors:
- resourcedetection
- transform/set_log_severity
- filter/remove_calico
- filter/remove_linux
- batch
Excluir mensagens de log de um determinado pod ou implantação do Kubernetes com rótulos ou anotações específicas
Suponha que você tenha a seguinte implantação do ` Kubernetes ` com as etiquetas e anotações nas quais deseja filtrar todas as mensagens de log:
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
Se você quiser filtrar por some-keyword-label ou some-keyword-annotation, pode estender o k8sattribute processador conforme mostrado no exemplo a seguir para coletar todas as etiquetas e anotações do pod:
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
Use o exemplo a seguir para extrair o some-keyword-label rótulo e some-keyword-annotation a anotação:
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
Depois de configurar o k8sattributes processador para extrair as etiquetas e anotações desejadas, você pode usar o filter processador filter_by_keyword ou para excluir mensagens de log de pods que tenham a some-keyword-label etiqueta ou some-keyword-annotation a anotação:
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).*")
Nesta service/pipelines/logs/processors seção, com base no exemplo anterior, inclua o novo filtro:
processors:
- resourcedetection
- filter/filter_by_keyword
- batch
O novo filtro é listado por último.. Os outros processadores mostrados são apenas para contexto e não são necessários para que o processador de filtro funcione.
Ocultar informações confidenciais dos registros
As mensagens de log às vezes contêm informações pessoalmente identificáveis (PII) ou outros dados confidenciais que precisam ser mantidos privados e não enviados para o servidor ou salvos. Essas informações podem incluir coisas como senhas, números de cartão de crédito ou qualquer outra coisa. O processador transform pode detectar essas informações usando uma expressão regular e substituí-la por outra coisa..
Exemplos
Estes exemplos seguem um padrão semelhante. Uma seção transform deve ser incluída no arquivo de configuração do opentelemetry-collector e essa conversão deve ser incluída no pipeline logs/processors no mesmo arquivo. Se você estiver usando Helm para instalar o coletor, a configuração entrará na seção config: do arquivo values.yaml na instalação.
Remover senhas das mensagens de log
Suponha que um aplicativo registre a senha fornecida sempre que ocorrer uma falha de autenticação O registro de log pode ser semelhante a este:
2024-02-14 19:40:31 WARNING failed login for user bob, password=bobo
É importante saber que ocorreu uma tentativa de login com falha, mas é inapropriado registrar a senha usada.
O aplicativo registra a senha com um formato conhecido.. O padrão é sempre password=xyz Uma expressão regular pode detectar esse padrão e substituí-lo por outra coisa:
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")
A diretiva replace_pattern ocorre uma vez para a mensagem body e uma vez para o atributo msg .. O coletor de telemetria aberto coloca o conteúdo da mensagem nos dois locais, portanto ambos precisam ser atualizados.
E inclua a conversão no pipeline do logs/processors :
logs:
receivers:
- otlp
- filelog/simple
processors:
- transform/redact_password
A conversão transforma a mensagem de log inicial em:
2024-02-15 15:45:37 WARNING failed login for user bob, password=REDACTED
Removendo nomes de host das mensagens de log
Suponha que outro aplicativo grave nomes do host no syslog:
Feb 15 15:52:36 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b service[45568]: This is a test error message from where.ever.ibm.com
Se os nomes de host forem considerados confidenciais, será possível impedir que eles sejam incluídos no log Se todos os hosts estiverem no mesmo domínio, neste exemplo, .ibm.com, uma expressão regular poderá reconhecer o padrão e obscurecer os nomes:
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>")
Novamente, o atributo body e o atributo msg são regravados porque o texto da mensagem de log ocorre em ambos os locais.
E novamente, inclua a conversão no pipeline:
logs:
receivers:
- filelog/syslog
processors:
- transform/redact_password
- transform/remove_hostnames
A mensagem é então regravada da seguinte forma:
Feb 15 15:52:36 li-8dc514cc-2e0d-11b2-a85c-f1d7ce42b83b service[45568]: This is a test error message from <hidden hostname>