diff --git a/armada/cli/apply.py b/armada/cli/apply.py index e7d34a7c..348eadb9 100644 --- a/armada/cli/apply.py +++ b/armada/cli/apply.py @@ -12,14 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging - from cliff import command as cmd from armada.handlers.armada import Armada -LOG = logging.getLogger(__name__) - def applyCharts(args): armada = Armada(open(args.file).read(), @@ -29,7 +25,8 @@ def applyCharts(args): args.skip_pre_flight, args.dry_run, args.wait, - args.timeout) + args.timeout, + args.debug_logging) armada.sync() class ApplyChartsCommand(cmd.Command): @@ -41,8 +38,8 @@ class ApplyChartsCommand(cmd.Command): default=False, help='Run charts with dry run') parser.add_argument('--skip-pre-flight', action='store_true', default=False, help='Skip Pre Flight') - parser.add_argument('--debug', action='store', - default=False, help='Run charts with dry run') + parser.add_argument('--debug-logging', action='store_true', + default=False, help='Show debug logs') parser.add_argument('--disable-update-pre', action='store_true', default=False, help='Disable pre upgrade actions') parser.add_argument('--disable-update-post', action='store_true', diff --git a/armada/cli/tiller.py b/armada/cli/tiller.py index f513e5e7..828860b3 100644 --- a/armada/cli/tiller.py +++ b/armada/cli/tiller.py @@ -12,14 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging - from cliff import command as cmd from armada.handlers.tiller import Tiller +from oslo_config import cfg +from oslo_log import log as logging + LOG = logging.getLogger(__name__) +CONF = cfg.CONF +DOMAIN = "armada" + +logging.setup(CONF, DOMAIN) + def tillerServer(args): tiller = Tiller() diff --git a/armada/conf/__init__.py b/armada/conf/__init__.py index b31db4b5..3a4dedd8 100644 --- a/armada/conf/__init__.py +++ b/armada/conf/__init__.py @@ -11,11 +11,3 @@ # 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. - -from oslo_config import cfg - -from armada.conf import default - -CONF = cfg.CONF - -default.register_opts(CONF) diff --git a/armada/conf/default.py b/armada/conf/default.py index 01e0b76f..950ae0fb 100644 --- a/armada/conf/default.py +++ b/armada/conf/default.py @@ -12,27 +12,161 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os + from oslo_config import cfg default_options = [ + cfg.BoolOpt( + 'debug', + default='false', + help='Print debugging output (set logging level to DEBUG instead of \ + default INFO level).'), + + cfg.ListOpt( + 'default_log_levels', + default='root=INFO, cliff=INFO, stevedore=INFO, iso8601=INFO', + help='List of logger=LEVEL pairs.'), + + cfg.BoolOpt( + 'fatal_deprecations', + default='true', + help='Enables or disables fatal status of deprecations.'), + + cfg.StrOpt( + 'kubernetes_config_path', + default='/home/user/.kube/', + help='Path to Kubernetes configurations.'), + + cfg.StrOpt( + 'instance_format', + default='[instance: %(uuid)s] ', + help='The format for an instance that is passed \ + with the log message.'), + + cfg.StrOpt( + 'instance_uuid_format', + default='[instance: %(uuid)s] ', + help='The format for an instance UUID that is passed \ + with the log message.'), + + cfg.StrOpt( + 'log_config_append', + default=None, + help='The name of a logging configuration file.'), + + cfg.StrOpt( + 'log_date_format', + default='%Y-%m-%d %H:%M:%S', + help='Date format for log records.'), + + cfg.StrOpt( + 'log_dir', + default=None, + help='(Optional) The base directory used for \ + relative log file paths.'), + + cfg.StrOpt( + 'log_file', + default=None, + help='(Optional) Path to Armada log file.'), + + cfg.StrOpt( + 'logging_context_format_string', + default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s \ + %(name)s [%(request_id)s %(user_identity)s] \ + %(instance)s%(message)s', + help='Format for context logging.'), + + cfg.StrOpt( + 'logging_debug_format_suffix', + default='%(funcName)s %(pathname)s:%(lineno)d', + help='Format string to use for log messages \ + when context is undefined.'), + + cfg.StrOpt( + 'logging_default_format_string', + default='%(asctime)s.%(msecs)03d %(process)d \ + %(levelname)s %(name)s [-] %(instance)s%(message)s', + help='Format string to use for log \ + messages when context is undefined.'), + + cfg.StrOpt( + 'logging_exception_prefix', + default='%(asctime)s.%(msecs)03d %(process)d \ + ERROR %(name)s %(instance)s', + help='Prefix each line of \ + exception output with this format.'), + + cfg.StrOpt( + 'logging_user_identity_format', + default='%(user)s %(tenant)s %(domain)s \ + %(user_domain)s %(project_domain)s', + help='Defines the format string for \ + %(user_identity)s that is used in logging_context_format_string.'), + + cfg.BoolOpt( + 'publish_errors', + default='true', + help='Enables or disables publication of error events.'), + + cfg.IntOpt( + 'rate_limit_burst', + default='0', + help='Maximum number of logged messages per rate_limit_interval.'), + + cfg.StrOpt( + 'rate_limit_except_level', + default='CRITICAL', + help='Log level name used by rate limiting: \ + CRITICAL, ERROR, INFO, WARNING, DEBUG'), + + cfg.IntOpt( + 'rate_limit_interval', + default='0', + help='Maximum number of logged messages per rate_limit_interval.'), + cfg.StrOpt( 'ssh_key_path', default='/home/user/.ssh/', help='Path to SSH private key.'), cfg.StrOpt( - 'logs', - default='/var/log/armada/armada.log', - help='Path to Armada logs.'), + 'syslog_log_facility', + default='LOG_USER', + help='Syslog facility to receive log lines. \ + This option is ignored if log_config_append is set.'), - cfg.StrOpt( - 'kubernetes_config_path', - default='/home/user/.kube/', - help='Path to Kubernetes configurations.') + cfg.BoolOpt( + 'use_journal', + default='false', + help='Enable journald for logging. (Must be a systemd environment)'), + + cfg.BoolOpt( + 'use_stderr', + default='true', + help='Log output to standard error.'), + + cfg.BoolOpt( + 'use_syslog', + default='true', + help='Log output to syslog.'), + + cfg.BoolOpt( + 'watch_log_file', + default='false', + help='Enables instantaneous recreation of a \ + logging file if the file is removed.') ] -def register_opts(conf): - conf.register_opts(default_options) +def register_opts(): + CONF = cfg.CONF + CONF.register_opts(default_options) + + # Load config file if exists + default_config_file = 'etc/armada/armada.conf' + if (os.path.exists(default_config_file)): + CONF(['--config-file', default_config_file]) def list_opts(): return {'DEFAULT': default_options} diff --git a/armada/handlers/armada.py b/armada/handlers/armada.py index 16c454e8..b0eb1972 100644 --- a/armada/handlers/armada.py +++ b/armada/handlers/armada.py @@ -26,14 +26,12 @@ from ..utils import git from ..utils import lint LOG = logging.getLogger(__name__) + CONF = cfg.CONF DOMAIN = "armada" -logging.register_options(CONF) logging.setup(CONF, DOMAIN) -LOG = logging.getLogger(__name__) - class Armada(object): ''' This is the main Armada class handling the Armada @@ -47,7 +45,8 @@ class Armada(object): skip_pre_flight=False, dry_run=False, wait=False, - timeout=None): + timeout=None, + debug=False): ''' Initialize the Armada Engine and establish a connection to Tiller @@ -61,6 +60,11 @@ class Armada(object): self.timeout = timeout self.config = yaml.load(config) self.tiller = Tiller() + self.debug = debug + + # Set debug value + CONF.set_default('debug', self.debug) + logging.setup(CONF, DOMAIN) def find_release_chart(self, known_releases, name): ''' diff --git a/armada/handlers/chartbuilder.py b/armada/handlers/chartbuilder.py index c112a8d4..ecf05eaa 100644 --- a/armada/handlers/chartbuilder.py +++ b/armada/handlers/chartbuilder.py @@ -14,7 +14,6 @@ import os import yaml -import logging from hapi.chart.template_pb2 import Template from hapi.chart.chart_pb2 import Chart @@ -24,8 +23,16 @@ from supermutes.dot import dotify from ..utils.git import git_clone, source_cleanup +from oslo_config import cfg +from oslo_log import log as logging + LOG = logging.getLogger(__name__) +CONF = cfg.CONF +DOMAIN = "armada" + +logging.setup(CONF, DOMAIN) + class ChartBuilder(object): ''' This class handles taking chart intentions as a paramter and diff --git a/armada/handlers/k8s.py b/armada/handlers/k8s.py index 13fea1d9..27ad7eee 100644 --- a/armada/handlers/k8s.py +++ b/armada/handlers/k8s.py @@ -14,10 +14,17 @@ from kubernetes import client, config from kubernetes.client.rest import ApiException -import logging + +from oslo_config import cfg +from oslo_log import log as logging LOG = logging.getLogger(__name__) +CONF = cfg.CONF +DOMAIN = "armada" + +logging.setup(CONF, DOMAIN) + class K8s(object): ''' Object to obtain the local kube config file diff --git a/armada/handlers/tiller.py b/armada/handlers/tiller.py index 494a9667..f15f66c3 100644 --- a/armada/handlers/tiller.py +++ b/armada/handlers/tiller.py @@ -13,7 +13,6 @@ # limitations under the License. import grpc -import logging from hapi.services.tiller_pb2 import ReleaseServiceStub, ListReleasesRequest, \ InstallReleaseRequest, UpdateReleaseRequest, UninstallReleaseRequest @@ -22,6 +21,9 @@ from hapi.chart.config_pb2 import Config from k8s import K8s from ..utils.release import release_prefix +from oslo_config import cfg +from oslo_log import log as logging + TILLER_PORT = 44134 TILLER_VERSION = b'2.4.2' TILLER_TIMEOUT = 300 @@ -36,6 +38,11 @@ MAX_MESSAGE_LENGTH = 429496729 LOG = logging.getLogger(__name__) +CONF = cfg.CONF +DOMAIN = "armada" + +logging.setup(CONF, DOMAIN) + class Tiller(object): ''' The Tiller class supports communication and requests to the Tiller Helm diff --git a/armada/log.py b/armada/log.py deleted file mode 100644 index dd61e996..00000000 --- a/armada/log.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2017 The Armada Authors. -# -# 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. - -from oslo_config import cfg -from oslo_log import log as logging - -CONF = cfg.CONF -DOMAIN = "armada" - -def set_console_formatter(**formatter_kwargs): - formatter_kwargs.setdefault( - 'fmt', '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') - formatter_kwargs.setdefault('datefmt', '%m-%d %H:%M') - - # Specify default log levels - custom_log_level_defaults = [ - 'root=INFO', - 'cliff=INFO', - 'stevedore=INFO', - 'iso8601=INFO' - ] - - logging.set_defaults( - default_log_levels=logging.get_default_log_levels() + - custom_log_level_defaults) - - # Setup logging configuration - logging.register_options(CONF) - logging.setup(CONF, DOMAIN) diff --git a/armada/shell.py b/armada/shell.py index 6b839d8c..6d8dd7e9 100644 --- a/armada/shell.py +++ b/armada/shell.py @@ -16,9 +16,9 @@ import sys from cliff import app from cliff import commandmanager as cm +from conf import default import armada -from armada import log class ArmadaApp(app.App): def __init__(self, **kwargs): @@ -35,7 +35,7 @@ class ArmadaApp(app.App): def configure_logging(self): super(ArmadaApp, self).configure_logging() - log.set_console_formatter() + default.register_opts() def main(argv=None): if argv is None: diff --git a/requirements.txt b/requirements.txt index 10a4b9d1..e01a7e9e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ grpcio==1.1.3 grpcio-tools==1.1.3 kubernetes==1.0.0 oslo.log==3.28.0 +oslo.messaging==5.28.0 protobuf==3.2.0 PyYAML==3.12 requests==2.17.3 diff --git a/server.py b/server.py index 0fa845a9..6060b5e4 100644 --- a/server.py +++ b/server.py @@ -43,8 +43,10 @@ class Tiller(object): message = "Tiller Server is {}" if tillerHandler().tiller_status(): resp.data = json.dumps({'message': message.format('Active')}) + LOG.info('Tiller Server is Active.') else: resp.data = json.dumps({'message': message.format('Not Present')}) + LOG.info('Tiller Server is Not Present.') resp.content_type = 'application/json' resp.status = HTTP_200