diff --git a/etc/ceilometer/ceilometer.conf.sample b/etc/ceilometer/ceilometer.conf.sample new file mode 100644 index 000000000..a4f952c96 --- /dev/null +++ b/etc/ceilometer/ceilometer.conf.sample @@ -0,0 +1,302 @@ +#################### +# ceilometer.conf sample # +#################### + +[DEFAULT] + +######## defined in ceilometer.openstack.common.cfg:CommonConfigOpts ######## + +# debug=false +#### (BoolOpt) Print debugging output + +# verbose=false +#### (BoolOpt) Print more verbose output + +# log_config= +#### (StrOpt) 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. + +# log_format=%(asctime)s %(levelname)8s [%(name)s] %(message)s +#### (StrOpt) A logging.Formatter log message format string which may use +#### any of the available logging.LogRecord attributes. Default: +#### %default + +# log_date_format=%Y-%m-%d %H:%M:%S +#### (StrOpt) Format string for %(asctime)s in log records. Default: +#### %default + +# log_file= +#### (StrOpt) (Optional) Name of log file to output to. If not set, +#### logging will go to stdout. + +# log_dir= +#### (StrOpt) (Optional) The directory to keep log files in (will be +#### prepended to --logfile) + +# use_syslog=false +#### (BoolOpt) Use syslog for logging. + +# syslog_log_facility=LOG_USER +#### (StrOpt) syslog facility to receive log lines + + +######## defined in ceilometer.meter ######## + +# metering_secret=change this or be hacked +#### (StrOpt) Secret value for signing metering messages + +# counter_source=openstack +#### (StrOpt) Source for counters emited on this instance + + +######## defined in ceilometer.policy ######## + +# policy_file=policy.json +#### (StrOpt) JSON file representing policy + +# policy_default_rule=default +#### (StrOpt) Rule checked when requested rule is not found + + +######## defined in ceilometer.publish ######## + +# metering_topic=metering +#### (StrOpt) the topic ceilometer uses for metering messages + +# control_exchange=ceilometer +#### (StrOpt) AMQP exchange to connect to if using RabbitMQ or Qpid + + +######## defined in ceilometer.api ######## + +# metering_api_port=8777 +#### (IntOpt) The port for the ceilometer API server + + +######## defined in ceilometer.central.manager ######## + +# disabled_central_pollsters= +#### (ListOpt) list of central pollsters to disable + + +######## defined in ceilometer.compute.notifications ######## + +# nova_control_exchange=nova +#### (StrOpt) Exchange name for Nova notifications + + +######## defined in ceilometer.image.notifications ######## + +# glance_control_exchange=glance_notifications +#### (StrOpt) Exchange name for Glance notifications + + +######## defined in ceilometer.network.notifications ######## + +# quantum_control_exchange=quantum +#### (StrOpt) Exchange name for Quantum notifications + + +######## defined in ceilometer.openstack.common.eventlet_backdoor ######## + +# backdoor_port= +#### (IntOpt) port for eventlet backdoor to listen + + +######## defined in ceilometer.openstack.common.log ######## + +# logdir= +#### (StrOpt) Log output to a per-service log file in named directory + +# logfile= +#### (StrOpt) Log output to a named file + +# use_stderr=true +#### (BoolOpt) Log output to standard error + +# logfile_mode=0644 +#### (StrOpt) Default file mode used when creating log files + +# logging_context_format_string=%(asctime)s %(levelname)s %(name)s [%(request_id)s %(user)s %(tenant)s] %(instance)s%(message)s +#### (StrOpt) format string to use for log messages with context + +# logging_default_format_string=%(asctime)s %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s +#### (StrOpt) format string to use for log messages without context + +# logging_debug_format_suffix=%(funcName)s %(pathname)s:%(lineno)d +#### (StrOpt) data to append to log format when level is DEBUG + +# logging_exception_prefix=%(asctime)s %(process)d TRACE %(name)s %(instance)s +#### (StrOpt) prefix each line of exception output with this format + +# default_log_levels=amqplib=WARN,sqlalchemy=WARN,boto=WARN,suds=INFO,keystone=INFO,eventlet.wsgi.server=WARN +#### (ListOpt) list of logger=LEVEL pairs + +# publish_errors=false +#### (BoolOpt) publish error events + +# fatal_deprecations=false +#### (BoolOpt) make deprecations fatal + +# instance_format="[instance: %(uuid)s] " +#### (StrOpt) If an instance is passed with the log message, format it +#### like this + +# instance_uuid_format="[instance: %(uuid)s] " +#### (StrOpt) If an instance UUID is passed with the log message, format +#### it like this + + +######## defined in ceilometer.openstack.common.notifier.api ######## + +#### (MultiStrOpt) Driver or drivers to handle sending notifications + +# default_notification_level=INFO +#### (StrOpt) Default notification level for outgoing notifications + +# default_publisher_id=$host +#### (StrOpt) Default publisher_id for outgoing notifications + + +######## defined in ceilometer.openstack.common.notifier.list_notifier ######## + +# list_notifier_drivers=ceilometer.openstack.common.notifier.no_op_notifier +#### (MultiStrOpt) List of drivers to send notifications + + +######## defined in ceilometer.openstack.common.notifier.rpc_notifier ######## + +# notification_topics=notifications +#### (ListOpt) AMQP topic used for openstack notifications + + +######## defined in ceilometer.openstack.common.rpc ######## + +# rpc_backend=ceilometer.openstack.common.rpc.impl_kombu +#### (StrOpt) The messaging module to use, defaults to kombu. + +# rpc_thread_pool_size=64 +#### (IntOpt) Size of RPC thread pool + +# rpc_conn_pool_size=30 +#### (IntOpt) Size of RPC connection pool + +# rpc_response_timeout=60 +#### (IntOpt) Seconds to wait for a response from call or multicall + +# rpc_cast_timeout=30 +#### (IntOpt) Seconds to wait before a cast expires (TTL). Only supported +#### by impl_zmq. + +# allowed_rpc_exception_modules=ceilometer.openstack.common.exception,nova.exception,cinder.exception +#### (ListOpt) Modules of exceptions that are permitted to be recreatedupon +#### receiving exception data from an rpc call. + +# fake_rabbit=false +#### (BoolOpt) If passed, use a fake RabbitMQ provider + + +######## defined in ceilometer.openstack.common.rpc.impl_kombu ######## + +# kombu_ssl_version= +#### (StrOpt) SSL version to use (valid only if SSL enabled) + +# kombu_ssl_keyfile= +#### (StrOpt) SSL key file (valid only if SSL enabled) + +# kombu_ssl_certfile= +#### (StrOpt) SSL cert file (valid only if SSL enabled) + +# kombu_ssl_ca_certs= +#### (StrOpt) SSL certification authority file (valid only if SSL enabled) + +# rabbit_host=localhost +#### (StrOpt) The RabbitMQ broker address where a single node is used + +# rabbit_port=5672 +#### (IntOpt) The RabbitMQ broker port where a single node is used + +# rabbit_hosts=$rabbit_host:$rabbit_port +#### (ListOpt) RabbitMQ HA cluster host:port pairs + +# rabbit_use_ssl=false +#### (BoolOpt) connect over SSL for RabbitMQ + +# rabbit_userid=guest +#### (StrOpt) the RabbitMQ userid + +# rabbit_password=guest +#### (StrOpt) the RabbitMQ password + +# rabbit_virtual_host=/ +#### (StrOpt) the RabbitMQ virtual host + +# rabbit_retry_interval=1 +#### (IntOpt) how frequently to retry connecting with RabbitMQ + +# rabbit_retry_backoff=2 +#### (IntOpt) how long to backoff for between retries when connecting to +#### RabbitMQ + +# rabbit_max_retries=0 +#### (IntOpt) maximum retries with trying to connect to RabbitMQ (the +#### default of 0 implies an infinite retry count) + +# rabbit_durable_queues=false +#### (BoolOpt) use durable queues in RabbitMQ + +# rabbit_ha_queues=false +#### (BoolOpt) use H/A queues in RabbitMQ (x-ha-policy: all).You need to +#### wipe RabbitMQ database when changing this option. + + +######## defined in ceilometer.openstack.common.rpc.matchmaker ######## + +# matchmaker_ringfile=/etc/nova/matchmaker_ring.json +#### (StrOpt) Matchmaker ring file (JSON) + + +######## defined in ceilometer.storage ######## + +# database_connection=mongodb://localhost:27017/ceilometer +#### (StrOpt) Database connection string + + +######## defined in ceilometer.storage.sqlalchemy.models ######## + +# mysql_engine=InnoDB +#### (StrOpt) MySQL engine + + +######## defined in ceilometer.storage.sqlalchemy.session ######## + +# sql_connection_debug=0 +#### (IntOpt) Verbosity of SQL debugging information. 0=None, +#### 100=Everything + +# sql_connection_trace=false +#### (BoolOpt) Add python stack traces to SQL as comment strings + +# sqlite_synchronous=true +#### (BoolOpt) If passed, use synchronous mode for sqlite + +# sql_idle_timeout=3600 +#### (IntOpt) timeout before idle sql connections are reaped + +# sql_max_retries=10 +#### (IntOpt) maximum db connection retries during startup. (setting -1 +#### implies an infinite retry count) + +# sql_retry_interval=10 +#### (IntOpt) interval between retries of opening a sql connection + + +######## defined in ceilometer.volume.notifications ######## + +# cinder_control_exchange=cinder +#### (StrOpt) Exchange name for Cinder notifications + + +# Total option count: 72 diff --git a/tools/conf/extract_opts.py b/tools/conf/extract_opts.py new file mode 100755 index 000000000..3b2829a96 --- /dev/null +++ b/tools/conf/extract_opts.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 SINA Corporation +# All Rights Reserved. +# Author: Zhongyue Luo +# +# 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. + +"""Extracts OpenStack config option info from module(s).""" + +import os +import re +import socket +import sys +import textwrap + +from ceilometer.openstack.common import cfg +from ceilometer.openstack.common import importutils + + +STROPT = "StrOpt" +BOOLOPT = "BoolOpt" +INTOPT = "IntOpt" +FLOATOPT = "FloatOpt" +LISTOPT = "ListOpt" +MULTISTROPT = "MultiStrOpt" + +OPTION_COUNT = 0 +OPTION_REGEX = re.compile(r"(%s)" % "|".join([STROPT, BOOLOPT, INTOPT, + FLOATOPT, LISTOPT, + MULTISTROPT])) +OPTION_HELP_INDENT = "####" + +PY_EXT = ".py" +BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")) +WORDWRAP_WIDTH = 60 + + +def main(srcfiles): + print '\n'.join(['#' * 20, '# ceilometer.conf sample #', '#' * 20, + '', '[DEFAULT]', '']) + _list_opts(cfg.CommonConfigOpts, + cfg.__name__ + ':' + cfg.CommonConfigOpts.__name__) + mods_by_pkg = dict() + for filepath in srcfiles: + pkg_name = filepath.split(os.sep)[1] + mod_str = '.'.join(['.'.join(filepath.split(os.sep)[:-1]), + os.path.basename(filepath).split('.')[0]]) + mods_by_pkg.setdefault(pkg_name, list()).append(mod_str) + # NOTE(lzyeval): place top level modules before packages + pkg_names = filter(lambda x: x.endswith(PY_EXT), mods_by_pkg.keys()) + pkg_names.sort() + ext_names = filter(lambda x: x not in pkg_names, mods_by_pkg.keys()) + ext_names.sort() + pkg_names.extend(ext_names) + for pkg_name in pkg_names: + mods = mods_by_pkg.get(pkg_name) + mods.sort() + for mod_str in mods: + _print_module(mod_str) + print "# Total option count: %d" % OPTION_COUNT + + +def _print_module(mod_str): + mod_obj = None + if mod_str.endswith('.__init__'): + mod_str = mod_str[:mod_str.rfind(".")] + try: + mod_obj = importutils.import_module(mod_str) + except (ValueError, AttributeError), err: + return + except ImportError, ie: + sys.stderr.write("%s\n" % str(ie)) + return + except Exception, e: + return + _list_opts(mod_obj, mod_str) + + +def _list_opts(obj, name): + opts = list() + for attr_str in dir(obj): + attr_obj = getattr(obj, attr_str) + if isinstance(attr_obj, cfg.Opt): + opts.append(attr_obj) + elif (isinstance(attr_obj, list) and + all(map(lambda x: isinstance(x, cfg.Opt), attr_obj))): + opts.extend(attr_obj) + if not opts: + return + global OPTION_COUNT + OPTION_COUNT += len(opts) + print '######## defined in %s ########\n' % name + for opt in opts: + _print_opt(opt) + print + + +def _get_my_ip(): + try: + csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + csock.connect(('8.8.8.8', 80)) + (addr, port) = csock.getsockname() + csock.close() + return addr + except socket.error: + return None + + +MY_IP = _get_my_ip() +HOST = socket.gethostname() + + +def _sanitize_default(s): + """Set up a reasonably sensible default for pybasedir, my_ip and host.""" + if s.startswith(BASEDIR): + return s.replace(BASEDIR, '/usr/lib/python/site-packages') + elif s == MY_IP: + return '10.0.0.1' + elif s == HOST: + return 'ceilometer' + elif s.strip() != s: + return '"%s"' % s + return s + + +def _wrap(msg, indent): + padding = ' ' * indent + prefix = "\n%s %s " % (OPTION_HELP_INDENT, padding) + return prefix.join(textwrap.wrap(msg, WORDWRAP_WIDTH)) + + +def _print_opt(opt): + opt_name, opt_default, opt_help = opt.dest, opt.default, opt.help + if not opt_help: + sys.stderr.write('WARNING: "%s" is missing help string.\n' % opt_name) + opt_type = None + try: + opt_type = OPTION_REGEX.search(str(type(opt))).group(0) + except (ValueError, AttributeError), err: + sys.stderr.write("%s\n" % str(err)) + sys.exit(1) + try: + if opt_default is None: + print '# %s=' % opt_name + elif opt_type == STROPT: + assert(isinstance(opt_default, basestring)) + print '# %s=%s' % (opt_name, _sanitize_default(opt_default)) + elif opt_type == BOOLOPT: + assert(isinstance(opt_default, bool)) + print '# %s=%s' % (opt_name, str(opt_default).lower()) + elif opt_type == INTOPT: + assert(isinstance(opt_default, int) and + not isinstance(opt_default, bool)) + print '# %s=%s' % (opt_name, opt_default) + elif opt_type == FLOATOPT: + assert(isinstance(opt_default, float)) + print '# %s=%s' % (opt_name, opt_default) + elif opt_type == LISTOPT: + assert(isinstance(opt_default, list)) + print '# %s=%s' % (opt_name, ','.join(opt_default)) + elif opt_type == MULTISTROPT: + assert(isinstance(opt_default, list)) + for default in opt_default: + print '# %s=%s' % (opt_name, default) + except Exception: + sys.stderr.write('Error in option "%s"\n' % opt_name) + sys.exit(1) + opt_type_tag = "(%s)" % opt_type + print OPTION_HELP_INDENT, opt_type_tag, _wrap(opt_help, len(opt_type_tag)) + print + + +if __name__ == '__main__': + if len(sys.argv) < 2: + print "usage: python %s [srcfile]...\n" % sys.argv[0] + sys.exit(0) + main(sys.argv[1:]) diff --git a/tools/conf/generate_sample.sh b/tools/conf/generate_sample.sh new file mode 100755 index 000000000..5379abcad --- /dev/null +++ b/tools/conf/generate_sample.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 SINA Corporation +# All Rights Reserved. +# Author: Zhongyue Luo +# +# 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. + +FILES=$(find ceilometer -type f -name "*.py" ! -path "ceilometer/tests/*" -exec \ + grep -l "Opt(" {} \; | sort -u) + +PYTHONPATH=./:${PYTHONPATH} \ + python $(dirname "$0")/extract_opts.py ${FILES} > \ + etc/ceilometer/ceilometer.conf.sample