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
30
31 try:
32 import thread
33 import threading
34 except ImportError:
35 thread = None
36
37 __author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
38 __status__ = "beta"
39 __version__ = "0.4.9.5"
40 __date__ = "02 October 2004"
41
42
43
44
45
46
47
48
49
50 if string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
51 _srcfile = __file__[:-4] + '.py'
52 else:
53 _srcfile = __file__
54 _srcfile = os.path.normcase(_srcfile)
55
56
57
58
59
60 if not hasattr(sys, "_getframe"):
61 _srcfile = None
62
63
64
65
66 _startTime = time.time()
67
68
69
70
71
72 raiseExceptions = 1
73
74
75
76
77
78
79
80
81
82
83
84 CRITICAL = 50
85 FATAL = CRITICAL
86 ERROR = 40
87 WARNING = 30
88 WARN = WARNING
89 INFO = 20
90 DEBUG = 10
91 NOTSET = 0
92
93 _levelNames = {
94 CRITICAL : 'CRITICAL',
95 ERROR : 'ERROR',
96 WARNING : 'WARNING',
97 INFO : 'INFO',
98 DEBUG : 'DEBUG',
99 NOTSET : 'NOTSET',
100 'CRITICAL' : CRITICAL,
101 'ERROR' : ERROR,
102 'WARN' : WARNING,
103 'WARNING' : WARNING,
104 'INFO' : INFO,
105 'DEBUG' : DEBUG,
106 'NOTSET' : NOTSET,
107 }
108
110 """
111 Return the textual representation of logging level 'level'.
112
113 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
114 INFO, DEBUG) then you get the corresponding string. If you have
115 associated levels with names using addLevelName then the name you have
116 associated with 'level' is returned.
117
118 If a numeric value corresponding to one of the defined levels is passed
119 in, the corresponding string representation is returned.
120
121 Otherwise, the string "Level %s" % level is returned.
122 """
123 return _levelNames.get(level, ("Level %s" % level))
124
126 """
127 Associate 'levelName' with 'level'.
128
129 This is used when converting levels to text during message formatting.
130 """
131 _acquireLock()
132 try:
133 _levelNames[level] = levelName
134 _levelNames[levelName] = level
135 finally:
136 _releaseLock()
137
138
139
140
141
142
143
144
145
146
147
148
149
150 _lock = None
151
153 """
154 Acquire the module-level lock for serializing access to shared data.
155
156 This should be released with _releaseLock().
157 """
158 global _lock
159 if (not _lock) and thread:
160 _lock = threading.RLock()
161 if _lock:
162 _lock.acquire()
163
165 """
166 Release the module-level lock acquired by calling _acquireLock().
167 """
168 if _lock:
169 _lock.release()
170
171
172
173
174
176 """
177 A LogRecord instance represents an event being logged.
178
179 LogRecord instances are created every time something is logged. They
180 contain all the information pertinent to the event being logged. The
181 main information passed in is in msg and args, which are combined
182 using str(msg) % args to create the message field of the record. The
183 record also includes information such as when the record was created,
184 the source line where the logging call was made, and any exception
185 information to be logged.
186 """
187 - def __init__(self, name, level, pathname, lineno, msg, args, exc_info):
188 """
189 Initialize a logging record with interesting information.
190 """
191 ct = time.time()
192 self.name = name
193 self.msg = msg
194 self.args = args
195 self.levelname = getLevelName(level)
196 self.levelno = level
197 self.pathname = pathname
198 try:
199 self.filename = os.path.basename(pathname)
200 self.module = os.path.splitext(self.filename)[0]
201 except:
202 self.filename = pathname
203 self.module = "Unknown module"
204 self.exc_info = exc_info
205 self.exc_text = None
206 self.lineno = lineno
207 self.created = ct
208 self.msecs = (ct - long(ct)) * 1000
209 self.relativeCreated = (self.created - _startTime) * 1000
210 if thread:
211 self.thread = thread.get_ident()
212 else:
213 self.thread = None
214 if hasattr(os, 'getpid'):
215 self.process = os.getpid()
216 else:
217 self.process = None
218
220 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
221 self.pathname, self.lineno, self.msg)
222
224 """
225 Return the message for this LogRecord.
226
227 Return the message for this LogRecord after merging any user-supplied
228 arguments with the message.
229 """
230 if not hasattr(types, "UnicodeType"):
231 msg = str(self.msg)
232 else:
233 try:
234 msg = str(self.msg)
235 except UnicodeError:
236 msg = self.msg
237 if self.args:
238 msg = msg % self.args
239 return msg
240
242 """
243 Make a LogRecord whose attributes are defined by the specified dictionary,
244 This function is useful for converting a logging event received over
245 a socket connection (which is sent as a dictionary) into a LogRecord
246 instance.
247 """
248 rv = LogRecord(None, None, "", 0, "", (), None)
249 rv.__dict__.update(dict)
250 return rv
251
252
253
254
255
381
382
383
384
385 _defaultFormatter = Formatter()
386
424
425
426
427
428
430 """
431 Filter instances are used to perform arbitrary filtering of LogRecords.
432
433 Loggers and Handlers can optionally use Filter instances to filter
434 records as desired. The base filter class only allows events which are
435 below a certain point in the logger hierarchy. For example, a filter
436 initialized with "A.B" will allow events logged by loggers "A.B",
437 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
438 initialized with the empty string, all events are passed.
439 """
441 """
442 Initialize a filter.
443
444 Initialize with the name of the logger which, together with its
445 children, will have its events allowed through the filter. If no
446 name is specified, allow every event.
447 """
448 self.name = name
449 self.nlen = len(name)
450
452 """
453 Determine if the specified record is to be logged.
454
455 Is the specified record to be logged? Returns 0 for no, nonzero for
456 yes. If deemed appropriate, the record may be modified in-place.
457 """
458 if self.nlen == 0:
459 return 1
460 elif self.name == record.name:
461 return 1
462 elif string.find(record.name, self.name, 0, self.nlen) != 0:
463 return 0
464 return (record.name[self.nlen] == ".")
465
467 """
468 A base class for loggers and handlers which allows them to share
469 common code.
470 """
472 """
473 Initialize the list of filters to be an empty list.
474 """
475 self.filters = []
476
478 """
479 Add the specified filter to this handler.
480 """
481 if not (filter in self.filters):
482 self.filters.append(filter)
483
485 """
486 Remove the specified filter from this handler.
487 """
488 if filter in self.filters:
489 self.filters.remove(filter)
490
492 """
493 Determine if a record is loggable by consulting all the filters.
494
495 The default is to allow the record to be logged; any filter can veto
496 this and the record is then dropped. Returns a zero value if a record
497 is to be dropped, else non-zero.
498 """
499 rv = 1
500 for f in self.filters:
501 if not f.filter(record):
502 rv = 0
503 break
504 return rv
505
506
507
508
509
510 _handlers = {}
511
513 """
514 Handler instances dispatch logging events to specific destinations.
515
516 The base handler class. Acts as a placeholder which defines the Handler
517 interface. Handlers can optionally use Formatter instances to format
518 records as desired. By default, no formatter is specified; in this case,
519 the 'raw' message as determined by record.message is logged.
520 """
522 """
523 Initializes the instance - basically setting the formatter to None
524 and the filter list to empty.
525 """
526 Filterer.__init__(self)
527 self.level = level
528 self.formatter = None
529
530 _acquireLock()
531 try:
532 _handlers[self] = 1
533 finally:
534 _releaseLock()
535 self.createLock()
536
538 """
539 Acquire a thread lock for serializing access to the underlying I/O.
540 """
541 if thread:
542 self.lock = thread.allocate_lock()
543 else:
544 self.lock = None
545
547 """
548 Acquire the I/O thread lock.
549 """
550 if self.lock:
551 self.lock.acquire()
552
554 """
555 Release the I/O thread lock.
556 """
557 if self.lock:
558 self.lock.release()
559
561 """
562 Set the logging level of this handler.
563 """
564 self.level = level
565
578
579 - def emit(self, record):
580 """
581 Do whatever it takes to actually log the specified logging record.
582
583 This version is intended to be implemented by subclasses and so
584 raises a NotImplementedError.
585 """
586 raise NotImplementedError, 'emit must be implemented '\
587 'by Handler subclasses'
588
590 """
591 Conditionally emit the specified logging record.
592
593 Emission depends on filters which may have been added to the handler.
594 Wrap the actual emission of the record with acquisition/release of
595 the I/O thread lock. Returns whether the filter passed the record for
596 emission.
597 """
598 rv = self.filter(record)
599 if rv:
600 self.acquire()
601 try:
602 self.emit(record)
603 finally:
604 self.release()
605 return rv
606
612
614 """
615 Ensure all logging output has been flushed.
616
617 This version does nothing and is intended to be implemented by
618 subclasses.
619 """
620 pass
621
623 """
624 Tidy up any resources used by the handler.
625
626 This version does removes the handler from an internal list
627 of handlers which is closed when shutdown() is called. Subclasses
628 should ensure that this gets called from overridden close()
629 methods.
630 """
631
632 _acquireLock()
633 try:
634 del _handlers[self]
635 finally:
636 _releaseLock()
637
639 """
640 Handle errors which occur during an emit() call.
641
642 This method should be called from handlers when an exception is
643 encountered during an emit() call. If raiseExceptions is false,
644 exceptions get silently ignored. This is what is mostly wanted
645 for a logging system - most users will not care about errors in
646 the logging system, they are more interested in application errors.
647 You could, however, replace this with a custom handler if you wish.
648 The record which was being processed is passed in to this method.
649 """
650 if raiseExceptions:
651 import traceback
652 ei = sys.exc_info()
653 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
654 del ei
655
657 """
658 A handler class which writes logging records, appropriately formatted,
659 to a stream. Note that this class does not close the stream, as
660 sys.stdout or sys.stderr may be used.
661 """
663 """
664 Initialize the handler.
665
666 If strm is not specified, sys.stderr is used.
667 """
668 Handler.__init__(self)
669 if not strm:
670 strm = sys.stderr
671 self.stream = strm
672 self.formatter = None
673
675 """
676 Flushes the stream.
677 """
678 self.stream.flush()
679
680 - def emit(self, record):
681 """
682 Emit a record.
683
684 If a formatter is specified, it is used to format the record.
685 The record is then written to the stream with a trailing newline
686 [N.B. this may be removed depending on feedback]. If exception
687 information is present, it is formatted using
688 traceback.print_exception and appended to the stream.
689 """
690 try:
691 msg = self.format(record)
692 fs = "%s\n"
693 if not hasattr(types, "UnicodeType"):
694 self.stream.write(fs % msg)
695 else:
696 try:
697 self.stream.write(fs % msg)
698 except UnicodeError:
699 self.stream.write(fs % msg.encode("UTF-8"))
700 self.flush()
701 except:
702 self.handleError(record)
703
705 """
706 A handler class which writes formatted logging records to disk files.
707 """
708 - def __init__(self, filename, mode="a"):
709 """
710 Open the specified file and use it as the stream for logging.
711 """
712 StreamHandler.__init__(self, open(filename, mode))
713
714
715 self.baseFilename = os.path.abspath(filename)
716 self.mode = mode
717
725
726
727
728
729
731 """
732 PlaceHolder instances are used in the Manager logger hierarchy to take
733 the place of nodes for which no loggers have been defined. This class is
734 intended for internal use only and not as part of the public API.
735 """
737 """
738 Initialize with the specified logger being a child of this placeholder.
739 """
740 self.loggers = [alogger]
741
743 """
744 Add the specified logger as a child of this placeholder.
745 """
746 if alogger not in self.loggers:
747 self.loggers.append(alogger)
748
749
750
751
752 _loggerClass = None
753
755 """
756 Set the class to be used when instantiating a logger. The class should
757 define __init__() such that only a name argument is required, and the
758 __init__() should call Logger.__init__()
759 """
760 if klass != Logger:
761 if not issubclass(klass, Logger):
762 raise TypeError, "logger not derived from logging.Logger: " + \
763 klass.__name__
764 global _loggerClass
765 _loggerClass = klass
766
768 """
769 Return the class to be used when instantiating a logger.
770 """
771
772 return _loggerClass
773
775 """
776 There is [under normal circumstances] just one Manager instance, which
777 holds the hierarchy of loggers.
778 """
780 """
781 Initialize the manager with the root node of the logger hierarchy.
782 """
783 self.root = rootnode
784 self.disable = 0
785 self.emittedNoHandlerWarning = 0
786 self.loggerDict = {}
787
789 """
790 Get a logger with the specified name (channel name), creating it
791 if it doesn't yet exist. This name is a dot-separated hierarchical
792 name, such as "a", "a.b", "a.b.c" or similar.
793
794 If a PlaceHolder existed for the specified name [i.e. the logger
795 didn't exist but a child of it did], replace it with the created
796 logger and fix up the parent/child references which pointed to the
797 placeholder to now point to the logger.
798 """
799 rv = None
800 _acquireLock()
801 try:
802 if self.loggerDict.has_key(name):
803 rv = self.loggerDict[name]
804 if isinstance(rv, PlaceHolder):
805 ph = rv
806 rv = _loggerClass(name)
807 rv.manager = self
808 self.loggerDict[name] = rv
809 self._fixupChildren(ph, rv)
810 self._fixupParents(rv)
811 else:
812 rv = _loggerClass(name)
813 rv.manager = self
814 self.loggerDict[name] = rv
815 self._fixupParents(rv)
816 finally:
817 _releaseLock()
818 return rv
819
821 """
822 Ensure that there are either loggers or placeholders all the way
823 from the specified logger to the root of the logger hierarchy.
824 """
825 name = alogger.name
826 i = string.rfind(name, ".")
827 rv = None
828 while (i > 0) and not rv:
829 substr = name[:i]
830 if not self.loggerDict.has_key(substr):
831 self.loggerDict[substr] = PlaceHolder(alogger)
832 else:
833 obj = self.loggerDict[substr]
834 if isinstance(obj, Logger):
835 rv = obj
836 else:
837 assert isinstance(obj, PlaceHolder)
838 obj.append(alogger)
839 i = string.rfind(name, ".", 0, i - 1)
840 if not rv:
841 rv = self.root
842 alogger.parent = rv
843
845 """
846 Ensure that children of the placeholder ph are connected to the
847 specified logger.
848 """
849 for c in ph.loggers:
850 if string.find(c.parent.name, alogger.name) <> 0:
851 alogger.parent = c.parent
852 c.parent = alogger
853
854
855
856
857
859 """
860 Instances of the Logger class represent a single logging channel. A
861 "logging channel" indicates an area of an application. Exactly how an
862 "area" is defined is up to the application developer. Since an
863 application can have any number of areas, logging channels are identified
864 by a unique string. Application areas can be nested (e.g. an area
865 of "input processing" might include sub-areas "read CSV files", "read
866 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
867 channel names are organized into a namespace hierarchy where levels are
868 separated by periods, much like the Java or Python package namespace. So
869 in the instance given above, channel names might be "input" for the upper
870 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
871 There is no arbitrary limit to the depth of nesting.
872 """
874 """
875 Initialize the logger with a name and an optional level.
876 """
877 Filterer.__init__(self)
878 self.name = name
879 self.level = level
880 self.parent = None
881 self.propagate = 1
882 self.handlers = []
883 self.disabled = 0
884
886 """
887 Set the logging level of this logger.
888 """
889 self.level = level
890
891 - def debug(self, msg, *args, **kwargs):
892 """
893 Log 'msg % args' with severity 'DEBUG'.
894
895 To pass exception information, use the keyword argument exc_info with
896 a true value, e.g.
897
898 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
899 """
900 if self.manager.disable >= DEBUG:
901 return
902 if DEBUG >= self.getEffectiveLevel():
903 apply(self._log, (DEBUG, msg, args), kwargs)
904
905 - def info(self, msg, *args, **kwargs):
906 """
907 Log 'msg % args' with severity 'INFO'.
908
909 To pass exception information, use the keyword argument exc_info with
910 a true value, e.g.
911
912 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
913 """
914 if self.manager.disable >= INFO:
915 return
916 if INFO >= self.getEffectiveLevel():
917 apply(self._log, (INFO, msg, args), kwargs)
918
919 - def warning(self, msg, *args, **kwargs):
920 """
921 Log 'msg % args' with severity 'WARNING'.
922
923 To pass exception information, use the keyword argument exc_info with
924 a true value, e.g.
925
926 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
927 """
928 if self.manager.disable >= WARNING:
929 return
930 if self.isEnabledFor(WARNING):
931 apply(self._log, (WARNING, msg, args), kwargs)
932
933 warn = warning
934
935 - def error(self, msg, *args, **kwargs):
936 """
937 Log 'msg % args' with severity 'ERROR'.
938
939 To pass exception information, use the keyword argument exc_info with
940 a true value, e.g.
941
942 logger.error("Houston, we have a %s", "major problem", exc_info=1)
943 """
944 if self.manager.disable >= ERROR:
945 return
946 if self.isEnabledFor(ERROR):
947 apply(self._log, (ERROR, msg, args), kwargs)
948
950 """
951 Convenience method for logging an ERROR with exception information.
952 """
953 apply(self.error, (msg,) + args, {'exc_info': 1})
954
955 - def critical(self, msg, *args, **kwargs):
956 """
957 Log 'msg % args' with severity 'CRITICAL'.
958
959 To pass exception information, use the keyword argument exc_info with
960 a true value, e.g.
961
962 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
963 """
964 if self.manager.disable >= CRITICAL:
965 return
966 if CRITICAL >= self.getEffectiveLevel():
967 apply(self._log, (CRITICAL, msg, args), kwargs)
968
969 fatal = critical
970
971 - def log(self, level, msg, *args, **kwargs):
972 """
973 Log 'msg % args' with the integer severity 'level'.
974
975 To pass exception information, use the keyword argument exc_info with
976 a true value, e.g.
977
978 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
979 """
980 if type(level) != types.IntType:
981 if raiseExceptions:
982 raise TypeError, "level must be an integer"
983 else:
984 return
985 if self.manager.disable >= level:
986 return
987 if self.isEnabledFor(level):
988 apply(self._log, (level, msg, args), kwargs)
989
991 """
992 Find the stack frame of the caller so that we can note the source
993 file name and line number.
994 """
995 f = sys._getframe(1)
996 while 1:
997 co = f.f_code
998 filename = os.path.normcase(co.co_filename)
999 if filename == _srcfile:
1000 f = f.f_back
1001 continue
1002 return filename, f.f_lineno
1003
1004 - def makeRecord(self, name, level, fn, lno, msg, args, exc_info):
1005 """
1006 A factory method which can be overridden in subclasses to create
1007 specialized LogRecords.
1008 """
1009 return LogRecord(name, level, fn, lno, msg, args, exc_info)
1010
1011 - def _log(self, level, msg, args, exc_info=None):
1012 """
1013 Low-level logging routine which creates a LogRecord and then calls
1014 all the handlers of this logger to handle the record.
1015 """
1016 if _srcfile:
1017 fn, lno = self.findCaller()
1018 else:
1019 fn, lno = "<unknown file>", 0
1020 if exc_info:
1021 if type(exc_info) != types.TupleType:
1022 exc_info = sys.exc_info()
1023 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info)
1024 self.handle(record)
1025
1027 """
1028 Call the handlers for the specified record.
1029
1030 This method is used for unpickled records received from a socket, as
1031 well as those created locally. Logger-level filtering is applied.
1032 """
1033 if (not self.disabled) and self.filter(record):
1034 self.callHandlers(record)
1035
1037 """
1038 Add the specified handler to this logger.
1039 """
1040 if not (hdlr in self.handlers):
1041 self.handlers.append(hdlr)
1042
1044 """
1045 Remove the specified handler from this logger.
1046 """
1047 if hdlr in self.handlers:
1048
1049 self.handlers.remove(hdlr)
1050
1052 """
1053 Pass a record to all relevant handlers.
1054
1055 Loop through all handlers for this logger and its parents in the
1056 logger hierarchy. If no handler was found, output a one-off error
1057 message to sys.stderr. Stop searching up the hierarchy whenever a
1058 logger with the "propagate" attribute set to zero is found - that
1059 will be the last logger whose handlers are called.
1060 """
1061 c = self
1062 found = 0
1063 while c:
1064 for hdlr in c.handlers:
1065 found = found + 1
1066 if record.levelno >= hdlr.level:
1067 hdlr.handle(record)
1068 if not c.propagate:
1069 c = None
1070 else:
1071 c = c.parent
1072 if (found == 0) and not self.manager.emittedNoHandlerWarning:
1073 sys.stderr.write("No handlers could be found for logger"
1074 " \"%s\"\n" % self.name)
1075 self.manager.emittedNoHandlerWarning = 1
1076
1078 """
1079 Get the effective level for this logger.
1080
1081 Loop through this logger and its parents in the logger hierarchy,
1082 looking for a non-zero logging level. Return the first one found.
1083 """
1084 logger = self
1085 while logger:
1086 if logger.level:
1087 return logger.level
1088 logger = logger.parent
1089 return NOTSET
1090
1092 """
1093 Is this logger enabled for level 'level'?
1094 """
1095 if self.manager.disable >= level:
1096 return 0
1097 return level >= self.getEffectiveLevel()
1098
1100 """
1101 A root logger is not that different to any other logger, except that
1102 it must have a logging level and there is only one instance of it in
1103 the hierarchy.
1104 """
1106 """
1107 Initialize the logger with the name "root".
1108 """
1109 Logger.__init__(self, "root", level)
1110
1111 _loggerClass = Logger
1112
1113 root = RootLogger(WARNING)
1114 Logger.root = root
1115 Logger.manager = Manager(Logger.root)
1116
1117
1118
1119
1120
1121 BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1122
1124 """
1125 Do basic configuration for the logging system.
1126
1127 This function does nothing if the root logger already has handlers
1128 configured. It is a convenience method intended for use by simple scripts
1129 to do one-shot configuration of the logging package.
1130
1131 The default behaviour is to create a StreamHandler which writes to
1132 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1133 add the handler to the root logger.
1134
1135 A number of optional keyword arguments may be specified, which can alter
1136 the default behaviour.
1137
1138 filename Specifies that a FileHandler be created, using the specified
1139 filename, rather than a StreamHandler.
1140 filemode Specifies the mode to open the file, if filename is specified
1141 (if filemode is unspecified, it defaults to "a").
1142 format Use the specified format string for the handler.
1143 datefmt Use the specified date/time format.
1144 level Set the root logger level to the specified level.
1145 stream Use the specified stream to initialize the StreamHandler. Note
1146 that this argument is incompatible with 'filename' - if both
1147 are present, 'stream' is ignored.
1148
1149 Note that you could specify a stream created using open(filename, mode)
1150 rather than passing the filename and mode in. However, it should be
1151 remembered that StreamHandler does not close its stream (since it may be
1152 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1153 when the handler is closed.
1154 """
1155 if len(root.handlers) == 0:
1156 filename = kwargs.get("filename")
1157 if filename:
1158 mode = kwargs.get("filemode", "a")
1159 hdlr = FileHandler(filename, mode)
1160 else:
1161 stream = kwargs.get("stream")
1162 hdlr = StreamHandler(stream)
1163 fs = kwargs.get("format", BASIC_FORMAT)
1164 dfs = kwargs.get("datefmt", None)
1165 fmt = Formatter(fs, dfs)
1166 hdlr.setFormatter(fmt)
1167 root.addHandler(hdlr)
1168 level = kwargs.get("level")
1169 if level:
1170 root.setLevel(level)
1171
1172
1173
1174
1175
1176
1178 """
1179 Return a logger with the specified name, creating it if necessary.
1180
1181 If no name is specified, return the root logger.
1182 """
1183 if name:
1184 return Logger.manager.getLogger(name)
1185 else:
1186 return root
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1204
1205 fatal = critical
1206
1207 -def error(msg, *args, **kwargs):
1214
1216 """
1217 Log a message with severity 'ERROR' on the root logger,
1218 with exception information.
1219 """
1220 apply(error, (msg,)+args, {'exc_info': 1})
1221
1222 -def warning(msg, *args, **kwargs):
1229
1230 warn = warning
1231
1232 -def info(msg, *args, **kwargs):
1239
1240 -def debug(msg, *args, **kwargs):
1247
1248 -def log(level, msg, *args, **kwargs):
1249 """
1250 Log 'msg % args' with the integer severity 'level' on the root logger.
1251 """
1252 if len(root.handlers) == 0:
1253 basicConfig()
1254 apply(root.log, (level, msg)+args, kwargs)
1255
1257 """
1258 Disable all logging calls less severe than 'level'.
1259 """
1260 root.manager.disable = level
1261
1263 """
1264 Perform any cleanup actions in the logging system (e.g. flushing
1265 buffers).
1266
1267 Should be called at application exit.
1268 """
1269 for h in _handlers.keys():
1270
1271
1272 try:
1273 h.flush()
1274 h.close()
1275 except:
1276 pass
1277
1278
1279 try:
1280 import atexit
1281 atexit.register(shutdown)
1282 except ImportError:
1288
1289 sys.exit = exithook
1290