Use structured fields for adapter debug and info logs.
PR Title Check / check-title (pull_request) Successful in 6s
Test Python Package / unit-tests (pull_request) Successful in 9s
Code Quality Pipeline / code-quality (pull_request) Failing after 14s
Test Python Package / integration-tests (pull_request) Successful in 1m2s
Test Python Package / coverage-report (pull_request) Successful in 11s

Replace f-string log messages with structlog keyword fields so events aggregate cleanly and Redis payloads are not logged verbatim.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Brian Bjarke Jensen
2026-07-10 14:00:34 +02:00
co-authored by Cursor
parent 4518a93a3a
commit b886a7c147
5 changed files with 25 additions and 18 deletions
@@ -73,7 +73,7 @@ class ConnectionAwareAdapter(ConnectionAwareInterface, ContextAwareInterface):
self._invalidate_health_cache()
return
if self._is_client_ready() and self.is_connected():
self.logger.info(f"Already connected to {self.connection_name}")
self.logger.info("Already connected", connection_name=self.connection_name)
return
self.disconnect()
self._establish_connection()
+11 -6
View File
@@ -88,7 +88,7 @@ class MinioAdapter(ObjectRepositoryInterface, ConnectionAwareAdapter):
raise ConnectionError(
f"Bucket '{bucket}' does not exist on Minio at {endpoint}"
)
self.logger.info(f"Creating bucket '{bucket}'")
self.logger.info("Creating bucket", bucket=bucket)
client.make_bucket(bucket)
self._client = client
self._bucket_name = bucket
@@ -138,7 +138,7 @@ class MinioAdapter(ObjectRepositoryInterface, ConnectionAwareAdapter):
content_type=content_type,
)
self.logger.debug(
f"Put object '{object_name}' into bucket '{self._bucket_name}'"
"Put object", object_name=object_name, bucket=self._bucket_name
)
def get(self, object_name: str) -> BytesIO | None:
@@ -163,13 +163,15 @@ class MinioAdapter(ObjectRepositoryInterface, ConnectionAwareAdapter):
buffer.write(chunk)
buffer.seek(0)
self.logger.debug(
f"Got object '{object_name}' from bucket '{self._bucket_name}'"
"Got object", object_name=object_name, bucket=self._bucket_name
)
return buffer
except minio.S3Error as exc:
if exc.code == "NoSuchKey":
self.logger.warning(
f"Object '{object_name}' not found in bucket '{self._bucket_name}'"
"Object not found",
object_name=object_name,
bucket=self._bucket_name,
)
return None
raise
@@ -193,7 +195,7 @@ class MinioAdapter(ObjectRepositoryInterface, ConnectionAwareAdapter):
object_name=object_name,
)
self.logger.debug(
f"Deleted object '{object_name}' from bucket '{self._bucket_name}'"
"Deleted object", object_name=object_name, bucket=self._bucket_name
)
def list_objects(self, prefix: str = "") -> list[str]:
@@ -215,6 +217,9 @@ class MinioAdapter(ObjectRepositoryInterface, ConnectionAwareAdapter):
obj.object_name for obj in objects if obj.object_name is not None
]
self.logger.debug(
f"Listed {len(object_names)} object(s) in bucket '{self._bucket_name}' with prefix '{prefix}'"
"Listed objects",
count=len(object_names),
bucket=self._bucket_name,
prefix=prefix,
)
return object_names
@@ -101,7 +101,7 @@ class RedisAdapter(JsonRepositoryInterface, ConnectionAwareAdapter):
assert self._client is not None
# Set data
self._client.json().set(key, self.path, data)
self.logger.debug(f"Set {key} to {data}")
self.logger.debug("Set key", key=key, data_keys=list(data.keys()))
def get(self, key: str) -> dict[str, Any] | None:
"""Get a JSON object from Redis."""
@@ -116,7 +116,7 @@ class RedisAdapter(JsonRepositoryInterface, ConnectionAwareAdapter):
dict[str, Any] | None,
self._client.json().get(key),
)
self.logger.debug(f"Got {data} from {key}")
self.logger.debug("Got value", key=key, found=data is not None)
return data
def delete(self, key: str) -> None:
@@ -129,7 +129,7 @@ class RedisAdapter(JsonRepositoryInterface, ConnectionAwareAdapter):
assert self._client is not None
# Delete data
self._client.json().delete(key)
self.logger.debug(f"Deleted {key}")
self.logger.debug("Deleted key", key=key)
def _validate_pattern(self, pattern: str) -> None:
if not isinstance(pattern, str) or len(pattern) == 0:
@@ -147,7 +147,7 @@ class RedisAdapter(JsonRepositoryInterface, ConnectionAwareAdapter):
self._client.keys(pattern),
)
keys: list[str] = [key.decode(self.encoding) for key in keys_raw]
self.logger.debug(f"Got {keys} matching {pattern}")
self.logger.debug("Listed keys", pattern=pattern, count=len(keys))
return keys
def scan_keys(
+7 -6
View File
@@ -102,7 +102,8 @@ def test_should_log_info_when_already_connected(
"""Test that the MinioAdapter logs info when connect is called while already connected."""
with caplog.at_level(logging.INFO):
minio_adapter.connect()
assert "Already connected to Minio" in caplog.text
assert "Already connected" in caplog.text
assert "Minio" in caplog.text
def test_should_raise_connection_error_when_unable_to_connect() -> None:
@@ -150,7 +151,8 @@ def test_connect_creates_bucket_when_create_bucket_if_missing_enabled(
with caplog.at_level(logging.INFO):
adapter.connect()
assert f"Creating bucket '{bucket_name}'" in caplog.text
assert "Creating bucket" in caplog.text
assert bucket_name in caplog.text
def test_should_log_error_on_exception_during_exit(
@@ -233,10 +235,9 @@ def test_should_log_warning_when_getting_nonexistent_object(
with caplog.at_level("WARNING"):
result = adapter.get(object_name)
assert result is None
assert (
f"Object '{object_name}' not found in bucket '{adapter._bucket_name}'"
in caplog.text
)
assert "Object not found" in caplog.text
assert object_name in caplog.text
assert adapter._bucket_name in caplog.text
def test_should_reraise_s3error_other_than_no_such_key() -> None:
+2 -1
View File
@@ -56,7 +56,8 @@ def test_should_log_info_when_already_connected(
"""Test that the RedisAdapter logs info when connect is called while already connected."""
with caplog.at_level(logging.INFO):
redis_adapter.connect()
assert "Already connected to Redis" in caplog.text
assert "Already connected" in caplog.text
assert "Redis" in caplog.text
def test_should_raise_connection_error_when_unable_to_connect() -> None: