Metadata-Version: 2.4
Name: ldr-logging
Version: 0.2.0
Summary: Louder's structured logging and tracing library
Author-email: Sam Kenney <sam.kenney@louder.com.au>
License-File: LICENSE.md
Requires-Python: >=3.13
Requires-Dist: google-cloud-logging>=3.16.0
Requires-Dist: ldr-environment>=0.1.0
Requires-Dist: pydantic>=2.13.4
Provides-Extra: tracing
Requires-Dist: opentelemetry-api>=1.42.1; extra == 'tracing'
Requires-Dist: opentelemetry-exporter-gcp-trace>=1.12.0; extra == 'tracing'
Requires-Dist: opentelemetry-resourcedetector-gcp>=1.12.0a0; extra == 'tracing'
Requires-Dist: opentelemetry-sdk>=1.42.1; extra == 'tracing'
Description-Content-Type: text/markdown

# Louder Logging

A Google Cloud Logging compliant structured logging library.


## Logging Setup

The following environment variables must be set for logging to function when using
the provided `ldr.logging.Entry` type.

```sh
# The name of the actual application running, e.g cloud run service / job name
export LDR_APPLICATION_NAME=application-name
# The version of the application, example here for poetry environments
export LDR_APPLICATION_VERSION=$(poetry version -s)
# The name of the service, can be the same as application name if the service is only
# one component, but in larger projects will be the name of the service offering rather
# than just the application name.
export LDR_APPLICATION_SERVICE_NAME=application-service-name
# The commit hash that this version of the code was committed with.
export LDR_APPLICATION_COMMIT_HASH=$(git rev-parse HEAD)
```

These can be omitted when using custom structured logs, or unstructured logs.

### Examples

```python
import ldr.logging
import logging

ldr.logging.setup(logging.DEBUG)

logging.info("Hello, world!")

entry = ldr.logging.Entry()
logging.warning()
```

Will write the following to stderr

```ndjson
{"logging.googleapis.com/diagnostic": {"instrumentation_source": [{"name": "python", "version": "3.11.3"}]},"severity": "INFO", "logging.googleapis.com/labels": {"python_logger": "google.cloud.logging_v2.handlers.structured_log"}, "logging.googleapis.com/trace": "", "logging.googleapis.com/spanId": "", "logging.googleapis.com/trace_sampled": false, "logging.googleapis.com/sourceLocation": {"line": 149, "file": "/Users/you/Library/Caches/pypoetry/virtualenvs/my-application-N_XRT3hE-py3.11/lib/python3.11/site-packages/google/cloud/logging_v2/handlers/structured_log.py", "function": "emit_instrumentation_info"}, "httpRequest": {} }
{"message": "Hello, world!","severity": "INFO", "logging.googleapis.com/labels": {"python_logger": "root"}, "logging.googleapis.com/trace": "", "logging.googleapis.com/spanId": "", "logging.googleapis.com/trace_sampled": false, "logging.googleapis.com/sourceLocation": {"line": 6, "file": "/Users/you/project/src/main.py", "function": "<module>"}, "httpRequest": {} }
{"client": "LOUD", "message": "Something weird happened but we've handled it", "app": {"name": "application-name", "version": "0.1.0", "service_name": "application-service-name", "commit_hash": "ea09ae9cc6768c50fcee903ed054556e5bfc8347"}, "extra": {"foo": "bar"},"severity": "WARNING", "logging.googleapis.com/labels": {"python_logger": "root"}, "logging.googleapis.com/trace": "", "logging.googleapis.com/spanId": "", "logging.googleapis.com/trace_sampled": false, "logging.googleapis.com/sourceLocation": {"line": 13, "file": "/Users/you/project/src/main.py", "function": "<module>"}, "httpRequest": {} }
```

## Tracing Setup

Tracing is gated behind the `tracing` extra. Install with `pip install 'ldr-logging[tracing]'`.

Tracing requires an instance of `ldr.logging.TraceConfig`. You can set the following env vars to use the
`ldr.logging.TraceConfig.from_env` method.

```sh
# The name of the actual application running, e.g cloud run service / job name
export LDR_APPLICATION_NAME=my-application-auth
# Optional: The application namespace, if the app is a component of a larger application
export LDR_APPLICATION_NAMESPACE=my-application
# Optional: A regex expression to specify which open telemetry resource attributes to propagate.
# This example will export all 'service.{key}' attributes.
# When unset, no resource attributes will be collected.
export LDR_OTEL_INCLUDE_RESOURCE_ATTRIBUTES_REGEX='^service\..*'
```

### Examples

#### Configure tracing

```python
import ldr.logging

ldr.logging.setup_tracing(ldr.logging.TraceConfig.from_env())

```

#### Configure tracing for a FastAPI app.

```python
# pip install fastapi opentelemetry-instrumentation-fastapi ldr-environment

import ldr.environment
import ldr.logging
from fastapi import FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor

trace_config = ldr.logging.TraceConfig.from_env()
app = FastAPI(name=trace_config.service_name)

ldr.logging.setup_tracing(
    config=trace_config,
    attributes={
        "deployment.environment": ldr.environment.get("ENVIRONMENT", "dev"),
    },
    instrumentor=FastAPIInstrumentor.instrument_app,
    app=app,
)
```

## Copyright

This project is licensed under the [MIT license](https://opensource.org/license/mit).
