A simple version of logging. config is implemented, which generally supports configuration through the config file.
Another better way is to use the logging. config. fileConfig (log_config_file) method to read in and modify the handler method.
Copy codeThe Code is as follows:
"""
Project trace system
"""
Import sys
Import ConfigParser
Import logging
Import logging. config
Import warnings
If _ name _ = "_ main __":
Log_config_file = "log. conf"
Log_data_file = "logs/run. log"
LEVEL_dic = {
"DEBUG": logging. DEBUG,
"INFO": logging. INFO,
"WARNING": logging. WARNING,
"ERROR": logging. ERROR,
"CRITICAL": logging. CRITICAL
}
Class LogConfig (object ):
Def _ init _ (self, log_config_file, log_data_file = None ):
Self. log_config_file = log_config_file
Self. log_data_file = log_data_file # for self app
Self. log_config = ConfigParser. RawConfigParser ()
Self. log_config.read (self. log_config_file)
Self. logger_prefix = "logger _"
Self. handler_prefix = "handler _"
Self. formatter_prefix = "formatter _"
Self. _ check_section ()
Self. _ parse_option ()
Def _ check_section (self ):
# Check logger
Self. _ check_logger ()
# Check handler
Self. _ check_handler ()
# Check formatter
Self. _ check_formatter ()
Def _ parse_option (self ):
# Parse formatter option
For formatter, formatter_info in self. formatters. items ():
Section_name = formatter_info ["section_name"]
F = self. log_config.get (section_name, "format ")
Datefmt = self. log_config.get (section_name, "datefmt ")
Self. formatters [formatter] ["value"] = logging. Formatter (f, datefmt)
# Parse handlers
For handler, handler_info in self. handlers. items ():
Section_name = handler_info ["section_name"]
Handler_class = self. log_config.get (section_name, "class ")
Handler_str = self. log_config.get (section_name, "args ")
Handler_args = eval (self. log_config.get (section_name, "args "))
Level = self. log_config.get (section_name, "level ")
Formatter = self. log_config.get (section_name, "formatter ")
_ Handler = eval ("logging." + handler_class)
# Only FileHandler has file path paramter.
If isinstance (_ handler, logging. FileHandler ):
If self. log_data_file:
Handler_args [0] = self. log_data_file
Else:
Warnings. warn ("fileHandler found, but log data file is not specified ")
Self. handlers [handler] ["value"] = _ handler (* handler_args)
Self. handlers [handler] ["value"]. setLevel (
LEVEL_dic.get (level. upper (), LEVEL_dic ["INFO"])
Self. handlers [handler] ["value"]. setFormatter (
Self. formatters [formatter] ["value"])
# Parse logger
For logger, logger_info in self. loggers. items ():
Section_name = logger_info ["section_name"]
Self. _ parse_logger (logger, section_name)
Def _ parse_logger (self, logger_name, section_name ):
"""
"""
Tuple_items = self. log_config.items (section_name)
Logger = logging. getLogger (logger_name)
For k, v in tuple_items:
If k = "handlers ":
Handlers = filter (None, [h. strip () for h in v. split (",")])
For h in handlers:
Logger. addHandler (self. handlers [h] ["value"])
If k = "level ":
Logger. setLevel (LEVEL_dic.get (v, LEVEL_dic ["INFO"])
If k = "propagate" and v:
Logger. propagate = int (v)
# Here other attributes cocould be added. TODO
Self. loggers [logger_name] ['value'] = logger
Def _ check_logger (self ):
_ Loggers = self. log_config.get ("loggers", "keys"). split (",")
Self. loggers = {}
For logger in _ loggers:
Logger = logger. strip ()
If logger:
Logger_section_name = self. logger_prefix + logger
If not self. log_config.has_section (logger_section_name ):
Raise Exception (
"ERROR: no logger section name: {0}". format (logger_section_name ))
Self. loggers. setdefault (logger ,{})
Self. loggers [logger] ["section_name"] = logger_section_name
If not self. loggers:
Raise Exception (
"ERROR: No logger keys in {0}". format (self. log_config_file ))
Def _ check_handler (self ):
_ Handlers = self. log_config.get ("handlers", "keys"). split (",")
Self. handlers = {}
For handler in _ handlers:
Handler = handler. strip ()
If handler:
Handler_section_name = self. handler_prefix + handler
If not self. log_config.has_section (handler_section_name ):
Raise Exception ("ERROR: no handler section name: {0}". format (handler_section_name ))
Self. handlers. setdefault (handler ,{})
Self. handlers [handler] ["section_name"] = handler_section_name
If not self. handlers:
Raise Exception ("ERROR: No handler keys in {0}". format (self. log_config_file ))
Def _ check_formatter (self ):
_ Formatters = self. log_config.get ("formatters", "keys"). split (",")
Self. formatters = {}
For formatter in _ formatters:
Formatter = formatter. strip ()
If formatter:
Formatter_section_name = self. formatter_prefix + formatter
If not self. log_config.has_section (formatter_section_name ):
Raise Exception ("ERROR: no formatter section name: {0}". format (formatter_section_name ))
Self. formatters. setdefault (formatter ,{})
Self. formatters [formatter] ["section_name"] = formatter_section_name
If not self. formatters:
Raise Exception ("ERROR: No formatter keys in {0}". format (self. log_config_file ))
Def getLogger (self, logger_name = "root "):
Return self. loggers [logger_name] ['value']
Class Trace (object ):
Def _ init _ (self, log_config_file, log_key = "root", log_data_file = None ):
Self. log_config_file = log_config_file
Self. log_data_file = log_data_file
Self. log_key = log_key
Log = LogConfig (self. log_config_file, self. log_data_file)
Self. logger = Log. getLogger (self. log_key)
Def info (self, key, info ):
Self.logger.info ("[{0}]: {1}". format (key, info ))
Def error (self, key, err_info ):
Self. logger. error ("[{0}]: {1}". format (key, err_info ))
Def warn (self, key, warn_info ):
Self. logger. warn ("[{0}]: {1}". format (key, warn_info ))
Def test ():
Log_key = "root"
T = Trace (log_config_file, log_key, log_data_file)
T.info ("test trace", "OK ")
If _ name _ = "_ main __":
Test ()
Log. conf
Copy codeThe Code is as follows:
[Loggers]
Keys = root, debug
[Handlers]
Keys = lelehandler, timedRotatingFileHandler
[Formatters]
Keys = simpleFormatter
[Logger_root]
Level = DEBUG
Handlers = lelehandler, timedRotatingFileHandler
[Logger_debug]
Level = DEBUG
Handlers = consoleHandler
Propagate = 0
[Handler_consoleHandler]
Class = StreamHandler
Level = DEBUG
Formatter = simpleFormatter
Args = (sys. stdout ,)
[Handler_timedRotatingFileHandler]
Class = handlers. TimedRotatingFileHandler
Level = DEBUG
Formatter = simpleFormatter
Args = ("./run. log", 'midnight ', 1, 10)
[Formatter_simpleFormatter]
Format = [% (asctime) s] [% (levelname) s] [% (process) d: % (thread) d] [% (filename) s: % (lineno) d]: % (message) s
Datefmt = % Y-% m-% d % H: % M: % S