0
|
1 import sys
|
|
2 import logging
|
|
3
|
|
4
|
|
5
|
|
6 def initLogger(filename='pipeline.log', filelevel='INFO',
|
|
7 streamlevel='WARNING', resetlog=True):
|
|
8 """General logger initialization for PPP functions.
|
|
9
|
|
10 Messages from WARNING level and higher will be logged to file and to
|
|
11 stderr. By default, INFO level will also be written to logfile. Both
|
|
12 levels are flexible.
|
|
13
|
|
14 Level groupings:
|
|
15 ERROR: Error messages should be generated by an exception call
|
|
16 WARNING: Non-terminal behavior that may be unusual (i.e. lists
|
|
17 with no values, blank strings)
|
|
18 INFO: Every major (user-facing) function should have the following:
|
|
19 -Message for function start
|
|
20 -List of input arguments and options
|
|
21 -Basic sanity checks (dimensions of input data)
|
|
22 -Statements before or after major function calls
|
|
23 -Message for function end
|
|
24 DEBUG: Mainly for developer use/debugging. Generate logs for
|
|
25 sub-functions that match INFO level for major functions.
|
|
26 Possible care should be used if there are lots of loops called.
|
|
27
|
|
28 Use: Call with either the individual function (in __name__=="__main__"
|
|
29 statement) or in pipeline file.
|
|
30
|
|
31 Parameters
|
|
32 ----------
|
|
33 filename : str ("pipeline.log")
|
|
34 Name of file that log will be written to
|
|
35
|
|
36 filelevel : {'INFO','DEBUG','WARNING','ERROR'}
|
|
37 Set minimum level of log messages that are written to log file.
|
|
38 Note that this acts as a de facto minumum for 'streamlevel' as well.
|
|
39
|
|
40 streamlevel : {'WARNING','DEBUG','INFO','ERROR'}
|
|
41 Set minimum level of log messages that are output to stream.
|
|
42
|
|
43 resetlog : bool (True)
|
|
44 If true, will overwrite logfile when opening. Set to false if log is
|
|
45 being initialized multiple times
|
|
46
|
|
47 Returns
|
|
48 -------
|
|
49 None
|
|
50
|
|
51 Exceptions
|
|
52 ----------
|
|
53 If filelevel or streamlevel are not a valid logging level
|
|
54
|
|
55 """
|
|
56 log_levels = ['DEBUG','INFO','WARNING','ERROR']
|
|
57 if filelevel is not None and filelevel.upper() not in log_levels:
|
|
58 raise Exception('filelevel value %s is not a valid level' %
|
|
59 filelevel)
|
|
60 if streamlevel is not None and streamlevel.upper() not in log_levels:
|
|
61 raise Exception('streamlevel value %s is not a valid level' %
|
|
62 streamlevel)
|
|
63 fmt_def = "%(asctime)s - %(funcName)s - %(levelname)s: %(message)s"
|
|
64 fmt_notime = "%(funcName)s - %(levelname)s: %(message)s"
|
|
65 fmtr = logging.Formatter(fmt=fmt_def)
|
|
66 fmtr_notime = logging.Formatter(fmt=fmt_notime)
|
|
67 filelogger = logging.getLogger()
|
|
68 filelogger.setLevel('INFO')
|
|
69 if streamlevel is not None:
|
|
70 s_handler = logging.StreamHandler()
|
|
71 s_handler.setFormatter(fmtr_notime)
|
|
72 s_handler.setLevel(streamlevel)
|
|
73 filelogger.addHandler(s_handler)
|
|
74 logmode = 'a'
|
|
75 if resetlog:
|
|
76 logmode = 'w'
|
|
77 if filelevel is not None:
|
|
78 f_handler = logging.FileHandler(filename,mode=logmode)
|
|
79 f_handler.setFormatter(fmtr)
|
|
80 f_handler.setLevel(filelevel)
|
|
81 #filelogger.setLevel(filelevel)
|
|
82 filelogger.addHandler(f_handler)
|
|
83 #Formats exception messages to be sent to appropriate loggers
|
|
84 def exp_handler(etype,val,tb):
|
|
85 logging.error("%s" % (val), exc_info=(etype,val,tb))
|
|
86
|
|
87 sys.excepthook = exp_handler
|
|
88
|
|
89
|
|
90 def logArgs(args, func_name=None, print_nones=False):
|
|
91 header = "Arguments"
|
|
92 if func_name is not None:
|
|
93 header+=" for"+func_name
|
|
94 for arg in vars(args):
|
|
95 val = vars(args)[arg]
|
|
96 if val is not None or print_nones:
|
|
97 logging.info('Argument %s: %s' % (arg,val))
|