cac41d1314
Sadly, I broke things. Change-Id: I7f1aa09d0a9bfddea710f571203a26c0f943f4df Signed-off-by: Paul Belanger <pabelanger@redhat.com>
340 lines
9.6 KiB
Python
Executable File
340 lines
9.6 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# 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.
|
|
|
|
|
|
"""Generate a sample logging configuration file
|
|
|
|
use log_config_generator.generate_log_config() to generate a sample
|
|
logging configuration file.
|
|
|
|
The sample splits up the log output for general logging and image
|
|
builds and applys some sensible rotation defaults.
|
|
"""
|
|
|
|
import argparse
|
|
import logging
|
|
import textwrap
|
|
import yaml
|
|
|
|
# default paths and outputs
|
|
MODULES_PATH = '../modules/openstack_project/templates/nodepool'
|
|
# default the project-config repo path to the same folder as this repo
|
|
CONFIG_FILE = '../../project-config/nodepool/nodepool.yaml'
|
|
LOGGING_CONFIG_FILE = MODULES_PATH + '/nodepool-builder.logging.conf.erb'
|
|
LOG_DIR = '/var/log/nodepool'
|
|
IMAGE_LOG_DIR = '<%= @image_log_document_root %>'
|
|
UPLOAD_LOG_DIR = '<%= @upload_log_document_root %>'
|
|
|
|
_BASIC_FILE = """
|
|
|
|
#
|
|
# THIS FILE HAS BEEN AUTOGENERATED
|
|
# Regenerate it with tools/nodepool_log_config.py
|
|
#
|
|
|
|
[loggers]
|
|
keys=root,nodepool,requests,shade,image,kazoo,
|
|
%(logger_titles)s
|
|
|
|
[handlers]
|
|
keys=console,debug,normal,image,
|
|
%(handler_titles)s
|
|
|
|
[formatters]
|
|
keys=simple
|
|
|
|
[logger_root]
|
|
level=WARNING
|
|
handlers=console
|
|
|
|
[logger_requests]
|
|
level=WARNING
|
|
handlers=debug,normal
|
|
qualname=requests
|
|
|
|
[logger_shade]
|
|
level=WARNING
|
|
handlers=debug,normal
|
|
qualname=shade
|
|
|
|
[logger_nodepool]
|
|
level=DEBUG
|
|
handlers=debug,normal
|
|
qualname=nodepool
|
|
|
|
[logger_image]
|
|
level=DEBUG
|
|
handlers=image
|
|
qualname=nodepool.image.build
|
|
propagate=0
|
|
|
|
[logger_kazoo]
|
|
level=INFO
|
|
handlers=debug,normal
|
|
qualname=kazoo
|
|
propagate=0
|
|
|
|
[handler_console]
|
|
level=WARNING
|
|
class=StreamHandler
|
|
formatter=simple
|
|
args=(sys.stdout,)
|
|
|
|
[handler_debug]
|
|
level=DEBUG
|
|
class=logging.handlers.TimedRotatingFileHandler
|
|
formatter=simple
|
|
args=('%(log_dir)s/builder-debug.log', 'H', 8, 30,)
|
|
|
|
[handler_normal]
|
|
level=INFO
|
|
class=logging.handlers.TimedRotatingFileHandler
|
|
formatter=simple
|
|
args=('%(log_dir)s/nodepool-builder.log', 'H', 8, 30,)
|
|
|
|
[handler_image]
|
|
level=DEBUG
|
|
class=logging.handlers.TimedRotatingFileHandler
|
|
formatter=simple
|
|
args=('%(image_log_dir)s/image.log', 'H', 8, 30,)
|
|
|
|
[formatter_simple]
|
|
format=%%(asctime)s %%(levelname)s %%(name)s: %%(message)s
|
|
datefmt=
|
|
|
|
# ==== loggers and handlers ====
|
|
|
|
%(loggers_and_handlers)s
|
|
"""
|
|
|
|
_IMAGE_HANDLER = """
|
|
[handler_%(title)s]
|
|
level=DEBUG
|
|
class=logging.handlers.TimedRotatingFileHandler
|
|
formatter=simple
|
|
args=('%(image_log_dir)s/%(filename)s', 'H', 8, 30,)
|
|
"""
|
|
|
|
_IMAGE_LOGGER = """
|
|
[logger_%(title)s]
|
|
level=DEBUG
|
|
handlers=%(handler)s
|
|
qualname=nodepool.image.build.%(qualname)s
|
|
propagate=0
|
|
"""
|
|
|
|
_UPLOAD_HANDLER = """
|
|
[handler_%(title)s]
|
|
level=DEBUG
|
|
class=logging.handlers.TimedRotatingFileHandler
|
|
formatter=simple
|
|
args=('%(upload_log_dir)s/%(filename)s', 'H', 8, 30,)
|
|
"""
|
|
|
|
_UPLOAD_LOGGER = """
|
|
[logger_%(title)s]
|
|
level=DEBUG
|
|
handlers=%(handler)s
|
|
qualname=nodepool.image.upload.%(qualname)s
|
|
propagate=0
|
|
"""
|
|
|
|
|
|
def _get_providers_and_images(config):
|
|
ret = []
|
|
for provider in config['providers']:
|
|
for image in provider['images']:
|
|
if 'diskimage' not in image:
|
|
ret.append((provider['name'], image['name']))
|
|
logging.debug("Added snapshot image: %s:%s" % (
|
|
provider['name'], image['name']))
|
|
|
|
# diskimages have a special provider
|
|
if 'diskimages' in config:
|
|
for diskimage in config['diskimages']:
|
|
ret.append(('dib', diskimage['name']))
|
|
logging.debug("Added dib image: %s" % diskimage['name'])
|
|
|
|
return ret
|
|
|
|
|
|
def _get_upload_providers(config):
|
|
ret = []
|
|
for provider in config['providers']:
|
|
ret.append(provider['name'])
|
|
logging.debug("Added upload provider: %s" % provider['name'])
|
|
return ret
|
|
|
|
|
|
def _generate_image_logger_and_handler(image_log_dir, provider, image):
|
|
handler = _IMAGE_HANDLER % {
|
|
'image_log_dir': image_log_dir,
|
|
'title': '%s_%s' % (provider, image),
|
|
'filename': '%s.%s.log' % (provider, image),
|
|
}
|
|
|
|
logger = _IMAGE_LOGGER % {
|
|
'title': '%s_%s' % (provider, image),
|
|
'handler': '%s_%s' % (provider, image),
|
|
'qualname': '%s%s' % (provider + "." if provider != 'dib' else '',
|
|
image),
|
|
}
|
|
|
|
return {
|
|
'handler_title': '%s_%s' % (provider, image),
|
|
'logger_title': '%s_%s' % (provider, image),
|
|
'handler': handler,
|
|
'logger': logger,
|
|
}
|
|
|
|
|
|
def _generate_upload_logger_and_handler(upload_log_dir, provider):
|
|
handler = _UPLOAD_HANDLER % {
|
|
'upload_log_dir': upload_log_dir,
|
|
'title': '%s_upload' % (provider),
|
|
'filename': '%s.log' % (provider),
|
|
}
|
|
|
|
logger = _UPLOAD_LOGGER % {
|
|
'title': '%s_upload' % (provider),
|
|
'handler': '%s_upload' % (provider),
|
|
'qualname': '%s' % (provider),
|
|
}
|
|
|
|
return {
|
|
'handler_title': '%s_upload' % (provider),
|
|
'logger_title': '%s_upload' % (provider),
|
|
'handler': handler,
|
|
'logger': logger,
|
|
}
|
|
|
|
|
|
def generate_log_config(config, log_dir, image_log_dir,
|
|
upload_log_dir, output):
|
|
|
|
"""Generate a sample logging file
|
|
|
|
The logging output will have the correct formatters and handlers
|
|
to split all image-build logs out into separate files grouped by
|
|
provider. e.g.
|
|
|
|
providers:
|
|
- name: foo
|
|
...
|
|
- images:
|
|
- name: image1
|
|
...
|
|
- name: image2
|
|
...
|
|
- name: moo
|
|
...
|
|
- images:
|
|
- name: image1
|
|
...
|
|
- name: image2
|
|
...
|
|
|
|
Will result in log files (in `image_log_dir`) of foo.image1.log,
|
|
foo.image2.log, moo.image1.log, moo.image2.log
|
|
|
|
diskimage-builder built images will have special provider "dib"
|
|
|
|
:param config: input config file
|
|
:param log_dir: directory for main log file
|
|
:param image_log_dir: directory for image build logs
|
|
:param upload_log_dir: directory for upload logs
|
|
:param output: open file handle to output sample configuration to
|
|
|
|
"""
|
|
|
|
loggers_and_handlers = []
|
|
logging.debug("Reading config file %s" % config.name)
|
|
config = yaml.load(config)
|
|
|
|
# image loggers
|
|
for (provider, image) in _get_providers_and_images(config):
|
|
loggers_and_handlers.append(
|
|
_generate_image_logger_and_handler(image_log_dir, provider, image))
|
|
|
|
# provider loggers (for upload)
|
|
for provider in _get_upload_providers(config):
|
|
loggers_and_handlers.append(
|
|
_generate_upload_logger_and_handler(upload_log_dir, provider))
|
|
|
|
# output all loggers and handlers
|
|
logger_titles = []
|
|
handler_titles = []
|
|
image_loggers_and_handlers = ""
|
|
for item in loggers_and_handlers:
|
|
logger_titles.append(item['logger_title'])
|
|
handler_titles.append(item['handler_title'])
|
|
image_loggers_and_handlers += item['logger'] + item['handler']
|
|
|
|
# Final output
|
|
final_output = _BASIC_FILE % {
|
|
'log_dir': log_dir,
|
|
'image_log_dir': image_log_dir,
|
|
'logger_titles': "\n".join(textwrap.wrap(', '.join(logger_titles),
|
|
break_long_words=False,
|
|
break_on_hyphens=False,
|
|
subsequent_indent=' ')),
|
|
'handler_titles': "\n".join(textwrap.wrap(', '.join(handler_titles),
|
|
break_long_words=False,
|
|
break_on_hyphens=False,
|
|
subsequent_indent=' ')),
|
|
'loggers_and_handlers': image_loggers_and_handlers,
|
|
}
|
|
|
|
logging.debug("Writing output to %s" % output.name)
|
|
output.write(final_output)
|
|
output.flush()
|
|
logging.debug("Done!")
|
|
|
|
|
|
def main():
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('-d', '--debug', action='store_true',
|
|
help="Enable debugging")
|
|
parser.add_argument('-c', '--config', default=CONFIG_FILE,
|
|
help="Config file to read in "
|
|
"(default: %s)" % CONFIG_FILE,
|
|
type=argparse.FileType('r'))
|
|
parser.add_argument('-o', '--output', default=LOGGING_CONFIG_FILE,
|
|
help="Output file "
|
|
"(default: %s)" % LOGGING_CONFIG_FILE,
|
|
type=argparse.FileType('w'))
|
|
parser.add_argument('-l', '--log-dir', default=LOG_DIR,
|
|
help="Output directory for logs "
|
|
"(default: %s)" % LOG_DIR)
|
|
parser.add_argument('-i', '--image-log-dir', default=IMAGE_LOG_DIR,
|
|
help="Output directory for image logs "
|
|
"(default: %s)" % IMAGE_LOG_DIR.replace('%', '%%'))
|
|
parser.add_argument('-u', '--upload-log-dir', default=UPLOAD_LOG_DIR,
|
|
help="Output directory for upload logs "
|
|
"(default: %s)" % UPLOAD_LOG_DIR.replace('%', '%%'))
|
|
args = parser.parse_args()
|
|
|
|
logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO)
|
|
|
|
generate_log_config(args.config,
|
|
args.log_dir,
|
|
args.image_log_dir,
|
|
args.upload_log_dir,
|
|
args.output)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|