Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/joblib/logger.py: 28%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Helpers for logging.
4This module needs much love to become useful.
5"""
7# Author: Gael Varoquaux <gael dot varoquaux at normalesup dot org>
8# Copyright (c) 2008 Gael Varoquaux
9# License: BSD Style, 3 clauses.
11from __future__ import print_function
13import logging
14import os
15import pprint
16import shutil
17import sys
18import time
20from .disk import mkdirp
23def _squeeze_time(t):
24 """Remove .1s to the time under Windows: this is the time it take to
25 stat files. This is needed to make results similar to timings under
26 Unix, for tests
27 """
28 if sys.platform.startswith("win"):
29 return max(0, t - 0.1)
30 else:
31 return t
34def format_time(t):
35 """Format a duration in seconds as a human-readable string.
37 Returns both seconds and minutes, e.g. ``'12.3s, 0.2min'``.
39 Parameters
40 ----------
41 t : float
42 Duration in seconds.
44 Returns
45 -------
46 str
47 Formatted string showing the duration in seconds and minutes.
48 """
49 t = _squeeze_time(t)
50 return "%.1fs, %.1fmin" % (t, t / 60.0)
53def short_format_time(t):
54 """Format a duration in seconds as a compact human-readable string.
56 Returns minutes for durations over 60 seconds, otherwise seconds.
58 Parameters
59 ----------
60 t : float
61 Duration in seconds.
63 Returns
64 -------
65 str
66 Formatted string: ``' 42.0s'`` for short durations or
67 ``' 1.2min'`` for longer ones.
68 """
69 t = _squeeze_time(t)
70 if t > 60:
71 return "%4.1fmin" % (t / 60.0)
72 else:
73 return " %5.1fs" % (t)
76def pformat(obj, indent=0, depth=3):
77 """Return a pretty-printed string representation of an object.
79 Uses :func:`pprint.pformat` with numpy print options temporarily
80 reduced to keep output concise when numpy is available.
82 Parameters
83 ----------
84 obj : object
85 The object to format.
86 indent : int, optional
87 Indentation level passed to :func:`pprint.pformat`. Default is 0.
88 depth : int, optional
89 Maximum nesting depth passed to :func:`pprint.pformat`. Default is 3.
91 Returns
92 -------
93 str
94 Pretty-printed string representation of ``obj``.
95 """
96 if "numpy" in sys.modules:
97 import numpy as np
99 print_options = np.get_printoptions()
100 np.set_printoptions(precision=6, threshold=64, edgeitems=1)
101 else:
102 print_options = None
103 out = pprint.pformat(obj, depth=depth, indent=indent)
104 if print_options:
105 np.set_printoptions(**print_options)
106 return out
109###############################################################################
110# class `Logger`
111###############################################################################
112class Logger(object):
113 """Base class for logging messages."""
115 def __init__(self, depth=3, name=None):
116 """
117 Parameters
118 ----------
119 depth: int, optional
120 The depth of objects printed.
121 name: str, optional
122 The namespace to log to. If None, defaults to joblib.
123 """
124 self.depth = depth
125 self._name = name if name else "joblib"
127 def warn(self, msg):
128 logging.getLogger(self._name).warning("[%s]: %s" % (self, msg))
130 def info(self, msg):
131 logging.info("[%s]: %s" % (self, msg))
133 def debug(self, msg):
134 # XXX: This conflicts with the debug flag used in children class
135 logging.getLogger(self._name).debug("[%s]: %s" % (self, msg))
137 def format(self, obj, indent=0):
138 """Return the formatted representation of the object."""
139 return pformat(obj, indent=indent, depth=self.depth)
142###############################################################################
143# class `PrintTime`
144###############################################################################
145class PrintTime(object):
146 """Print and log messages while keeping track of time."""
148 def __init__(self, logfile=None, logdir=None):
149 if logfile is not None and logdir is not None:
150 raise ValueError("Cannot specify both logfile and logdir")
151 # XXX: Need argument docstring
152 self.last_time = time.time()
153 self.start_time = self.last_time
154 if logdir is not None:
155 logfile = os.path.join(logdir, "joblib.log")
156 self.logfile = logfile
157 if logfile is not None:
158 mkdirp(os.path.dirname(logfile))
159 if os.path.exists(logfile):
160 # Rotate the logs
161 for i in range(1, 9):
162 try:
163 shutil.move(logfile + ".%i" % i, logfile + ".%i" % (i + 1))
164 except: # noqa: E722
165 "No reason failing here"
166 # Use a copy rather than a move, so that a process
167 # monitoring this file does not get lost.
168 try:
169 shutil.copy(logfile, logfile + ".1")
170 except: # noqa: E722
171 "No reason failing here"
172 try:
173 with open(logfile, "w") as logfile:
174 logfile.write("\nLogging joblib python script\n")
175 logfile.write("\n---%s---\n" % time.ctime(self.last_time))
176 except: # noqa: E722
177 """ Multiprocessing writing to files can create race
178 conditions. Rather fail silently than crash the
179 computation.
180 """
181 # XXX: We actually need a debug flag to disable this
182 # silent failure.
184 def __call__(self, msg="", total=False):
185 """Print the time elapsed between the last call and the current
186 call, with an optional message.
187 """
188 if not total:
189 time_lapse = time.time() - self.last_time
190 full_msg = "%s: %s" % (msg, format_time(time_lapse))
191 else:
192 # FIXME: Too much logic duplicated
193 time_lapse = time.time() - self.start_time
194 full_msg = "%s: %.2fs, %.1f min" % (msg, time_lapse, time_lapse / 60)
195 print(full_msg, file=sys.stderr)
196 if self.logfile is not None:
197 try:
198 with open(self.logfile, "a") as f:
199 print(full_msg, file=f)
200 except: # noqa: E722
201 """ Multiprocessing writing to files can create race
202 conditions. Rather fail silently than crash the
203 calculation.
204 """
205 # XXX: We actually need a debug flag to disable this
206 # silent failure.
207 self.last_time = time.time()