KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17
System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64
User : nobody ( 99)
PHP Version : 5.2.17
Disable Function : NONE
Directory :  /proc/21573/root/usr/lib/python2.4/site-packages/setroubleshoot/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //proc/21573/root/usr/lib/python2.4/site-packages/setroubleshoot/log.py
# Authors: John Dennis <jdennis@redhat.com>
#
# Copyright (C) 2006,2007,2008 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

'''
The python logging module gives us loggers and handlers, sometimes
that's a bit obscure, we rename this concepts to be more friendly:

loggers  --> log_categories
handlers --> log_output

loggers are organized in a tree structure with a single root
logger. handlers may be attached to to any logger in the logger tree
(for example if you wanted to direct output from one category to a
specific place). When a handler wishes to output it walks the tree up
to the root calling each handler it finds. For simplicity sake by
default we attach all our handlers to the root logger. Thus all the
output handlers have equal opportunity to output a logging message
from one of the loggers.

Messages may be filtered by specifying a level. There are 3 places a
level may be set: 

1) on the logger
2) on the handler
3) on the root logger (special case of item 1, global level)

A message has a level attached to it. The decision process of when to
emit a message works like this:

1) The path in the logger tree is walked from the logger to the root
   logger. The first logger encountered with a level other than NOTSET
   defines the effective level, if the message level is greater than
   or equal to the effective level it is accepted for output. If only
   NOTSET is found this becomes the effective level and the message is
   accepted for output.

2) If the message passes the logging (category) level test then every
   logger in the path from the logger to the root logger is given an
   opportunity to emit the message by iterating over its list of
   output handlers. If the message level is greater than or equal to
   tbe level of the output handler it is output.

One consequence of this is that if an output handler is bound to both
the category logger and the root logger it will be emitted
twice. However, if you bind distinct output loggers to tbe category
logger and the root logger then each output logger may have its own
level and destination.

Note: the logging modules provides for propagation flags which stop
traversal to the root as well as filters for more complex filtering
then simple level testing, this offers more fine grained control.

Thus for a message to be output it must:

1) first pass the level test for the logging category.

2) secondly also pass the level test for every output handler bound to
   every level in the path from the logger to the root.

It is tempting to want to set the global level on the root logger and
default the level on any category logger to NOTSET. This would cause
the root logger's level to take effect for any category logger without
an explicit level (e.g. the root logger is the default global
level). The notion of inheriting a level from your ancestors is nice,
but in practice its difficult to meet expectations using level
inheritance, instead we set a level on every logger and forego
inheritance, here's why:

If the root level was higher than an explicitly set category level the
message would be filtered. This would be counter to the expectation if
an explict level was set for any category it would be respected and
would be output. To get around this one could set the level on the
root logger to pass everything (e.g. NOTSET). This would allow
explicitly set category levels to be respected.  However, if a
category did not have an explicit level set it would default to NOTSET
which would pass the message to the root, which being NOTSET would
pass the message to all of its output handlers. The effect would be
any category without an explicit level set would always output, this
also is not what is expected. The solution is not to try and set the
default global level on the root logger and depend on inheritance, but
rather explicitly set the level of every logger, either to the level
requested for that category, or to the default global level if an
explicit level is absent for the category.

Why is there a global debug flag that is checked before any call to
log_xxx.debug()? The logger.debug() function will check the levels and
not output anything if the level settings would prohibit the debug
message, clearly the debug flag is unnecessary, right? This is true,
however, if one considers the amount of work the logging library does
just to determine the log message will be discarded and observe that
in most all cases debug logging will be turned off this consititues a
performance hit, especially considering the large number of
logger.debug() calls throughout the code. In 'C' or similar languages
one could use preprocessor macros to eliminate debug logging in
production code, but this option is not available in python so we wrap
all logger.debug() calls in an 'if debug:' test to prevent spending
cycles on an operation which will be thrown away. Having a global
debug flag does require reevaluatiing it anytime the level of any
logging category changes because if any category is set for debug
logging the flag must be true so the loggers can be given a chance to
evaluate the message for their category.

'''

__all__ = ['log_init',
           'debug',
           'profile',
           'set_default_category_level',
           'set_category_level',
           'enable_log_output',
           'set_log_output_level',
           'dump_log_levels',
          ]

import os
import logging
import logging.handlers
import re
import sys
from types import *

from setroubleshoot.config import *

log_init_done = False
loggers = {}
log_handlers = {}
config_category_level = {}

min_logger_level = logging.CRITICAL
global_level = logging.NOTSET
debug = False
profile = False

# Get the root logger
root_logger = logging.getLogger()

def log_init(program_name, options=None):
    global log_init_done, global_level, debug, profile
    if log_init_done:
        return
    log_init_done = True
    pkg_name = get_config('general','pkg_name')
    syslog_format = '%s: [%%(name)s.%%(levelname)s] %%(message)s' % (pkg_name)

    # The root logger always outputs the message if it's reached.
    root_logger.setLevel(logging.NOTSET)

    # Create syslog handler before doing anything else, just in case we have to report
    # error messages from the logging init
    try:
        syslog_handler = logging.handlers.SysLogHandler(address='/dev/log') 
        syslog_handler.setLevel(logging.ERROR)
        log_handlers['syslog'] = syslog_handler
        syslog_formatter = logging.Formatter(syslog_format)
        syslog_handler.setFormatter(syslog_formatter)
        enable_log_output('syslog')
    except Exception, e:
        print >> sys.stderr, "exception when creating syslog handler: %s" % (e)
        log_handlers['syslog'] = None

    # Get the logging configuration options.
    program_name = os.path.basename(program_name)
    config_section = '%s_log' % program_name

    global_level   = map_level(get_option(config_section, 'level', 'warning', options))
    filename       = get_option(config_section, 'filename', None, options)
    filemode       = get_option(config_section, 'filemode', 'w', options)
    format         = get_option(config_section, 'format', None, options, 'raw')
    cfg_categories = get_option(config_section, 'categories', ','.join(LOG_CATEGORIES), options)
    console_flag   = get_option(config_section, 'console', False, options, bool)
    profile        = get_option(config_section, 'profile', False, options, bool)

    if filename:
        filename = os.path.expandvars(os.path.expanduser(filename))
    
    formatter = logging.Formatter(format)

    # Create console handler
    try:
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.NOTSET)
        log_handlers['console'] = console_handler
        console_handler.setFormatter(formatter)
    except IOError:
        log_handlers['console'] = None

    # Create file handler
    if filename:
        try:
            file_handler = logging.FileHandler(filename, filemode)
            file_handler.setLevel(logging.NOTSET)
            log_handlers['file'] = file_handler
            file_handler.setFormatter(formatter)
            enable_log_output('file')
        except IOError, e:
            # Could not open the log file - use console instead
            log_handlers['file'] = None
            enable_log_output('console')
            logging.error("Could not open log file (%s) - using stderr", filename)
    else:
        log_handlers['file'] = None

    # Note: levels NOTSET=0, DEBUG=10, INFO=20, WARNING=30, ERROR=40, CRITICAL=50

    # Iterate through categories defined in the config file.
    # For each category in the config file record the level specified for it

    for category_name, category_level in parse_log_categories(cfg_categories):
        config_category_level[category_name] = map_level(category_level)

    # Iterate over all the category loggers, create them and install
    # their name as an exported symbol of tbis module.

    g = globals()
    for category_name in LOG_CATEGORIES:
        # Generate the exported symbol name of this category logger
        logger_obj_name = "log_%s" % (category_name)
        # Create the logger object, name it after it's category
        logger_obj = logging.getLogger(category_name)
        # Remember this category logger
        loggers[category_name] = logger_obj

        # Insert this category logger into this modules namespace under the exported symbol name.
        g[logger_obj_name] = logger_obj
        __all__.append(logger_obj_name)

        # Set the level for the category, defaulting to NOTSET, otherwise overridden by the config
        # setting for this logger.
        set_category_level(config_category_level.get(category_name, logging.NOTSET), category_name)

    if profile:
        log_stats.setLevel(logging.INFO)

    if console_flag:
        enable_log_output('console')

    set_default_category_level(global_level)
    #dump_log_levels()

def map_level(map_str):
    'Parse a string representing a level, map it to a number'
    if map_str is None:
        return logging.NOTSET
    try:
        level = int(map_str)
    except ValueError:
        map_str = map_str.upper()
        if map_str not in ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET']:
            return logging.NOTSET
        level = logging.getLevelName(map_str)
    return level

def parse_log_categories(str):
    '''Iteratate over a category list in a string, return an array of pairs (name,level)'''
    result = []
    category_re = re.compile('^\s*(~\s*)?([^:\s]+)(\s*:\s*([^:\s]+))?\s*$')
    categories = str.split(',')
    for category in categories:
        match = category_re.search(category)
        if match:
            negate = match.group(1)
            category_name = match.group(2)
            category_level = match.group(4)
            if negate:
                category_level = logging.CRITICAL
            result.append((category_name, category_level))
    return result


def set_debug_flag():
    '''If one or more logging categories are at debug level turn the
    global debug flag on.'''
    global debug

    min_logger_level = get_min_category_level()
    category_level = min(min_logger_level, global_level)
    if category_level < logging.INFO:
        debug = True
    else:
        debug = False
        

def set_category_level(requested_level, category):
    requested_level = map_level(requested_level)

    cfg_level = config_category_level.get(category)
    if cfg_level:
        category_level = cfg_level
    else:
        category_level = requested_level

    logger_obj = loggers.get(category)
    if not logger_obj: return
    logger_obj.setLevel(category_level)
    set_debug_flag()

def set_default_category_level(requested_level):
    for logger_name, logger_obj in loggers.items():
        set_category_level(requested_level, logger_name)
        
def get_min_category_level():
    min_logger_level = logging.CRITICAL
    for logger_obj in loggers.values():
        category_level = logger_obj.level
        if category_level != logging.NOTSET and category_level < min_logger_level:
            min_logger_level = category_level

    return min_logger_level

def enable_log_output(output_name, enable=True, logger=root_logger):
    handler = log_handlers.get(output_name)
    if not handler: return
    if enable:
        if handler not in logger.handlers:
            logger.addHandler(handler)
    else:
        if handler in logger.handlers:
            logger.removeHandler(handler)

def set_log_output_level(requested_level, handlers=None):
    requested_level = map_level(requested_level)

    if handlers is None:
        handlers = ['file', 'console']

    if not (type(handlers) is ListType or type(handlers) is TupleType):
        handlers = [handlers]

    for handler_name in handlers:
        handler_obj = log_handlers.get(handler_name)
        if handler_obj is not None:
            handler_obj.setLevel(requested_level)

def dump_log_levels():
    print "Logging global_level=%s debug=%s" % (logging.getLevelName(global_level), debug)
    print "Loggers:"
    logger_names = loggers.keys()
    logger_names.sort()
    for logger_name in logger_names:
        level = logging.getLevelName(loggers[logger_name].level)
        print "    %-20s %s" % (logger_name, level)

    print "Handlers:"
    handler_names = log_handlers.keys()
    handler_names.sort()
    for handler_name in handler_names:
        if log_handlers[handler_name]:
            level = logging.getLevelName(log_handlers[handler_name].level)
        else:
            level = 'no handler'
        print "    %-20s %s" % (handler_name, level)

Anon7 - 2021