<@ULVA73B9P> I have a Prefect 3 self hosted server...
# ask-marvin
n
@Marvin I have a Prefect 3 self hosted server. How do I enable opentelemetry to ingest logs on kubernetes?
m
thought for 354.5 seconds
Short answer: In Prefect 3 self-hosted, there isn’t a built‑in OpenTelemetry log exporter in the SDK. The recommended way on Kubernetes is to run an OpenTelemetry Collector as a DaemonSet and have it scrape your Prefect pods’ stdout logs from /var/log/containers. Optionally, set Prefect to emit JSON logs to make parsing easier. You can also add OTLP receivers for traces/metrics if you want those too. Here’s a practical setup you can copy and adapt. 1) Deploy an OpenTelemetry Collector DaemonSet that scrapes container logs - Mount host log paths - Use the filelog receiver to read /var/log/containers/*.log - Add k8sattributes to enrich with namespace/pod labels - Export to your backend (OTLP, Loki, Datadog, etc.) Example ConfigMap for the collector:
Copy code
apiVersion: v1
kind: ConfigMap
metadata:
  name: otel-collector-config
data:
  config.yaml: |
    receivers:
      filelog:
        include:
          - /var/log/containers/*.log
        start_at: end
        # Operators help parse container log format and JSON lines
        operators:
          - type: container
          - type: json_parser
            parse_from: body
            on_error: send
      # Optional: allow SDKs to send OTLP traces/metrics directly
      otlp:
        protocols:
          grpc:
          http:

    processors:
      k8sattributes:
        auth_type: serviceAccount
      batch:

    exporters:
      # Replace with your backend (examples: otlp, loki, datadog, etc.)
      otlp:
        endpoint: your-otel-backend:4317
        tls:
          insecure: true

    service:
      pipelines:
        logs:
          receivers: [filelog]
          processors: [k8sattributes, batch]
          exporters: [otlp]
        # Optional: enable if you’ll send traces/metrics via OTLP
        traces:
          receivers: [otlp]
          processors: [batch]
          exporters: [otlp]
        metrics:
          receivers: [otlp]
          processors: [batch]
          exporters: [otlp]
Example DaemonSet volumes (abbreviated):
Copy code
# In your Otel Collector DaemonSet
spec:
  template:
    spec:
      serviceAccountName: otel-collector
      volumes:
        - name: varlog
          hostPath:
            path: /var/log
        - name: varlibdockercontainers
          hostPath:
            path: /var/lib/docker/containers
      containers:
        - name: otel-collector
          image: otel/opentelemetry-collector-contrib:latest
          args: ["--config=/etc/otel/config.yaml"]
          volumeMounts:
            - name: varlog
              mountPath: /var/log
              readOnly: true
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
          ports:
            - name: otlp-grpc
              containerPort: 4317
            - name: otlp-http
              containerPort: 4318
2) Ensure Prefect pods log to stdout (default) or switch to JSON for easier parsing - Prefect already writes rich-formatted logs to stdout. The collector will ingest these from /var/log/containers. - If you want clean JSON logs, provide a logging override and mount it into your worker/flow pods. Minimal JSON logging override:
Copy code
version: 1
disable_existing_loggers: False

formatters:
  json:
    class: prefect.logging.formatters.JsonFormatter

handlers:
  console:
    class: prefect.logging.handlers.PrefectConsoleHandler
    level: INFO
    formatter: json

loggers:
  prefect:
    level: INFO
    handlers: [console]
    propagate: false
Then set this in your pods: - Mount the file (e.g., ConfigMap) at /etc/prefect/logging.yml - Set env var:
PREFECT_LOGGING_SETTINGS_PATH=/etc/prefect/logging.yml
Tip for flow-run pods: apply the env/volume in your Kubernetes work pool’s base job template so every flow pod inherits it. 3) (Optional) Export traces/metrics via OTLP from your Prefect runtime
- Prefect 3 can create OpenTelemetry spans for flow/task runs, but no exporter is configured by default. If you want traces, configure the OTel Python SDK in your runtime or run it with the OTel distro so OTLP exporters are set via env vars. - Resource metrics (CPU/memory) can be exported if you set OTEL endpoints and have the OTel dependencies installed. Useful env vars: -
OTEL_EXPORTER_OTLP_ENDPOINT=<http://otel-collector:4318>
- or
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
,
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
- Make sure opentelemetry-sdk and opentelemetry-exporter-otlp are installed in your flow image. Notes and references - Prefect logging customization: Logging customization (Prefect 3) - Prefect telemetry overview: Telemetry (Prefect 3) - OpenTelemetry Collector filelog receiver: filelog receiver docs - k8sattributes processor: k8sattributes processor docs - Python OTel configuration (env vars): OpenTelemetry Python configuration Quick sanity checks - You do not need to change Prefect code to get logs into OTel on Kubernetes; scraping stdout via filelog is the simplest and most robust approach. - If you want to correlate logs with K8s metadata, ensure the collector has k8s RBAC and k8sattributes enabled. - If you prefer a direct code‑level log exporter, you can implement a custom logging handler in Prefect, but it’s usually unnecessary on Kubernetes. Questions to tailor this for you - Do you want to ingest logs from flow-run pods, the worker pod(s), the Prefect Server API/Orion pods, or all of the above? - What’s your log backend (OTLP to another collector, Loki, Datadog, etc.)? - Do you also want traces and/or metrics exported from Prefect runtimes? If yes, I can share a minimal OTel SDK init snippet or env var setup for Python 3.12 containers.