Skip to main content

Utilities for interacting with logging facilities in GKE workloads

Project description

gke-logging

PyPI version

Utilities for interacting with logging facilities in GKE workloads

Installation

Requirements

  • Python 3.7+
  • Poetry (for development only)

Install from PyPI (recommended)

pip install gke-logging

Installing from Github

pip install git+https://github.com/StationA/gke-logging.git#egg=gke-logging

Installing from source

git clone https://github.com/StationA/gke-logging.git
cd gke-logging
poetry install

Usage

gke_logging.GKELoggingFormatter

One of the core components is the GKELoggingFormatter, which is an implementation of the built-in logging.Formatter protocol that translates a logging.LogRecord into a JSON format that GKE's logging infrastructure can understand. At a minimum, this enables any software running on GKE to integrate structured logging simply by applying this formatter for your loggers, e.g.:

import logging

from gke_logging import GKELoggingFormatter


LOGGER = logging.getLogger(__name__)
h = logging.StreamHandler()
h.setFormatter(GKELoggingFormatter())
LOGGER.addHandler(h)
LOGGER.setLevel(logging.INFO)


# ...

LOGGER.info("Look at me! I can haz GKE structured logging!")
# Prints out: {"time": "2022-01-13T23:22:26.336686+00:00", "severity": "INFO", "message": "Look at me! I can haz GKE structured logging!", "logging.googleapis.com/sourceLocation": {"file": "test_log.py", "line": "14", "function": "<module>"}, "logging.googleapis.com/labels": {}}

Furthermore, this formatter allows you to set app-level metadata to be sent along with each log message, which is useful in order to better organize collected log data:

# ...
h.setFormatter(
    GKELoggingFormatter(default_labels=dict(app_id="my-cool-app", version="0.1.0"))
)
# ...

Also the formatter also allows you to add HTTP metadata to any logs that occur during the course of a request. This enhances logs that are emitted during request-handling logic in APIs with additional data. This functionality is primarily utilized in the included GKELoggingMiddleware in order to provide basic access logs.

gke_logging.asgi.GKELoggingMiddleware

gke_logging.asgi.GKELoggingMiddleware is an ASGI middleware that emits basic access logs in "common log format", with a default behavior that integrates with the GKELoggingFormatter to write the access logs in a format that GKE's logging infrastructure better understands. By implementing per the ASGI spec, this means it can work with any ASGI-compatible server, including FastAPI, starlette, and ASGI implementations:

from fastapi import FastAPI
from gke_logging.asgi import GKELoggingMiddleware

app = FastAPI()
app.add_middleware(GKELoggingMiddleware)

@app.get("/")
def get_it() -> str:
    return "OK"

Additionally, because this middleware integrates with gke_logging.context bindings, it enables any logger used during the course of handling a request to emit logs that also contain request-time data, e.g. request URL, user-agent, response latency, etc.

import logging

from fastapi import FastAPI
from gke_logging import GKELoggingFormatter
from gke_logging.asgi import GKELoggingMiddleware

app = FastAPI()
app.add_middleware(GKELoggingMiddleware)


root_logger = logging.getLogger()
h = logging.StreamHandler()
h.setFormatter(GKELoggingFormatter())
root_logger.setLevel(logging.INFO)
root_logger.addHandler(h)


@app.get("/")
def get_it() -> str:
    # Any log records created during request-handling will be enriched with other HTTP request data
    root_logger.info("TEST")
    return "OK"

gke_logging.context

In order to control additional metadata labels for log records that correspond to one logical operation, e.g. an HTTP request, a batch job operation, etc., you should use the helper functions exported in gke_logging.context:

import logging

from contextvars import copy_context

from gke_logging import GKELoggingFormatter
from gke_logging.context import set_labels


LOGGER = logging.getLogger(__name__)
h = logging.StreamHandler()
h.setFormatter(GKELoggingFormatter())
LOGGER.addHandler(h)
LOGGER.setLevel(logging.INFO)

# ...


def run_job(job_id: str):
    set_labels(job_id=job_id)
    LOGGER.info("TEST")


ctx = copy_context()
for i in range(10):
    ctx.run(run_job, f"{i + 1}")

Because ContextVars bind natively to Python's asyncio, you can use these same helper functions within asynchronous tasks in a similar fashion.

Additional examples

Additional usage examples can be found in examples/

Contributing

When contributing to this repository, please follow the steps below:

  1. Fork the repository
  2. Submit your patch in one commit, or a series of well-defined commits
  3. Submit your pull request and make sure you reference the issue you are addressing

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

gke-logging-0.0.4.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

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

gke_logging-0.0.4-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file gke-logging-0.0.4.tar.gz.

File metadata

  • Download URL: gke-logging-0.0.4.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.12 CPython/3.7.10 Linux/5.15.23-76051523-generic

File hashes

Hashes for gke-logging-0.0.4.tar.gz
Algorithm Hash digest
SHA256 9191721b6cf140c42fc3751966caf835599147f5b78d5408b093abafe4bfadfd
MD5 f014f1cab96031071706db9eab14ed0c
BLAKE2b-256 b60480ada5db9b5fd2f35c4bb86e42fd8e43dbcd469df6e75734894702e5f7c8

See more details on using hashes here.

File details

Details for the file gke_logging-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: gke_logging-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.12 CPython/3.7.10 Linux/5.15.23-76051523-generic

File hashes

Hashes for gke_logging-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 f0af3675fcbbf469954f70c0db20ea6eb4fd88dca6a9f491fdb4c416785a6601
MD5 56c53c68403c5baea7c12f4ce6295a7b
BLAKE2b-256 48dd8dd0d1008c9ec645a9baf007e887c220931fa80d89b74245012c376c72de

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