Source code for google.cloud.forseti.common.util.logger

# Copyright 2017 The Forseti Security Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""A basic util that wraps logging.

Setup logging for Forseti Security. Logs to console and syslog.
"""

import logging
import logging.handlers
import os

from google.cloud.forseti import __version__ as forseti_version

DEFAULT_LOG_FMT = ('%(asctime)s %(levelname)s '
                   '%(name)s(%(funcName)s): %(message).1024s')

SYSLOG_LOG_FMT = ('%(levelname)s [forseti-security][' + forseti_version + '] '
                  '%(name)s(%(funcName)s): %(message).1024s')

# %(asctime)s is used as the marker by multiline parser to determine
# the first line of a log record that spans multiple lines.
# So if this is moved or changed here, update "format_firstline" in the logging
# parser config.
FORSETI_LOG_FMT = '%(asctime)s ' + SYSLOG_LOG_FMT


LOGGERS = {}
LOGLEVELS = {
    'debug': logging.DEBUG,
    'info': logging.INFO,
    'warning': logging.WARN,
    'error': logging.ERROR,
}
LOGLEVEL = logging.INFO
LOG_TO_CONSOLE = False


[docs]def _create_syslog_handler(): """Create the syslog handler. Returns: handler: A configured syslog handler. """ syslog_handler = logging.handlers.SysLogHandler() syslog_handler.setFormatter(logging.Formatter(SYSLOG_LOG_FMT)) return syslog_handler
[docs]def get_logger(module_name): """Setup the logger. Args: module_name (str): The name of the mdule to describe the log entry. Returns: logger: An instance of the configured logger. """ if os.path.exists('/var/log/forseti.log'): # ubuntu on GCE try: default_log_handler = logging.FileHandler('/var/log/forseti.log') default_log_handler.setFormatter(logging.Formatter(FORSETI_LOG_FMT)) # users of CLI on server vm can not write to /var/log/forseti.log except IOError: # pylint:disable=redefined-variable-type default_log_handler = _create_syslog_handler() # pylint:enable=redefined-variable-type else: default_log_handler = _create_syslog_handler() logger_instance = logging.getLogger(module_name) logger_instance.addHandler(default_log_handler) logger_instance.setLevel(LOGLEVEL) # Prevent output to CLI's stdout via other ancestor loggers. logger_instance.propagate = False if LOG_TO_CONSOLE: console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter(DEFAULT_LOG_FMT)) logger_instance.addHandler(console_handler) LOGGERS[module_name] = logger_instance return logger_instance
[docs]def _map_logger(func): """Map function to current loggers. Args: func (function): Function to call on every logger. """ for logger in LOGGERS.itervalues(): func(logger)
[docs]def set_logger_level(level): """Modify log level of existing loggers as well as the default for new loggers. Args: level (int): The log level to set the loggers to. """ # pylint: disable=global-statement global LOGLEVEL LOGLEVEL = level _map_logger(lambda logger: logger.setLevel(level))
[docs]def enable_console_log(): """Enable console logging for all the new loggers and add console handlers to all the existing loggers.""" # pylint: disable=global-statement global LOG_TO_CONSOLE LOG_TO_CONSOLE = True console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter(DEFAULT_LOG_FMT)) _map_logger(lambda logger: logger.addHandler(console_handler))
[docs]def set_logger_level_from_config(level_name): """Set the logger level from a config value. Args: level_name (str): The log level name. The accepted values are in the LOGLEVELS variable. """ set_logger_level(LOGLEVELS.get(level_name, LOGLEVEL))