> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Logging do Python

export const VersionRequirements = ({versions = []}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const boundaries = {
    upper: " or lower",
    exact: "",
    lower: " or higher"
  };
  const containerStyle = {
    marginTop: "0.5rem",
    marginBottom: "1.5rem"
  };
  const lineStyle = {
    display: "block",
    margin: "0 0 0.35rem 0",
    fontSize: "0.875rem",
    lineHeight: "1.4"
  };
  const pillBaseStyle = {
    display: "inline-block",
    padding: "0.1em 0.4em",
    borderRadius: "0.25rem",
    border: "1px solid",
    fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
    fontSize: "0.85em",
    fontWeight: 500
  };
  const pillColors = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#e9d5ff",
      color: "#9333ea"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#99f6e4",
      color: "#0d9488"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#bbf7d0",
      color: "#16a34a"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#bfdbfe",
      color: "#2563eb"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fecaca",
      color: "#dc2626"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fed7aa",
      color: "#ea580c"
    }
  };
  const defaultPillColor = {
    background: "#f4f4f5",
    borderColor: "#e4e4e7",
    color: "#52525b"
  };
  const getPillStyle = name => ({
    ...pillBaseStyle,
    ...pillColors[name] || defaultPillColor
  });
  const getBoundText = bound => {
    return boundaries[bound] || boundaries.lower;
  };
  return <div style={containerStyle}>
      {versions.map((v, i) => <p key={`${v.name}-${v.version}-${v.bound || "lower"}-${i}`} style={lineStyle}>
          This feature requires{" "}
          <code style={getPillStyle(v.name)}>{v.name}</code> version {v.version}
          {getBoundText(v.bound)}.
        </p>)}
    </div>;
};

<VersionRequirements
  versions={[
{ name: "AppSignal for Python", version: "1.6.0" }
]}
/>

Esta documentação descreve como configurar o logging com a integração AppSignal for Python.

<Warning>
  O logging só está disponível ao usar o [modo
  collector](/python/configuration/collector), que é um **recurso
  experimental**.
</Warning>

## Configurar logging

<Warning>
  🔐 Não envie <strong>Informações Pessoais Identificáveis (PII)</strong> para a AppSignal. Filtre PII (por exemplo, nomes, e-mails) dos logs e use um ID, hash ou identificador pseudonimizado no lugar. <br /> <br /> Para **entidades cobertas pela HIPAA**, mais informações sobre como assinar um Business Associate Agreement (BAA) podem ser encontradas em nossa [documentação de Business Add-Ons](/support/business-add-ons).
</Warning>

Você não precisa criar uma fonte de log para enviar logs da integração AppSignal for Python. Uma fonte de log "application" será criada automaticamente.

Ao usar o [modo collector](/python/configuration/collector), o AppSignal instrumenta automaticamente o módulo `logging` embutido do Python via OpenTelemetry, anexando um handler ao logger raiz.

### Desabilitando a instrumentação de logging

A instrumentação para o módulo `logging` do Python pode ser desabilitada usando a [opção de configuração `disable_default_instrumentations`](/python/configuration/options#option-disable_default_instrumentations):

<CodeGroup>
  ```python Python theme={null}
  # __appsignal__.py
  appsignal = Appsignal(
      # ...
      disable_default_instrumentations=["logging"],
  )
  ```
</CodeGroup>

Isso desabilita a instrumentação automática do módulo `logging` por meio da anexação de um handler ao logger raiz, o que significa que os logs enviados ao módulo `logging` do Python não serão mais capturados pelo AppSignal.

Você ainda pode enviar logs diretamente usando a API de logs do OpenTelemetry, conforme descrito na seção [Enviando logs com OpenTelemetry](#sending-logs-with-opentelemetry) abaixo.

#### Anexando handlers manualmente

Quando a instrumentação automática está desabilitada, você pode anexar o `LoggingHandler` do OpenTelemetry a loggers específicos por conta própria, em vez de depender do AppSignal adicioná-lo ao logger raiz:

<CodeGroup>
  ```python Python theme={null}
  import logging
  from opentelemetry.sdk._logs import LoggingHandler

  handler = LoggingHandler(level=logging.NOTSET)
  logging.getLogger("myapp").addHandler(handler)
  ```
</CodeGroup>

Isso te dá controle sobre quais loggers enviam sua saída ao AppSignal.

### Nível de log

O módulo `logging` do Python tem como padrão `WARNING`, o que significa que mensagens `INFO` e `DEBUG` não são capturadas por padrão. Para capturar mensagens de severidade mais baixa, defina explicitamente o nível do logger raiz:

<CodeGroup>
  ```python Python theme={null}
  import logging
  logging.root.setLevel(logging.INFO)
  ```
</CodeGroup>

### Quais logs são capturados

O AppSignal captura logs enviados ao logger raiz e a qualquer logger que propague para ele. A propagação é controlada pelo atributo `propagate` em cada logger, que tem como padrão `True` no Python.

Loggers com `propagate=False` **não** terão suas mensagens capturadas pelo AppSignal.

## Configuração de Framework

### Django

O Django configura alguns loggers com `propagate=False` por padrão, o que impede que eles cheguem ao AppSignal. Sobrescreva-os em `settings.py` para reativar a propagação:

<CodeGroup>
  ```python Python theme={null}
  # settings.py
  LOGGING = {
      "version": 1,
      "disable_existing_loggers": False,
      "handlers": {
          "console": {"class": "logging.StreamHandler"},
      },
      "loggers": {
          "django.server": {
              "handlers": ["console"],
              "level": "INFO",
              "propagate": True,
          },
          "myapp": {
              "handlers": ["console"],
              "level": "INFO",
              "propagate": True,
          },
      },
  }
  ```
</CodeGroup>

Definir `"propagate": True` garante que as mensagens do logger cheguem ao logger raiz, onde o handler do AppSignal está anexado.

#### Anexando handlers manualmente

Como alternativa, você pode anexar o `LoggingHandler` diretamente aos loggers do Django em vez de depender da propagação para o logger raiz:

<CodeGroup>
  ```python Python theme={null}
  # settings.py
  import logging
  from opentelemetry.sdk._logs import LoggingHandler

  LOGGING = {
      "version": 1,
      "handlers": {
          "console": {"class": "logging.StreamHandler"},
          "appsignal": {"()": LoggingHandler, "level": logging.NOTSET},
      },
      "loggers": {
          "django.server": {
              "handlers": ["console", "appsignal"],
              "level": "INFO",
          },
          "myapp": {
              "handlers": ["console", "appsignal"],
              "level": "INFO",
          },
      },
  }
  ```
</CodeGroup>

### Celery

O Celery faz fork dos processos worker, então o AppSignal precisa ser iniciado para cada fork. Use o sinal `worker_process_init` para reinicializar o AppSignal e configurar o logging em cada processo worker. Veja a [página de instrumentação do Celery](/python/instrumentations/celery) para mais detalhes sobre como instrumentar tarefas do Celery.

<CodeGroup>
  ```python Python theme={null}
  # tasks.py
  import logging
  import appsignal
  from celery.signals import worker_process_init

  @worker_process_init.connect(weak=False)
  def init_worker_logging(*args, **kwargs):
      appsignal.start()
      logging.root.setLevel(logging.INFO)
      logging.getLogger("celery").propagate = True
  ```
</CodeGroup>

## Enviando logs com OpenTelemetry

Você também pode enviar logs diretamente usando a API de logs do OpenTelemetry, sem passar pelo módulo `logging` do Python:

<CodeGroup>
  ```python Python theme={null}
  from opentelemetry._logs import get_logger_provider
  from opentelemetry.sdk._logs import SeverityNumber

  logger_provider = get_logger_provider()
  logger = logger_provider.get_logger("my-app")

  logger.emit(
      logger_provider.get_logger("my-app").create_log_record(
          body="Log message line",
          severity_number=SeverityNumber.INFO,
      )
  )
  ```
</CodeGroup>

## Precisa de ajuda?

Depois de configurar sua aplicação Python para enviar logs, os logs devem aparecer no AppSignal. Se você tiver dúvidas sobre este passo ou o AppSignal não estiver recebendo logs, você sempre pode [entrar em contato](mailto:support@appsignal.com) para obter ajuda. Vamos te ajudar a voltar ao normal!
