Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion structlog_gcp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .base import build_processors # noqa: F401
from .base import build_gcp_processors, build_processors # noqa: F401

__all__ = [
"build_gcp_processors",
"build_processors",
]
41 changes: 38 additions & 3 deletions structlog_gcp/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,44 @@ def build_processors(
service: str | None = None,
version: str | None = None,
) -> list[Processor]:
"""Build structlog processors to export logs for Google Cloud Logging.

This builder function is expected to be your go-to function to expose structlog logs to Google
Cloud Logging format.

It configures the Google Cloud Logging-specific processors but also good defaults processors.

If you need more control over which processors are exactly configured, check the
:ref:`build_gcp_processors` function.
"""

procs: list[Processor] = []

procs.extend(build_gcp_processors(service, version))
procs.append(structlog.processors.JSONRenderer())

return procs


def build_gcp_processors(
service: str | None = None,
version: str | None = None,
) -> list[Processor]:
"""Build only the Google Cloud Logging-specific processors.

This builds a set of processors to format logs according to what Google Cloud Logging expects.

See: https://cloud.google.com/functions/docs/monitoring/logging#writing_structured_logs

Use this builder function if you want to customize the processors before and after the
GCP-specific processors.

In particular, this builder function **doesn't** configure the final JSON renderer. You are
expected to provide your own.

For a simpler, more general alternative, use :ref:`build_processors` instead.
"""

procs: list[Processor] = []

# Add a timestamp in ISO 8601 format.
Expand All @@ -29,7 +67,4 @@ def build_processors(
# Finally: Cloud Logging formatter
procs.append(processors.finalize_cloud_logging)

# Format as JSON
procs.append(structlog.processors.JSONRenderer())

return procs
16 changes: 16 additions & 0 deletions tests/test_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,19 @@ def test_extra_labels(stdout: T_stdout, logger: WrappedLogger) -> None:
"test5": {"date": "datetime.date(2023, 1, 1)"},
}
assert msg == expected


def test_core_processors_only(stdout: T_stdout, mock_logger_env: None) -> None:
processors = structlog_gcp.build_gcp_processors()
processors.append(structlog.processors.KeyValueRenderer())

structlog.configure(processors=processors)
logger = structlog.get_logger()

logger.info("test")
msg = stdout().strip()

# No JSON formmating, no contextvars
expected = "message='test' time='2023-04-01T08:00:00.000000Z' severity='INFO' logging.googleapis.com/sourceLocation={'file': '/app/test.py', 'line': '42', 'function': 'test:test123'}"

assert msg == expected