1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 Logging package for Python. Based on PEP 282 and comments thereto in
19 comp.lang.python, and influenced by Apache's log4j system.
20
21 Should work under Python versions >= 1.5.2, except that source line
22 information is not available unless 'sys._getframe()' is.
23
24 Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
25
26 To use, simply 'import logging' and log away!
27 """
28
29 import sys, os, types, time, string, cStringIO, traceback
30
31 try:
32 import codecs
33 except ImportError:
34 codecs = None
35
36 try:
37 import thread
38 import threading
39 except ImportError:
40 thread = None
41
42 __author__ = "Vinay Sajip <[email protected]>"
43 __status__ = "beta"
44 __version__ = "0.4.9.7"
45 __date__ = "07 October 2005"
46
47
48
49
50
51
52
53
54
55 if hasattr(sys, 'frozen'):
56 _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
57 elif string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
58 _srcfile = __file__[:-4] + '.py'
59 else:
60 _srcfile = __file__
61 _srcfile = os.path.normcase(_srcfile)
62
63
65 """Return the frame object for the caller's stack frame."""
66 try:
67 raise Exception
68 except:
69 return sys.exc_traceback.tb_frame.f_back
70
71 if hasattr(sys, '_getframe'): currentframe = sys._getframe
72
73
74
75
76
77
78
79
80
81
82
83
84 _startTime = time.time()
85
86
87
88
89
90 raiseExceptions = 1
91
92
93
94
95
96
97
98
99
100
101
102
103 CRITICAL = 50
104 FATAL = CRITICAL
105 ERROR = 40
106 WARNING = 30
107 WARN = WARNING
108 INFO = 20
109 DEBUG = 10
110 NOTSET = 0
111
112 _levelNames = {
113 CRITICAL : 'CRITICAL',
114 ERROR : 'ERROR',
115 WARNING : 'WARNING',
116 INFO : 'INFO',
117 DEBUG : 'DEBUG',
118 NOTSET : 'NOTSET',
119 'CRITICAL' : CRITICAL,
120 'ERROR' : ERROR,
121 'WARN' : WARNING,
122 'WARNING' : WARNING,
123 'INFO' : INFO,
124 'DEBUG' : DEBUG,
125 'NOTSET' : NOTSET,
126 }
127
129 """
130 Return the textual representation of logging level 'level'.
131
132 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
133 INFO, DEBUG) then you get the corresponding string. If you have
134 associated levels with names using addLevelName then the name you have
135 associated with 'level' is returned.
136
137 If a numeric value corresponding to one of the defined levels is passed
138 in, the corresponding string representation is returned.
139
140 Otherwise, the string "Level %s" % level is returned.
141 """
142 return _levelNames.get(level, ("Level %s" % level))
143
145 """
146 Associate 'levelName' with 'level'.
147
148 This is used when converting levels to text during message formatting.
149 """
150 _acquireLock()
151 try:
152 _levelNames[level] = levelName
153 _levelNames[levelName] = level
154 finally:
155 _releaseLock()
156
157
158
159
160
161
162
163
164
165
166
167
168
169 _lock = None
170
172 """
173 Acquire the module-level lock for serializing access to shared data.
174
175 This should be released with _releaseLock().
176 """
177 global _lock
178 if (not _lock) and thread:
179 _lock = threading.RLock()
180 if _lock:
181 _lock.acquire()
182
184 """
185 Release the module-level lock acquired by calling _acquireLock().
186 """
187 if _lock:
188 _lock.release()
189
190
191
192
193
195 """
196 A LogRecord instance represents an event being logged.
197
198 LogRecord instances are created every time something is logged. They
199 contain all the information pertinent to the event being logged. The
200 main information passed in is in msg and args, which are combined
201 using str(msg) % args to create the message field of the record. The
202 record also includes information such as when the record was created,
203 the source line where the logging call was made, and any exception
204 information to be logged.
205 """
206 - def __init__(self, name, level, pathname, lineno, msg, args, exc_info):
207 """
208 Initialize a logging record with interesting information.
209 """
210 ct = time.time()
211 self.name = name
212 self.msg = msg
213
214
215
216
217
218
219
220
221
222
223
224
225
226 if args and (len(args) == 1) and args[0] and (type(args[0]) == types.DictType):
227 args = args[0]
228 self.args = args
229 self.levelname = getLevelName(level)
230 self.levelno = level
231 self.pathname = pathname
232 try:
233 self.filename = os.path.basename(pathname)
234 self.module = os.path.splitext(self.filename)[0]
235 except:
236 self.filename = pathname
237 self.module = "Unknown module"
238 self.exc_info = exc_info
239 self.exc_text = None
240 self.lineno = lineno
241 self.created = ct
242 self.msecs = (ct - long(ct)) * 1000
243 self.relativeCreated = (self.created - _startTime) * 1000
244 if thread:
245 self.thread = thread.get_ident()
246 self.threadName = threading.currentThread().getName()
247 else:
248 self.thread = None
249 self.threadName = None
250 if hasattr(os, 'getpid'):
251 self.process = os.getpid()
252 else:
253 self.process = None
254
256 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
257 self.pathname, self.lineno, self.msg)
258
260 """
261 Return the message for this LogRecord.
262
263 Return the message for this LogRecord after merging any user-supplied
264 arguments with the message.
265 """
266 if not hasattr(types, "UnicodeType"):
267 msg = str(self.msg)
268 else:
269 msg = self.msg
270 if type(msg) not in (types.UnicodeType, types.StringType):
271 try:
272 msg = str(self.msg)
273 except UnicodeError:
274 msg = self.msg
275 if self.args:
276 msg = msg % self.args
277 return msg
278
280 """
281 Make a LogRecord whose attributes are defined by the specified dictionary,
282 This function is useful for converting a logging event received over
283 a socket connection (which is sent as a dictionary) into a LogRecord
284 instance.
285 """
286 rv = LogRecord(None, None, "", 0, "", (), None)
287 rv.__dict__.update(dict)
288 return rv
289
290
291
292
293
419
420
421
422
423 _defaultFormatter = Formatter()
424
462
463
464
465
466
468 """
469 Filter instances are used to perform arbitrary filtering of LogRecords.
470
471 Loggers and Handlers can optionally use Filter instances to filter
472 records as desired. The base filter class only allows events which are
473 below a certain point in the logger hierarchy. For example, a filter
474 initialized with "A.B" will allow events logged by loggers "A.B",
475 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
476 initialized with the empty string, all events are passed.
477 """
479 """
480 Initialize a filter.
481
482 Initialize with the name of the logger which, together with its
483 children, will have its events allowed through the filter. If no
484 name is specified, allow every event.
485 """
486 self.name = name
487 self.nlen = len(name)
488
490 """
491 Determine if the specified record is to be logged.
492
493 Is the specified record to be logged? Returns 0 for no, nonzero for
494 yes. If deemed appropriate, the record may be modified in-place.
495 """
496 if self.nlen == 0:
497 return 1
498 elif self.name == record.name:
499 return 1
500 elif string.find(record.name, self.name, 0, self.nlen) != 0:
501 return 0
502 return (record.name[self.nlen] == ".")
503
505 """
506 A base class for loggers and handlers which allows them to share
507 common code.
508 """
510 """
511 Initialize the list of filters to be an empty list.
512 """
513 self.filters = []
514
516 """
517 Add the specified filter to this handler.
518 """
519 if not (filter in self.filters):
520 self.filters.append(filter)
521
523 """
524 Remove the specified filter from this handler.
525 """
526 if filter in self.filters:
527 self.filters.remove(filter)
528
530 """
531 Determine if a record is loggable by consulting all the filters.
532
533 The default is to allow the record to be logged; any filter can veto
534 this and the record is then dropped. Returns a zero value if a record
535 is to be dropped, else non-zero.
536 """
537 rv = 1
538 for f in self.filters:
539 if not f.filter(record):
540 rv = 0
541 break
542 return rv
543
544
545
546
547
548 _handlers = {}
549 _handlerList = []
550
552 """
553 Handler instances dispatch logging events to specific destinations.
554
555 The base handler class. Acts as a placeholder which defines the Handler
556 interface. Handlers can optionally use Formatter instances to format
557 records as desired. By default, no formatter is specified; in this case,
558 the 'raw' message as determined by record.message is logged.
559 """
561 """
562 Initializes the instance - basically setting the formatter to None
563 and the filter list to empty.
564 """
565 Filterer.__init__(self)
566 self.level = level
567 self.formatter = None
568
569 _acquireLock()
570 try:
571 _handlers[self] = 1
572 _handlerList.insert(0, self)
573 finally:
574 _releaseLock()
575 self.createLock()
576
578 """
579 Acquire a thread lock for serializing access to the underlying I/O.
580 """
581 if thread:
582 self.lock = threading.RLock()
583 else:
584 self.lock = None
585
587 """
588 Acquire the I/O thread lock.
589 """
590 if self.lock:
591 self.lock.acquire()
592
594 """
595 Release the I/O thread lock.
596 """
597 if self.lock:
598 self.lock.release()
599
601 """
602 Set the logging level of this handler.
603 """
604 self.level = level
605
618
619 - def emit(self, record):
620 """
621 Do whatever it takes to actually log the specified logging record.
622
623 This version is intended to be implemented by subclasses and so
624 raises a NotImplementedError.
625 """
626 raise NotImplementedError, 'emit must be implemented '\
627 'by Handler subclasses'
628
630 """
631 Conditionally emit the specified logging record.
632
633 Emission depends on filters which may have been added to the handler.
634 Wrap the actual emission of the record with acquisition/release of
635 the I/O thread lock. Returns whether the filter passed the record for
636 emission.
637 """
638 rv = self.filter(record)
639 if rv:
640 self.acquire()
641 try:
642 self.emit(record)
643 finally:
644 self.release()
645 return rv
646
652
654 """
655 Ensure all logging output has been flushed.
656
657 This version does nothing and is intended to be implemented by
658 subclasses.
659 """
660 pass
661
663 """
664 Tidy up any resources used by the handler.
665
666 This version does removes the handler from an internal list
667 of handlers which is closed when shutdown() is called. Subclasses
668 should ensure that this gets called from overridden close()
669 methods.
670 """
671
672 _acquireLock()
673 try:
674 del _handlers[self]
675 _handlerList.remove(self)
676 finally:
677 _releaseLock()
678
680 """
681 Handle errors which occur during an emit() call.
682
683 This method should be called from handlers when an exception is
684 encountered during an emit() call. If raiseExceptions is false,
685 exceptions get silently ignored. This is what is mostly wanted
686 for a logging system - most users will not care about errors in
687 the logging system, they are more interested in application errors.
688 You could, however, replace this with a custom handler if you wish.
689 The record which was being processed is passed in to this method.
690 """
691 if raiseExceptions:
692 ei = sys.exc_info()
693 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
694 del ei
695
697 """
698 A handler class which writes logging records, appropriately formatted,
699 to a stream. Note that this class does not close the stream, as
700 sys.stdout or sys.stderr may be used.
701 """
703 """
704 Initialize the handler.
705
706 If strm is not specified, sys.stderr is used.
707 """
708 Handler.__init__(self)
709 if strm is None:
710 strm = sys.stderr
711 self.stream = strm
712 self.formatter = None
713
715 """
716 Flushes the stream.
717 """
718 self.stream.flush()
719
720 - def emit(self, record):
721 """
722 Emit a record.
723
724 If a formatter is specified, it is used to format the record.
725 The record is then written to the stream with a trailing newline
726 [N.B. this may be removed depending on feedback]. If exception
727 information is present, it is formatted using
728 traceback.print_exception and appended to the stream.
729 """
730 try:
731 msg = self.format(record)
732 fs = "%s\n"
733 if not hasattr(types, "UnicodeType"):
734 self.stream.write(fs % msg)
735 else:
736 try:
737 self.stream.write(fs % msg)
738 except UnicodeError:
739 self.stream.write(fs % msg.encode("UTF-8"))
740 self.flush()
741 except (KeyboardInterrupt, SystemExit):
742 raise
743 except:
744 self.handleError(record)
745
747 """
748 A handler class which writes formatted logging records to disk files.
749 """
765
773
774
775
776
777
779 """
780 PlaceHolder instances are used in the Manager logger hierarchy to take
781 the place of nodes for which no loggers have been defined. This class is
782 intended for internal use only and not as part of the public API.
783 """
785 """
786 Initialize with the specified logger being a child of this placeholder.
787 """
788
789 self.loggerMap = { alogger : None }
790
792 """
793 Add the specified logger as a child of this placeholder.
794 """
795
796 if not self.loggerMap.has_key(alogger):
797
798 self.loggerMap[alogger] = None
799
800
801
802
803 _loggerClass = None
804
806 """
807 Set the class to be used when instantiating a logger. The class should
808 define __init__() such that only a name argument is required, and the
809 __init__() should call Logger.__init__()
810 """
811 if klass != Logger:
812 if not issubclass(klass, Logger):
813 raise TypeError, "logger not derived from logging.Logger: " + \
814 klass.__name__
815 global _loggerClass
816 _loggerClass = klass
817
819 """
820 Return the class to be used when instantiating a logger.
821 """
822
823 return _loggerClass
824
826 """
827 There is [under normal circumstances] just one Manager instance, which
828 holds the hierarchy of loggers.
829 """
831 """
832 Initialize the manager with the root node of the logger hierarchy.
833 """
834 self.root = rootnode
835 self.disable = 0
836 self.emittedNoHandlerWarning = 0
837 self.loggerDict = {}
838
840 """
841 Get a logger with the specified name (channel name), creating it
842 if it doesn't yet exist. This name is a dot-separated hierarchical
843 name, such as "a", "a.b", "a.b.c" or similar.
844
845 If a PlaceHolder existed for the specified name [i.e. the logger
846 didn't exist but a child of it did], replace it with the created
847 logger and fix up the parent/child references which pointed to the
848 placeholder to now point to the logger.
849 """
850 rv = None
851 _acquireLock()
852 try:
853 if self.loggerDict.has_key(name):
854 rv = self.loggerDict[name]
855 if isinstance(rv, PlaceHolder):
856 ph = rv
857 rv = _loggerClass(name)
858 rv.manager = self
859 self.loggerDict[name] = rv
860 self._fixupChildren(ph, rv)
861 self._fixupParents(rv)
862 else:
863 rv = _loggerClass(name)
864 rv.manager = self
865 self.loggerDict[name] = rv
866 self._fixupParents(rv)
867 finally:
868 _releaseLock()
869 return rv
870
872 """
873 Ensure that there are either loggers or placeholders all the way
874 from the specified logger to the root of the logger hierarchy.
875 """
876 name = alogger.name
877 i = string.rfind(name, ".")
878 rv = None
879 while (i > 0) and not rv:
880 substr = name[:i]
881 if not self.loggerDict.has_key(substr):
882 self.loggerDict[substr] = PlaceHolder(alogger)
883 else:
884 obj = self.loggerDict[substr]
885 if isinstance(obj, Logger):
886 rv = obj
887 else:
888 assert isinstance(obj, PlaceHolder)
889 obj.append(alogger)
890 i = string.rfind(name, ".", 0, i - 1)
891 if not rv:
892 rv = self.root
893 alogger.parent = rv
894
896 """
897 Ensure that children of the placeholder ph are connected to the
898 specified logger.
899 """
900
901 for c in ph.loggerMap.keys():
902 if string.find(c.parent.name, alogger.name) <> 0:
903 alogger.parent = c.parent
904 c.parent = alogger
905
906
907
908
909
911 """
912 Instances of the Logger class represent a single logging channel. A
913 "logging channel" indicates an area of an application. Exactly how an
914 "area" is defined is up to the application developer. Since an
915 application can have any number of areas, logging channels are identified
916 by a unique string. Application areas can be nested (e.g. an area
917 of "input processing" might include sub-areas "read CSV files", "read
918 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
919 channel names are organized into a namespace hierarchy where levels are
920 separated by periods, much like the Java or Python package namespace. So
921 in the instance given above, channel names might be "input" for the upper
922 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
923 There is no arbitrary limit to the depth of nesting.
924 """
926 """
927 Initialize the logger with a name and an optional level.
928 """
929 Filterer.__init__(self)
930 self.name = name
931 self.level = level
932 self.parent = None
933 self.propagate = 1
934 self.handlers = []
935 self.disabled = 0
936
938 """
939 Set the logging level of this logger.
940 """
941 self.level = level
942
943 - def debug(self, msg, *args, **kwargs):
944 """
945 Log 'msg % args' with severity 'DEBUG'.
946
947 To pass exception information, use the keyword argument exc_info with
948 a true value, e.g.
949
950 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
951 """
952 if self.manager.disable >= DEBUG:
953 return
954 if DEBUG >= self.getEffectiveLevel():
955 apply(self._log, (DEBUG, msg, args), kwargs)
956
957 - def info(self, msg, *args, **kwargs):
958 """
959 Log 'msg % args' with severity 'INFO'.
960
961 To pass exception information, use the keyword argument exc_info with
962 a true value, e.g.
963
964 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
965 """
966 if self.manager.disable >= INFO:
967 return
968 if INFO >= self.getEffectiveLevel():
969 apply(self._log, (INFO, msg, args), kwargs)
970
971 - def warning(self, msg, *args, **kwargs):
972 """
973 Log 'msg % args' with severity 'WARNING'.
974
975 To pass exception information, use the keyword argument exc_info with
976 a true value, e.g.
977
978 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
979 """
980 if self.manager.disable >= WARNING:
981 return
982 if self.isEnabledFor(WARNING):
983 apply(self._log, (WARNING, msg, args), kwargs)
984
985 warn = warning
986
987 - def error(self, msg, *args, **kwargs):
988 """
989 Log 'msg % args' with severity 'ERROR'.
990
991 To pass exception information, use the keyword argument exc_info with
992 a true value, e.g.
993
994 logger.error("Houston, we have a %s", "major problem", exc_info=1)
995 """
996 if self.manager.disable >= ERROR:
997 return
998 if self.isEnabledFor(ERROR):
999 apply(self._log, (ERROR, msg, args), kwargs)
1000
1002 """
1003 Convenience method for logging an ERROR with exception information.
1004 """
1005 apply(self.error, (msg,) + args, {'exc_info': 1})
1006
1007 - def critical(self, msg, *args, **kwargs):
1008 """
1009 Log 'msg % args' with severity 'CRITICAL'.
1010
1011 To pass exception information, use the keyword argument exc_info with
1012 a true value, e.g.
1013
1014 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1015 """
1016 if self.manager.disable >= CRITICAL:
1017 return
1018 if CRITICAL >= self.getEffectiveLevel():
1019 apply(self._log, (CRITICAL, msg, args), kwargs)
1020
1021 fatal = critical
1022
1023 - def log(self, level, msg, *args, **kwargs):
1024 """
1025 Log 'msg % args' with the integer severity 'level'.
1026
1027 To pass exception information, use the keyword argument exc_info with
1028 a true value, e.g.
1029
1030 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1031 """
1032 if type(level) != types.IntType:
1033 if raiseExceptions:
1034 raise TypeError, "level must be an integer"
1035 else:
1036 return
1037 if self.manager.disable >= level:
1038 return
1039 if self.isEnabledFor(level):
1040 apply(self._log, (level, msg, args), kwargs)
1041
1043 """
1044 Find the stack frame of the caller so that we can note the source
1045 file name, line number and function name.
1046 """
1047 f = currentframe().f_back
1048 rv = "(unknown file)", 0, "(unknown function)"
1049 while hasattr(f, "f_code"):
1050 co = f.f_code
1051 filename = os.path.normcase(co.co_filename)
1052 if filename == _srcfile:
1053 f = f.f_back
1054 continue
1055 rv = (filename, f.f_lineno, co.co_name)
1056 break
1057 return rv
1058
1059 - def makeRecord(self, name, level, fn, lno, msg, args, exc_info):
1060 """
1061 A factory method which can be overridden in subclasses to create
1062 specialized LogRecords.
1063 """
1064 return LogRecord(name, level, fn, lno, msg, args, exc_info)
1065
1066 - def _log(self, level, msg, args, exc_info=None):
1067 """
1068 Low-level logging routine which creates a LogRecord and then calls
1069 all the handlers of this logger to handle the record.
1070 """
1071 if _srcfile:
1072 fn, lno, func = self.findCaller()
1073 else:
1074 fn, lno, func = "(unknown file)", 0, "(unknown function)"
1075 if exc_info:
1076 if type(exc_info) != types.TupleType:
1077 exc_info = sys.exc_info()
1078 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info)
1079 self.handle(record)
1080
1082 """
1083 Call the handlers for the specified record.
1084
1085 This method is used for unpickled records received from a socket, as
1086 well as those created locally. Logger-level filtering is applied.
1087 """
1088 if (not self.disabled) and self.filter(record):
1089 self.callHandlers(record)
1090
1092 """
1093 Add the specified handler to this logger.
1094 """
1095 if not (hdlr in self.handlers):
1096 self.handlers.append(hdlr)
1097
1099 """
1100 Remove the specified handler from this logger.
1101 """
1102 if hdlr in self.handlers:
1103
1104 hdlr.acquire()
1105 try:
1106 self.handlers.remove(hdlr)
1107 finally:
1108 hdlr.release()
1109
1111 """
1112 Pass a record to all relevant handlers.
1113
1114 Loop through all handlers for this logger and its parents in the
1115 logger hierarchy. If no handler was found, output a one-off error
1116 message to sys.stderr. Stop searching up the hierarchy whenever a
1117 logger with the "propagate" attribute set to zero is found - that
1118 will be the last logger whose handlers are called.
1119 """
1120 c = self
1121 found = 0
1122 while c:
1123 for hdlr in c.handlers:
1124 found = found + 1
1125 if record.levelno >= hdlr.level:
1126 hdlr.handle(record)
1127 if not c.propagate:
1128 c = None
1129 else:
1130 c = c.parent
1131 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
1132 sys.stderr.write("No handlers could be found for logger"
1133 " \"%s\"\n" % self.name)
1134 self.manager.emittedNoHandlerWarning = 1
1135
1137 """
1138 Get the effective level for this logger.
1139
1140 Loop through this logger and its parents in the logger hierarchy,
1141 looking for a non-zero logging level. Return the first one found.
1142 """
1143 logger = self
1144 while logger:
1145 if logger.level:
1146 return logger.level
1147 logger = logger.parent
1148 return NOTSET
1149
1151 """
1152 Is this logger enabled for level 'level'?
1153 """
1154 if self.manager.disable >= level:
1155 return 0
1156 return level >= self.getEffectiveLevel()
1157
1159 """
1160 A root logger is not that different to any other logger, except that
1161 it must have a logging level and there is only one instance of it in
1162 the hierarchy.
1163 """
1165 """
1166 Initialize the logger with the name "root".
1167 """
1168 Logger.__init__(self, "root", level)
1169
1170 _loggerClass = Logger
1171
1172 root = RootLogger(WARNING)
1173 Logger.root = root
1174 Logger.manager = Manager(Logger.root)
1175
1176
1177
1178
1179
1180 BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1181
1183 """
1184 Do basic configuration for the logging system.
1185
1186 This function does nothing if the root logger already has handlers
1187 configured. It is a convenience method intended for use by simple scripts
1188 to do one-shot configuration of the logging package.
1189
1190 The default behaviour is to create a StreamHandler which writes to
1191 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1192 add the handler to the root logger.
1193
1194 A number of optional keyword arguments may be specified, which can alter
1195 the default behaviour.
1196
1197 filename Specifies that a FileHandler be created, using the specified
1198 filename, rather than a StreamHandler.
1199 filemode Specifies the mode to open the file, if filename is specified
1200 (if filemode is unspecified, it defaults to 'a').
1201 format Use the specified format string for the handler.
1202 datefmt Use the specified date/time format.
1203 level Set the root logger level to the specified level.
1204 stream Use the specified stream to initialize the StreamHandler. Note
1205 that this argument is incompatible with 'filename' - if both
1206 are present, 'stream' is ignored.
1207
1208 Note that you could specify a stream created using open(filename, mode)
1209 rather than passing the filename and mode in. However, it should be
1210 remembered that StreamHandler does not close its stream (since it may be
1211 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1212 when the handler is closed.
1213 """
1214 if len(root.handlers) == 0:
1215 filename = kwargs.get("filename")
1216 if filename:
1217 mode = kwargs.get("filemode", 'a')
1218 hdlr = FileHandler(filename, mode)
1219 else:
1220 stream = kwargs.get("stream")
1221 hdlr = StreamHandler(stream)
1222 fs = kwargs.get("format", BASIC_FORMAT)
1223 dfs = kwargs.get("datefmt", None)
1224 fmt = Formatter(fs, dfs)
1225 hdlr.setFormatter(fmt)
1226 root.addHandler(hdlr)
1227 level = kwargs.get("level")
1228 if level:
1229 root.setLevel(level)
1230
1231
1232
1233
1234
1235
1237 """
1238 Return a logger with the specified name, creating it if necessary.
1239
1240 If no name is specified, return the root logger.
1241 """
1242 if name:
1243 return Logger.manager.getLogger(name)
1244 else:
1245 return root
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1257 """
1258 Log a message with severity 'CRITICAL' on the root logger.
1259 """
1260 if len(root.handlers) == 0:
1261 basicConfig()
1262 apply(root.critical, (msg,)+args, kwargs)
1263
1264 fatal = critical
1265
1266 -def error(msg, *args, **kwargs):
1267 """
1268 Log a message with severity 'ERROR' on the root logger.
1269 """
1270 if len(root.handlers) == 0:
1271 basicConfig()
1272 apply(root.error, (msg,)+args, kwargs)
1273
1275 """
1276 Log a message with severity 'ERROR' on the root logger,
1277 with exception information.
1278 """
1279 apply(error, (msg,)+args, {'exc_info': 1})
1280
1281 -def warning(msg, *args, **kwargs):
1282 """
1283 Log a message with severity 'WARNING' on the root logger.
1284 """
1285 if len(root.handlers) == 0:
1286 basicConfig()
1287 apply(root.warning, (msg,)+args, kwargs)
1288
1289 warn = warning
1290
1291 -def info(msg, *args, **kwargs):
1292 """
1293 Log a message with severity 'INFO' on the root logger.
1294 """
1295 if len(root.handlers) == 0:
1296 basicConfig()
1297 apply(root.info, (msg,)+args, kwargs)
1298
1299 -def debug(msg, *args, **kwargs):
1300 """
1301 Log a message with severity 'DEBUG' on the root logger.
1302 """
1303 if len(root.handlers) == 0:
1304 basicConfig()
1305 apply(root.debug, (msg,)+args, kwargs)
1306
1307 -def log(level, msg, *args, **kwargs):
1308 """
1309 Log 'msg % args' with the integer severity 'level' on the root logger.
1310 """
1311 if len(root.handlers) == 0:
1312 basicConfig()
1313 apply(root.log, (level, msg)+args, kwargs)
1314
1316 """
1317 Disable all logging calls less severe than 'level'.
1318 """
1319 root.manager.disable = level
1320
1322 """
1323 Perform any cleanup actions in the logging system (e.g. flushing
1324 buffers).
1325
1326 Should be called at application exit.
1327 """
1328 for h in _handlerList[:]:
1329
1330
1331 try:
1332 h.flush()
1333 h.close()
1334 except:
1335 if raiseExceptions:
1336 raise
1337
1338
1339
1340 try:
1341 import atexit
1342 atexit.register(shutdown)
1343 except ImportError:
1344 - def exithook(status, old_exit=sys.exit):
1349
1350 sys.exit = exithook
1351