Skip to content

Commit 34e97f0

Browse files
committed
use same logger throughout zarr-python
1 parent 71067ba commit 34e97f0

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

src/zarr/__init__.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import functools
2+
import logging
3+
from typing import Literal
4+
15
from zarr._version import version as __version__
26
from zarr.api.synchronous import (
37
array,
@@ -37,6 +41,8 @@
3741
# in case setuptools scm screw up and find version to be 0.0.0
3842
assert not __version__.startswith("0.0.0")
3943

44+
_logger = logging.getLogger(__name__)
45+
4046

4147
def print_debug_info() -> None:
4248
"""
@@ -85,6 +91,58 @@ def print_packages(packages: list[str]) -> None:
8591
print_packages(optional)
8692

8793

94+
# The decorator ensures this always returns the same handler (and it is only
95+
# attached once).
96+
@functools.cache
97+
def _ensure_handler() -> logging.Handler:
98+
"""
99+
The first time this function is called, attach a `StreamHandler` using the
100+
same format as `logging.basicConfig` to the Zarr-Python root logger.
101+
102+
Return this handler every time this function is called.
103+
"""
104+
handler = logging.StreamHandler()
105+
handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
106+
_logger.addHandler(handler)
107+
return handler
108+
109+
110+
def set_log_level(
111+
level: Literal["NOTSET", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
112+
) -> None:
113+
"""Set the logging level for Zarr-Python.
114+
115+
Zarr-Python uses the standard library `logging` framework under the root
116+
logger 'zarr'. This is a helper function to:
117+
118+
- set Zarr-Python's root logger level
119+
- set the root logger handler's level, creating the handler
120+
if it does not exist yet
121+
122+
Parameters
123+
----------
124+
level : str
125+
The logging level to set.
126+
"""
127+
_logger.setLevel(level)
128+
_ensure_handler().setLevel(level)
129+
130+
131+
def set_format(log_format: str) -> None:
132+
"""Set the format of logging messages from Zarr-Python.
133+
134+
Zarr-Python uses the standard library `logging` framework under the root
135+
logger 'zarr'. This sets the format of log messages from the root logger's StreamHandler.
136+
137+
Parameters
138+
----------
139+
log_format : str
140+
A string determining the log format (as defined in the standard library's `logging` module
141+
for logging.Formatter)
142+
"""
143+
_ensure_handler().setFormatter(logging.Formatter(fmt=log_format))
144+
145+
88146
__all__ = [
89147
"Array",
90148
"AsyncArray",

src/zarr/_cli/cli.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import typer
66

7+
import zarr
78
import zarr.metadata.migrate_v3 as migrate_metadata
89
from zarr.core.sync import sync
910
from zarr.storage._common import make_store
@@ -13,17 +14,13 @@
1314
logger = logging.getLogger(__name__)
1415

1516

16-
def _set_logging_config(*, verbose: bool) -> None:
17+
def _set_logging_level(*, verbose: bool) -> None:
1718
if verbose:
18-
lvl = logging.INFO
19+
lvl = "INFO"
1920
else:
20-
lvl = logging.WARNING
21-
fmt = "%(message)s"
22-
logging.basicConfig(level=lvl, format=fmt)
23-
24-
25-
def _set_verbose_level() -> None:
26-
logging.getLogger().setLevel(logging.INFO)
21+
lvl = "WARNING"
22+
zarr.set_log_level(cast(Literal["INFO", "WARNING"], lvl))
23+
zarr.set_format("%(message)s")
2724

2825

2926
class ZarrFormat(str, Enum):
@@ -96,7 +93,7 @@ def migrate(
9693
(every group / array). v2 files (.zarray, .zattrs etc.) will be left as-is.
9794
"""
9895
if dry_run:
99-
_set_verbose_level()
96+
_set_logging_level(verbose=True)
10097
logger.info(
10198
"Dry run enabled - no new files will be created or changed. Log of files that would be created on a real run:"
10299
)
@@ -154,7 +151,7 @@ def remove_metadata(
154151
Note - this will remove metadata files at all levels of the hierarchy (every group and array).
155152
"""
156153
if dry_run:
157-
_set_verbose_level()
154+
_set_logging_level(verbose=True)
158155
logger.info(
159156
"Dry run enabled - no files will be deleted or changed. Log of files that would be deleted on a real run:"
160157
)
@@ -182,7 +179,7 @@ def main(
182179
"""
183180
See available commands below - access help for individual commands with zarr COMMAND --help.
184181
"""
185-
_set_logging_config(verbose=verbose)
182+
_set_logging_level(verbose=verbose)
186183

187184

188185
if __name__ == "__main__":

0 commit comments

Comments
 (0)