Skip to main content

Collection of Python logging, tracing and profiling tools

Project description

🪵
Troncos

Collection of Python logging, tracing and profiling tools
CI status

Etymology

"Troncos" is the plural of the spanish word "Tronco", which translates to "trunk" or "log".

Installation

# With pip
$ pip install troncos

Tracing

Troncos is designed to take advantage of ddtrace made by DataDog.

The ddtrace docs can be found here.

Enabling the tracer

Configure ddtrace as usual and run configure_tracer to send spans to Tempo.

This is typically done in settings.py of you want to profile a Django application, or in __init__.py in the root project package.

TRACE_HOST is usually the host IP of the K8s pod, TRACE_PORT is usually 4318 when the Grafana agent is used to collect spans using HTTP.

import ddtrace

from troncos.tracing import configure_tracer

# Configure tracer as described in the ddtrace docs.
ddtrace.config.django["service_name"] = 'SERVICE_NAME'
ddtrace.tracer.set_tags(
    tags={
        "fulfillment_center": 'osl2',
    }
)

# Patch third-party modules
ddtrace.patch_all()

# Configure the ddtrace tracer to send traces to Tempo.
TRACE_HOST = "127.0.0.1" # Usually obtained from env variables.
TRACE_PORT = "4318"
configure_tracer(
    enabled=False, # Set to True when TRACE_HOST is configured.
    service_name='SERVICE_NAME',
    endpoint=f"http://{TRACE_HOST}:{TRACE_PORT}/v1/traces",
)

ddtrace also uses env variables to configure the service name, environment and version etc.

Add the following environment variables to your application.

DD_ENV="{{ environment }}"
DD_SERVICE="{{ app }}"
DD_VERSION="{{ version }}"
# tracecontext/w3c is usually used to propagate distributed traces across services.
DD_TRACE_PROPAGATION_STYLE_EXTRACT="tracecontext"
DD_TRACE_PROPAGATION_STYLE_INJECT="tracecontext"

Debugging during development

By setting the environment variable OTEL_TRACE_DEBUG=True you will enable traces to be printed to stdout via the ConsoleSpanExporter as well as through http/grpc. Also specifying OTEL_TRACE_DEBUG_FILE=/some/file/path will output traces to the specified file path instead of the console/stdout.

Using the GRPC span exporter

Using the GRPC span exporter gives you significant performance gains. If you are running a critical service with high load in production, we recommend using GRPC.

TRACE_PORT is usually 4317 when the Grafana agent is used to collect spans using GRPC.

poetry add troncos -E grpc

or

[tool.poetry.dependencies]
troncos = {version="?", extras = ["grpc"]}
from troncos.tracing import configure_tracer, Exporter

TRACE_HOST = "127.0.0.1" # Usually obtained from env variables.
TRACE_PORT = "4317"

configure_tracer(
    enabled=False, # Set to True when TRACE_HOST is configured.
    service_name='SERVICE_NAME',
    endpoint=f"http://{TRACE_HOST}:{TRACE_PORT}",
    exporter=Exporter.GRPC
)

Setting headers for the exporter

from troncos.tracing import configure_tracer, Exporter, ExporterType

TRACE_HOST = "127.0.0.1" # Usually obtained from env variables.
TRACE_PORT = "4317"

configure_tracer(
    enabled=False, # Set to True when TRACE_HOST is configured.
    service_name='SERVICE_NAME',
    endpoint=f"http://{TRACE_HOST}:{TRACE_PORT}",
    exporter=Exporter(ExporterType.GRPC, headers={"my", "header"}),
)

Instrument your code

Manual instrumentation of your code is described in the ddtrace docs.

Add tracing context to your log

Adding the tracing context to your log makes it easier to find relevant traces in Grafana. Troncos include a Structlog processor designed to do this.

import structlog

from troncos.contrib.structlog.processors import trace_injection_processor

structlog.configure(
    processors=[
        trace_injection_processor,
    ],
)

Logging of major actions in your application

Finding relevant traces in Grafana can be difficult. One way to make finding the relevant traces easier it to log every major action in your application. This typically means logging every incoming HTTP request to your server or every task executed by your Celery worker.

The structlog processor above needs to be enabled before logging your major actions is relevant.

ASGI middleware

Log ASGI requests.

from starlette.applications import Starlette

from troncos.contrib.asgi.logging.middleware import AsgiLoggingMiddleware

application = AsgiLoggingMiddleware(Starlette())

Django middleware

Log Django requests. This is not needed if you run Django with ASGI and use the ASGI middleware.

MIDDLEWARE = [
    "troncos.contrib.django.logging.middleware.DjangoLoggingMiddleware",
    ...
]

Celery signals

` Log Celery tasks. Run the code bellow when you configure Celery.

from troncos.contrib.celery.logging.signals import (
    connect_troncos_logging_celery_signals,
)

connect_troncos_logging_celery_signals()

Profiling

Enabling the continuous py-spy profiler

Start the profiler by running the start_py_spy_profiler method early in your application. This is typically done in settings.py of you want to profile a Django application, or in __init__.py in the root project package.

from troncos.profiling import start_py_spy_profiler

start_py_spy_profiler(server_address="http://127.0.0.1:4100")

Enabling the ddtrace profiler

Start the profiler by importing the profiler module early in your application. This is typically done in settings.py of you want to profile a Django application, or in __init__.py in the root project package.

import troncos.profiling.auto

Setup profile endpoint

Use one of the methods bellow based on your selected framework.

Django

Add the profile view to the url config.

from django.urls import path

from troncos.contrib.django.profiling.views import profiling_view

urlpatterns = [
    path("/debug/pprof", profiling_view, name="profiling"),
]
Starlette

Add the profile view to your router.

from starlette.routing import Route

from troncos.contrib.starlette.profiling.views import profiling_view

routes = [
    Route("/debug/pprof", profiling_view),
]
ASGI

Mount the generic ASGI profiling application. There is no generic way to do this, please check the relevant ASGI framework documentation.

from troncos.contrib.asgi.profiling.app import profiling_asgi_app

# FastAPI example
from fastapi import FastAPI

app = FastAPI()

app.mount("/debug/pprof", profiling_asgi_app)

Verify setup

You can verify that your setup works with the pprof cli:

$ pprof -http :6060 "http://localhost:8080/debug/pprof"

Enable scraping

When you deploy your application, be sure to use the custom oda annotation for scraping:

annotations:
  phlare.oda.com/port: "8080"
  phlare.oda.com/scrape: "true"

Logging

Troncos is not designed to take control over your logger. But, we do include logging related tools to make instrumenting your code easier.

Configure Structlog

Troncos contains a helper method that lets you configure Structlog.

First, run poetry add structlog to install structlog in your project.

You can now replace your existing logger config with

from troncos.contrib.structlog import configure_structlog

configure_structlog(format="json", level="INFO")

Adding tracing context to your log

Troncos has a Structlog processor that can be used to add the span_id and trace_id properties to your log. More information can be found in the Tracing section in this document. This is used by the configure_structlog helper method by default.

Request logging middleware

Finding the relevant traces in Tempo and Grafana can be difficult. The request logging middleware exist to make it easier to connect HTTP requests to traces. More information can be found in the Tracing section in this document.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

troncos-4.3.1.tar.gz (20.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

troncos-4.3.1-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file troncos-4.3.1.tar.gz.

File metadata

  • Download URL: troncos-4.3.1.tar.gz
  • Upload date:
  • Size: 20.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.12.1 Linux/6.2.0-1018-azure

File hashes

Hashes for troncos-4.3.1.tar.gz
Algorithm Hash digest
SHA256 fb2393878c0e0740a6fc81471e096d85f99723787ad5e1b384496031a11c5831
MD5 20f28e3afc661d3b6795f38b0d61eacd
BLAKE2b-256 198dcff9fbbdfe7271a501c572eec8086395eeadd5084fa4452458f68618f1de

See more details on using hashes here.

File details

Details for the file troncos-4.3.1-py3-none-any.whl.

File metadata

  • Download URL: troncos-4.3.1-py3-none-any.whl
  • Upload date:
  • Size: 25.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.12.1 Linux/6.2.0-1018-azure

File hashes

Hashes for troncos-4.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 739b95ff45ed1f3d459ca8af499546be325e98b611fba438a4474ee60966752f
MD5 b7d0871f4fce5158cc025845a34671a1
BLAKE2b-256 b7c77cca015b3b9daef8e9f563e7141c4cd232cf9da56f0cb514926a08c00268

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page