Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Commit 8b08195

Browse files
Merge pull request #156 from encode/tweak-logging
Tweak logging
2 parents 88b381a + 0b59a9f commit 8b08195

4 files changed

Lines changed: 50 additions & 10 deletions

File tree

databases/backends/mysql.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from sqlalchemy.sql import ClauseElement
1111
from sqlalchemy.types import TypeEngine
1212

13-
from databases.core import DatabaseURL
13+
from databases.core import LOG_EXTRA, DatabaseURL
1414
from databases.interfaces import ConnectionBackend, DatabaseBackend, TransactionBackend
1515

1616
logger = logging.getLogger("databases")
@@ -179,7 +179,8 @@ def _compile(
179179
compiled._textual_ordered_columns,
180180
)
181181

182-
logger.debug("Query: %s\nArgs: %s", compiled.string, args)
182+
query_message = compiled.string.replace(" \n", " ").replace("\n", " ")
183+
logger.debug("Query: %s Args: %s", query_message, repr(args), extra=LOG_EXTRA)
183184
return compiled.string, args, CompilationContext(execution_context)
184185

185186
@property

databases/backends/postgres.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from sqlalchemy.sql.schema import Column
1010
from sqlalchemy.types import TypeEngine
1111

12-
from databases.core import DatabaseURL
12+
from databases.core import LOG_EXTRA, DatabaseURL
1313
from databases.interfaces import ConnectionBackend, DatabaseBackend, TransactionBackend
1414

1515
logger = logging.getLogger("databases")
@@ -192,7 +192,10 @@ def _compile(self, query: ClauseElement) -> typing.Tuple[str, list, tuple]:
192192
for key, val in compiled_params
193193
]
194194

195-
logger.debug("Query: %s\nArgs: %s", compiled_query, args)
195+
query_message = compiled_query.replace(" \n", " ").replace("\n", " ")
196+
logger.debug(
197+
"Query: %s Args: %s", query_message, repr(tuple(args)), extra=LOG_EXTRA
198+
)
196199
return compiled_query, args, compiled._result_columns
197200

198201
@property

databases/backends/sqlite.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from sqlalchemy.sql import ClauseElement
1010
from sqlalchemy.types import TypeEngine
1111

12-
from databases.core import DatabaseURL
12+
from databases.core import LOG_EXTRA, DatabaseURL
1313
from databases.interfaces import ConnectionBackend, DatabaseBackend, TransactionBackend
1414

1515
logger = logging.getLogger("databases")
@@ -154,7 +154,10 @@ def _compile(
154154
compiled._textual_ordered_columns,
155155
)
156156

157-
logger.debug("Query: %s\nArgs: %s", compiled.string, args)
157+
query_message = compiled.string.replace(" \n", " ").replace("\n", " ")
158+
logger.debug(
159+
"Query: %s Args: %s", query_message, repr(tuple(args)), extra=LOG_EXTRA
160+
)
158161
return compiled.string, args, CompilationContext(execution_context)
159162

160163
@property

databases/core.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import asyncio
22
import functools
3+
import logging
34
import sys
45
import typing
56
from types import TracebackType
@@ -16,6 +17,27 @@
1617
else: # pragma: no cover
1718
from aiocontextvars import ContextVar
1819

20+
try: # pragma: no cover
21+
import click
22+
23+
# Extra log info for optional coloured terminal outputs.
24+
LOG_EXTRA = {
25+
"color_message": "Query: " + click.style("%s", bold=True) + " Args: %s"
26+
}
27+
CONNECT_EXTRA = {
28+
"color_message": "Connected to database " + click.style("%s", bold=True)
29+
}
30+
DISCONNECT_EXTRA = {
31+
"color_message": "Disconnected from database " + click.style("%s", bold=True)
32+
}
33+
except ImportError: # pragma: no cover
34+
LOG_EXTRA = {}
35+
CONNECT_EXTRA = {}
36+
DISCONNECT_EXTRA = {}
37+
38+
39+
logger = logging.getLogger("databases")
40+
1941

2042
class Database:
2143
SUPPORTED_BACKENDS = {
@@ -63,6 +85,9 @@ async def connect(self) -> None:
6385
assert not self.is_connected, "Already connected."
6486

6587
await self._backend.connect()
88+
logger.info(
89+
"Connected to database %s", self.url.obscure_password, extra=CONNECT_EXTRA
90+
)
6691
self.is_connected = True
6792

6893
if self._force_rollback:
@@ -80,6 +105,11 @@ async def disconnect(self) -> None:
80105
await self._global_transaction.__aexit__()
81106

82107
await self._backend.disconnect()
108+
logger.info(
109+
"Disconnected from database %s",
110+
self.url.obscure_password,
111+
extra=DISCONNECT_EXTRA,
112+
)
83113
self.is_connected = False
84114

85115
async def __aenter__(self) -> "Database":
@@ -412,14 +442,17 @@ def replace(self, **kwargs: typing.Any) -> "DatabaseURL":
412442
components = self.components._replace(**kwargs)
413443
return self.__class__(components.geturl())
414444

445+
@property
446+
def obscure_password(self) -> str:
447+
if self.password:
448+
return self.replace(password="********")._url
449+
return self._url
450+
415451
def __str__(self) -> str:
416452
return self._url
417453

418454
def __repr__(self) -> str:
419-
url = str(self)
420-
if self.password:
421-
url = str(self.replace(password="********"))
422-
return f"{self.__class__.__name__}({repr(url)})"
455+
return f"{self.__class__.__name__}({repr(self.obscure_password)})"
423456

424457
def __eq__(self, other: typing.Any) -> bool:
425458
return str(self) == str(other)

0 commit comments

Comments
 (0)