LSST Applications 24.1.0,g0b6bd0c080+e62dec11b2,g17e5ecfddb+2f99ec5bff,g1d67935e3f+aeba7d5376,g33b6a96d52+e24369602a,g38293774b4+ac198e9f13,g396055baef+a9fc9fe987,g3b44f30a73+6ed7a0bf37,g45a0052f0b+d5a0214cf8,g48ccf36440+89c08d0516,g5c4744a4d9+9e5e24d318,g6c8d09e9e7+60190443eb,g8b9e2231ea+b61c7debcc,g9c8be92ad0+d5a0214cf8,g9d27549199+9e5e24d318,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+8c170280cc,gaa63f70f4e+a45a85e39e,gabf319e997+a153293d79,gb22ebf5633+adf3385ca5,gbec6a3398f+aeba7d5376,gc75b51116a+846e1f9efd,gca4adeb000+d5a0214cf8,gd01420fc67+aeba7d5376,gd82bb2a289+52e0a19ca3,gd877ba84e5+aeba7d5376,gd95cd18b76+8a093cac5b,gdb4cecd868+a5301bf5a0,gecc7e12556+d5a0214cf8,gf14d0188e3+a153293d79,gf3ee170dca+60190443eb,gf4ac96e456+a153293d79,gf51b12da82+3612beda7c,gf8609944d8+9adb1d6802,gf9f5ea5b4d+ac198e9f13,gff490e6085+9d6cf01b2b
LSST Data Management Base Package
Loading...
Searching...
No Matches
utils.py
Go to the documentation of this file.
1#!/usr/bin/env python
2#
3# LSST Data Management System
4#
5# Copyright 2016 AURA/LSST.
6#
7# This product includes software developed by the
8# LSST Project (http://www.lsst.org/).
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the LSST License Statement and
21# the GNU General Public License along with this program. If not,
22# see <https://www.lsstcorp.org/LegalNotices/>.
23#
24
25__all__ = [
26 "traceSetAt",
27 "temporaryLogLevel",
28 "LogRedirect",
29 "enable_notebook_logging",
30 "disable_notebook_logging",
31]
32
33from contextlib import contextmanager
34import os
35import sys
36import threading
37
38from lsst.log import Log
39
40
41def traceSetAt(name, number):
42 """Adjusts logging level to display messages with the trace number being
43 less than or equal to the provided value.
44
45 Parameters
46 ----------
47 name : `str`
48 Name of the logger.
49 number : `int`
50 The trace number threshold for display.
51 """
52 for i in range(6):
53 level = Log.INFO if i > number else Log.DEBUG
54 Log.getLogger('TRACE%d.%s' % (i, name)).setLevel(level)
55
56
57@contextmanager
58def temporaryLogLevel(name, level):
59 """A context manager that temporarily sets the level of a `Log`.
60
61 Parameters
62 ----------
63 name : `str`
64 Name of the log to modify.
65 level : `int`
66 Integer enumeration constant indicating the temporary log level.
67 """
68 log = Log.getLogger(name)
69 old = log.getLevel()
70 log.setLevel(level)
71 try:
72 yield
73 finally:
74 log.setLevel(old)
75
76
78 """Redirect a logging file descriptor to a Python stream.
79
80 Parameters
81 ----------
82 fd : `int`
83 File descriptor number, usually 1 for standard out, the default log
84 output location.
85 dest : `io.TextIOBase`
86 Destination text stream, often `sys.stderr` for ipython or Jupyter
87 notebooks.
88 encoding : `str`
89 Text encoding of the data written to fd.
90 errors : `str`
91 Encoding error handling.
92
93 Notes
94 -----
95 Inspired by `this Stack Overflow answer
96 <https://stackoverflow.com/questions/41216215>`_
97 """
98
99 def __init__(self, fd=1, dest=sys.stderr, encoding="utf-8", errors="strict"):
100 self._fd = fd
101 self._dest = dest
102 # Save original filehandle so we can restore it later.
103 self._filehandle = os.dup(fd)
104
105 # Redirect `fd` to the write end of the pipe.
106 pipe_read, pipe_write = os.pipe()
107 os.dup2(pipe_write, fd)
108 os.close(pipe_write)
109
110 # This thread reads from the read end of the pipe.
111 def consumer_thread(f, data):
112 while True:
113 buf = os.read(f, 1024)
114 if not buf:
115 break
116 data.write(buf.decode(encoding, errors))
117 os.close(f)
118 return
119
120 # Spawn consumer thread with the desired destination stream.
121 self._thread = threading.Thread(target=consumer_thread, args=(pipe_read, dest))
122 self._thread.start()
123
124 def finish(self):
125 """Stop redirecting output.
126 """
127
128 # Cleanup: flush streams, restore `fd`
129 self._dest.flush()
130 # This dup2 closes the saved file descriptor, which is now the write
131 # end of the pipe, causing the thread's read to terminate
132 os.dup2(self._filehandle, self._fd)
133 os.close(self._filehandle)
134 self._thread.join()
135
136
137_redirect = None
138
139
140def enable_notebook_logging(dest=sys.stderr):
141 """Enable notebook output for log4cxx messages."""
142 global _redirect
143 if _redirect is None:
144 _redirect = LogRedirect(dest=dest)
145
146
148 """Stop notebook output for log4cxx messages."""
149 global _redirect
150 if _redirect is not None:
151 _redirect.finish()
152 _redirect = None
def __init__(self, fd=1, dest=sys.stderr, encoding="utf-8", errors="strict")
Definition: utils.py:99
def setLevel(loggername, level)
def temporaryLogLevel(name, level)
Definition: utils.py:58
def enable_notebook_logging(dest=sys.stderr)
Definition: utils.py:140
def traceSetAt(name, number)
Definition: utils.py:41
def disable_notebook_logging()
Definition: utils.py:147
Definition: Log.h:717