lsst-utils 29.2025.4000__py3-none-any.whl → 29.2025.4100__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lsst/utils/logging.py +29 -1
- lsst/utils/timer.py +33 -5
- lsst/utils/version.py +1 -1
- {lsst_utils-29.2025.4000.dist-info → lsst_utils-29.2025.4100.dist-info}/METADATA +2 -1
- {lsst_utils-29.2025.4000.dist-info → lsst_utils-29.2025.4100.dist-info}/RECORD +10 -10
- {lsst_utils-29.2025.4000.dist-info → lsst_utils-29.2025.4100.dist-info}/WHEEL +0 -0
- {lsst_utils-29.2025.4000.dist-info → lsst_utils-29.2025.4100.dist-info}/licenses/COPYRIGHT +0 -0
- {lsst_utils-29.2025.4000.dist-info → lsst_utils-29.2025.4100.dist-info}/licenses/LICENSE +0 -0
- {lsst_utils-29.2025.4000.dist-info → lsst_utils-29.2025.4100.dist-info}/top_level.txt +0 -0
- {lsst_utils-29.2025.4000.dist-info → lsst_utils-29.2025.4100.dist-info}/zip-safe +0 -0
lsst/utils/logging.py
CHANGED
|
@@ -28,13 +28,24 @@ import time
|
|
|
28
28
|
from collections.abc import Generator
|
|
29
29
|
from contextlib import contextmanager
|
|
30
30
|
from logging import LoggerAdapter
|
|
31
|
-
from typing import Any, TypeAlias
|
|
31
|
+
from typing import TYPE_CHECKING, Any, TypeAlias, TypeGuard
|
|
32
32
|
|
|
33
33
|
try:
|
|
34
34
|
import lsst.log.utils as logUtils
|
|
35
35
|
except ImportError:
|
|
36
36
|
logUtils = None
|
|
37
37
|
|
|
38
|
+
try:
|
|
39
|
+
from structlog import get_context as get_structlog_context
|
|
40
|
+
except ImportError:
|
|
41
|
+
get_structlog_context = None # type: ignore[assignment]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if TYPE_CHECKING:
|
|
45
|
+
try:
|
|
46
|
+
from structlog.typing import BindableLogger
|
|
47
|
+
except ImportError:
|
|
48
|
+
BindableLogger: TypeAlias = Any # type: ignore[no-redef]
|
|
38
49
|
|
|
39
50
|
# log level for trace (verbose debug).
|
|
40
51
|
TRACE = 5
|
|
@@ -45,6 +56,23 @@ VERBOSE = (logging.INFO + logging.DEBUG) // 2
|
|
|
45
56
|
logging.addLevelName(VERBOSE, "VERBOSE")
|
|
46
57
|
|
|
47
58
|
|
|
59
|
+
def _is_structlog_logger(
|
|
60
|
+
logger: logging.Logger | LsstLogAdapter | BindableLogger,
|
|
61
|
+
) -> TypeGuard[BindableLogger]:
|
|
62
|
+
"""Check if the given logger is a structlog logger."""
|
|
63
|
+
if get_structlog_context is None:
|
|
64
|
+
return False # type: ignore[unreachable]
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
# Returns a dict for structlog loggers; raises for stdlib logger
|
|
68
|
+
# objects.
|
|
69
|
+
get_structlog_context(logger) # type: ignore[arg-type]
|
|
70
|
+
return True
|
|
71
|
+
except Exception:
|
|
72
|
+
# In practice this is usually ValueError or AttributeError.
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
|
|
48
76
|
def _calculate_base_stacklevel(default: int, offset: int) -> int:
|
|
49
77
|
"""Calculate the default logging stacklevel to use.
|
|
50
78
|
|
lsst/utils/timer.py
CHANGED
|
@@ -32,7 +32,7 @@ from typing import TYPE_CHECKING, Any, TypeVar, overload
|
|
|
32
32
|
from astropy import units as u
|
|
33
33
|
|
|
34
34
|
from .introspection import find_outside_stacklevel
|
|
35
|
-
from .logging import LsstLoggers
|
|
35
|
+
from .logging import LsstLoggers, _is_structlog_logger
|
|
36
36
|
from .usage import _get_current_rusage, get_current_mem_usage, get_peak_mem_usage
|
|
37
37
|
|
|
38
38
|
if TYPE_CHECKING:
|
|
@@ -374,9 +374,10 @@ def time_this(
|
|
|
374
374
|
level: int = logging.DEBUG,
|
|
375
375
|
prefix: str | None = "timer",
|
|
376
376
|
args: Iterable[Any] = (),
|
|
377
|
+
kwargs: dict[str, Any] | None = None,
|
|
377
378
|
mem_usage: bool = False,
|
|
378
379
|
mem_child: bool = False,
|
|
379
|
-
mem_unit: u.
|
|
380
|
+
mem_unit: u.Unit = u.byte,
|
|
380
381
|
mem_fmt: str = ".0f",
|
|
381
382
|
force_mem_usage: bool = False,
|
|
382
383
|
) -> Iterator[_TimerResult]:
|
|
@@ -386,7 +387,8 @@ def time_this(
|
|
|
386
387
|
----------
|
|
387
388
|
log : `logging.Logger`, optional
|
|
388
389
|
Logger to use to report the timer message. The root logger will
|
|
389
|
-
be used if none is given.
|
|
390
|
+
be used if none is given. Is also allowed to be a `structlog` bound
|
|
391
|
+
logger.
|
|
390
392
|
msg : `str`, optional
|
|
391
393
|
Context to include in log message.
|
|
392
394
|
level : `int`, optional
|
|
@@ -400,6 +402,11 @@ def time_this(
|
|
|
400
402
|
args : iterable of any
|
|
401
403
|
Additional parameters passed to the log command that should be
|
|
402
404
|
written to ``msg``.
|
|
405
|
+
kwargs : `dict`, optional
|
|
406
|
+
Additional keyword parameters passed to the log command. If a Structlog
|
|
407
|
+
is used then these will be added to the structured data. Otherwise
|
|
408
|
+
they will be converted to a single string for inclusion in the log
|
|
409
|
+
message.
|
|
403
410
|
mem_usage : `bool`, optional
|
|
404
411
|
Flag indicating whether to include the memory usage in the report.
|
|
405
412
|
Defaults, to False. Does nothing if the log message will not be
|
|
@@ -424,10 +431,17 @@ def time_this(
|
|
|
424
431
|
"""
|
|
425
432
|
if log is None:
|
|
426
433
|
log = logging.getLogger()
|
|
427
|
-
|
|
434
|
+
is_structlog = _is_structlog_logger(log)
|
|
435
|
+
if prefix and not is_structlog:
|
|
436
|
+
# Struct log loggers do not have a name property and so the prefix
|
|
437
|
+
# is not applied to them.
|
|
428
438
|
log_name = f"{prefix}.{log.name}" if not isinstance(log, logging.RootLogger) else prefix
|
|
429
439
|
log = logging.getLogger(log_name)
|
|
430
440
|
|
|
441
|
+
# Some structured data that can be used if we have been given a
|
|
442
|
+
# structlog logger.
|
|
443
|
+
structured_args: dict[str, Any] = {}
|
|
444
|
+
|
|
431
445
|
start = time.time()
|
|
432
446
|
|
|
433
447
|
if mem_usage and not log.isEnabledFor(level):
|
|
@@ -467,6 +481,7 @@ def time_this(
|
|
|
467
481
|
# caller (1 is this file, 2 is contextlib, 3 is user)
|
|
468
482
|
params += (": " if msg else "", duration)
|
|
469
483
|
msg += "%sTook %.4f seconds"
|
|
484
|
+
structured_args["duration"] = duration
|
|
470
485
|
if errmsg:
|
|
471
486
|
params += (f" (timed code triggered exception of {errmsg!r})",)
|
|
472
487
|
msg += "%s"
|
|
@@ -502,7 +517,20 @@ def time_this(
|
|
|
502
517
|
f", delta: {current_delta:{mem_fmt}}"
|
|
503
518
|
f", peak delta: {peak_delta:{mem_fmt}}"
|
|
504
519
|
)
|
|
505
|
-
|
|
520
|
+
structured_args["mem_current_usage"] = float(current_usage.value)
|
|
521
|
+
structured_args["mem_current_delta"] = float(current_delta.value)
|
|
522
|
+
structured_args["mem_peak_delta"] = float(peak_delta.value)
|
|
523
|
+
if not is_structlog:
|
|
524
|
+
# Can only use the structured content if we have structlog logger
|
|
525
|
+
# but stacklevel is only supported by standard loggers.
|
|
526
|
+
structured_args = {"stacklevel": 3}
|
|
527
|
+
if kwargs is not None:
|
|
528
|
+
msg += " %s"
|
|
529
|
+
params += ("; ".join(f"{k}={v!r}" for k, v in kwargs.items()),)
|
|
530
|
+
elif kwargs:
|
|
531
|
+
structured_args.update(kwargs)
|
|
532
|
+
|
|
533
|
+
log.log(level, msg, *params, **structured_args)
|
|
506
534
|
|
|
507
535
|
|
|
508
536
|
@contextmanager
|
lsst/utils/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "29.2025.
|
|
2
|
+
__version__ = "29.2025.4100"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-utils
|
|
3
|
-
Version: 29.2025.
|
|
3
|
+
Version: 29.2025.4100
|
|
4
4
|
Summary: Utility functions from Rubin Observatory Data Management for the Legacy Survey of Space and Time (LSST).
|
|
5
5
|
Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -22,6 +22,7 @@ Requires-Dist: psutil>=5.7
|
|
|
22
22
|
Requires-Dist: deprecated>=1.2
|
|
23
23
|
Requires-Dist: pyyaml>=5.1
|
|
24
24
|
Requires-Dist: astropy>=5.0
|
|
25
|
+
Requires-Dist: structlog
|
|
25
26
|
Requires-Dist: threadpoolctl
|
|
26
27
|
Provides-Extra: test
|
|
27
28
|
Requires-Dist: pytest>=3.2; extra == "test"
|
|
@@ -9,24 +9,24 @@ lsst/utils/doImport.py,sha256=JbD_AR1GQ1PVdK--OJy5tVz1U2Kabe1ETyQoyaq6rpQ,4241
|
|
|
9
9
|
lsst/utils/inheritDoc.py,sha256=doMsQKcDssZvsTAYJSmHxOWXM4D1wPrDSCTHiaRGUvw,2719
|
|
10
10
|
lsst/utils/introspection.py,sha256=Y1ImDWl5i1O9iRbOoSJhr8Rz57y-_WMgwDtbGJBVxJk,14735
|
|
11
11
|
lsst/utils/iteration.py,sha256=FHDGWcAbWzJdN1RVP-LdtatBfmCW9x_2MdQ5iwmT1sE,9278
|
|
12
|
-
lsst/utils/logging.py,sha256=
|
|
12
|
+
lsst/utils/logging.py,sha256=TPtKK5ShYAEeIFlqhYkEGGSDeUwiMWWzOb1CQGHMBlU,16256
|
|
13
13
|
lsst/utils/packages.py,sha256=D2eD2Qy3P_Os7RbUKsG2mPyLoSLjqejUX6lNhaC16wg,27455
|
|
14
14
|
lsst/utils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
lsst/utils/tests.py,sha256=1cjyXtEL2LNhnPKjtiTt9cdPmlaEWgaWBx9BfM-xSmA,39152
|
|
16
16
|
lsst/utils/threads.py,sha256=WNl3uvbE7bx5UyxTX0fwN5AkU3Yty_m8y_pMKcMCdv8,2551
|
|
17
|
-
lsst/utils/timer.py,sha256=
|
|
17
|
+
lsst/utils/timer.py,sha256=p_qOEQEIqfQubQJmaN4pK-3YUqZCocY08fBgpnSTXh0,21961
|
|
18
18
|
lsst/utils/usage.py,sha256=qunydx-KlcbNp-vFcBtvBayWwZAa0tHtSWvz5BycvLA,4598
|
|
19
|
-
lsst/utils/version.py,sha256=
|
|
19
|
+
lsst/utils/version.py,sha256=imQpc8l8n1Xj3guWKoFaXrBR3HnAY8jkMITBuZx-5DA,55
|
|
20
20
|
lsst/utils/wrappers.py,sha256=KCvsrGXziLQ5pC8ytiFEXeDH9mBSo8eCZ8g08f7s404,19209
|
|
21
21
|
lsst/utils/plotting/__init__.py,sha256=OEAZv2W12UAcUfDxH5H_k8v7cK4fVTOssuqNksZTuIs,507
|
|
22
22
|
lsst/utils/plotting/figures.py,sha256=pLkD7MpYk1Zs2hozA2-6r_uUd1129Uoi9EAEkMvtCjk,4356
|
|
23
23
|
lsst/utils/plotting/limits.py,sha256=6ilPmb4wg4aVtjlBgm75FPBrjDVSkW_ywZrj_QIQD2U,5839
|
|
24
24
|
lsst/utils/plotting/publication_plots.py,sha256=-uOL2ptI3N52KxfhtJNsUt7SqeGdT78GF-_QjHKKmV8,5016
|
|
25
25
|
lsst/utils/plotting/rubin.mplstyle,sha256=mjLPYzolUjeCXq8z4ltXLvEf8IuyT4TS0Nx8JJ05v6I,1063
|
|
26
|
-
lsst_utils-29.2025.
|
|
27
|
-
lsst_utils-29.2025.
|
|
28
|
-
lsst_utils-29.2025.
|
|
29
|
-
lsst_utils-29.2025.
|
|
30
|
-
lsst_utils-29.2025.
|
|
31
|
-
lsst_utils-29.2025.
|
|
32
|
-
lsst_utils-29.2025.
|
|
26
|
+
lsst_utils-29.2025.4100.dist-info/licenses/COPYRIGHT,sha256=I6Bxnp_LkIqDjafZNIXM8jfjYWC4XIlpNpZ7jkdeZK0,361
|
|
27
|
+
lsst_utils-29.2025.4100.dist-info/licenses/LICENSE,sha256=7wrtgl8meQ0_RIuv2TjIKpAnNrl-ODH-QLwyHe9citI,1516
|
|
28
|
+
lsst_utils-29.2025.4100.dist-info/METADATA,sha256=cj8DGTjiJoiu4vsBTeqSyYkCVrcG7jg6nL9-nai87x4,1716
|
|
29
|
+
lsst_utils-29.2025.4100.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
30
|
+
lsst_utils-29.2025.4100.dist-info/top_level.txt,sha256=eUWiOuVVm9wwTrnAgiJT6tp6HQHXxIhj2QSZ7NYZH80,5
|
|
31
|
+
lsst_utils-29.2025.4100.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
32
|
+
lsst_utils-29.2025.4100.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|