> ## 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 aus 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" }
]}
/>

Diese Dokumentation beschreibt, wie Sie Logging mit der AppSignal for Python-Integration konfigurieren.

<Warning>
  Logging ist nur im [Collector-Modus](/python/configuration/collector)
  verfügbar, der ein **experimentelles Feature** ist.
</Warning>

## Logging konfigurieren

<Warning>
  🔐 Senden Sie keine <strong>personenbezogenen Daten (Personal Identifiable Information, PII)</strong> an AppSignal. Filtern Sie PII (z. B. Namen, E-Mail-Adressen) aus Logs und verwenden Sie stattdessen eine ID, einen Hash oder einen pseudonymisierten Bezeichner. <br /> <br /> Für **HIPAA-pflichtige Stellen** finden Sie weitere Informationen zum Abschluss eines Business Associate Agreement (BAA) in unserer [Business Add-Ons-Dokumentation](/support/business-add-ons).
</Warning>

Sie müssen keine Log-Quelle erstellen, um Logs aus der AppSignal for Python-Integration zu senden. Eine "application"-Log-Quelle wird automatisch erstellt.

Im [Collector-Modus](/python/configuration/collector) instrumentiert AppSignal automatisch das integrierte `logging`-Modul von Python über OpenTelemetry und hängt einen Handler an den Root-Logger.

### Logging-Instrumentierung deaktivieren

Die Instrumentierung des `logging`-Moduls von Python kann mit der [Konfigurationsoption `disable_default_instrumentations`](/python/configuration/options#option-disable_default_instrumentations) deaktiviert werden:

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

Dies deaktiviert die automatische Instrumentierung des `logging`-Moduls durch Anhängen eines Handlers an den Root-Logger, was bedeutet, dass Logs, die an das `logging`-Modul von Python gesendet werden, nicht mehr von AppSignal erfasst werden.

Sie können Logs weiterhin direkt über die OpenTelemetry Logs API senden, wie im Abschnitt [Logs mit OpenTelemetry senden](#sending-logs-with-opentelemetry) unten beschrieben.

#### Handler manuell anhängen

Wenn die automatische Instrumentierung deaktiviert ist, können Sie den OpenTelemetry-`LoggingHandler` selbst an bestimmte Logger anhängen, anstatt darauf zu setzen, dass AppSignal ihn an den Root-Logger anhängt:

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

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

Damit haben Sie die Kontrolle darüber, welche Logger ihre Ausgabe an AppSignal senden.

### Log-Level

Das `logging`-Modul von Python verwendet standardmäßig `WARNING`, was bedeutet, dass `INFO`- und `DEBUG`-Nachrichten standardmäßig nicht erfasst werden. Um Nachrichten mit niedrigerer Severity zu erfassen, setzen Sie das Level des Root-Loggers explizit:

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

### Welche Logs erfasst werden

AppSignal erfasst Logs, die an den Root-Logger gesendet werden, sowie an jeden Logger, der an ihn propagiert. Die Propagierung wird durch das Attribut `propagate` an jedem Logger gesteuert, das in Python standardmäßig auf `True` gesetzt ist.

Logger mit `propagate=False` lassen ihre Nachrichten **nicht** von AppSignal erfassen.

## Framework-Setup

### Django

Django konfiguriert einige Logger standardmäßig mit `propagate=False`, was verhindert, dass sie AppSignal erreichen. Überschreiben Sie diese in `settings.py`, um die Propagierung wieder zu aktivieren:

<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>

Das Setzen von `"propagate": True` stellt sicher, dass die Nachrichten des Loggers den Root-Logger erreichen, an den der Handler von AppSignal angehängt ist.

#### Handler manuell anhängen

Alternativ können Sie den `LoggingHandler` direkt an die Logger von Django anhängen, anstatt sich auf die Propagierung zum Root-Logger zu verlassen:

<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

Celery forkt Worker-Prozesse, daher muss AppSignal für jeden Fork gestartet werden. Verwenden Sie das `worker_process_init`-Signal, um AppSignal neu zu initialisieren und Logging in jedem Worker-Prozess zu konfigurieren. Weitere Details zur Instrumentierung von Celery-Tasks finden Sie auf der [Seite zur Celery-Instrumentierung](/python/instrumentations/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>

## Logs mit OpenTelemetry senden

Sie können Logs auch direkt über die OpenTelemetry Logs API senden, ohne den Umweg über das `logging`-Modul von 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>

## Brauchen Sie Hilfe?

Nachdem Sie Ihre Python-Anwendung so konfiguriert haben, dass sie Logs sendet, sollten die Logs in AppSignal erscheinen. Wenn Sie sich bei diesem Schritt unsicher sind oder AppSignal keine Logs empfängt, können Sie sich jederzeit für [Unterstützung an uns wenden](mailto:support@appsignal.com). Wir helfen Ihnen, wieder auf Kurs zu kommen!
