mirror of
https://github.com/valitydev/salt.git
synced 2024-11-06 16:45:27 +00:00
commit
7a2973a10a
@ -230,9 +230,21 @@
|
||||
#log_file: /var/log/salt/master
|
||||
#
|
||||
# The level of messages to send to the log file.
|
||||
# One of 'info', 'quiet', 'critical', 'error', 'debug', 'warning'.
|
||||
# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'.
|
||||
# Default: 'warning'
|
||||
#log_level: warning
|
||||
#log_level_logfile:
|
||||
#
|
||||
# The date and time format used in log messages. Allowed date/time formating
|
||||
# can be seen here:
|
||||
# http://docs.python.org/library/time.html#time.strftime
|
||||
#log_datefmt: '%H:%M:%S'
|
||||
#
|
||||
# The format of the console logging messages. Allowed formatting options can
|
||||
# be seen here:
|
||||
# http://docs.python.org/library/logging.html#logrecord-attributes
|
||||
#log_fmt_console: '[%(levelname)-8s] %(message)s'
|
||||
#log_fmt_logfile: '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s'
|
||||
#
|
||||
# Logger levels can be used to tweak specific loggers logging levels.
|
||||
# For example, if you want to have the salt library at the 'warning' level,
|
||||
|
@ -150,7 +150,7 @@
|
||||
# the master but used to reference a local directory on the minion.
|
||||
|
||||
# Set the file client, the client defaults to looking on the master server for
|
||||
# files, but can be directed to look at the local file directory setting
|
||||
# files, but can be directed to look at the local file directory setting
|
||||
# defined below by setting it to local.
|
||||
#file_client: remote
|
||||
|
||||
@ -207,9 +207,19 @@
|
||||
#log_file: /var/log/salt/minion
|
||||
#
|
||||
# The level of messages to send to the log file.
|
||||
# One of 'info', 'quiet', 'critical', 'error', 'debug', 'warning'.
|
||||
# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'.
|
||||
# Default: 'warning'
|
||||
#log_level: warning
|
||||
#log_level_logfile:
|
||||
#
|
||||
# The date and time format used in log messages. Allowed date/time formating
|
||||
# can be seen on http://docs.python.org/library/time.html#time.strftime
|
||||
#log_datefmt: '%H:%M:%S'
|
||||
#
|
||||
# The format of the console logging messages. Allowed formatting options can
|
||||
# be seen on http://docs.python.org/library/logging.html#logrecord-attributes
|
||||
#log_fmt_console: '[%(levelname)-8s] %(message)s'
|
||||
#log_fmt_logfile: '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s'
|
||||
#
|
||||
# Logger levels can be used to tweak specific loggers logging levels.
|
||||
# For example, if you want to have the salt library at the 'warning' level,
|
||||
|
@ -18,15 +18,12 @@ except ImportError as e:
|
||||
if e.args[0] != 'No module named _msgpack':
|
||||
raise
|
||||
|
||||
log_format = '%(asctime)s,%(msecs)03.0f [%(name)-15s][%(levelname)-8s] %(message)s'
|
||||
|
||||
class Master(object):
|
||||
'''
|
||||
Creates a master server
|
||||
'''
|
||||
def __init__(self):
|
||||
self.cli = self.__parse_cli()
|
||||
self.opts = salt.config.master_config(self.cli['config'])
|
||||
# command line overrides config
|
||||
if self.cli['user']:
|
||||
self.opts['user'] = self.cli['user']
|
||||
@ -62,14 +59,23 @@ class Master(object):
|
||||
parser.add_option('-l',
|
||||
'--log-level',
|
||||
dest='log_level',
|
||||
default='warning',
|
||||
choices=list(salt.log.LOG_LEVELS),
|
||||
help='Console log level. One of %s. For the logfile settings '
|
||||
'see the config file. Default: \'%%default\'.' %
|
||||
'see the config file. Default: \'warning\'.' %
|
||||
', '.join([repr(l) for l in salt.log.LOG_LEVELS]))
|
||||
|
||||
options, args = parser.parse_args()
|
||||
salt.log.setup_console_logger(options.log_level, log_format=log_format)
|
||||
|
||||
self.opts = salt.config.master_config(options.config)
|
||||
|
||||
if not options.log_level:
|
||||
options.log_level = self.opts['log_level']
|
||||
|
||||
salt.log.setup_console_logger(
|
||||
options.log_level,
|
||||
log_format=self.opts['log_fmt_console'],
|
||||
date_format=self.opts['log_datefmt']
|
||||
)
|
||||
|
||||
cli = {'daemon': options.daemon,
|
||||
'config': options.config,
|
||||
@ -92,12 +98,17 @@ class Master(object):
|
||||
self.opts['sock_dir'],
|
||||
],
|
||||
self.opts['user'])
|
||||
|
||||
import salt.log
|
||||
salt.log.setup_logfile_logger(
|
||||
self.opts['log_file'], self.opts['log_level']
|
||||
self.opts['log_file'],
|
||||
self.opts['log_level_logfile'] or self.opts['log_level'],
|
||||
log_format=self.opts['log_fmt_logfile'],
|
||||
date_format=self.opts['log_datefmt']
|
||||
)
|
||||
for name, level in self.opts['log_granular_levels'].items():
|
||||
salt.log.set_logger_level(name, level)
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
# Late import so logging works correctly
|
||||
@ -129,7 +140,6 @@ class Minion(object):
|
||||
'''
|
||||
def __init__(self):
|
||||
self.cli = self.__parse_cli()
|
||||
self.opts = salt.config.minion_config(self.cli['config'])
|
||||
# command line overrides config
|
||||
if self.cli['user']:
|
||||
self.opts['user'] = self.cli['user']
|
||||
@ -163,14 +173,23 @@ class Minion(object):
|
||||
parser.add_option('-l',
|
||||
'--log-level',
|
||||
dest='log_level',
|
||||
default='warning',
|
||||
choices=list(salt.log.LOG_LEVELS),
|
||||
help='Console log level. One of %s. For the logfile settings '
|
||||
'see the config file. Default: \'%%default\'.' %
|
||||
'see the config file. Default: \'warning\'.' %
|
||||
', '.join([repr(l) for l in salt.log.LOG_LEVELS]))
|
||||
|
||||
options, args = parser.parse_args()
|
||||
salt.log.setup_console_logger(options.log_level, log_format=log_format)
|
||||
|
||||
self.opts = salt.config.minion_config(options.config)
|
||||
|
||||
if not options.log_level:
|
||||
options.log_level = self.opts['log_level']
|
||||
|
||||
salt.log.setup_console_logger(
|
||||
options.log_level,
|
||||
log_format=self.opts['log_fmt_console'],
|
||||
date_format=self.opts['log_datefmt']
|
||||
)
|
||||
|
||||
cli = {'daemon': options.daemon,
|
||||
'config': options.config,
|
||||
@ -189,12 +208,17 @@ class Minion(object):
|
||||
os.path.dirname(self.opts['log_file']),
|
||||
],
|
||||
self.opts['user'])
|
||||
|
||||
import salt.log
|
||||
salt.log.setup_logfile_logger(
|
||||
self.opts['log_file'], self.opts['log_level']
|
||||
self.opts['log_file'],
|
||||
self.opts['log_level_logfile'] or self.opts['log_level'],
|
||||
log_format=self.opts['log_fmt_logfile'],
|
||||
date_format=self.opts['log_datefmt']
|
||||
)
|
||||
for name, level in self.opts['log_granular_levels'].items():
|
||||
salt.log.set_logger_level(name, level)
|
||||
|
||||
import logging
|
||||
# Late import so logging works correctly
|
||||
import salt.minion
|
||||
@ -203,18 +227,18 @@ class Minion(object):
|
||||
# Late import so logging works correctly
|
||||
import salt.utils
|
||||
# If the minion key has not been accepted, then Salt enters a loop
|
||||
# waiting for it, if we daemonize later then the minion cound halt
|
||||
# waiting for it, if we daemonize later then the minion could halt
|
||||
# the boot process waiting for a key to be accepted on the master.
|
||||
# This is the latest safe place to daemonize
|
||||
salt.utils.daemonize()
|
||||
minion = salt.minion.Minion(self.opts)
|
||||
set_pidfile(self.cli['pidfile'])
|
||||
if check_user(self.opts['user'], log):
|
||||
try:
|
||||
try:
|
||||
minion = salt.minion.Minion(self.opts)
|
||||
set_pidfile(self.cli['pidfile'])
|
||||
if check_user(self.opts['user'], log):
|
||||
minion.tune_in()
|
||||
except KeyboardInterrupt:
|
||||
log.warn('Stopping the Salt Minion')
|
||||
raise SystemExit('\nExiting on Ctrl-c')
|
||||
except KeyboardInterrupt:
|
||||
log.warn('Stopping the Salt Minion')
|
||||
raise SystemExit('\nExiting on Ctrl-c')
|
||||
|
||||
|
||||
class Syndic(object):
|
||||
@ -223,7 +247,6 @@ class Syndic(object):
|
||||
'''
|
||||
def __init__(self):
|
||||
self.cli = self.__parse_cli()
|
||||
self.opts = self.__prep_opts()
|
||||
# command line overrides config
|
||||
if self.cli['user']:
|
||||
self.opts['user'] = self.cli['user']
|
||||
@ -283,14 +306,22 @@ class Syndic(object):
|
||||
parser.add_option('-l',
|
||||
'--log-level',
|
||||
dest='log_level',
|
||||
default='warning',
|
||||
choices=list(salt.log.LOG_LEVELS),
|
||||
help='Console log level. One of %s. For the logfile settings '
|
||||
'see the config file. Default: \'%%default\'.' %
|
||||
'see the config file. Default: \'warning\'.' %
|
||||
', '.join([repr(l) for l in salt.log.LOG_LEVELS]))
|
||||
|
||||
options, args = parser.parse_args()
|
||||
salt.log.setup_console_logger(options.log_level, log_format=log_format)
|
||||
self.opts = self.__prep_opts()
|
||||
|
||||
if not options.log_level:
|
||||
options.log_level = self.opts['log_level']
|
||||
|
||||
salt.log.setup_console_logger(
|
||||
options.log_level,
|
||||
log_format=self.opts['log_fmt_console'],
|
||||
date_format=self.opts['log_datefmt']
|
||||
)
|
||||
|
||||
cli = {'daemon': options.daemon,
|
||||
'minion_config': options.minion_config,
|
||||
|
@ -26,6 +26,9 @@ from salt.exceptions import SaltClientError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__dflt_log_datefmt = '%H:%M:%S'
|
||||
__dflt_log_fmt_console = '[%(levelname)-8s] %(message)s'
|
||||
__dflt_log_fmt_logfile = '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s'
|
||||
|
||||
def _validate_file_roots(file_roots):
|
||||
'''
|
||||
@ -86,8 +89,12 @@ def load_config(opts, path, env_var):
|
||||
opts.update(_read_conf_file(path))
|
||||
opts['conf_file'] = path
|
||||
except Exception as e:
|
||||
import salt.log
|
||||
msg = 'Error parsing configuration file: {0} - {1}'
|
||||
log.warn(msg.format(path, e))
|
||||
if salt.log.is_console_configured():
|
||||
log.warn(msg.format(path, e))
|
||||
else:
|
||||
print msg.format(path, e)
|
||||
else:
|
||||
log.debug('Missing configuration file: {0}'.format(path))
|
||||
|
||||
@ -178,6 +185,10 @@ def minion_config(path):
|
||||
'sub_timeout': 60,
|
||||
'log_file': '/var/log/salt/minion',
|
||||
'log_level': 'warning',
|
||||
'log_level_logfile': None,
|
||||
'log_datefmt': __dflt_log_datefmt,
|
||||
'log_fmt_console': __dflt_log_fmt_console,
|
||||
'log_fmt_logfile': __dflt_log_fmt_logfile,
|
||||
'log_granular_levels': {},
|
||||
'test': False,
|
||||
'cython_enable': False,
|
||||
@ -256,6 +267,10 @@ def master_config(path):
|
||||
'job_cache': True,
|
||||
'log_file': '/var/log/salt/master',
|
||||
'log_level': 'warning',
|
||||
'log_level_logfile': None,
|
||||
'log_datefmt': __dflt_log_datefmt,
|
||||
'log_fmt_console': __dflt_log_fmt_console,
|
||||
'log_fmt_logfile': __dflt_log_fmt_logfile,
|
||||
'log_granular_levels': {},
|
||||
'pidfile': '/var/run/salt-master.pid',
|
||||
'cluster_masters': [],
|
||||
|
98
salt/log.py
98
salt/log.py
@ -5,16 +5,17 @@
|
||||
This is where Salt's logging gets set up.
|
||||
|
||||
|
||||
:copyright: 2011 :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:copyright: 2011-2012 :email:`Pedro Algarvio (pedro@algarvio.me)`
|
||||
:license: Apache 2.0, see LICENSE for more details.
|
||||
'''
|
||||
|
||||
import re
|
||||
import sys
|
||||
import logging
|
||||
import logging.handlers
|
||||
|
||||
TRACE = 5
|
||||
GARBAGE = 1
|
||||
TRACE = logging.TRACE = 5
|
||||
GARBAGE = logging.GARBAGE = 1
|
||||
|
||||
LOG_LEVELS = {
|
||||
'debug': logging.DEBUG,
|
||||
@ -28,13 +29,65 @@ LOG_LEVELS = {
|
||||
|
||||
LoggingLoggerClass = logging.getLoggerClass()
|
||||
|
||||
MODNAME_PATTERN = re.compile(r'(?P<name>%%\(name\)(?P<digits>\-(?:[\d]+))?s)')
|
||||
MAX_LOGGER_MODNAME_LENGTH = 4
|
||||
|
||||
__CONSOLE_CONFIGURED = False
|
||||
__LOGFILE_CONFIGURED = False
|
||||
|
||||
def is_console_configured():
|
||||
global __CONSOLE_CONFIGURED
|
||||
return __CONSOLE_CONFIGURED
|
||||
|
||||
def is_logfile_configured():
|
||||
global __LOGFILE_CONFIGURED
|
||||
return __LOGFILE_CONFIGURED
|
||||
|
||||
|
||||
class Logging(LoggingLoggerClass):
|
||||
def __new__(cls, logger_name, *args, **kwargs):
|
||||
global MAX_LOGGER_MODNAME_LENGTH
|
||||
# This makes module name padding increase to the biggest module name
|
||||
# so that logs keep readability.
|
||||
#
|
||||
# This code will only run when a new logger is created, ie:
|
||||
#
|
||||
# logging.getLogger(__name__)
|
||||
#
|
||||
instance = super(Logging, cls).__new__(cls)
|
||||
|
||||
try:
|
||||
max_logger_name = max(logging.Logger.manager.loggerDict.keys())
|
||||
|
||||
if len(max_logger_name) > MAX_LOGGER_MODNAME_LENGTH:
|
||||
MAX_LOGGER_MODNAME_LENGTH = len(max_logger_name)
|
||||
for handler in logging.getLogger().handlers:
|
||||
if not handler.lock:
|
||||
handler.createLock()
|
||||
handler.acquire()
|
||||
|
||||
formatter = handler.formatter
|
||||
fmt = formatter._fmt.replace('%', '%%')
|
||||
|
||||
match = MODNAME_PATTERN.search(fmt)
|
||||
if match:
|
||||
fmt = fmt.replace(match.group('name'), '%%(name)-%ds')
|
||||
formatter = logging.Formatter(
|
||||
fmt % MAX_LOGGER_MODNAME_LENGTH,
|
||||
datefmt=formatter.datefmt
|
||||
)
|
||||
handler.setFormatter(formatter)
|
||||
handler.release()
|
||||
except ValueError:
|
||||
# There are no registered loggers yet
|
||||
pass
|
||||
return instance
|
||||
|
||||
def garbage(self, msg, *args, **kwargs):
|
||||
return LoggingLoggerClass.log(self, 1, msg, *args, **kwargs)
|
||||
return LoggingLoggerClass.log(self, GARBAGE, msg, *args, **kwargs)
|
||||
|
||||
def trace(self, msg, *args, **kwargs):
|
||||
return LoggingLoggerClass.log(self, 5, msg, *args, **kwargs)
|
||||
return LoggingLoggerClass.log(self, TRACE, msg, *args, **kwargs)
|
||||
|
||||
|
||||
def getLogger(name):
|
||||
@ -49,16 +102,20 @@ def init():
|
||||
'''
|
||||
if logging.getLoggerClass() is not Logging:
|
||||
logging.setLoggerClass(Logging)
|
||||
logging.addLevelName(5, 'TRACE')
|
||||
logging.addLevelName(1, 'GARBAGE')
|
||||
logging.addLevelName(TRACE, 'TRACE')
|
||||
logging.addLevelName(GARBAGE, 'GARBAGE')
|
||||
# Set the root logger at the lowest level possible
|
||||
logging.getLogger().setLevel(1)
|
||||
logging.getLogger().setLevel(GARBAGE)
|
||||
|
||||
|
||||
def setup_console_logger(log_level='error', log_format=None, date_format=None):
|
||||
'''
|
||||
Setup the console logger
|
||||
'''
|
||||
if is_console_configured():
|
||||
logging.getLogger(__name__).warning("Console logging already configured")
|
||||
return
|
||||
|
||||
init()
|
||||
level = LOG_LEVELS.get(log_level.lower(), logging.ERROR)
|
||||
|
||||
@ -78,11 +135,20 @@ def setup_console_logger(log_level='error', log_format=None, date_format=None):
|
||||
handler.setFormatter(formatter)
|
||||
rootLogger.addHandler(handler)
|
||||
|
||||
global __CONSOLE_CONFIGURED
|
||||
__CONSOLE_CONFIGURED = True
|
||||
|
||||
def setup_logfile_logger(log_path, log_level='error'):
|
||||
|
||||
def setup_logfile_logger(log_path, log_level='error', log_format=None,
|
||||
date_format=None):
|
||||
'''
|
||||
Setup the logfile logger
|
||||
'''
|
||||
|
||||
if is_logfile_configured():
|
||||
logging.getLogger(__name__).warning("Logfile logging already configured")
|
||||
return
|
||||
|
||||
init()
|
||||
level = LOG_LEVELS.get(log_level.lower(), logging.ERROR)
|
||||
|
||||
@ -99,13 +165,21 @@ def setup_logfile_logger(log_path, log_level='error'):
|
||||
sys.exit(2)
|
||||
|
||||
handler.setLevel(level)
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s [%(name)-15s][%(levelname)-8s] %(message)s',
|
||||
)
|
||||
|
||||
# Set the default console formatter config
|
||||
if not log_format:
|
||||
log_format = '%(asctime)s [%(name)-15s][%(levelname)-8s] %(message)s'
|
||||
if not date_format:
|
||||
date_format = '%H:%M:%S'
|
||||
|
||||
formatter = logging.Formatter(log_format, datefmt=date_format)
|
||||
|
||||
handler.setFormatter(formatter)
|
||||
rootLogger.addHandler(handler)
|
||||
|
||||
global __LOGFILE_CONFIGURED
|
||||
__LOGFILE_CONFIGURED = True
|
||||
|
||||
|
||||
def set_logger_level(logger_name, log_level='error'):
|
||||
'''
|
||||
|
@ -312,11 +312,16 @@ def dns_check(addr, safe=False):
|
||||
try:
|
||||
addr = socket.gethostbyname(addr)
|
||||
except socket.gaierror:
|
||||
err = ('This master address: {0} was previously resolvable but '
|
||||
err = ('This master address: \'{0}\' was previously resolvable but '
|
||||
'now fails to resolve! The previously resolved ip addr '
|
||||
'will continue to be used').format(addr)
|
||||
if safe:
|
||||
log.error(err)
|
||||
import salt.log
|
||||
if salt.log.is_console_configured():
|
||||
# If logging is not configured it also means that either
|
||||
# the master or minion instance calling this hasn't even
|
||||
# started running
|
||||
log.error(err)
|
||||
raise SaltClientError
|
||||
else:
|
||||
err = err.format(addr)
|
||||
|
Loading…
Reference in New Issue
Block a user