First round of logging functionality:
* Adds option group for logging-only configuration settings * Adds /etc and /etc/logging.cnf.sample as an example of setting up logging configuration directly with a config file * Adds to glance.common.config a couple function useful in adding logging options and setting up the logger(s) Next round will include the addition of a --debug option and lots more debugging output to the loggers.
This commit is contained in:
parent
087ebf5fec
commit
61711e0378
@ -22,6 +22,7 @@
|
|||||||
Glance API Server
|
Glance API Server
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
import optparse
|
import optparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -36,6 +37,7 @@ from glance.common import server
|
|||||||
import glance.store
|
import glance.store
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger('glance-api')
|
||||||
DEFAULT_STORE_CHOICES = ['file', 'swift', 's3']
|
DEFAULT_STORE_CHOICES = ['file', 'swift', 's3']
|
||||||
|
|
||||||
|
|
||||||
@ -61,15 +63,6 @@ def create_options(parser):
|
|||||||
"Default: %default")
|
"Default: %default")
|
||||||
parser.add_option('--daemonize', default=False, action="store_true",
|
parser.add_option('--daemonize', default=False, action="store_true",
|
||||||
help="Daemonize this process")
|
help="Daemonize this process")
|
||||||
parser.add_option('--use-syslog', default=True, action="store_true",
|
|
||||||
help="Output to syslog when daemonizing. "
|
|
||||||
"Default: %default")
|
|
||||||
parser.add_option('--logfile', default=None,
|
|
||||||
metavar="PATH",
|
|
||||||
help="(Optional) Name of log file to output to.")
|
|
||||||
parser.add_option("--logdir", default=None,
|
|
||||||
help="(Optional) The directory to keep log files in "
|
|
||||||
"(will be prepended to --logfile)")
|
|
||||||
parser.add_option("--pidfile", default=None,
|
parser.add_option("--pidfile", default=None,
|
||||||
help="(Optional) Name of pid file for the server")
|
help="(Optional) Name of pid file for the server")
|
||||||
parser.add_option('--working-directory', '--working-dir',
|
parser.add_option('--working-directory', '--working-dir',
|
||||||
@ -96,6 +89,7 @@ def create_options(parser):
|
|||||||
"virtual machine images to. Choices: ('%s') "
|
"virtual machine images to. Choices: ('%s') "
|
||||||
"Default: %%default" % "','".join(DEFAULT_STORE_CHOICES))
|
"Default: %%default" % "','".join(DEFAULT_STORE_CHOICES))
|
||||||
glance.store.add_options(parser)
|
glance.store.add_options(parser)
|
||||||
|
config.add_log_options(parser)
|
||||||
|
|
||||||
|
|
||||||
def main(_args):
|
def main(_args):
|
||||||
@ -113,4 +107,10 @@ if __name__ == '__main__':
|
|||||||
% version.version_string())
|
% version.version_string())
|
||||||
create_options(oparser)
|
create_options(oparser)
|
||||||
(options, args) = config.parse_options(oparser)
|
(options, args) = config.parse_options(oparser)
|
||||||
|
|
||||||
|
try:
|
||||||
|
config.setup_logging('glance-api', options)
|
||||||
|
except RuntimeError, e:
|
||||||
|
sys.exit("ERROR: %s" % e)
|
||||||
|
|
||||||
server.serve('glance-api', main, options, args)
|
server.serve('glance-api', main, options, args)
|
||||||
|
@ -57,15 +57,6 @@ def create_options(parser):
|
|||||||
"Default: %default")
|
"Default: %default")
|
||||||
parser.add_option('--daemonize', default=False, action="store_true",
|
parser.add_option('--daemonize', default=False, action="store_true",
|
||||||
help="Daemonize this process")
|
help="Daemonize this process")
|
||||||
parser.add_option('--use-syslog', default=True, action="store_true",
|
|
||||||
help="Output to syslog when daemonizing. "
|
|
||||||
"Default: %default")
|
|
||||||
parser.add_option('--logfile', default=None,
|
|
||||||
metavar="PATH",
|
|
||||||
help="(Optional) Name of log file to output to.")
|
|
||||||
parser.add_option("--logdir", default=None,
|
|
||||||
help="(Optional) The directory to keep log files in "
|
|
||||||
"(will be prepended to --logfile)")
|
|
||||||
parser.add_option("--pidfile", default=None,
|
parser.add_option("--pidfile", default=None,
|
||||||
help="(Optional) Name of pid file for the server")
|
help="(Optional) Name of pid file for the server")
|
||||||
parser.add_option('--working-directory', '--working-dir',
|
parser.add_option('--working-directory', '--working-dir',
|
||||||
@ -79,6 +70,7 @@ def create_options(parser):
|
|||||||
default='sqlite:///glance.sqlite',
|
default='sqlite:///glance.sqlite',
|
||||||
help="A valid SQLAlchemy connection string for the "
|
help="A valid SQLAlchemy connection string for the "
|
||||||
"registry database. Default: %default")
|
"registry database. Default: %default")
|
||||||
|
config.add_log_options(parser)
|
||||||
|
|
||||||
|
|
||||||
def main(_args):
|
def main(_args):
|
||||||
@ -96,4 +88,10 @@ if __name__ == '__main__':
|
|||||||
% version.version_string())
|
% version.version_string())
|
||||||
create_options(oparser)
|
create_options(oparser)
|
||||||
(options, args) = config.parse_options(oparser)
|
(options, args) = config.parse_options(oparser)
|
||||||
|
|
||||||
|
try:
|
||||||
|
config.setup_logging('glance-registry', options)
|
||||||
|
except RuntimeError, e:
|
||||||
|
sys.exit("ERROR: %s" % e)
|
||||||
|
|
||||||
server.serve('glance-registry', main, options, args)
|
server.serve('glance-registry', main, options, args)
|
||||||
|
54
etc/logging.cnf.sample
Normal file
54
etc/logging.cnf.sample
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
[loggers]
|
||||||
|
keys=root,api,registry,combined
|
||||||
|
|
||||||
|
[formatters]
|
||||||
|
keys=normal,normal_with_name,debug
|
||||||
|
|
||||||
|
[handlers]
|
||||||
|
keys=production,file,devel
|
||||||
|
|
||||||
|
[logger_root]
|
||||||
|
level=NOTSET
|
||||||
|
handlers=devel
|
||||||
|
|
||||||
|
[logger_api]
|
||||||
|
level=DEBUG
|
||||||
|
handlers=devel
|
||||||
|
qualname=glance-api
|
||||||
|
|
||||||
|
[logger_registry]
|
||||||
|
level=DEBUG
|
||||||
|
handlers=devel
|
||||||
|
qualname=glance-registry
|
||||||
|
|
||||||
|
[logger_combined]
|
||||||
|
level=DEBUG
|
||||||
|
handlers=devel
|
||||||
|
qualname=glance-combined
|
||||||
|
|
||||||
|
[handler_production]
|
||||||
|
class=handlers.SysLogHandler
|
||||||
|
level=ERROR
|
||||||
|
formatter=normal_with_name
|
||||||
|
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)
|
||||||
|
|
||||||
|
[handler_file]
|
||||||
|
class=FileHandler
|
||||||
|
level=DEBUG
|
||||||
|
formatter=normal_with_name
|
||||||
|
args=('glance.log', 'w')
|
||||||
|
|
||||||
|
[handler_devel]
|
||||||
|
class=StreamHandler
|
||||||
|
level=NOTSET
|
||||||
|
formatter=debug
|
||||||
|
args=(sys.stdout,)
|
||||||
|
|
||||||
|
[formatter_normal]
|
||||||
|
format=%(asctime)s %(levelname)s %(message)s
|
||||||
|
|
||||||
|
[formatter_normal_with_name]
|
||||||
|
format=(%(name)s): %(asctime)s %(levelname)s %(message)s
|
||||||
|
|
||||||
|
[formatter_debug]
|
||||||
|
format=(%(name)s): %(asctime)s %(levelname)s %(module)s %(funcName)s %(message)s
|
@ -16,6 +16,20 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Routines for configuring Glance
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import logging.config
|
||||||
|
import logging.handlers
|
||||||
|
import optparse
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_LOG_FORMAT = "%(asctime)s (%(name)s): %(levelname)s %(message)s"
|
||||||
|
LOGGING_HANDLER_CHOICES = ['syslog', 'file', 'stream']
|
||||||
|
|
||||||
|
|
||||||
def parse_options(parser, cli_args=None):
|
def parse_options(parser, cli_args=None):
|
||||||
"""
|
"""
|
||||||
@ -52,3 +66,77 @@ def options_to_conf(options):
|
|||||||
:params options: Mapping of typed option key/values
|
:params options: Mapping of typed option key/values
|
||||||
"""
|
"""
|
||||||
return dict([(k, str(v)) for k, v in options.items()])
|
return dict([(k, str(v)) for k, v in options.items()])
|
||||||
|
|
||||||
|
|
||||||
|
def add_log_options(parser):
|
||||||
|
"""
|
||||||
|
Given a supplied optparse.OptionParser, adds an OptionGroup that
|
||||||
|
represents all the configuration options around logging.
|
||||||
|
|
||||||
|
:param parser: optparse.OptionParser
|
||||||
|
"""
|
||||||
|
help_text = "The following configuration options are specific to logging "\
|
||||||
|
"functionality for this program."
|
||||||
|
|
||||||
|
group = optparse.OptionGroup(parser, "Logging Options", help_text)
|
||||||
|
group.add_option('--log-config', default=None, metavar="PATH",
|
||||||
|
help="If this option is specified, the logging "
|
||||||
|
"configuration file specified is used and overrides "
|
||||||
|
"any other logging options specified. Please see "
|
||||||
|
"the Python logging module documentation for "
|
||||||
|
"details on logging configuration files.")
|
||||||
|
group.add_option('--log-handler', default='stream', metavar="HANDLER",
|
||||||
|
choices=LOGGING_HANDLER_CHOICES,
|
||||||
|
help="What logging handler to use? "
|
||||||
|
"Default: %default")
|
||||||
|
group.add_option('--log-format', metavar="FORMAT",
|
||||||
|
default=DEFAULT_LOG_FORMAT,
|
||||||
|
help="Format string for log records. Default: %default")
|
||||||
|
group.add_option('--log-file', default=None,
|
||||||
|
metavar="PATH",
|
||||||
|
help="(Optional) Name of log file to output to.")
|
||||||
|
group.add_option("--log-dir", default=None,
|
||||||
|
help="(Optional) The directory to keep log files in "
|
||||||
|
"(will be prepended to --logfile)")
|
||||||
|
parser.add_option_group(group)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_logging(prog_name, options):
|
||||||
|
"""
|
||||||
|
Sets up the logging options for a log with supplied name
|
||||||
|
|
||||||
|
:param prog_name: Name of the log/program
|
||||||
|
:param options: Mapping of typed option key/values
|
||||||
|
"""
|
||||||
|
|
||||||
|
if options['log_config']:
|
||||||
|
# Use a logging configuration file for all settings...
|
||||||
|
if os.path.exists(options['log_config']):
|
||||||
|
logging.config.fileConfig(options['log_config'])
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unable to locate specified logging "
|
||||||
|
"config file: %s" % options['log_config'])
|
||||||
|
else:
|
||||||
|
# Set log configuration from options...
|
||||||
|
logger = logging.getLogger(prog_name)
|
||||||
|
formatter = logging.Formatter(options['log_format'])
|
||||||
|
|
||||||
|
if options['log_handler'] == 'syslog':
|
||||||
|
syslog = logging.handlers.SysLogHandler(address='/dev/log')
|
||||||
|
syslog.setFormatter(formatter)
|
||||||
|
logger.addHandler(syslog)
|
||||||
|
else:
|
||||||
|
logfile = options['log_file']
|
||||||
|
logdir = options['log_dir']
|
||||||
|
if not logfile:
|
||||||
|
logfile = '%s.log' % prog_name
|
||||||
|
if logdir:
|
||||||
|
logfile = os.path.join(logdir, logfile)
|
||||||
|
logfile = logging.FileHandler(logfile)
|
||||||
|
logfile.setFormatter(formatter)
|
||||||
|
logger.addHandler(logfile)
|
||||||
|
|
||||||
|
if options['verbose']:
|
||||||
|
logging.getLogger(prog_name).setLevel(logging.DEBUG)
|
||||||
|
else:
|
||||||
|
logging.getLogger(prog_name).setLevel(logging.WARNING)
|
||||||
|
@ -87,14 +87,14 @@ def daemonize(args, name, main, options):
|
|||||||
"""Does the work of daemonizing the process"""
|
"""Does the work of daemonizing the process"""
|
||||||
logging.getLogger('amqplib').setLevel(logging.WARN)
|
logging.getLogger('amqplib').setLevel(logging.WARN)
|
||||||
pidfile = options['pidfile']
|
pidfile = options['pidfile']
|
||||||
logfile = options['logfile']
|
logfile = options['log_file']
|
||||||
if not logfile:
|
if not logfile:
|
||||||
logfile = None
|
logfile = None
|
||||||
logdir = options['logdir']
|
logdir = options['log_dir']
|
||||||
if not logdir:
|
if not logdir:
|
||||||
logdir = None
|
logdir = None
|
||||||
daemonize = options['daemonize']
|
daemonize = options['daemonize']
|
||||||
use_syslog = options['use_syslog']
|
use_syslog = options['log_handler'] == 'syslog'
|
||||||
files_to_keep = []
|
files_to_keep = []
|
||||||
if daemonize:
|
if daemonize:
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
@ -105,7 +105,7 @@ def daemonize(args, name, main, options):
|
|||||||
syslog.setFormatter(formatter)
|
syslog.setFormatter(formatter)
|
||||||
logger.addHandler(syslog)
|
logger.addHandler(syslog)
|
||||||
files_to_keep.append(syslog.socket)
|
files_to_keep.append(syslog.socket)
|
||||||
else:
|
elif options['log_handler'] == 'file':
|
||||||
if not logfile:
|
if not logfile:
|
||||||
logfile = '%s.log' % name
|
logfile = '%s.log' % name
|
||||||
if logdir:
|
if logdir:
|
||||||
|
Loading…
Reference in New Issue
Block a user