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
13 changes: 5 additions & 8 deletions .github/workflows/build-test-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,13 @@ jobs:
run: hatch run pytest --color=yes

- name: mypy
run: hatch run mypy structlog_gcp
run: hatch run mypy

- name: ruff
run: hatch run ruff check structlog_gcp
- name: lint
run: hatch run ruff check

- name: black
run: hatch run black --check --diff structlog_gcp

- name: isort
run: hatch run isort --check --diff structlog_gcp
- name: format
run: hatch run ruff format --diff

- name: Build
run: hatch build --clean
Expand Down
19 changes: 4 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
DIRS = structlog_gcp

all: lint fmt

.PHONY: lint
lint:
$(MAKE) ruff
$(MAKE) mypy

.PHONY: ruff
ruff:
hatch run ruff check $(DIRS)
all: fmt mypy test

.PHONY: mypy
mypy:
hatch run mypy $(DIRS)
hatch run mypy

.PHONY: fmt
fmt:
hatch run black $(DIRS)
hatch run isort $(DIRS)
hatch run ruff format
hatch run ruff check --fix

.PHONY: test
test:
Expand Down
23 changes: 5 additions & 18 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "structlog-gcp"
description = 'A structlog set of processors to output as Google Cloud Logging format'
description = "A structlog set of processors to output as Google Cloud Logging format"
readme = "README.md"
requires-python = ">=3.10"
license = "MIT"
Expand All @@ -15,9 +15,9 @@ authors = [
classifiers = [
"Development Status :: 4 - Beta",
"Programming Language :: Python",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
]
Expand All @@ -36,9 +36,7 @@ path = "structlog_gcp/__about__.py"

[tool.hatch.envs.default]
dependencies = [
"black",
"ruff",
"isort",
"mypy",
"pytest",
"pytest-cov",
Expand Down Expand Up @@ -67,20 +65,9 @@ omit = [
"structlog_gcp/__about__.py",
]

[tool.coverage.report]
exclude_lines = [
"no cov",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
]

[tool.isort]
profile = "black"

[tool.mypy]
strict = true
files = ["structlog_gcp", "tests"]

[tool.ruff]
ignore = [
"E501",
]
[tool.ruff.lint]
extend-select = ["I"]
13 changes: 8 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
from typing import Callable, Generator
from unittest.mock import patch

import pytest
import structlog
from _pytest.capture import CaptureFixture
from structlog.typing import WrappedLogger

import structlog_gcp

from . import fakes


@pytest.fixture
def mock_logger_env():
def mock_logger_env() -> Generator[None, None, None]:
with (
patch(
"structlog.processors.CallsiteParameterAdder",
Expand All @@ -24,7 +27,7 @@ def mock_logger_env():


@pytest.fixture
def logger(mock_logger_env):
def logger(mock_logger_env: None) -> Generator[WrappedLogger, None, None]:
"""Setup a logger for testing and return it"""

structlog.reset_defaults()
Expand All @@ -38,10 +41,10 @@ def logger(mock_logger_env):


@pytest.fixture
def stdout(capsys):
def read():
def stdout(capsys: CaptureFixture[str]) -> Callable[[], str]:
def read() -> str:
output = capsys.readouterr()
assert "" == output.err
return output.out

yield read
return read
21 changes: 16 additions & 5 deletions tests/fakes.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
"""Fake implementations of structlog processors with side-effects"""

from typing import Collection

from structlog.processors import CallsiteParameter
from structlog.typing import EventDict, WrappedLogger


class CallsiteParameterAdder:
def __init__(self, *args, **kwargs):
def __init__(self, parameters: Collection[CallsiteParameter]) -> None:
pass

def __call__(self, logger, method_name, event_dict):
def __call__(
self, logger: WrappedLogger, method_name: str, event_dict: EventDict
) -> EventDict:
event_dict["pathname"] = "/app/test.py"
event_dict["lineno"] = 42
event_dict["module"] = "test"
Expand All @@ -14,15 +21,19 @@ def __call__(self, logger, method_name, event_dict):


class TimeStamper:
def __init__(self, *args, **kwargs):
def __init__(self, fmt: str) -> None:
pass

def __call__(self, logger, method_name, event_dict):
def __call__(
self, logger: WrappedLogger, method_name: str, event_dict: EventDict
) -> EventDict:
event_dict["timestamp"] = "2023-04-01T08:00:00.000000Z"
return event_dict


def format_exc_info(logger, method_name, event_dict):
def format_exc_info(
logger: WrappedLogger, method_name: str, event_dict: EventDict
) -> EventDict:
exc_info = event_dict.pop("exc_info", None)
if exc_info:
event_dict["exception"] = "Traceback blabla"
Expand Down
17 changes: 10 additions & 7 deletions tests/test_log.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import datetime
import json
from typing import Callable
from unittest.mock import patch

import structlog
from structlog.typing import WrappedLogger

import structlog_gcp

T_stdout = Callable[[], str]

def test_normal(stdout, logger):

def test_normal(stdout: T_stdout, logger: WrappedLogger) -> None:
logger.info("test")

msg = json.loads(stdout())
Expand All @@ -25,7 +29,7 @@ def test_normal(stdout, logger):
assert msg == expected


def test_error(stdout, logger):
def test_error(stdout: T_stdout, logger: WrappedLogger) -> None:
try:
1 / 0
except ZeroDivisionError:
Expand Down Expand Up @@ -60,7 +64,7 @@ def test_error(stdout, logger):
assert msg == expected


def test_service_context_default(stdout, logger):
def test_service_context_default(stdout: T_stdout, logger: WrappedLogger) -> None:
try:
1 / 0
except ZeroDivisionError:
Expand All @@ -75,7 +79,7 @@ def test_service_context_default(stdout, logger):


@patch.dict("os.environ", {"K_SERVICE": "test-service", "K_REVISION": "test-version"})
def test_service_context_envvar(stdout, mock_logger_env):
def test_service_context_envvar(stdout: T_stdout, mock_logger_env: None) -> None:
processors = structlog_gcp.build_processors()
structlog.configure(processors=processors)
logger = structlog.get_logger()
Expand All @@ -93,7 +97,7 @@ def test_service_context_envvar(stdout, mock_logger_env):
}


def test_service_context_custom(stdout, mock_logger_env):
def test_service_context_custom(stdout: T_stdout, mock_logger_env: None) -> None:
processors = structlog_gcp.build_processors(
service="my-service",
version="deadbeef",
Expand All @@ -114,7 +118,7 @@ def test_service_context_custom(stdout, mock_logger_env):
}


def test_extra_labels(stdout, logger):
def test_extra_labels(stdout: T_stdout, logger: WrappedLogger) -> None:
logger.info(
"test",
test1="test1",
Expand All @@ -135,7 +139,6 @@ def test_extra_labels(stdout, logger):
"severity": "INFO",
"time": "2023-04-01T08:00:00.000000Z",
"message": "test",

# This should be parsed automatically by Cloud Logging into dedicated keys and saved into a JSON payload.
# See: https://cloud.google.com/logging/docs/structured-logging#special-payload-fields
"test1": "test1",
Expand Down