From c9298994005dc7a61945bf27c226185b8b989fc6 Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Wed, 18 Dec 2019 19:39:39 +0100 Subject: [PATCH] Retire repository Fuel repositories are all retired in openstack namespace, retire remaining fuel repos in x namespace since they are unused now. This change removes all content from the repository and adds the usual README file to point out that the repository is retired following the process from https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project See also http://lists.openstack.org/pipermail/openstack-discuss/2019-December/011675.html A related change is: https://review.opendev.org/699752 . Change-Id: I8aded54f1b9f3b79f3a4bf8f607d3695b92f528b --- .gitignore | 4 - LICENSE | 201 - README.md | 95 - README.rst | 10 + contrib/README.md | 2 - contrib/ceilometer.toml | 74 - contrib/filter_alarms_tcp_notifier.toml | 24 - contrib/tools/common.sh | 28 - contrib/tools/diagnostic.sh | 41 - .../puppet/manifests/.gitignore | 2 - deployment_scripts/puppet/manifests/Gemfile | 23 - deployment_scripts/puppet/manifests/Rakefile | 14 - .../puppet/manifests/aggregator.pp | 109 - deployment_scripts/puppet/manifests/base.pp | 379 -- deployment_scripts/puppet/manifests/cinder.pp | 69 - .../puppet/manifests/cleanup_apt_config.pp | 26 - .../puppet/manifests/collectd.pp | 368 -- .../puppet/manifests/compute.pp | 58 - .../puppet/manifests/configure_afd_filters.pp | 72 - .../puppet/manifests/configure_apt.pp | 31 - .../puppet/manifests/controller.pp | 329 -- .../puppet/manifests/hiera_override.pp | 253 -- .../puppet/manifests/install_ocf_script.pp | 24 - deployment_scripts/puppet/modules/.gitkeep | 0 .../modules/fuel_lma_collector/.fixtures.yml | 9 - .../modules/fuel_lma_collector/.gitignore | 8 - .../puppet/modules/fuel_lma_collector/Gemfile | 27 - .../puppet/modules/fuel_lma_collector/LICENSE | 202 - .../modules/fuel_lma_collector/README.md | 29 - .../modules/fuel_lma_collector/Rakefile | 28 - .../fuel_lma_collector/files/diagnostics.sh | 467 --- .../parser/functions/get_afd_filters.rb | 170 - .../parser/functions/get_cluster_names.rb | 53 - .../provider/hiera_custom_source/ruby.rb | 61 - .../lib/puppet/type/hiera_custom_source.rb | 25 - .../fuel_lma_collector/manifests/afds.pp | 53 - .../manifests/hiera_data.pp | 54 - .../manifests/mod_status.pp | 64 - .../fuel_lma_collector/manifests/params.pp | 17 - .../fuel_lma_collector/manifests/tools.pp | 28 - .../modules/fuel_lma_collector/metadata.json | 24 - .../classes/fuel_lma_collector_afds_spec.rb | 153 - .../fuel_lma_collector_hiera_data_spec.rb | 69 - .../spec/functions/get_afd_filters_spec.rb | 450 -- .../modules/fuel_lma_collector/spec/spec.opts | 6 - .../fuel_lma_collector/spec/spec_helper.rb | 22 - .../templates/alarming.yaml.erb | 3691 ----------------- .../templates/apache/status.conf.erb | 13 - .../templates/apache/status.load.erb | 1 - .../templates/clusters.yaml.erb | 976 ----- .../templates/metrics.yaml.erb | 21 - .../templates/node_profiles.yaml.erb | 45 - .../puppet/modules/heka/.fixtures.yml | 7 - .../puppet/modules/heka/.gitignore | 4 - .../puppet/modules/heka/Gemfile | 27 - .../puppet/modules/heka/LICENSE | 202 - .../puppet/modules/heka/README.md | 49 - .../puppet/modules/heka/Rakefile | 28 - .../parser/functions/validate_buffering.rb | 71 - .../heka/manifests/decoder/multidecoder.pp | 43 - .../modules/heka/manifests/decoder/sandbox.pp | 34 - .../heka/manifests/decoder/scribbler.pp | 33 - .../modules/heka/manifests/encoder/es_json.pp | 37 - .../modules/heka/manifests/encoder/payload.pp | 32 - .../modules/heka/manifests/encoder/sandbox.pp | 35 - .../modules/heka/manifests/filter/sandbox.pp | 37 - .../puppet/modules/heka/manifests/init.pp | 311 -- .../modules/heka/manifests/input/amqp.pp | 42 - .../heka/manifests/input/httplisten.pp | 32 - .../heka/manifests/input/logstreamer.pp | 39 - .../modules/heka/manifests/input/process.pp | 35 - .../modules/heka/manifests/input/tcp.pp | 38 - .../heka/manifests/output/dashboard.pp | 33 - .../heka/manifests/output/elasticsearch.pp | 43 - .../modules/heka/manifests/output/http.pp | 46 - .../modules/heka/manifests/output/sandbox.pp | 35 - .../modules/heka/manifests/output/tcp.pp | 40 - .../puppet/modules/heka/manifests/params.pp | 45 - .../modules/heka/manifests/splitter/regex.pp | 31 - .../modules/heka/manifests/splitter/token.pp | 31 - .../puppet/modules/heka/metadata.json | 23 - .../spec/defines/heka_decoder_sandbox_spec.rb | 33 - .../spec/defines/heka_encoder_es_json_spec.rb | 32 - .../spec/defines/heka_encoder_sandbox_spec.rb | 33 - .../spec/defines/heka_filter_sandbox_spec.rb | 33 - .../spec/defines/heka_input_logstream_spec.rb | 39 - .../spec/defines/heka_output_http_spec.rb | 38 - .../spec/defines/heka_output_sandbox_spec.rb | 33 - .../modules/heka/spec/defines/heka_spec.rb | 40 - .../spec/functions/validate_buffering_spec.rb | 24 - .../puppet/modules/heka/spec/spec.opts | 6 - .../puppet/modules/heka/spec/spec_helper.rb | 22 - .../templates/decoder/multidecoder.toml.erb | 5 - .../heka/templates/decoder/sandbox.toml.erb | 14 - .../heka/templates/decoder/scribbler.toml.erb | 8 - .../heka/templates/encoder/es_json.toml.erb | 8 - .../heka/templates/encoder/payload.toml.erb | 4 - .../heka/templates/encoder/sandbox.toml.erb | 13 - .../heka/templates/filter/sandbox.toml.erb | 19 - .../modules/heka/templates/global.toml.erb | 18 - .../modules/heka/templates/hekad.initd.erb | 105 - .../heka/templates/hekad.upstart.conf.erb | 21 - .../modules/heka/templates/hekad_wrapper.erb | 9 - .../heka/templates/input/amqp.toml.erb | 13 - .../heka/templates/input/httplisten.toml.erb | 5 - .../heka/templates/input/logstreamer.toml.erb | 12 - .../heka/templates/input/process.toml.erb | 28 - .../modules/heka/templates/input/tcp.toml.erb | 5 - .../modules/heka/templates/logrotate.conf.erb | 22 - .../modules/heka/templates/logrotate.cron.erb | 54 - .../heka/templates/output/dashboard.toml.erb | 3 - .../templates/output/elasticsearch.toml.erb | 21 - .../heka/templates/output/http.toml.erb | 32 - .../heka/templates/output/sandbox.toml.erb | 16 - .../heka/templates/output/smtp.toml.erb | 16 - .../heka/templates/output/tcp.toml.erb | 16 - .../heka/templates/splitter/regex.toml.erb | 6 - .../heka/templates/splitter/token.toml.erb | 3 - .../puppet/modules/heka/tests/init.pp | 26 - .../modules/lma_collector/.fixtures.yml | 17 - .../puppet/modules/lma_collector/.gitignore | 8 - .../puppet/modules/lma_collector/Gemfile | 27 - .../puppet/modules/lma_collector/LICENSE | 202 - .../puppet/modules/lma_collector/README.md | 1122 ----- .../puppet/modules/lma_collector/Rakefile | 130 - .../files/collectd/build_ceph_perf_types.py | 83 - .../files/collectd/ceph_osd_perf.py | 117 - .../files/collectd/ceph_osd_stats.py | 67 - .../files/collectd/ceph_pg_mon_status.py | 97 - .../files/collectd/ceph_pool_osd.py | 136 - .../files/collectd/check_local_endpoint.py | 47 - .../files/collectd/check_openstack_api.py | 129 - .../files/collectd/collectd_apache_check.py | 61 - .../files/collectd/collectd_base.py | 344 -- .../files/collectd/collectd_fake.py | 73 - .../files/collectd/collectd_libvirt_check.py | 60 - .../collectd/collectd_memcached_check.py | 71 - .../files/collectd/collectd_mysql_check.py | 114 - .../files/collectd/collectd_openstack.py | 409 -- .../files/collectd/collectd_pacemaker.py | 308 -- .../files/collectd/elasticsearch_cluster.py | 103 - .../lma_collector/files/collectd/haproxy.py | 318 -- .../files/collectd/http_check.py | 100 - .../files/collectd/hypervisor_stats.py | 158 - .../lma_collector/files/collectd/influxdb.py | 140 - .../files/collectd/openstack_cinder.py | 107 - .../collectd/openstack_cinder_services.py | 94 - .../files/collectd/openstack_glance.py | 102 - .../files/collectd/openstack_keystone.py | 100 - .../files/collectd/openstack_neutron.py | 129 - .../collectd/openstack_neutron_agents.py | 97 - .../files/collectd/openstack_nova.py | 84 - .../files/collectd/openstack_nova_services.py | 99 - .../files/collectd/rabbitmq_info.py | 133 - .../files/collectd/types/ceph.db | 46 - .../files/collectd/types/ceph_perf.db | 74 - .../lma_collector/files/ocf-lma_collector | 337 -- .../files/plugins/common/accumulator.lua | 63 - .../files/plugins/common/afd.lua | 185 - .../files/plugins/common/afd_alarm.lua | 216 - .../files/plugins/common/afd_alarms.lua | 120 - .../files/plugins/common/afd_rule.lua | 324 -- .../files/plugins/common/gse.lua | 164 - .../files/plugins/common/gse_cluster.lua | 154 - .../files/plugins/common/gse_constants.lua | 39 - .../files/plugins/common/gse_policy.lua | 109 - .../files/plugins/common/gse_utils.lua | 58 - .../files/plugins/common/influxdb.lua | 114 - .../files/plugins/common/lma_utils.lua | 313 -- .../files/plugins/common/patterns.lua | 147 - .../files/plugins/common/table_utils.lua | 109 - .../files/plugins/common/value_matching.lua | 171 - .../files/plugins/decoders/ceilometer.lua | 135 - .../files/plugins/decoders/collectd.lua | 452 -- .../files/plugins/decoders/generic_syslog.lua | 50 - .../plugins/decoders/keystone_wsgi_log.lua | 73 - .../files/plugins/decoders/libvirt_log.lua | 63 - .../files/plugins/decoders/metric.lua | 90 - .../files/plugins/decoders/mysql_log.lua | 57 - .../files/plugins/decoders/noop.lua | 28 - .../files/plugins/decoders/notification.lua | 191 - .../files/plugins/decoders/openstack_log.lua | 143 - .../files/plugins/decoders/ovs_log.lua | 62 - .../files/plugins/decoders/pacemaker_log.lua | 75 - .../plugins/decoders/pacemaker_resources.lua | 47 - .../files/plugins/decoders/rabbitmq.lua | 71 - .../encoders/es_ceilometer_resources.lua | 66 - .../files/plugins/encoders/status_nagios.lua | 87 - .../files/plugins/encoders/status_smtp.lua | 79 - .../files/plugins/filters/afd.lua | 99 - .../plugins/filters/gse_afd_tcp_notifier.lua | 117 - .../plugins/filters/gse_cluster_filter.lua | 139 - .../plugins/filters/hdd_errors_counter.lua | 89 - .../files/plugins/filters/heka_monitoring.lua | 85 - .../filters/http_metrics_aggregator.lua | 185 - .../plugins/filters/influxdb_accumulator.lua | 142 - .../plugins/filters/influxdb_annotation.lua | 92 - .../files/plugins/filters/logs_counter.lua | 87 - .../filters/resource_creation_time.lua | 82 - .../files/plugins/filters/watchdog.lua | 24 - .../files/plugins/outputs/lastfile.lua | 27 - .../lib/facter/canonical_timezone.rb | 25 - .../lib/facter/collectd_version.rb | 28 - .../lib/facter/libvirt_daemon.rb | 24 - .../lib/facter/ovs_directory_exists.rb | 19 - .../lib/facter/pacemaker_resources.rb | 34 - .../adapt_collectd_python_plugin_config.rb | 59 - .../parser/functions/sanitize_name_for_lua.rb | 27 - .../lma_collector/manifests/afd/api.pp | 28 - .../lma_collector/manifests/afd_filter.pp | 64 - .../lma_collector/manifests/afd_nagios.pp | 69 - .../manifests/aggregator/client.pp | 38 - .../manifests/aggregator/server.pp | 74 - .../manifests/collectd/apache.pp | 36 - .../lma_collector/manifests/collectd/base.pp | 153 - .../manifests/collectd/ceph_mon.pp | 21 - .../manifests/collectd/ceph_osd.pp | 24 - .../collectd/check_local_endpoint.pp | 47 - .../lma_collector/manifests/collectd/dbi.pp | 31 - .../manifests/collectd/dbi_mysql_status.pp | 42 - .../manifests/collectd/dbi_services.pp | 66 - .../manifests/collectd/elasticsearch.pp | 29 - .../manifests/collectd/haproxy.pp | 42 - .../manifests/collectd/http_check.pp | 56 - .../manifests/collectd/hypervisor.pp | 47 - .../manifests/collectd/influxdb.pp | 30 - .../manifests/collectd/libvirt.pp | 40 - .../manifests/collectd/libvirt_check.pp | 36 - .../manifests/collectd/memcached.pp | 35 - .../lma_collector/manifests/collectd/mysql.pp | 56 - .../manifests/collectd/openstack.pp | 79 - .../manifests/collectd/openstack_checks.pp | 45 - .../manifests/collectd/pacemaker.pp | 54 - .../manifests/collectd/python.pp | 35 - .../manifests/collectd/python_base.pp | 45 - .../collectd/python_openstack_base.pp | 39 - .../manifests/collectd/rabbitmq.pp | 48 - .../lma_collector/manifests/elasticsearch.pp | 50 - .../manifests/gse_cluster_filter.pp | 101 - .../lma_collector/manifests/gse_nagios.pp | 71 - .../lma_collector/manifests/gse_policies.pp | 30 - .../modules/lma_collector/manifests/heka.pp | 140 - .../lma_collector/manifests/influxdb.pp | 87 - .../modules/lma_collector/manifests/init.pp | 106 - .../manifests/logs/aggregated_http_metrics.pp | 45 - .../lma_collector/manifests/logs/counter.pp | 41 - .../manifests/logs/hdd_errors_counter.pp | 39 - .../manifests/logs/http_metrics.pp | 31 - .../manifests/logs/keystone_wsgi.pp | 46 - .../lma_collector/manifests/logs/libvirt.pp | 64 - .../lma_collector/manifests/logs/mysql.pp | 42 - .../lma_collector/manifests/logs/openstack.pp | 47 - .../logs/openstack_decoder_splitter.pp | 43 - .../lma_collector/manifests/logs/ovs.pp | 40 - .../lma_collector/manifests/logs/pacemaker.pp | 44 - .../lma_collector/manifests/logs/rabbitmq.pp | 50 - .../lma_collector/manifests/logs/swift.pp | 80 - .../lma_collector/manifests/logs/system.pp | 43 - .../manifests/notifications/input.pp | 80 - .../manifests/notifications/metrics.pp | 31 - .../modules/lma_collector/manifests/params.pp | 184 - .../lma_collector/manifests/service/log.pp | 33 - .../lma_collector/manifests/service/metric.pp | 33 - .../modules/lma_collector/metadata.json | 27 - .../classes/lma_collector_afd_api_spec.rb | 25 - .../lma_collector_aggregator_client_spec.rb | 32 - .../lma_collector_aggregator_server_spec.rb | 38 - .../lma_collector_collectd_apache_spec.rb | 35 - .../lma_collector_collectd_base_spec.rb | 37 - .../lma_collector_collectd_ceph_mon_spec.rb | 30 - .../lma_collector_collectd_ceph_osd_spec.rb | 26 - .../lma_collector_collectd_dbi_spec.rb | 35 - .../lma_collector_collectd_haproxy_spec.rb | 41 - .../lma_collector_collectd_http_check_spec.rb | 94 - .../lma_collector_collectd_hypervisor_spec.rb | 48 - .../classes/lma_collector_collectd_libvirt.rb | 25 - ...a_collector_collectd_libvirt_check_spec.rb | 26 - .../lma_collector_collectd_memcached_spec.rb | 34 - .../lma_collector_collectd_mysql_spec.rb | 56 - ...ollector_collectd_openstack_checks_spec.rb | 45 - .../lma_collector_collectd_pacemaker_spec.rb | 45 - ...lma_collector_collectd_python_base_spec.rb | 35 - ...tor_collectd_python_openstack_base_spec.rb | 31 - .../lma_collector_collectd_rabbitmq_spec.rb | 41 - .../lma_collector_elasticsearch_spec.rb | 41 - .../lma_collector_gse_policies_spec.rb | 66 - .../classes/lma_collector_influxdb_spec.rb | 56 - .../lma_collector_logs_counter_spec.rb | 28 - ...or_logs_openstack_decoder_splitter_spec.rb | 29 - .../classes/lma_collector_logs_swift_spec.rb | 43 - .../classes/lma_collector_logs_system_spec.rb | 26 - .../lma_collector_notifications_input_spec.rb | 32 - .../classes/lma_collector_service_spec.rb | 39 - .../spec/classes/lma_collector_spec.rb | 25 - .../defines/lma_collector_afd_nagios_spec.rb | 34 - ...ollector_collectd_dbi_mysql_status_spec.rb | 26 - ...ma_collector_collectd_dbi_services_spec.rb | 27 - .../lma_collector_collectd_openstack_spec.rb | 48 - .../lma_collector_collectd_python_spec.rb | 43 - .../lma_collector_gse_cluster_filter_spec.rb | 62 - .../defines/lma_collector_gse_nagios_spec.rb | 34 - .../spec/defines/lma_collector_heka_spec.rb | 78 - .../lma_collector_logs_openstack_spec.rb | 41 - .../functions/sanitize_name_for_lua_spec.rb | 9 - .../modules/lma_collector/spec/spec.opts | 6 - .../modules/lma_collector/spec/spec_helper.rb | 22 - .../collectd_dbi_mysql_status.conf.erb | 40 - .../templates/collectd_dbi_services.conf.erb | 90 - .../templates/collectd_python.conf.erb | 30 - .../templates/extra_fields.lua.erb | 24 - .../templates/gse_policies.lua.erb | 51 - .../templates/gse_topology.lua.erb | 28 - .../lma_collector/templates/hooks_daemon.erb | 3 - .../templates/lma_alarms.lua.erb | 48 - .../modules/lma_collector/tests/init.pp | 26 - .../tests/lua/mocks/extra_fields.lua | 23 - .../tests/lua/test_accumulator.lua | 68 - .../lma_collector/tests/lua/test_afd.lua | 155 - .../tests/lua/test_afd_alarm.lua | 1080 ----- .../lma_collector/tests/lua/test_gse.lua | 248 -- .../tests/lua/test_gse_cluster_policy.lua | 201 - .../tests/lua/test_gse_utils.lua | 36 - .../lma_collector/tests/lua/test_influxdb.lua | 52 - .../tests/lua/test_lma_utils.lua | 102 - .../lma_collector/tests/lua/test_patterns.lua | 122 - .../tests/lua/test_table_utils.lua | 86 - .../tests/lua/test_value_matching.lua | 229 - deployment_tasks.yaml | 167 - doc/.gitignore | 2 - doc/dev/Makefile | 191 - doc/dev/source/_static/.gitkeep | 0 doc/dev/source/common_message_format.rst | 53 - doc/dev/source/conf.py | 33 - doc/dev/source/index.rst | 20 - doc/dev/source/install_without_fuel.rst | 109 - doc/dev/source/logs.rst | 83 - doc/dev/source/metrics.rst | 79 - doc/dev/source/notifications.rst | 88 - doc/dev/source/outputs.rst | 82 - doc/dev/source/overview.rst | 68 - doc/dev/source/tests.rst | 15 - doc/images/AFD_and_GSE_message_flow.svg | 1056 ----- doc/images/collector_settings.png | Bin 113862 -> 0 bytes doc/images/toolchain_map.png | Bin 1105154 -> 0 bytes doc/qa/Makefile | 177 - doc/qa/source/_static/.gitkeep | 0 doc/qa/source/appendix.rst | 13 - doc/qa/source/conf.py | 39 - doc/qa/source/index.rst | 18 - doc/qa/source/strategy.rst | 56 - doc/qa/source/testing.rst | 203 - doc/qa/source/tests/deploy.rst | 87 - doc/qa/source/tests/deploy_ha_mode.rst | 89 - .../display_dashboards_in_grafana_ui.rst | 59 - .../display_nova_metrics_in_grafana_ui.rst | 27 - doc/qa/source/tests/install.rst | 29 - .../network_failure_on_analytics_node.rst | 33 - ...uery_cinder_notifications_in_kibana_ui.rst | 27 - ...uery_glance_notifications_in_kibana_ui.rst | 26 - .../query_heat_notifications_in_kibana_ui.rst | 26 - ...ry_keystone_notifications_in_kibana_ui.rst | 26 - .../source/tests/query_logs_in_kibana_ui.rst | 24 - ...ery_neutron_notifications_in_kibana_ui.rst | 27 - .../query_nova_notifications_in_kibana_ui.rst | 28 - ...ort_node_alerts_with_critical_severity.rst | 83 - ...port_node_alerts_with_warning_severity.rst | 83 - ..._service_alerts_with_critical_severity.rst | 109 - ...t_service_alerts_with_warning_severity.rst | 105 - doc/qa/source/tests/scale_compute.rst | 43 - doc/qa/source/tests/scale_controller.rst | 43 - doc/qa/source/tests/scale_elasticsearch.rst | 48 - doc/qa/source/tests/scale_influx.rst | 50 - .../tests/scale_infrastructure_alerting.rst | 42 - .../tests/shutdown_elasticsearch_node.rst | 49 - doc/qa/source/tests/shutdown_influx_node.rst | 35 - .../shutdown_infrastructure_alerting_node.rst | 35 - doc/qa/source/tests/uninstall_plugins.rst | 18 - .../tests/uninstall_plugins_with_env.rst | 25 - doc/user/Makefile | 191 - doc/user/source/_static/.gitkeep | 0 doc/user/source/appendix_alarms.rst | 2987 ------------- doc/user/source/appendix_metrics.rst | 86 - doc/user/source/conf.py | 265 -- doc/user/source/configure_alarms.rst | 1113 ----- doc/user/source/configure_plugin.rst | 301 -- doc/user/source/index.rst | 50 - doc/user/source/install.rst | 112 - doc/user/source/intro.rst | 80 - doc/user/source/licenses.rst | 84 - doc/user/source/limitations.rst | 14 - doc/user/source/metrics/apache.rst | 17 - doc/user/source/metrics/ceph.rst | 128 - doc/user/source/metrics/checks.rst | 16 - doc/user/source/metrics/clusters.rst | 25 - doc/user/source/metrics/elasticsearch.rst | 19 - doc/user/source/metrics/haproxy.rst | 96 - doc/user/source/metrics/influxdb.rst | 62 - doc/user/source/metrics/libvirt.rst | 64 - doc/user/source/metrics/lma.rst | 69 - doc/user/source/metrics/memcached.rst | 31 - doc/user/source/metrics/mysql.rst | 108 - doc/user/source/metrics/openstack.rst | 247 -- doc/user/source/metrics/pacemaker.rst | 67 - doc/user/source/metrics/rabbitmq.rst | 25 - doc/user/source/metrics/system.rst | 142 - doc/user/source/prerequisites.rst | 29 - doc/user/source/references.rst | 18 - doc/user/source/release_notes.rst | 166 - doc/user/source/requirements.rst | 22 - environment_config.yaml | 89 - functions.sh | 53 - metadata.yaml | 37 - pre_build_hook | 62 - repositories/centos/.gitignore | 1 - repositories/centos/.gitkeep | 0 repositories/ubuntu/.gitignore | 1 - repositories/ubuntu/.gitkeep | 0 specs/lma-collector-plugin-spec.rst | 191 - tasks.yaml | 1 - test-requirements.txt | 4 - tox.ini | 90 - uninstall.sh | 2 - 422 files changed, 10 insertions(+), 40938 deletions(-) delete mode 100644 .gitignore delete mode 100644 LICENSE delete mode 100644 README.md create mode 100644 README.rst delete mode 100644 contrib/README.md delete mode 100644 contrib/ceilometer.toml delete mode 100644 contrib/filter_alarms_tcp_notifier.toml delete mode 100644 contrib/tools/common.sh delete mode 100644 contrib/tools/diagnostic.sh delete mode 100644 deployment_scripts/puppet/manifests/.gitignore delete mode 100644 deployment_scripts/puppet/manifests/Gemfile delete mode 100644 deployment_scripts/puppet/manifests/Rakefile delete mode 100644 deployment_scripts/puppet/manifests/aggregator.pp delete mode 100644 deployment_scripts/puppet/manifests/base.pp delete mode 100644 deployment_scripts/puppet/manifests/cinder.pp delete mode 100644 deployment_scripts/puppet/manifests/cleanup_apt_config.pp delete mode 100644 deployment_scripts/puppet/manifests/collectd.pp delete mode 100644 deployment_scripts/puppet/manifests/compute.pp delete mode 100644 deployment_scripts/puppet/manifests/configure_afd_filters.pp delete mode 100644 deployment_scripts/puppet/manifests/configure_apt.pp delete mode 100644 deployment_scripts/puppet/manifests/controller.pp delete mode 100644 deployment_scripts/puppet/manifests/hiera_override.pp delete mode 100644 deployment_scripts/puppet/manifests/install_ocf_script.pp delete mode 100644 deployment_scripts/puppet/modules/.gitkeep delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/.fixtures.yml delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/.gitignore delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/Gemfile delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/LICENSE delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/README.md delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/Rakefile delete mode 100755 deployment_scripts/puppet/modules/fuel_lma_collector/files/diagnostics.sh delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/parser/functions/get_afd_filters.rb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/parser/functions/get_cluster_names.rb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/provider/hiera_custom_source/ruby.rb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/type/hiera_custom_source.rb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/manifests/afds.pp delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/manifests/hiera_data.pp delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/manifests/mod_status.pp delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/manifests/params.pp delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/manifests/tools.pp delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/metadata.json delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/spec/classes/fuel_lma_collector_afds_spec.rb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/spec/defines/fuel_lma_collector_hiera_data_spec.rb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/spec/functions/get_afd_filters_spec.rb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/spec/spec.opts delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/spec/spec_helper.rb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/templates/alarming.yaml.erb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/templates/apache/status.conf.erb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/templates/apache/status.load.erb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/templates/clusters.yaml.erb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/templates/metrics.yaml.erb delete mode 100644 deployment_scripts/puppet/modules/fuel_lma_collector/templates/node_profiles.yaml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/.fixtures.yml delete mode 100644 deployment_scripts/puppet/modules/heka/.gitignore delete mode 100644 deployment_scripts/puppet/modules/heka/Gemfile delete mode 100644 deployment_scripts/puppet/modules/heka/LICENSE delete mode 100644 deployment_scripts/puppet/modules/heka/README.md delete mode 100644 deployment_scripts/puppet/modules/heka/Rakefile delete mode 100644 deployment_scripts/puppet/modules/heka/lib/puppet/parser/functions/validate_buffering.rb delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/decoder/multidecoder.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/decoder/sandbox.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/decoder/scribbler.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/encoder/es_json.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/encoder/payload.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/encoder/sandbox.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/filter/sandbox.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/init.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/input/amqp.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/input/httplisten.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/input/logstreamer.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/input/process.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/input/tcp.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/output/dashboard.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/output/elasticsearch.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/output/http.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/output/sandbox.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/output/tcp.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/params.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/splitter/regex.pp delete mode 100644 deployment_scripts/puppet/modules/heka/manifests/splitter/token.pp delete mode 100644 deployment_scripts/puppet/modules/heka/metadata.json delete mode 100644 deployment_scripts/puppet/modules/heka/spec/defines/heka_decoder_sandbox_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/defines/heka_encoder_es_json_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/defines/heka_encoder_sandbox_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/defines/heka_filter_sandbox_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/defines/heka_input_logstream_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/defines/heka_output_http_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/defines/heka_output_sandbox_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/defines/heka_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/functions/validate_buffering_spec.rb delete mode 100644 deployment_scripts/puppet/modules/heka/spec/spec.opts delete mode 100644 deployment_scripts/puppet/modules/heka/spec/spec_helper.rb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/decoder/multidecoder.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/decoder/sandbox.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/decoder/scribbler.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/encoder/es_json.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/encoder/payload.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/encoder/sandbox.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/filter/sandbox.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/global.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/hekad.initd.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/hekad.upstart.conf.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/hekad_wrapper.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/input/amqp.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/input/httplisten.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/input/logstreamer.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/input/process.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/input/tcp.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/logrotate.conf.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/logrotate.cron.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/output/dashboard.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/output/elasticsearch.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/output/http.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/output/sandbox.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/output/smtp.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/output/tcp.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/splitter/regex.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/templates/splitter/token.toml.erb delete mode 100644 deployment_scripts/puppet/modules/heka/tests/init.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/.fixtures.yml delete mode 100644 deployment_scripts/puppet/modules/lma_collector/.gitignore delete mode 100644 deployment_scripts/puppet/modules/lma_collector/Gemfile delete mode 100644 deployment_scripts/puppet/modules/lma_collector/LICENSE delete mode 100644 deployment_scripts/puppet/modules/lma_collector/README.md delete mode 100644 deployment_scripts/puppet/modules/lma_collector/Rakefile delete mode 100755 deployment_scripts/puppet/modules/lma_collector/files/collectd/build_ceph_perf_types.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_osd_perf.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_osd_stats.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_pg_mon_status.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_pool_osd.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/check_local_endpoint.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/check_openstack_api.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_apache_check.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_base.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_fake.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_libvirt_check.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_memcached_check.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_mysql_check.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_openstack.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_pacemaker.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/elasticsearch_cluster.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/haproxy.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/http_check.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/hypervisor_stats.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/influxdb.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_cinder.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_cinder_services.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_glance.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_keystone.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron_agents.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_nova.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_nova_services.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/rabbitmq_info.py delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/types/ceph.db delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/collectd/types/ceph_perf.db delete mode 100755 deployment_scripts/puppet/modules/lma_collector/files/ocf-lma_collector delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/accumulator.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_alarm.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_alarms.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_rule.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_cluster.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_constants.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_policy.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_utils.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/influxdb.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/lma_utils.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/patterns.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/table_utils.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/common/value_matching.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/ceilometer.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/collectd.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/generic_syslog.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/keystone_wsgi_log.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/libvirt_log.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/metric.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/mysql_log.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/noop.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/notification.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/openstack_log.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/ovs_log.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/pacemaker_log.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/pacemaker_resources.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/rabbitmq.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/es_ceilometer_resources.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/status_nagios.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/status_smtp.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/afd.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/gse_afd_tcp_notifier.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/gse_cluster_filter.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/hdd_errors_counter.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/heka_monitoring.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/http_metrics_aggregator.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/influxdb_accumulator.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/influxdb_annotation.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/logs_counter.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/resource_creation_time.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/watchdog.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/files/plugins/outputs/lastfile.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/lib/facter/canonical_timezone.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/lib/facter/collectd_version.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/lib/facter/libvirt_daemon.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/lib/facter/ovs_directory_exists.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/lib/facter/pacemaker_resources.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/lib/puppet/parser/functions/adapt_collectd_python_plugin_config.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/lib/puppet/parser/functions/sanitize_name_for_lua.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/afd/api.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/afd_filter.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/afd_nagios.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/aggregator/client.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/aggregator/server.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/apache.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/base.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/ceph_mon.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/ceph_osd.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/check_local_endpoint.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi_mysql_status.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi_services.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/elasticsearch.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/haproxy.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/http_check.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/hypervisor.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/influxdb.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/libvirt.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/libvirt_check.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/memcached.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/mysql.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/openstack.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/openstack_checks.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/pacemaker.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python_base.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python_openstack_base.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/collectd/rabbitmq.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/elasticsearch.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/gse_cluster_filter.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/gse_nagios.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/gse_policies.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/heka.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/influxdb.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/init.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/aggregated_http_metrics.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/counter.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/hdd_errors_counter.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/http_metrics.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/keystone_wsgi.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/libvirt.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/mysql.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/openstack.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/openstack_decoder_splitter.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/ovs.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/pacemaker.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/rabbitmq.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/swift.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/logs/system.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/notifications/input.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/notifications/metrics.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/params.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/service/log.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/manifests/service/metric.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/metadata.json delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_afd_api_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_aggregator_client_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_aggregator_server_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_apache_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_base_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_ceph_mon_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_ceph_osd_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_dbi_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_haproxy_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_http_check_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_hypervisor_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_libvirt.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_libvirt_check_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_memcached_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_mysql_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_openstack_checks_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_pacemaker_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_python_base_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_python_openstack_base_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_rabbitmq_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_elasticsearch_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_gse_policies_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_influxdb_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_counter_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_openstack_decoder_splitter_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_swift_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_system_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_notifications_input_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_service_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_afd_nagios_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_dbi_mysql_status_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_dbi_services_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_openstack_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_python_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_gse_cluster_filter_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_gse_nagios_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_heka_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_logs_openstack_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/functions/sanitize_name_for_lua_spec.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/spec.opts delete mode 100644 deployment_scripts/puppet/modules/lma_collector/spec/spec_helper.rb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/templates/collectd_dbi_mysql_status.conf.erb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/templates/collectd_dbi_services.conf.erb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/templates/collectd_python.conf.erb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/templates/extra_fields.lua.erb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/templates/gse_policies.lua.erb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/templates/gse_topology.lua.erb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/templates/hooks_daemon.erb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/templates/lma_alarms.lua.erb delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/init.pp delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/mocks/extra_fields.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_accumulator.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_afd.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_afd_alarm.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse_cluster_policy.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse_utils.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_influxdb.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_lma_utils.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_patterns.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_table_utils.lua delete mode 100644 deployment_scripts/puppet/modules/lma_collector/tests/lua/test_value_matching.lua delete mode 100644 deployment_tasks.yaml delete mode 100644 doc/.gitignore delete mode 100644 doc/dev/Makefile delete mode 100644 doc/dev/source/_static/.gitkeep delete mode 100644 doc/dev/source/common_message_format.rst delete mode 100644 doc/dev/source/conf.py delete mode 100644 doc/dev/source/index.rst delete mode 100644 doc/dev/source/install_without_fuel.rst delete mode 100644 doc/dev/source/logs.rst delete mode 100644 doc/dev/source/metrics.rst delete mode 100644 doc/dev/source/notifications.rst delete mode 100644 doc/dev/source/outputs.rst delete mode 100644 doc/dev/source/overview.rst delete mode 100644 doc/dev/source/tests.rst delete mode 100755 doc/images/AFD_and_GSE_message_flow.svg delete mode 100644 doc/images/collector_settings.png delete mode 100644 doc/images/toolchain_map.png delete mode 100644 doc/qa/Makefile delete mode 100644 doc/qa/source/_static/.gitkeep delete mode 100644 doc/qa/source/appendix.rst delete mode 100644 doc/qa/source/conf.py delete mode 100644 doc/qa/source/index.rst delete mode 100644 doc/qa/source/strategy.rst delete mode 100644 doc/qa/source/testing.rst delete mode 100644 doc/qa/source/tests/deploy.rst delete mode 100644 doc/qa/source/tests/deploy_ha_mode.rst delete mode 100644 doc/qa/source/tests/display_dashboards_in_grafana_ui.rst delete mode 100644 doc/qa/source/tests/display_nova_metrics_in_grafana_ui.rst delete mode 100644 doc/qa/source/tests/install.rst delete mode 100644 doc/qa/source/tests/network_failure_on_analytics_node.rst delete mode 100644 doc/qa/source/tests/query_cinder_notifications_in_kibana_ui.rst delete mode 100644 doc/qa/source/tests/query_glance_notifications_in_kibana_ui.rst delete mode 100644 doc/qa/source/tests/query_heat_notifications_in_kibana_ui.rst delete mode 100644 doc/qa/source/tests/query_keystone_notifications_in_kibana_ui.rst delete mode 100644 doc/qa/source/tests/query_logs_in_kibana_ui.rst delete mode 100644 doc/qa/source/tests/query_neutron_notifications_in_kibana_ui.rst delete mode 100644 doc/qa/source/tests/query_nova_notifications_in_kibana_ui.rst delete mode 100644 doc/qa/source/tests/report_node_alerts_with_critical_severity.rst delete mode 100644 doc/qa/source/tests/report_node_alerts_with_warning_severity.rst delete mode 100644 doc/qa/source/tests/report_service_alerts_with_critical_severity.rst delete mode 100644 doc/qa/source/tests/report_service_alerts_with_warning_severity.rst delete mode 100644 doc/qa/source/tests/scale_compute.rst delete mode 100644 doc/qa/source/tests/scale_controller.rst delete mode 100644 doc/qa/source/tests/scale_elasticsearch.rst delete mode 100644 doc/qa/source/tests/scale_influx.rst delete mode 100644 doc/qa/source/tests/scale_infrastructure_alerting.rst delete mode 100644 doc/qa/source/tests/shutdown_elasticsearch_node.rst delete mode 100644 doc/qa/source/tests/shutdown_influx_node.rst delete mode 100644 doc/qa/source/tests/shutdown_infrastructure_alerting_node.rst delete mode 100644 doc/qa/source/tests/uninstall_plugins.rst delete mode 100644 doc/qa/source/tests/uninstall_plugins_with_env.rst delete mode 100644 doc/user/Makefile delete mode 100644 doc/user/source/_static/.gitkeep delete mode 100644 doc/user/source/appendix_alarms.rst delete mode 100644 doc/user/source/appendix_metrics.rst delete mode 100644 doc/user/source/conf.py delete mode 100644 doc/user/source/configure_alarms.rst delete mode 100644 doc/user/source/configure_plugin.rst delete mode 100644 doc/user/source/index.rst delete mode 100644 doc/user/source/install.rst delete mode 100644 doc/user/source/intro.rst delete mode 100644 doc/user/source/licenses.rst delete mode 100644 doc/user/source/limitations.rst delete mode 100644 doc/user/source/metrics/apache.rst delete mode 100644 doc/user/source/metrics/ceph.rst delete mode 100644 doc/user/source/metrics/checks.rst delete mode 100644 doc/user/source/metrics/clusters.rst delete mode 100644 doc/user/source/metrics/elasticsearch.rst delete mode 100644 doc/user/source/metrics/haproxy.rst delete mode 100644 doc/user/source/metrics/influxdb.rst delete mode 100644 doc/user/source/metrics/libvirt.rst delete mode 100644 doc/user/source/metrics/lma.rst delete mode 100644 doc/user/source/metrics/memcached.rst delete mode 100644 doc/user/source/metrics/mysql.rst delete mode 100644 doc/user/source/metrics/openstack.rst delete mode 100644 doc/user/source/metrics/pacemaker.rst delete mode 100644 doc/user/source/metrics/rabbitmq.rst delete mode 100644 doc/user/source/metrics/system.rst delete mode 100644 doc/user/source/prerequisites.rst delete mode 100644 doc/user/source/references.rst delete mode 100644 doc/user/source/release_notes.rst delete mode 100644 doc/user/source/requirements.rst delete mode 100644 environment_config.yaml delete mode 100644 functions.sh delete mode 100644 metadata.yaml delete mode 100755 pre_build_hook delete mode 100644 repositories/centos/.gitignore delete mode 100644 repositories/centos/.gitkeep delete mode 100644 repositories/ubuntu/.gitignore delete mode 100644 repositories/ubuntu/.gitkeep delete mode 100644 specs/lma-collector-plugin-spec.rst delete mode 100644 tasks.yaml delete mode 100644 test-requirements.txt delete mode 100644 tox.ini delete mode 100755 uninstall.sh diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8e2bf9da4..000000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.bundled_gems/ -.build/ -lma_collector*rpm -.tox \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index b09cd7856..000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/README.md b/README.md deleted file mode 100644 index a25ed1a94..000000000 --- a/README.md +++ /dev/null @@ -1,95 +0,0 @@ -The StackLight Collector Plugin for Fuel -======================================== - -The StackLight Collector Plugin is used to install and -configure several software components that are used to -collect and process all the data that we think is relevant -to provide deep operational insights about your OpenStack environment. -These finely integrated components are collectively referred to as -the StackLight Collector (or just the Collector). - -The Collecor is a key component of the so-called Logging, -Monitoring and Alerting (LMA) toolchain of Mirantis OpenStack. - -Please start with the [StackLight Collector Plugin Overview]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/overview.html) -to getting started. - -Release Notes -------------- - -A summary description of the features are provided in the [Release Notes]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/releases.html) -section of the plugin's documentation. - -Requirements ------------- - -The requirements are provided in the [Requirements]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/overview.html#requirements) -section of the plugin's documentation. - -Known issues ------------- - -All known issues are listed on [Launchpad]( -https://bugs.launchpad.net/lma-toolchain). - -Limitations ------------ - -All known limitations are described in the [Limitations]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/overview.html#limitations) -section of the plugin's documentation. - -Installation ------------- - -The installation instructions of the StackLight Collector are provided -in the [Installation]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/installation.html#installation) -section of the plugin's documentation. - -User Guide ----------- - -Instructions for how to configure the StackLight Collector -are provided in the [Configuration Guide]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/configuration.html) -and [Alarms Configuration Guide]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/alarms.html) -sections of the plugin's documentation. - -Communication -------------- - -The *OpenStack Development Mailing List* is the preferred way to communicate -with the members of the project. -Emails should be sent to `openstack-dev@lists.openstack.org` with the subject -prefixed by `[fuel][plugins][lma]`. - -Reporting Bugs --------------- - -Bugs should be filed against the [LMA toolchain project]( -https://launchpad.net/lma-toolchain) on Launchpad (not Github!). - -Contributing ------------- - -If you would like to contribute to the development of this plugin, -you must follow the [OpenStack development workflow]( -http://docs.openstack.org/infra/manual/developers.html#development-workflow) -instructions. - -Patch reviews take place on the [OpenStack Gerrit]( -https://review.openstack.org/#/q/status:open+project:openstack/fuel-plugin-lma-collector,n,z) -system. - -Contributors ------------- - -* Guillaume Thouvenin -* Patrick Petit -* Simon Pasquier -* Swann Croiset diff --git a/README.rst b/README.rst new file mode 100644 index 000000000..86e34d67c --- /dev/null +++ b/README.rst @@ -0,0 +1,10 @@ +This project is no longer maintained. + +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". + +For any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/contrib/README.md b/contrib/README.md deleted file mode 100644 index 97a1cb0e3..000000000 --- a/contrib/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This directory contains various scripts and tools that help with the deployment -and management of the StackLight toolchain. These materials are provided as-is. diff --git a/contrib/ceilometer.toml b/contrib/ceilometer.toml deleted file mode 100644 index 159f3b288..000000000 --- a/contrib/ceilometer.toml +++ /dev/null @@ -1,74 +0,0 @@ -[openstack_sample_amqp] -type = "AMQPInput" -url = "amqp://:@:5673/" -exchange = "ceilometer" -exchange_type = "topic" -exchange_durability = false -exchange_auto_delete = false -queue_auto_delete = false -queue = "metering.sample" -routing_key = "metering.sample" -decoder = "sample_decoder" -splitter = "NullSplitter" -can_exit = false - -[sample_decoder] -type = "SandboxDecoder" -filename = "/usr/share/lma_collector/decoders/metering.lua" -module_directory = "/usr/share/lma_collector_modules;/usr/share/heka/lua_modules" - -[sample_decoder.config] - - #decode_resources = "TRUE" - metadata_fields = 'status deleted container_format min_ram updated_at min_disk is_public size checksum created_at disk_format protected instance_host host display_name instance_id instance_type status state' - -[ceilometer_influxdb_accumulator_filter] -type = "SandboxFilter" -filename = "/usr/share/lma_collector/filters/influxdb_accumulator.lua" -preserve_data = false -message_matcher = "Fields[aggregator] == NIL && Type =~ /ceilometer_samples$/" -ticker_interval = 1 -module_directory = "/usr/share/lma_collector_modules;/usr/share/heka/lua_modules" - -[ceilometer_influxdb_accumulator_filter.config] - tag_fields = 'deployment_id environment_label hostname tenant_id user_id' - time_precision = 'ms' - payload_name = 'sample_data' - bulk_metric_type_matcher = 'ceilometer_samples$' - flush_count = 10 - -[influxdb_encoder] -type = "PayloadEncoder" -append_newlines = false -prefix_ts = false - -[samples_influxdb_output] -type = "HttpOutput" -message_matcher = "Fields[payload_type] == 'txt' && Fields[payload_name] == 'sample_data'" -encoder = "influxdb_encoder" -address = "http://10.109.41.14:8086/write?db=ceilometer&precision=ms" -username = "ceilo" -password = "" -http_timeout = 5000 -method = "POST" - -[samples_influxdb_output.headers] - Content-Type = ["application/x-www-form-urlencoded"] - -[elasticsearch_resource_output] -type = "ElasticSearchOutput" -message_matcher = "Type == 'resource'" -encoder = "elasticsearch_resource_encoder" -flush_interval = 5000 -flush_count = 10 -server = "http://:9200" - -[elasticsearch_resource_encoder] -type = "SandboxEncoder" -filename = "/usr/share/lma_collector/encoders/es_bulk.lua" -module_directory = "/usr/share/lma_collector_modules;/usr/share/heka/lua_modules" - - [elasticsearch_resource_encoder.config] - index = "ceilometer_resource" - type_name = "source" - diff --git a/contrib/filter_alarms_tcp_notifier.toml b/contrib/filter_alarms_tcp_notifier.toml deleted file mode 100644 index b0ec391fa..000000000 --- a/contrib/filter_alarms_tcp_notifier.toml +++ /dev/null @@ -1,24 +0,0 @@ -[gse_afd_notification_filter] -type = "SandboxFilter" -filename = "/usr/share/lma_collector/filters/gse_afd_tcp_notifier.lua" -message_matcher="(Type =~ /heka.sandbox.gse_.*metric$/ || Type =~ /heka.sandbox.afd_.*metric$/) && Fields[aggregator] == NIL" -module_directory = "/usr/share/lma_collector_modules;/usr/share/heka/lua_modules" - -[gse_afd_notification_filter.config] - not_ok_mode = false - debug_mode = false - -[rst_encoder] -type = "RstEncoder" - -[tcp_notifier_output] -type = "TcpOutput" -message_matcher = "Type == 'heka.sandbox.gse_afd_notification'" -encoder = "rst_encoder" -address = "127.0.0.1:40000" -use_buffering = true - -[tcp_notifier_output.buffering] - full_action = "drop" - max_buffer_size = 268435456 - max_file_size = 67108864 \ No newline at end of file diff --git a/contrib/tools/common.sh b/contrib/tools/common.sh deleted file mode 100644 index 3db8f562b..000000000 --- a/contrib/tools/common.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# Copyright 2016 Mirantis, Inc. -# -# 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. - -function check_fuel_nodes_file { - if [ ! -f "$1" ]; then - echo "You must first run the following command on the Fuel master node:" - echo " fuel nodes > $1" - exit 1 - fi -} - -# Get IPs list of online nodes from 'fuel command' output. -function get_ready_nodes { - # "fuel nodes" command output differs form Fuel 8 and 9 for online nodes: True/False and 0/1 - fuel nodes | grep ready | awk -F '|' -vOFS=':' '{print $5,$9 }'|tr -d ' '|grep -E ':1|:True'|awk -F ':' '{print $1}' -} diff --git a/contrib/tools/diagnostic.sh b/contrib/tools/diagnostic.sh deleted file mode 100644 index 343c28e78..000000000 --- a/contrib/tools/diagnostic.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -# Copyright 2016 Mirantis, Inc. -# -# 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. - -set -e - -DIAG_DIR=/var/lma_diagnostics - -. "$(dirname "$(readlink -f "$0")")"/common.sh - -node_list=$(get_ready_nodes) - -rm -rf "$DIAG_DIR" -mkdir $DIAG_DIR - -echo "Running lma_diagnostic tool on all nodes which are ready and online (this can take several minutes)" -mco rpc --timeout 300 --verbose --display all --agent execute_shell_command --action execute --argument cmd="/usr/local/bin/lma_diagnostics" > "$DIAG_DIR/outputs.log" 2>&1 - -for n in $node_list; do - echo "Downloading diagnostic for node $n" - rsync -arz "$n:$DIAG_DIR" "$DIAG_DIR/$n/" || echo "Fail to retrieve diagnostic from $n" -done - -fuel plugins > "$DIAG_DIR/fuel_plugins" - -CURRENT_DATE=$(date +%Y-%m-%d_%H-%M-%s) -tar czvf "${DIAG_DIR}.${CURRENT_DATE}.tgz" -C "$DIAG_DIR" . >/dev/null -echo "The diagnostic archive is here: ${DIAG_DIR}.${CURRENT_DATE}.tgz" - -exit 0 diff --git a/deployment_scripts/puppet/manifests/.gitignore b/deployment_scripts/puppet/manifests/.gitignore deleted file mode 100644 index 25e75852c..000000000 --- a/deployment_scripts/puppet/manifests/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Gemfile.lock -.bundle diff --git a/deployment_scripts/puppet/manifests/Gemfile b/deployment_scripts/puppet/manifests/Gemfile deleted file mode 100644 index 7d2ce4e5d..000000000 --- a/deployment_scripts/puppet/manifests/Gemfile +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -source 'https://rubygems.org' - -group :development, :test do - gem 'rake' - gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.4.0' - # Newer puppetlabs_spec_helper depends on rubocop-rspec that requires ruby >= 2.2.0 - gem 'puppetlabs_spec_helper', '~> 1.1.1' - # puppet-lint >= 2.2.0 don't support Puppet 3.x anymore - gem 'puppet-lint', '~> 2.1.0' -end diff --git a/deployment_scripts/puppet/manifests/Rakefile b/deployment_scripts/puppet/manifests/Rakefile deleted file mode 100644 index 8f70d7920..000000000 --- a/deployment_scripts/puppet/manifests/Rakefile +++ /dev/null @@ -1,14 +0,0 @@ -require 'puppet-lint/tasks/puppet-lint' -require 'puppet-syntax/tasks/puppet-syntax' - -PuppetLint.configuration.fail_on_warnings = true -PuppetLint.configuration.send('disable_80chars') -PuppetLint.configuration.send('disable_class_inherits_from_params_class') -PuppetLint.configuration.send('disable_class_parameter_defaults') -PuppetLint.configuration.send('disable_variable_contains_dash') - -desc "Run lint, and syntax tests." -task :test => [ - :lint, - :syntax, -] diff --git a/deployment_scripts/puppet/manifests/aggregator.pp b/deployment_scripts/puppet/manifests/aggregator.pp deleted file mode 100644 index bab92dd68..000000000 --- a/deployment_scripts/puppet/manifests/aggregator.pp +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: aggregator.pp') - -prepare_network_config(hiera_hash('network_scheme', {})) -$mgmt_address = get_network_role_property('management', 'ipaddr') -$lma_collector = hiera_hash('lma_collector') - -$node_profiles = hiera_hash('lma::collector::node_profiles') -$is_controller = $node_profiles['controller'] -$is_mysql_server = $node_profiles['mysql'] -$is_rabbitmq = $node_profiles['rabbitmq'] - -$network_metadata = hiera_hash('network_metadata') -$controllers = get_nodes_hash_by_roles($network_metadata, ['primary-controller', 'controller']) - -$aggregator_address = hiera('management_vip') -$management_network = hiera('management_network_range') -$aggregator_port = 5565 -$check_port = 5566 - -if $is_controller or $is_rabbitmq or $is_mysql_server { - # On nodes where pacemaker is deployed, make sure the Log and Metric collector services - # are configured with the "pacemaker" provider - Service<| title == 'log_collector' |> { - provider => 'pacemaker' - } - Service<| title == 'metric_collector' |> { - provider => 'pacemaker' - } -} - -# On a dedicated environment, without controllers, we don't deploy the -# aggregator client. -if size(keys($controllers)) > 0 { - class { 'lma_collector::aggregator::client': - address => $aggregator_address, - port => $aggregator_port, - } -} - -if $is_controller { - class { 'lma_collector::aggregator::server': - listen_address => $mgmt_address, - listen_port => $aggregator_port, - http_check_port => $check_port, - } - - # Hacks needed to leverage the haproxy_service defined type - include haproxy::params - Haproxy::Service { use_include => true } - Haproxy::Balancermember { use_include => true } - - # HAProxy configuration - openstack::ha::haproxy_service { 'lma': - order => '999', - listen_port => $aggregator_port, - balancermember_port => $aggregator_port, - haproxy_config_options => { - 'option' => ['httpchk', 'tcplog'], - 'balance' => 'roundrobin', - 'mode' => 'tcp', - }, - balancermember_options => "check port ${check_port}", - internal => true, - internal_virtual_ip => $aggregator_address, - public => false, - public_virtual_ip => undef, - ipaddresses => [ $mgmt_address ], - server_names => [ $::hostname ], - } - - # Allow traffic from HAProxy to the local LMA collector - firewall { '998 lma': - port => [$aggregator_port, $check_port], - source => $management_network, - destination => $mgmt_address, - proto => 'tcp', - action => 'accept', - } - - # Configure the GSE filters emitting the status metrics for: - # - service clusters - # - node clusters - # - global clusters - create_resources(lma_collector::gse_cluster_filter, { - 'service' => $lma_collector['gse_cluster_service'], - 'node' => $lma_collector['gse_cluster_node'], - 'global' => $lma_collector['gse_cluster_global'], - }, { - require => Class['lma_collector::gse_policies'] - }) - - class { 'lma_collector::gse_policies': - policies => $lma_collector['gse_policies'] - } -} diff --git a/deployment_scripts/puppet/manifests/base.pp b/deployment_scripts/puppet/manifests/base.pp deleted file mode 100644 index 07c88b38c..000000000 --- a/deployment_scripts/puppet/manifests/base.pp +++ /dev/null @@ -1,379 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: base.pp') - -$heka_version = '0.10.0' - -# TODO(spasquier): fail if Neutron isn't used -prepare_network_config(hiera_hash('network_scheme', {})) -$fuel_version = 0 + hiera('fuel_version') -$lma_collector = hiera_hash('lma_collector') - -$node_profiles = hiera_hash('lma::collector::node_profiles') -$is_controller = $node_profiles['controller'] -$is_base_os = $node_profiles['base_os'] -$is_mysql_server = $node_profiles['mysql'] -$is_rabbitmq = $node_profiles['rabbitmq'] - -if $lma_collector['environment_label'] != '' { - $environment_label = $lma_collector['environment_label'] -} else { - $environment_label = join(['env-', hiera('deployment_id')], '') -} -$tags = { - deployment_id => hiera('deployment_id'), - openstack_region => 'RegionOne', - openstack_release => hiera('openstack_version'), - openstack_roles => join(hiera('roles'), ','), - environment_label => $environment_label, -} - -if $is_controller { - # "keystone" group required for lma_collector::logs::openstack to be able - # to read log files located in /var/log/keystone - $additional_groups = ['haclient', 'keystone'] -} else { - $additional_groups = [] -} - -case $::osfamily { - 'Debian': { - $heka_user = 'heka' - } - 'RedHat': { - # For CentOS, the LMA collector needs to run as root because the files - # created by RSyslog aren't created with the correct mode for now. - $heka_user = 'root' - } - default: { - fail("${::osfamily} not supported") - } -} - -class { 'lma_collector': - tags => $tags, -} - -if $is_controller { - $install_heka_init_script = false - # On controller nodes the increase of the AFD filters puts too much load on - # the heka pipeline which can block heka (idle packs). - # It was observed that a poolsize set to 200 solves the issue. - $poolsize = 200 -} else { - $install_heka_init_script = true - $poolsize = 100 -} - -lma_collector::heka { 'log_collector': - user => $heka_user, - groups => $additional_groups, - install_init_script => $install_heka_init_script, - version => $heka_version, - heka_monitoring => false, - require => Class['lma_collector'], -} - -lma_collector::heka { 'metric_collector': - user => $heka_user, - groups => $additional_groups, - install_init_script => $install_heka_init_script, - version => $heka_version, - poolsize => $poolsize, - heka_monitoring => false, - require => Class['lma_collector'], -} - -# The LMA collector service is managed by Pacemaker on nodes that are -# running RabbitMQ and database in detached mode and also on controller nodes. -# We use pacemaker_wrappers::service to reconfigure the service resource -# to use the "pacemaker" service provider -if $is_controller or $is_rabbitmq or $is_mysql_server { - - $rabbitmq_resource = 'master_p_rabbitmq-server' - - if $fuel_version < 9.0 { - pacemaker_wrappers::service { 'log_collector': - ensure => present, - prefix => false, - primitive_class => 'ocf', - primitive_type => 'ocf-lma_collector', - complex_type => 'clone', - use_handler => false, - ms_metadata => { - # the resource should start as soon as the dependent resources (eg RabbitMQ) - # are running *locally* - 'interleave' => true, - }, - metadata => { - # Make sure that Pacemaker tries to restart the resource if it fails - # too many times - 'failure-timeout' => '120s', - 'migration-threshold' => '3', - }, - parameters => { - 'service_name' => 'log_collector', - 'config' => '/etc/log_collector', - 'log_file' => '/var/log/log_collector.log', - 'user' => $heka_user, - }, - operations => { - 'monitor' => { - 'interval' => '20', - 'timeout' => '10', - }, - 'start' => { - 'timeout' => '30', - }, - 'stop' => { - 'timeout' => '30', - }, - }, - } - - if $is_rabbitmq { - cs_rsc_colocation { "${log_service_name}-with-rabbitmq": - ensure => present, - alias => 'log_collector', - primitives => ['clone_log_collector', $rabbitmq_resource], - score => 0, - require => Pacemaker_wrappers::Service['log_collector'], - } - - cs_rsc_order { 'log_collector-after-rabbitmq': - ensure => present, - alias => 'log_collector', - first => $rabbitmq_resource, - second => 'clone_log_collector', - # Heka cannot start if RabbitMQ isn't ready to accept connections. But - # once it is initialized, it can recover from a RabbitMQ outage. This is - # why we set score to 0 (interleave) meaning that the collector should - # start once RabbitMQ is active but a restart of RabbitMQ - # won't trigger a restart of the LMA collector. - score => 0, - require => Cs_rsc_colocation['log_collector'], - before => Class['lma_collector'], - } - } - - pacemaker_wrappers::service { 'metric_collector': - ensure => present, - prefix => false, - primitive_class => 'ocf', - primitive_type => 'ocf-lma_collector', - complex_type => 'clone', - use_handler => false, - ms_metadata => { - # The resource can start at any time - 'interleave' => false, - }, - metadata => { - # Make sure that Pacemaker tries to restart the resource if it fails - # too many times - 'failure-timeout' => '120s', - 'migration-threshold' => '3', - }, - parameters => { - 'service_name' => 'metric_collector', - 'config' => '/etc/metric_collector', - 'log_file' => '/var/log/metric_collector.log', - 'user' => $heka_user, - }, - operations => { - 'monitor' => { - 'interval' => '20', - 'timeout' => '10', - }, - 'start' => { - 'timeout' => '30', - }, - 'stop' => { - 'timeout' => '30', - }, - }, - } - } else { - pacemaker::service { 'log_collector': - ensure => present, - prefix => false, - primitive_class => 'ocf', - primitive_type => 'ocf-lma_collector', - use_handler => false, - complex_type => 'clone', - complex_metadata => { - # the resource should start as soon as the dependent resources - # (eg RabbitMQ) are running *locally* - 'interleave' => true, - }, - metadata => { - # Make sure that Pacemaker tries to restart the resource if it fails - # too many times - 'failure-timeout' => '120s', - 'migration-threshold' => '3', - }, - parameters => { - 'service_name' => 'log_collector', - 'config' => '/etc/log_collector', - 'log_file' => '/var/log/log_collector.log', - 'user' => $heka_user, - }, - operations => { - 'monitor' => { - 'interval' => '20', - 'timeout' => '10', - }, - 'start' => { - 'timeout' => '30', - }, - 'stop' => { - 'timeout' => '30', - }, - }, - require => Lma_collector::Heka['log_collector'], - } - - if $is_rabbitmq { - pcmk_colocation { 'log_collector-with-rabbitmq': - ensure => present, - alias => 'log_collector', - first => $rabbitmq_resource, - second => 'clone_log_collector', - score => 0, - require => Pacemaker::Service['log_collector'], - } - - pcmk_order { 'log_collector-after-rabbitmq': - ensure => present, - first => $rabbitmq_resource, - second => 'clone_log_collector', - # Heka cannot start if RabbitMQ isn't ready to accept connections. But - # once it is initialized, it can recover from a RabbitMQ outage. This is - # why we set score to 0 (interleave) meaning that the collector should - # start once RabbitMQ is active but a restart of RabbitMQ - # won't trigger a restart of the LMA collector. - score => 0, - require => Pcmk_colocation['log_collector-with-rabbitmq'], - } - } - - pacemaker::service { 'metric_collector': - ensure => present, - prefix => false, - primitive_class => 'ocf', - primitive_type => 'ocf-lma_collector', - use_handler => false, - complex_type => 'clone', - complex_metadata => { - # The resource can start at any time - 'interleave' => false, - }, - metadata => { - # Make sure that Pacemaker tries to restart the resource if it fails - # too many times - 'failure-timeout' => '120s', - 'migration-threshold' => '3', - }, - parameters => { - 'service_name' => 'metric_collector', - 'config' => '/etc/metric_collector', - 'log_file' => '/var/log/metric_collector.log', - 'user' => $heka_user, - }, - operations => { - 'monitor' => { - 'interval' => '20', - 'timeout' => '10', - }, - 'start' => { - 'timeout' => '30', - }, - 'stop' => { - 'timeout' => '30', - }, - }, - require => Lma_collector::Heka['metric_collector'], - } - } -} - -class { 'lma_collector::logs::hdd_errors_counter': - require => Class['lma_collector'] -} - -if hiera('lma::collector::elasticsearch::server', false) { - class { 'lma_collector::logs::system': - require => Class['lma_collector'], - } - - if (str2bool($::ovs_log_directory)){ - # install logstreamer for open vSwitch if log directory exists - class { 'lma_collector::logs::ovs': - require => Class['lma_collector'], - } - } - - class { 'lma_collector::elasticsearch': - server => hiera('lma::collector::elasticsearch::server'), - port => hiera('lma::collector::elasticsearch::rest_port'), - flush_interval => hiera('lma::collector::elasticsearch::flush_interval'), - flush_count => hiera('lma::collector::elasticsearch::flush_count'), - require => Class['lma_collector'], - } - - if $is_mysql_server { - class { 'lma_collector::logs::mysql': - require => Class['lma_collector'], - } - } - - if $is_rabbitmq { - class { 'lma_collector::logs::rabbitmq': - require => Class['lma_collector'], - } - } -} - -if hiera('lma::collector::influxdb::server', false) { - class { 'lma_collector::influxdb': - server => hiera('lma::collector::influxdb::server'), - port => hiera('lma::collector::influxdb::port'), - database => hiera('lma::collector::influxdb::database'), - user => hiera('lma::collector::influxdb::user'), - password => hiera('lma::collector::influxdb::password'), - tag_fields => ['deployment_id', 'environment_label', 'tenant_id', 'user_id'], - require => Class['lma_collector'], - } -} - -if $is_rabbitmq and (hiera('lma::collector::elasticsearch::server', false) or hiera('lma::collector::influxdb::server', false)){ - # OpenStack notifications are always useful for indexation and metrics - # collection - $messaging_address = get_network_role_property('mgmt/messaging', 'ipaddr') - $rabbit = hiera_hash('rabbit') - - class { 'lma_collector::notifications::input': - topic => 'lma_notifications', - host => $messaging_address, - port => hiera('amqp_port', '5673'), - user => 'nova', - password => $rabbit['password'], - } - - if hiera('lma::collector::influxdb::server', false) { - class { 'lma_collector::notifications::metrics': } - } -} - -class { 'fuel_lma_collector::tools': } diff --git a/deployment_scripts/puppet/manifests/cinder.pp b/deployment_scripts/puppet/manifests/cinder.pp deleted file mode 100644 index ab91efeaf..000000000 --- a/deployment_scripts/puppet/manifests/cinder.pp +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: cinder.pp') - -$ceilometer = hiera_hash('ceilometer', {}) - -$node_profiles = hiera_hash('lma::collector::node_profiles') -$is_controller = $node_profiles['controller'] -$is_rabbitmq = $node_profiles['rabbitmq'] -$is_mysql_server = $node_profiles['mysql'] - -if $is_controller or $is_rabbitmq or $is_mysql_server { - # On nodes where pacemaker is deployed, make sure Log and Metric collector services - # are configured with the "pacemaker" provider - Service<| title == 'log_collector' |> { - provider => 'pacemaker' - } - Service<| title == 'metric_collector' |> { - provider => 'pacemaker' - } -} - -if hiera('lma::collector::influxdb::server', false) { - class { 'lma_collector::logs::counter': - hostname => $::hostname, - } -} - -if hiera('lma::collector::elasticsearch::server', false) { - lma_collector::logs::openstack { 'cinder': } -} - -if $ceilometer['enabled'] { - $notification_topics = ['notifications', 'lma_notifications'] -} -else { - $notification_topics = ['lma_notifications'] -} - -# OpenStack notifcations are always useful for indexation and metrics collection -include cinder::params -$volume_service = $::cinder::params::volume_service - -cinder_config { 'DEFAULT/notification_topics': - value => join($notification_topics, ','), - notify => Service[$volume_service], -} - -cinder_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$volume_service], -} - -service { $volume_service: - hasstatus => true, - hasrestart => true, -} diff --git a/deployment_scripts/puppet/manifests/cleanup_apt_config.pp b/deployment_scripts/puppet/manifests/cleanup_apt_config.pp deleted file mode 100644 index 58c71fef7..000000000 --- a/deployment_scripts/puppet/manifests/cleanup_apt_config.pp +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: cleanup_apt_config.pp') - -case $::osfamily { - 'Debian': { - file { '/etc/apt/apt.conf.d/99norecommends': - ensure => absent, - } - } - default: { - # Currently only Debian like distributions need specific configuration. - } -} diff --git a/deployment_scripts/puppet/manifests/collectd.pp b/deployment_scripts/puppet/manifests/collectd.pp deleted file mode 100644 index 2edd29f02..000000000 --- a/deployment_scripts/puppet/manifests/collectd.pp +++ /dev/null @@ -1,368 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: collectd.pp') - -if hiera('lma::collector::influxdb::server', false) { - prepare_network_config(hiera_hash('network_scheme', {})) - - $fuel_version = 0 + hiera('fuel_version') - $management_vip = hiera('management_vip') - $mgmt_address = get_network_role_property('management', 'ipaddr') - $lma_collector = hiera_hash('lma_collector') - $node_profiles = hiera_hash('lma::collector::node_profiles') - $is_controller = $node_profiles['controller'] - $is_base_os = $node_profiles['base_os'] - $is_mysql_server = $node_profiles['mysql'] - $is_rabbitmq = $node_profiles['rabbitmq'] - $is_compute = $node_profiles['compute'] - $is_ceph_osd = $node_profiles['ceph_osd'] - $is_elasticsearch_node = $node_profiles['elasticsearch'] - $is_influxdb_node = $node_profiles['influxdb'] - $nova = hiera_hash('nova', {}) - $neutron = hiera_hash('quantum_settings', {}) - $cinder = hiera_hash('cinder', {}) - $haproxy_socket = '/var/lib/haproxy/stats' - $storage_options = hiera_hash('storage', {}) - if $storage_options['volumes_ceph'] or $storage_options['images_ceph'] or - $storage_options['objects_ceph'] or $storage_options['ephemeral_ceph']{ - $ceph_enabled = true - } else { - $ceph_enabled = false - } - - if $is_controller or $is_rabbitmq { - Service<| title == 'metric_collector' |> { - provider => 'pacemaker' - } - } - - if $is_elasticsearch_node { - $process_matches = [{name => 'elasticsearch', regex => 'java'}] - } else { - $process_matches = undef - } - if $is_influxdb_node { - $processes = ['influxd', 'grafana-server', 'hekad', 'collectd'] - } else { - $processes = ['hekad', 'collectd'] - } - if $is_controller { - # collectd plugins on controller do many network I/O operations, so - # it is recommended to increase this value - $read_threads = 10 - } else { - $read_threads = 5 - } - class { 'lma_collector::collectd::base': - processes => $processes, - process_matches => $process_matches, - # Purge the default configuration shipped with the collectd package - purge => true, - read_threads => $read_threads, - } - - if $is_mysql_server { - class { 'lma_collector::collectd::mysql': - username => hiera('lma::collector::monitor::mysql_username'), - password => hiera('lma::collector::monitor::mysql_password'), - socket => hiera('lma::collector::monitor::mysql_socket'), - require => Class['lma_collector::collectd::base'], - } - - lma_collector::collectd::dbi_mysql_status { 'mysql_status': - username => hiera('lma::collector::monitor::mysql_username'), - dbname => hiera('lma::collector::monitor::mysql_db'), - password => hiera('lma::collector::monitor::mysql_password'), - require => Class['lma_collector::collectd::base'], - } - } - - if $is_rabbitmq { - $rabbit = hiera_hash('rabbit') - if $rabbit['user'] { - $rabbitmq_user = $rabbit['user'] - } - else { - $rabbitmq_user = 'nova' - } - class { 'lma_collector::collectd::rabbitmq': - username => $rabbitmq_user, - password => $rabbit['password'], - require => Class['lma_collector::collectd::base'], - } - } - - # Configure Pacemaker plugin - if $is_controller { - $pacemaker_master_resource = 'vip__management' - $controller_resources = { - 'vip__public' => 'vip__public', - 'vip__management' => 'vip__management', - 'vip__vrouter_pub' => 'vip__vrouter_pub', - 'vip__vrouter' => 'vip__vrouter', - 'p_haproxy' => 'haproxy', - } - } else { - $pacemaker_master_resource = undef - $controller_resources = {} - } - # Deal with detach-* plugins - if $is_mysql_server { - if $fuel_version < 9.0 { - $mysql_resource_name = 'p_mysql' - } else { - $mysql_resource_name = 'p_mysqld' - } - $mysql_resource = { - "${mysql_resource_name}" => 'mysqld', - } - } - else { - $mysql_resource = {} - } - if $is_rabbitmq { - $rabbitmq_resource = { - 'p_rabbitmq-server' => 'rabbitmq', - } - } - else { - $rabbitmq_resource = {} - } - $resources = merge($controller_resources, $mysql_resource, $rabbitmq_resource) - - if ! empty($resources) { - class { 'lma_collector::collectd::pacemaker': - resources => $resources, - notify_resource => $pacemaker_master_resource, - hostname => $::fqdn, - require => Class['lma_collector::collectd::base'], - } - } - - if $is_controller { - # Configure OpenStack plugins - $openstack_service_config = { - user => 'nova', - password => $nova['user_password'], - tenant => 'services', - keystone_url => "http://${management_vip}:5000/v2.0", - pacemaker_master_resource => $pacemaker_master_resource, - require => Class['lma_collector::collectd::base'], - } - $openstack_services = { - 'nova_services' => $openstack_service_config, - 'cinder_services' => $openstack_service_config, - 'keystone' => $openstack_service_config, - 'neutron_agents' => $openstack_service_config, - } - - $nova_polling = { - 'polling_interval' => 60, - 'pagination_limit' => 500, - } - $cinder_polling = { - 'polling_interval' => 60, - 'pagination_limit' => 500, - } - $glance_polling = { - 'polling_interval' => 60, - 'pagination_limit' => 25, - } - $neutron_polling = { - 'polling_interval' => 60, - 'pagination_limit' => 100, - } - $openstack_resources = { - 'nova' => merge($openstack_service_config, $nova_polling), - 'cinder' => merge($openstack_service_config, $cinder_polling), - 'glance' => merge($openstack_service_config, $glance_polling), - 'neutron' => merge($openstack_service_config, $neutron_polling), - } - create_resources(lma_collector::collectd::openstack, $openstack_services) - create_resources(lma_collector::collectd::openstack, $openstack_resources) - - # FIXME(elemoine) use the special attribute * when Fuel uses a Puppet version - # that supports it. - class { 'lma_collector::collectd::openstack_checks': - user => $openstack_service_config[user], - password => $openstack_service_config[password], - tenant => $openstack_service_config[tenant], - keystone_url => $openstack_service_config[keystone_url], - pacemaker_master_resource => $openstack_service_config[pacemaker_master_resource], - require => Class['lma_collector::collectd::base'], - } - - # FIXME(elemoine) use the special attribute * when Fuel uses a Puppet version - # that supports it. - class { 'lma_collector::collectd::hypervisor': - user => $openstack_service_config[user], - password => $openstack_service_config[password], - tenant => $openstack_service_config[tenant], - keystone_url => $openstack_service_config[keystone_url], - pacemaker_master_resource => $openstack_service_config[pacemaker_master_resource], - # Fuel sets cpu_allocation_ratio to 8.0 in nova.conf - cpu_allocation_ratio => 8.0, - require => Class['lma_collector::collectd::base'], - } - - class { 'lma_collector::collectd::haproxy': - socket => $haproxy_socket, - # Ignore internal stats ('Stats' for 6.1, 'stats' for 7.0), lma proxies and - # Nova EC2 - proxy_ignore => ['Stats', 'stats', 'lma', 'nova-api-1'], - proxy_names => { - 'ceilometer' => 'ceilometer-api', - 'cinder-api' => 'cinder-api', - 'glance-api' => 'glance-api', - 'glance-registry' => 'glance-registry-api', - 'heat-api' => 'heat-api', - 'heat-api-cfn' => 'heat-cfn-api', - 'heat-api-cloudwatch' => 'heat-cloudwatch-api', - 'horizon' => 'horizon-web', - 'horizon-ssl' => 'horizon-https', - 'keystone-1' => 'keystone-public-api', - 'keystone-2' => 'keystone-admin-api', - 'murano' => 'murano-api', - 'mysqld' => 'mysqld-tcp', - 'neutron' => 'neutron-api', - # starting with Mitaka (and later) - 'nova-api' => 'nova-api', - # before Mitaka - 'nova-api-2' => 'nova-api', - 'nova-novncproxy' => 'nova-novncproxy-websocket', - 'nova-metadata-api' => 'nova-metadata-api', - 'sahara' => 'sahara-api', - 'swift' => 'swift-api', - }, - require => Class['lma_collector::collectd::base'], - } - - if $ceph_enabled { - class { 'lma_collector::collectd::ceph_mon': - require => Class['lma_collector::collectd::base'], - } - } - - class { 'lma_collector::collectd::memcached': - host => get_network_role_property('mgmt/memcache', 'ipaddr'), - require => Class['lma_collector::collectd::base'], - } - - # Enable the Apache status module - class { 'fuel_lma_collector::mod_status': } - class { 'lma_collector::collectd::apache': - require => Class['lma_collector::collectd::base'], - } - - # Check local endpoint - $cinder_api = get_network_role_property('cinder/api', 'ipaddr') - $glance_api = get_network_role_property('glance/api', 'ipaddr') - $heat_api = get_network_role_property('heat/api', 'ipaddr') - $keystone_api = get_network_role_property('keystone/api', 'ipaddr') - $neutron_api = get_network_role_property('neutron/api', 'ipaddr') - $nova_api = get_network_role_property('nova/api', 'ipaddr') - $swift_api = get_network_role_property('swift/api', 'ipaddr') - if $fuel_version < 9.0 { - $cinder_expected_code = 200 - } else { - # Since Mitaka, Cinder returns 300 instead of 200 in previous releases - $cinder_expected_code = 300 - } - class { 'lma_collector::collectd::check_local_endpoint': - urls => { - 'cinder-api' => "http://${cinder_api}:8776", - 'glance-api' => "http://${glance_api}:9292", - 'heat-api' => "http://${heat_api}:8004", - 'heat-cfn-api' => "http://${heat_api}:8000", - 'keystone-public-api' => "http://${keystone_api}:5000", - 'neutron-api' => "http://${neutron_api}:9696", - 'nova-api' => "http://${nova_api}:8774", - 'swift-api' => "http://${swift_api}:8080/info", - }, - expected_codes => { - 'cinder-api' => $cinder_expected_code, - 'glance-api' => 300, - 'heat-api' => 300, - 'heat-cfn-api' => 300, - 'keystone-public-api' => 300, - 'neutron-api' => 200, - 'nova-api' => 200, - 'swift-api' => 200, - }, - timeout => 1, - max_retries => 3, - require => Class['lma_collector::collectd::base'], - } - - $influxdb_server = hiera('lma::collector::influxdb::server') - $influxdb_port = hiera('lma::collector::influxdb::port') - class { 'lma_collector::collectd::http_check': - urls => { - 'influxdb-cluster' => "http://${influxdb_server}:${influxdb_port}/ping", - }, - expected_codes => { - 'influxdb-cluster' => 204 - }, - timeout => 1, - max_retries => 3, - pacemaker_master_resource => $pacemaker_master_resource, - require => Class['lma_collector::collectd::base'], - } - } - - # Compute - if $is_compute { - class { 'lma_collector::collectd::libvirt': - require => Class['lma_collector::collectd::base'], - } - class { 'lma_collector::collectd::libvirt_check': - require => Class['lma_collector::collectd::base'], - } - } - - # Ceph OSD - if $is_ceph_osd { - class { 'lma_collector::collectd::ceph_osd': - require => Class['lma_collector::collectd::base'], - } - } - - # InfluxDB - if $is_influxdb_node { - class { 'lma_collector::collectd::influxdb': - username => 'root', - password => hiera('lma::collector::influxdb::root_password'), - address => hiera('lma::collector::influxdb::listen_address'), - port => hiera('lma::collector::influxdb::influxdb_port', 8086), - require => Class['lma_collector::collectd::base'], - } - } - - # Elasticsearch - if $is_elasticsearch_node { - class { 'lma_collector::collectd::elasticsearch': - address => hiera('lma::collector::elasticsearch::listen_address'), - port => hiera('lma::collector::elasticsearch::rest_port', 9200), - require => Class['lma_collector::collectd::base'], - } - } - - if $is_influxdb_node or $is_elasticsearch_node { - class { 'lma_collector::collectd::haproxy': - socket => $haproxy_socket, - require => Class['lma_collector::collectd::base'], - } - } -} diff --git a/deployment_scripts/puppet/manifests/compute.pp b/deployment_scripts/puppet/manifests/compute.pp deleted file mode 100644 index 025f90871..000000000 --- a/deployment_scripts/puppet/manifests/compute.pp +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: compute.pp') - -$ceilometer = hiera_hash('ceilometer', {}) - -if hiera('lma::collector::elasticsearch::server', false) { - lma_collector::logs::openstack { 'nova': } - lma_collector::logs::openstack { 'neutron': } - class { 'lma_collector::logs::libvirt': } -} - -if hiera('lma::collector::influxdb::server', false) { - class { 'lma_collector::logs::counter': - hostname => $::hostname, - } -} - -if $ceilometer['enabled'] { - $notification_topics = ['notifications', 'lma_notifications'] -} -else { - $notification_topics = ['lma_notifications'] -} - -# OpenStack notifcations are always useful for indexation and metrics collection -include nova::params -$compute_service = $::nova::params::compute_service_name - -nova_config { 'DEFAULT/notification_topics': - value => join($notification_topics, ','), - notify => Service[$compute_service], -} -nova_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$compute_service], -} -nova_config { 'DEFAULT/notify_on_state_change': - value => 'vm_and_task_state', - notify => Service[$compute_service], -} - -service { $compute_service: - hasstatus => true, - hasrestart => true, -} diff --git a/deployment_scripts/puppet/manifests/configure_afd_filters.pp b/deployment_scripts/puppet/manifests/configure_afd_filters.pp deleted file mode 100644 index c6f5dda80..000000000 --- a/deployment_scripts/puppet/manifests/configure_afd_filters.pp +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: configure_afd_filters.pp') - -$lma = hiera_hash('lma_collector', {}) -$node_profiles = hiera_hash('lma::collector::node_profiles') -$is_controller = $node_profiles['controller'] -$is_mysql_server = $node_profiles['mysql'] -$is_rabbitmq = $node_profiles['rabbitmq'] - -$alarms_definitions = $lma['alarms'] -if $alarms_definitions == undef { - fail('Alarms definitions not found. Check files in /etc/hiera/override.') -} - -if $is_controller or $is_rabbitmq or $is_mysql_server { - # On nodes where pacemaker is deployed, make sure the LMA service is - # configured with the "pacemaker" provider - Service<| title == 'log_collector' |> { - provider => 'pacemaker' - } - Service<| title == 'metric_collector' |> { - provider => 'pacemaker' - } -} - -class { 'fuel_lma_collector::afds': - roles => hiera('roles'), - node_profiles => $lma['node_profiles'], - node_cluster_alarms => $lma['node_cluster_alarms'], - service_cluster_alarms => $lma['service_cluster_alarms'], - metrics => $lma['metrics'], - alarms => $alarms_definitions, -} - -# Forward AFD status to Nagios if deployed -if hiera('lma::collector::infrastructure_alerting::server', false) { - lma_collector::afd_nagios { 'nodes': - ensure => present, - hostname => $::hostname, - server => hiera('lma::collector::infrastructure_alerting::server'), - http_port => hiera('lma::collector::infrastructure_alerting::http_port'), - http_path => hiera('lma::collector::infrastructure_alerting::http_path'), - user => hiera('lma::collector::infrastructure_alerting::user'), - password => hiera('lma::collector::infrastructure_alerting::password'), - service_template => '%{node_role}.%{source}', - message_type => 'afd_node_metric', - } - lma_collector::afd_nagios { 'services': - ensure => present, - hostname => $::hostname, - server => hiera('lma::collector::infrastructure_alerting::server'), - http_port => hiera('lma::collector::infrastructure_alerting::http_port'), - http_path => hiera('lma::collector::infrastructure_alerting::http_path'), - user => hiera('lma::collector::infrastructure_alerting::user'), - password => hiera('lma::collector::infrastructure_alerting::password'), - service_template => '%{service}.%{source}', - message_type => 'afd_service_metric', - } -} diff --git a/deployment_scripts/puppet/manifests/configure_apt.pp b/deployment_scripts/puppet/manifests/configure_apt.pp deleted file mode 100644 index bffdcc0e3..000000000 --- a/deployment_scripts/puppet/manifests/configure_apt.pp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: configure_apt.pp') - -$str = 'APT::Install-Suggests "0"; -APT::Install-Recommends "0"; -' - -case $::osfamily { - 'Debian': { - file { '/etc/apt/apt.conf.d/99norecommends': - ensure => file, - content => $str, - } - } - default: { - # Currently only Debian like distributions need specific configuration. - } -} diff --git a/deployment_scripts/puppet/manifests/controller.pp b/deployment_scripts/puppet/manifests/controller.pp deleted file mode 100644 index 3454f4517..000000000 --- a/deployment_scripts/puppet/manifests/controller.pp +++ /dev/null @@ -1,329 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: controller.pp') - -$ceilometer = hiera_hash('ceilometer', {}) -$lma_collector = hiera_hash('lma_collector') -$rabbit = hiera_hash('rabbit') -$storage_options = hiera_hash('storage', {}) -$murano = hiera_hash('murano') -$sahara = hiera_hash('sahara') - -if $ceilometer['enabled'] { - $notification_topics = ['notifications', 'lma_notifications'] -} -else { - $notification_topics = ['lma_notifications'] -} - -# Make sure the Log and Metric collector services are configured with the -# "pacemaker" provider -Service<| title == 'log_collector' |> { - provider => 'pacemaker' -} -Service<| title == 'metric_collector' |> { - provider => 'pacemaker' -} - -# OpenStack logs and notifications are useful for deriving metrics, so we enable -# them even if Elasticsearch is disabled. -if hiera('lma::collector::elasticsearch::server', false) or hiera('lma::collector::influxdb::server', false){ - # Sahara notifications - if $sahara['enabled'] { - include sahara::params - $sahara_api_service = $::sahara::params::api_service_name - $sahara_engine_service = $::sahara::params::engine_service_name - - sahara_config { 'DEFAULT/enable_notifications': - value => true, - notify => Service[$sahara_api_service, $sahara_engine_service], - } - sahara_config { 'DEFAULT/notification_topics': - value => $notification_topics, - notify => Service[$sahara_api_service, $sahara_engine_service], - } - sahara_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$sahara_api_service, $sahara_engine_service], - } - - service { [$sahara_api_service, $sahara_engine_service]: - hasstatus => true, - hasrestart => true, - } - } - - # Nova notifications - include nova::params - $nova_api_service = $::nova::params::api_service_name - $nova_conductor_service = $::nova::params::conductor_service_name - $nova_scheduler_service = $::nova::params::scheduler_service_name - - nova_config { 'DEFAULT/notification_topics': - value => $notification_topics, - notify => Service[$nova_api_service, $nova_conductor_service, $nova_scheduler_service], - } - nova_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$nova_api_service, $nova_conductor_service, $nova_scheduler_service], - } - nova_config { 'DEFAULT/notify_on_state_change': - value => 'vm_and_task_state', - notify => Service[$nova_api_service, $nova_conductor_service, $nova_scheduler_service], - } - - service { [$nova_api_service, $nova_conductor_service, $nova_scheduler_service]: - hasstatus => true, - hasrestart => true, - } - - # Cinder notifications - include cinder::params - $cinder_api_service = $::cinder::params::api_service - $cinder_scheduler_service = $::cinder::params::scheduler_service - $cinder_volume_service = $::cinder::params::volume_service - - if $storage_options['volumes_ceph'] { - # In this case, cinder-volume runs on controller node - $cinder_services = [$cinder_api_service, $cinder_scheduler_service, $cinder_volume_service] - } else { - $cinder_services = [$cinder_api_service, $cinder_scheduler_service] - } - - cinder_config { 'DEFAULT/notification_topics': - value => $notification_topics, - notify => Service[$cinder_services], - } - cinder_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$cinder_services], - } - - service { $cinder_services: - hasstatus => true, - hasrestart => true, - } - - # Keystone notifications - # Keystone is executed as a WSGI application inside Apache so the Apache - # service needs to be restarted if necessary - include apache::params - include apache::service - - keystone_config { 'DEFAULT/notification_topics': - value => $notification_topics, - notify => Class['apache::service'], - } - keystone_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Class['apache::service'], - } - - # Neutron notifications - include neutron::params - - neutron_config { 'DEFAULT/notification_topics': - value => $notification_topics, - notify => Service[$::neutron::params::server_service], - } - neutron_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$::neutron::params::server_service], - } - - # Enable pagination for Neutron - neutron_config { 'DEFAULT/allow_pagination': - value => true, - notify => Service[$::neutron::params::server_service], - } - neutron_config { 'DEFAULT/pagination_max_limit': - value => '100', - notify => Service[$::neutron::params::server_service], - } - - service { $::neutron::params::server_service: - hasstatus => true, - hasrestart => true, - } - - # Glance notifications - include glance::params - - $glance_api_service = $::glance::params::api_service_name - $glance_registry_service = $::glance::params::registry_service_name - - # Default value is 'image.localhost' for Glance - $glance_publisher_id = "image.${::hostname}" - - glance_api_config { 'DEFAULT/notification_topics': - value => $notification_topics, - notify => Service[$glance_api_service], - } - glance_api_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$glance_api_service], - } - glance_api_config { 'DEFAULT/default_publisher_id': - value => $glance_publisher_id, - notify => Service[$glance_api_service], - } - glance_registry_config { 'DEFAULT/notification_topics': - value => $notification_topics, - notify => Service[$glance_registry_service], - } - glance_registry_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$glance_registry_service], - } - glance_registry_config { 'DEFAULT/default_publisher_id': - value => $glance_publisher_id, - notify => Service[$glance_registry_service], - } - - service { [$glance_api_service, $glance_registry_service]: - hasstatus => true, - hasrestart => true, - } - - # Heat notifications - include heat::params - - $heat_api_service = $::heat::params::api_service_name - $heat_engine_service = $::heat::params::engine_service_name - - heat_config { 'DEFAULT/notification_topics': - value => $notification_topics, - notify => Service[$heat_api_service, $heat_engine_service], - } - heat_config { 'DEFAULT/notification_driver': - value => 'messaging', - notify => Service[$heat_api_service, $heat_engine_service], - } - - service { $heat_api_service: - hasstatus => true, - hasrestart => true, - } - - # The heat-engine service is managed by Pacemaker. - service { $heat_engine_service: - hasstatus => true, - hasrestart => true, - provider => 'pacemaker', - } - - lma_collector::logs::openstack { 'nova': } - - # For every virtual network that exists, Neutron spawns one metadata proxy - # service that will log to a separate file in the Neutron log directory. - # Eventually it may be hundreds of these files and Heka will have trouble - # coping with the situation. See bug #1547402 for details. - lma_collector::logs::openstack { 'neutron': - service_match => '(dhcp-agent|l3-agent|metadata-agent|neutron-netns-cleanup|openvswitch-agent|server)', - } - lma_collector::logs::openstack { 'cinder': } - lma_collector::logs::openstack { 'glance': } - lma_collector::logs::openstack { 'heat': } - lma_collector::logs::openstack { 'keystone': } - class {'lma_collector::logs::keystone_wsgi': } - lma_collector::logs::openstack { 'horizon': } - - if $murano['enabled'] { - lma_collector::logs::openstack { 'murano': } - } - - if $sahara['enabled'] { - lma_collector::logs::openstack { 'sahara': } - } - - if ! $storage_options['objects_ceph'] { - class { 'lma_collector::logs::swift': - file_match => 'swift-all\.log\.?(?P\d*)$', - priority => '["^Seq"]', - } - } - - class { 'lma_collector::logs::pacemaker': } -} - -# Metrics -if hiera('lma::collector::influxdb::server', false) { - class { 'lma_collector::logs::counter': - hostname => $::hostname, - } - - # TODO(all): This class is still called to ensure the sandbox deletion - # when upgrading the plugin. Can be removed for next release after 0.10.0. - class { 'lma_collector::logs::http_metrics': } - - class { 'lma_collector::logs::aggregated_http_metrics': } -} - -if hiera('lma::collector::infrastructure_alerting::server', false) { - $deployment_id = hiera('deployment_id') - - lma_collector::gse_nagios { 'global': - openstack_deployment_name => $deployment_id, - server => hiera('lma::collector::infrastructure_alerting::server'), - http_port => hiera('lma::collector::infrastructure_alerting::http_port'), - http_path => hiera('lma::collector::infrastructure_alerting::http_path'), - user => hiera('lma::collector::infrastructure_alerting::user'), - password => hiera('lma::collector::infrastructure_alerting::password'), - message_type => $lma_collector['gse_cluster_global']['output_message_type'], - # Following parameter must match the lma_infrastructure_alerting::params::nagios_global_vhostname_prefix - virtual_hostname => '00-global-clusters', - } - - lma_collector::gse_nagios { 'nodes': - openstack_deployment_name => $deployment_id, - server => hiera('lma::collector::infrastructure_alerting::server'), - http_port => hiera('lma::collector::infrastructure_alerting::http_port'), - http_path => hiera('lma::collector::infrastructure_alerting::http_path'), - user => hiera('lma::collector::infrastructure_alerting::user'), - password => hiera('lma::collector::infrastructure_alerting::password'), - message_type => $lma_collector['gse_cluster_node']['output_message_type'], - # Following parameter must match the lma_infrastructure_alerting::params::nagios_node_vhostname_prefix - virtual_hostname => '00-node-clusters', - } - - # Purge remaining files from previous 0.10.x version - $toml_metric_collector_to_purge = prefix([ - 'filter-afd_api_backends.toml', 'filter-afd_api_endpoints.toml', - 'filter-afd_service_rabbitmq_disk.toml', - 'filter-afd_service_rabbitmq_memory.toml', - 'filter-afd_service_rabbitmq_queue.toml', - 'filter-afd_workers.toml', - 'filter-service_heartbeat.toml', - 'encoder-nagios_gse_global_clusters.toml', - 'encoder-nagios_gse_node_clusters.toml', - 'output-nagios_gse_global_clusters.toml', - 'output-nagios_gse_node_clusters.toml', - ], '/etc/metric_collector/') - - file { $toml_metric_collector_to_purge: - ensure => absent, - } -> - lma_collector::gse_nagios { 'services': - openstack_deployment_name => $deployment_id, - server => hiera('lma::collector::infrastructure_alerting::server'), - http_port => hiera('lma::collector::infrastructure_alerting::http_port'), - http_path => hiera('lma::collector::infrastructure_alerting::http_path'), - user => hiera('lma::collector::infrastructure_alerting::user'), - password => hiera('lma::collector::infrastructure_alerting::password'), - message_type => $lma_collector['gse_cluster_service']['output_message_type'], - # Following parameter must match the lma_infrastructure_alerting::params::nagios_node_vhostname_prefix - virtual_hostname => '00-service-clusters', - } -} diff --git a/deployment_scripts/puppet/manifests/hiera_override.pp b/deployment_scripts/puppet/manifests/hiera_override.pp deleted file mode 100644 index 49d2c0efa..000000000 --- a/deployment_scripts/puppet/manifests/hiera_override.pp +++ /dev/null @@ -1,253 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: hiera_override.pp') - -prepare_network_config(hiera_hash('network_scheme', {})) -$plugin_data = hiera_hash('lma_collector', undef) - -if ($plugin_data) { - $network_metadata = hiera_hash('network_metadata') - $is_controller_node = roles_include(['controller', 'primary-controller']) - $is_base_os_node = roles_include('base-os') - $is_compute = roles_include('compute') - $is_ceph_osd = roles_include('ceph-osd') - $has_controller = count(get_nodes_hash_by_roles($network_metadata, ['primary-controller'])) > 0 - # The detached RabbitMQ plugin has no primary role in 8.0 - $has_detached_rabbitmq = count(get_nodes_hash_by_roles($network_metadata, ['primary-standalone-rabbitmq', 'standalone-rabbitmq'])) > 0 - $has_detached_database = count(get_nodes_hash_by_roles($network_metadata, ['primary-standalone-database'])) > 0 - - if roles_include(['standalone-database', 'primary-standalone-database']) { - $is_mysql_node = true - } else { - $is_mysql_node = $is_controller_node and ! $has_detached_database - } - - if roles_include(['standalone-rabbitmq', 'primary-standalone-rabbitmq']) { - $is_rabbitmq_node = true - } else { - $is_rabbitmq_node = $is_controller_node and ! $has_detached_rabbitmq - } - - # Elasticsearch - $is_elasticsearch_node = roles_include(['elasticsearch_kibana', 'primary-elasticsearch_kibana']) - $es_listen_address = get_network_role_property('elasticsearch', 'ipaddr') - $elasticsearch_mode = $plugin_data['elasticsearch_mode'] - $es_nodes = get_nodes_hash_by_roles($network_metadata, ['elasticsearch_kibana', 'primary-elasticsearch_kibana']) - $es_nodes_count = count($es_nodes) - - case $elasticsearch_mode { - 'remote': { - $es_server = $plugin_data['elasticsearch_address'] - $monitor_elasticsearch = false - } - 'local': { - $es_vip_name = 'es_vip_mgmt' - if $network_metadata['vips'][$es_vip_name] { - $es_server = $network_metadata['vips'][$es_vip_name]['ipaddr'] - $monitor_elasticsearch = true - } elsif $es_nodes_count > 0 { - $es_server = $es_nodes[0]['internal_address'] - $monitor_elasticsearch = true - } else { - $es_server = undef - $monitor_elasticsearch = false - } - } - default: { - fail("'${elasticsearch_mode}' mode not supported for Elasticsearch") - } - } - if $es_nodes_count > 0 or $es_server { - $es_is_deployed = true - } else { - $es_is_deployed = false - } - - $es_flush_interval = 5 - if $is_controller_node or hiera('debug', false) { - # Increase the flush count when debug level log is enabled or for - # controllers because OpenStack APIs + Pacemaker can generate many log - # messages. - $es_flush_count = 100 - } else { - $es_flush_count = 10 - } - - # InfluxDB - $is_influxdb_node = roles_include(['influxdb_grafana', 'primary-influxdb_grafana']) - $influxdb_listen_address = get_network_role_property('influxdb_vip', 'ipaddr') - $influxdb_mode = $plugin_data['influxdb_mode'] - $influxdb_nodes = get_nodes_hash_by_roles($network_metadata, ['influxdb_grafana', 'primary-influxdb_grafana']) - $influxdb_nodes_count = count($influxdb_nodes) - $influxdb_grafana = hiera_hash('influxdb_grafana', {}) - - case $influxdb_mode { - 'remote': { - $influxdb_server = $plugin_data['influxdb_address'] - $influxdb_database = $plugin_data['influxdb_database'] - $influxdb_user = $plugin_data['influxdb_user'] - $influxdb_password = $plugin_data['influxdb_password'] - $monitor_influxdb = false - } - 'local': { - $influxdb_vip_name = 'influxdb' - if $network_metadata['vips'][$influxdb_vip_name] { - $influxdb_server = $network_metadata['vips'][$influxdb_vip_name]['ipaddr'] - $monitor_influxdb = true - } elsif $influxdb_nodes_count > 0 { - $influxdb_server = $influxdb_nodes[0]['internal_address'] - $monitor_influxdb = true - } else { - $monitor_influxdb = false - $influxdb_server = undef - } - $influxdb_database = $influxdb_grafana['influxdb_dbname'] - $influxdb_user = $influxdb_grafana['influxdb_username'] - $influxdb_password = $influxdb_grafana['influxdb_userpass'] - $influxdb_root_password = $influxdb_grafana['influxdb_rootpass'] - } - default: { - fail("'${influxdb_mode}' mode not supported for InfluxDB") - } - } - if $influxdb_nodes_count > 0 or $influxdb_server { - $influxdb_is_deployed = true - } else { - $influxdb_is_deployed = false - } - if $has_controller { - $nova = hiera_hash('nova', {}) - $mysql_username = 'nova' - $mysql_password = $nova['db_password'] - $mysql_db = 'nova' - } elsif $is_mysql_node { - $influxdb_plugin = hiera_hash('influxdb_grafana', {}) - if $influxdb_plugin['mysql_mode'] == 'local' { - # Use the Grafana credentials when the MySQL server is deployed in the - # same environment but without controller (eg dedicated environment scenario) - $mysql_username = $influxdb_plugin['mysql_username'] - $mysql_password = $influxdb_plugin['mysql_password'] - $mysql_db = $influxdb_plugin['mysql_dbname'] - } - } - - # Infrastructure Alerting - $lma_infra_alerting = hiera('lma_infrastructure_alerting', {}) - $infra_alerting_nodes = get_nodes_hash_by_roles($network_metadata, ['infrastructure_alerting', 'primary-infrastructure_alerting']) - $infra_alerting_nodes_count = count($infra_alerting_nodes) - $infra_vip_name = 'infrastructure_alerting_mgmt_vip' - if $network_metadata['vips'][$infra_vip_name] { - $nagios_server = $network_metadata['vips'][$infra_vip_name]['ipaddr'] - $nagios_password = $lma_infra_alerting['nagios_password'] - } else { - $nagios_server = undef - } - if $infra_alerting_nodes_count > 0 and $nagios_server { - $nagios_is_deployed = true - } else { - $nagios_is_deployed = false - } - - $hiera_file = '/etc/hiera/plugins/lma_collector.yaml' - - $calculated_content = inline_template(' ---- -lma::collector::node_profiles: - controller: <%= @is_controller_node %> - influxdb: <%= @is_influxdb_node %> - elasticsearch: <%= @is_elasticsearch_node %> - rabbitmq: <%= @is_rabbitmq_node %> - mysql: <%= @is_mysql_node %> - base_os: <%= @is_base_os_node %> - compute: <%= @is_compute %> - ceph_osd: <%= @is_ceph_osd %> - -lma::collector::monitor::mysql_db: <%= @mysql_db %> -lma::collector::monitor::mysql_username: <%= @mysql_username %> -lma::collector::monitor::mysql_password: <%= @mysql_password %> -lma::collector::monitor::mysql_socket: /var/run/mysqld/mysqld.sock - -<% if @es_is_deployed -%> -lma::collector::elasticsearch::server: <%= @es_server %> -lma::collector::elasticsearch::rest_port: 9200 -lma::collector::elasticsearch::flush_interval: <%= @es_flush_interval %> -lma::collector::elasticsearch::flush_count: <%= @es_flush_count %> -<% if @is_elasticsearch_node -%> -lma::collector::elasticsearch::listen_address: <%= @es_listen_address %> -<% end -%> -<% end -%> -<% if @influxdb_is_deployed -%> -lma::collector::influxdb::server: <%= @influxdb_server %> -lma::collector::influxdb::port: 8086 -lma::collector::influxdb::database: <%= @influxdb_database %> -lma::collector::influxdb::user: <%= @influxdb_user %> -lma::collector::influxdb::password: <%= @influxdb_password %> -lma::collector::influxdb::root_password: <%= @influxdb_root_password %> -<% if @is_influxdb_node -%> -lma::collector::influxdb::listen_address: <%= @influxdb_listen_address %> -<% end -%> -<% end -%> -<% if @nagios_is_deployed -%> -lma::collector::infrastructure_alerting::server: <%= @nagios_server %> -lma::collector::infrastructure_alerting::http_port: 80 -lma::collector::infrastructure_alerting::http_path: status -lma::collector::infrastructure_alerting::user: nagiosadmin -lma::collector::infrastructure_alerting::password: <%= @nagios_password %> -<% end -%> - ') - - file { $hiera_file: - ensure => file, - content => $calculated_content, - } - - $storage_options = hiera_hash('storage', {}) - $public_ssl = hiera('public_ssl', {}) - $tls_enabled = $public_ssl['horizon'] or false - - $ceilometer = hiera_hash('ceilometer', {}) - $ceilometer_enabled = pick($ceilometer['enabled'], false) - $contrail_plugin = hiera('contrail', false) - - # detach_rabbitmq_enabled is used in templates - $detach_rabbitmq = hiera('detach-rabbitmq', {}) - $detach_rabbitmq_enabled = $detach_rabbitmq['metadata'] and $detach_rabbitmq['metadata']['enabled'] - - # detach_database_enabled is used in templates - $detach_database = hiera('detach-database', {}) - $detach_database_enabled = $detach_database['metadata'] and $detach_database['metadata']['enabled'] - - fuel_lma_collector::hiera_data { 'clusters': - content => template('fuel_lma_collector/clusters.yaml.erb') - } - - fuel_lma_collector::hiera_data { 'alarming': - content => template('fuel_lma_collector/alarming.yaml.erb') - } - - fuel_lma_collector::hiera_data { 'node_profiles': - content => template('fuel_lma_collector/node_profiles.yaml.erb') - } - - fuel_lma_collector::hiera_data { 'metrics': - content => template('fuel_lma_collector/metrics.yaml.erb') - } - - # This file has been renamed 'clusters.yaml' and need to be removed - # for rolling upgrade - file { '/etc/hiera/override/gse_filters.yaml': - ensure => absent, - } -} diff --git a/deployment_scripts/puppet/manifests/install_ocf_script.pp b/deployment_scripts/puppet/manifests/install_ocf_script.pp deleted file mode 100644 index 449104f55..000000000 --- a/deployment_scripts/puppet/manifests/install_ocf_script.pp +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. - -notice('fuel-plugin-lma-collector: install_ocf_scripts.pp') - -file { 'ocf-lma_collector': - ensure => present, - source => 'puppet:///modules/lma_collector/ocf-lma_collector', - path => '/usr/lib/ocf/resource.d/fuel/ocf-lma_collector', - mode => '0755', - owner => 'root', - group => 'root', -} diff --git a/deployment_scripts/puppet/modules/.gitkeep b/deployment_scripts/puppet/modules/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/.fixtures.yml b/deployment_scripts/puppet/modules/fuel_lma_collector/.fixtures.yml deleted file mode 100644 index 560a6798c..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/.fixtures.yml +++ /dev/null @@ -1,9 +0,0 @@ -fixtures: - repositories: - stdlib: - repo: "git://github.com/puppetlabs/puppetlabs-stdlib" - ref: "4.7.0" - symlinks: - fuel_lma_collector: "#{source_dir}" - lma_collector: "#{source_dir}/../lma_collector" - heka: "#{source_dir}/../heka" diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/.gitignore b/deployment_scripts/puppet/modules/fuel_lma_collector/.gitignore deleted file mode 100644 index 91a269438..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -spec/fixtures/modules/* -spec/fixtures/manifests/* -Gemfile.lock -tests/lua/mocks/date_time.lua -.bundle -tests/lua/mocks/inspect.lua -tests/lua/mocks/anomaly.lua -tests/lua/mocks/annotation.lua diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/Gemfile b/deployment_scripts/puppet/modules/fuel_lma_collector/Gemfile deleted file mode 100644 index e8a2c49ed..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/Gemfile +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -source 'https://rubygems.org' - -group :development, :test do - gem 'rake' - gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.4.0' - gem 'rspec' - gem 'rspec-puppet' - gem 'rspec-puppet-facts' - # Newer puppetlabs_spec_helper depends on rubocop-rspec that requires ruby >= 2.2.0 - gem 'puppetlabs_spec_helper', '~> 1.1.1' - # puppet-lint >= 2.2.0 don't support Puppet 3.x anymore - gem 'puppet-lint', '~> 2.1.0' - gem 'metadata-json-lint' -end diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/LICENSE b/deployment_scripts/puppet/modules/fuel_lma_collector/LICENSE deleted file mode 100644 index e06d20818..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. - diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/README.md b/deployment_scripts/puppet/modules/fuel_lma_collector/README.md deleted file mode 100644 index 8a8f2ca9d..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# fuel_lma_collector - -## Overview - -The `fuel_lma_collector` module provides classes and defines to ease the -deployment of the LMA collectors in a Fuel environment. - -## Usage - -TBD - -Limitations ------------ - - -License -------- - -Licensed under the terms of the Apache License, version 2.0. - -Contact -------- - -Simon Pasquier, - -Support -------- - -See the Contact section. diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/Rakefile b/deployment_scripts/puppet/modules/fuel_lma_collector/Rakefile deleted file mode 100644 index 678462cf7..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/Rakefile +++ /dev/null @@ -1,28 +0,0 @@ -require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-lint/tasks/puppet-lint' -require 'puppet-syntax/tasks/puppet-syntax' -require 'metadata-json-lint/rake_task' - -PuppetLint.configuration.fail_on_warnings = true -PuppetLint.configuration.send('disable_80chars') -PuppetLint.configuration.send('disable_class_inherits_from_params_class') -PuppetLint.configuration.send('disable_class_parameter_defaults') - -exclude_paths = [ - "pkg/**/*", - "vendor/**/*", - "spec/**/*", -] -Rake::Task[:lint].clear -PuppetLint::RakeTask.new :lint do |config| - config.ignore_paths = exclude_paths -end -PuppetSyntax.exclude_paths = exclude_paths - -desc "Run metadata_lint, lint, syntax, and spec tests." -task :test => [ - :metadata_lint, - :lint, - :syntax, - :spec, -] diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/files/diagnostics.sh b/deployment_scripts/puppet/modules/fuel_lma_collector/files/diagnostics.sh deleted file mode 100755 index 781331c09..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/files/diagnostics.sh +++ /dev/null @@ -1,467 +0,0 @@ -#!/bin/bash -# Copyright 2016 Mirantis, Inc. -# -# 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. - -DIAG_DIR=/var/lma_diagnostics -rm -rf "$DIAG_DIR" -mkdir -p "$DIAG_DIR" || exit 1 - -ES_PORT=9200 -INFLUXDB_PORT=8086 -NUM_COLLECTORS=1 -DIAG_LOG_FILENAME="$DIAG_DIR/diagnostics.log" - -function log_info { - echo "$(date +%Y-%m-%d-%H-%M-%S) INFO $@" | tee -a $DIAG_LOG_FILENAME -} - -function log_err { - echo "$(date +%Y-%m-%d-%H-%M-%S) ERROR $@" | tee -a $DIAG_LOG_FILENAME -} - -log_info $(hostname) role $(hiera roles) - -function has_collector { - if [ -d /etc/log_collector ]; then - NUM_COLLECTORS=2 - return 0 - fi - if [ -d /etc/lma_collector ]; then - return 0 - fi - return 1 -} -function has_collectd { - if [ -d /etc/collectd ]; then - return 0 - fi - return 1 -} -function has_influxdb { - if [ -d /etc/influxdb ]; then - return 0 - fi - return 1 -} -function has_elasticsearch { - if [ -d /etc/elasticsearch ]; then - return 0 - fi - return 1 -} - -function has_nagios { - if [ -d /etc/nagios3 ]; then - return 0 - fi - return 1 -} - -function has_pacemaker { - if which crm > /dev/null 2>&1; then - return 0 - fi - return 1 -} - -function check_net_listen { - process=$1 - out=$2 - expect=${3:-1} - port=$4 - - if [ -n "$port" ]; then - netstat -apn | grep LISTEN | grep "$process"|grep -E ":$port" > "$out" - else - netstat -apn | grep LISTEN | grep "$process" > "$out" - port='any' - fi - cnt=$(cat "$out" | wc -l) - if [ "$cnt" -eq 0 ]; then - log_err "'$process' process does not LISTEN on port: $port" - elif [ "$cnt" -ne "$expect" ]; then - log_err "$cnt LISTEN ports for process $process, $expect expected on port: $port!" - else - log_info "$expect process(es) $process is/are listening on port $port" - fi - - return $cnt -} - -function check_process { - process=$1 - out=$2 - expect=${3:-1} - ps auxf | grep -v grep | grep -E -- "$process" > $out - cnt=$(ps auxf | grep -v grep | grep -E -- "$process" | wc -l) - if [ "$cnt" -eq 0 ]; then - log_err "'$process' process not found" - elif [ "$expect" != "any" ] && [ "$cnt" -ne "$expect" ]; then - log_err "$cnt '$process' processes found, $expect expected!" - else - log_info "$cnt process(es) '$process' found" - fi - return $cnt -} - -function tail_file { - file="$1" - base_dir=${2:-$DIAG_DIR} - path=$(dirname "$file") - filename=$(basename "$file") - out="${base_dir}${path}/${filename}" - mkdir -p $(dirname "$out") - num=${3:-10000} - - if [ -f "$file" ]; then - tail -n $num "$file" >> "$out" 2>&1 - log_info "tail -n $num $file -> $out" - else - log_err "$file doesn't exist" - fi - return $? -} - -function copy_file { - src="$1" - base_dir=${2:-$DIAG_DIR} - - path=$(dirname "$src") - out_dir="${base_dir}${path}" - mkdir -p "$out_dir" - if [ -d "$src" ]; then - log_info "Copy directory $src -> $out_dir" - cp -rfL "$src" "$out_dir" 2>/dev/null || log_err "Failed to copy $src into $out_dir/" - elif [ -f "$src" ]; then - log_info "Copy file $src -> $out_dir/" - cp -fL "$src" "$out_dir" 2>/dev/null || log_err "Failed to copy $src into $out_dir/" - else - log_err "Fail to copy .. '$src' doesn't exist" - fi -} - -function run_cmd { - cmd=$1 - output_file=$2 - to=${3:-11} - log_info "Running command: '$cmd' -> $output_file" - eval "timeout $to $cmd" > "$output_file" 2>&1 - if [ $? -ne 0 ]; then - log_err "command failed: '$cmd', check $output_file" - return 1 - fi - return 0 -} - -function diag_collectd { - log_info "** Collectd" - copy_file /etc/collectd - find "/usr/lib/collectd/" -name '*.py' | while read f; do - copy_file "$f" - done - - diag_output="${DIAG_DIR}/diag.collectd" - mkdir -p "${diag_output}" - tail_file /var/log/collectd.log - check_process "collectd -C" "${diag_output}/processes" - check_process collectdmon "${diag_output}/processes" -} - -function diag_influxdb { - log_info "** InfluxDB" - GRAFANA_PORT=8000 - if grep lma::grafana::tls::enabled /etc/hiera/plugins/influxdb_grafana.yaml|grep false 2>&1 >/dev/null; then - FRONTEND_GRAFANA_PORT=80 - else - FRONTEND_GRAFANA_PORT=443 - fi - - copy_file /etc/influxdb - tail_file /var/log/influxdb/influxd.log - - diag_output="${DIAG_DIR}/diag.influxdb" - mkdir -p "${diag_output}" - check_process "/usr/bin/influxd" "${diag_output}/processes" - check_net_listen influxd "${diag_output}/netstat" 1 $INFLUXDB_PORT - listening=$? - if [ $listening -gt 0 ]; then - local_address=$(netstat -apn | grep LISTEN | grep ":$INFLUXDB_PORT" | awk '{print $4}') - run_cmd "curl -S -i $local_address/ping" "${diag_output}/test_ping" 5 - if [ $? -ne 0 ]; then - log_err "Fail to reach Influxdb ($local_address)" - fi - fi - - address=$(hiera lma::influxdb::vip) - if [ "$address" != "nil" ]; then - run_cmd "curl -S -i ${address}:${INFLUXDB_PORT}/ping" "${diag_output}/test_ping.vip" 5 - if [ $? -ne 0 ]; then - log_err "Fail to reach Influxdb (${address}:${INFLUXDB_PORT})" - fi - fi - - copy_file /etc/grafana - tail_file /var/log/grafana/grafana.log - - diag_output="${DIAG_DIR}/diag.grafana" - mkdir -p "${diag_output}" - check_process grafana-server "${diag_output}/processes" - check_net_listen grafana "${diag_output}/netstat" 1 $GRAFANA_PORT - - address=$(hiera lma::grafana::vip) - if [ $FRONTEND_GRAFANA_PORT == "443" ]; then - run_cmd "curl -S -k -i https://${address}:${FRONTEND_GRAFANA_PORT}/login" "${diag_output}/vip_test" 5 - else - run_cmd "curl -S -i http://${address}:${FRONTEND_GRAFANA_PORT}/login" "${diag_output}/vip_test" 5 - fi - if [ $? -ne 0 ]; then - log_err "Fail to reach Grafana ($address:$FRONTEND_GRAFANA_PORT)" - fi -} - -function diag_elasticsearch { - log_info "** Elasticsearch" - copy_file /etc/elasticsearch - for l in $(ls /var/log/elasticsearch/es-01/*.log); do - tail_file "$l" - done - # Get previous logs - es_previous_logs=$(ls /var/log/elasticsearch/es-01/*.log.2* 2>/dev/null | tail -n 2 ) - if [ -n "$es_previous_logs" ]; then - for l in ; do - tail_file "$l" - done - fi - - diag_output="${DIAG_DIR}/diag.elasticsearch" - mkdir -p "${diag_output}" - check_process "-cp.*elasticsearch-.*\.jar" "${diag_output}/processes" - check_net_listen java "${diag_output}/netstat.$ES_PORT" 1 $ES_PORT - listening=$? - local_address=$(netstat -apn | grep LISTEN | grep ":$ES_PORT" | awk '{print $4}') - if [ $listening -gt 0 ]; then - run_cmd "curl -S -i $local_address/_cat/indices?v" "${diag_output}/indices" 5 - run_cmd "curl -S -i $local_address/_cluster/health?pretty" "${diag_output}/cluster_health" 5 - if [ $? -ne 0 ]; then - log_err "Fail to reach local Elasticsearch ($address)" - fi - fi - - address=$(hiera lma::elasticsearch::vip) - if [ "$address" != "nil" ]; then - address="${address}:${ES_PORT}" - - run_cmd "curl -S -i ${address}/_cluster/health?pretty" "${diag_output}/cluster_health.vip" 5 - if [ $? -ne 0 ]; then - log_err "Fail to reach Elasticsearch through the VIP ($address)" - fi - fi - - log_info "** Kibana" - KIBANA_PORT=5601 - copy_file /opt/kibana/config - diag_output="${DIAG_DIR}/diag.kibana" - mkdir -p "$diag_output" - check_net_listen node "${diag_output}/netstat.${KIBANA_PORT}" 1 $KIBANA_PORT -} - -function diag_collector { - log_info "** LMA Collector" - diag_output="${DIAG_DIR}/diag.collector" - mkdir -p "$diag_output" - check_process "hekad -config" "${diag_output}/processes" $NUM_COLLECTORS - - # Dashboard - check_net_listen hekad "${diag_output}/netstat.4352" 1 4352 - # HTTP input - check_net_listen hekad "${diag_output}/netstat.8325" 1 8325 - - if [ $NUM_COLLECTORS -eq 2 ]; then - # TCP metric input - check_net_listen hekad "${diag_output}/netstat.5567" 1 5567 - # Dashboard - check_net_listen hekad "${diag_output}/netstat.4353" 1 4353 - fi - - etc_dir="/etc/lma_collector /etc/log_collector /etc/metric_collector" - for d in $etc_dir; do - if [ -d "$d" ]; then - copy_file "$d" - fi - done - - for d in /usr/share/lma_collector /usr/share/lma_collector_modules; do - copy_file "$d" - done - - cache_dir="/var/cache/lma_collector /var/cache/log_collector /var/cache/metric_collector" - for d in $cache_dir; do - if [ ! -d "$d" ]; then - continue - fi - collector_name=$(basename $d) - out="${diag_output}/${collector_name}.cache" - find "$d" -ls |grep -v "dashboard/" > "$out" - find "$d" -name checkpoint.txt | while read f; do - echo $f >> "$out" - cat $f >> "$out" - echo >> "$out" - done - done - - log_file="/var/log/lma_collector.log /var/log/log_collector.log /var/log/metric_collector.log" - log_file="${log_file} /var/log/upstart/lma_collector.log /var/log/upstart/log_collector.log /var/log/upstart/metric_collector.log" - for l in $log_file; do - if [ -f "$l" ]; then - tail_file "$l" - fi - done -} - -function diag_nagios { - log_info "** Nagios" - diag_output="${DIAG_DIR}/diag.nagios" - mkdir -p "$diag_output" - - if grep tls_enabled /etc/hiera/plugins/lma_infrastructure_alerting.yaml|grep false 2>&1 >/dev/null; then - NAGIOS_PORT=80 - else - NAGIOS_PORT=443 - fi - - copy_file /etc/nagios3/ - copy_file /etc/apache2-nagios/ - - run_cmd "nagios3 -v /etc/nagios3/nagios.cfg" "$diag_output/configuration_validation" - if [ $? -ne 0 ]; then - log_err "Nagios configuration error" - fi - - # Nagios/Apache2 are running only on one node at a time - if crm resource status nagios3 2>&1 |grep $(hostname)|grep "is running" >/dev/null; then - log_info "Nagios is running on this node" - check_process "nagios3 -d" "$diag_output/processes.nagios3" - check_process "apache2 -k" "$diag_output/processes.apache2" any - else - log_info "Nagios is running elsewhere" - fi - - tail_file /var/nagios/nagios.log - tail_file /var/log/apache2/nagios_error.log - tail_file /var/log/apache2/nagios_access.log - tail_file /var/log/apache2/nagios_wsgi_error.log - tail_file /var/log/apache2/nagios_wsgi_access.log - - wsgi_address=$(hiera lma::infrastructure_alerting::vip) - run_cmd "curl -S -i $wsgi_address:80/status" "${diag_output}/nagios_wsgi_test" - if [ $? -ne 0 ]; then - log_err "Fail to reach Apache/Nagios ($wsgi_address:80)" - fi - - # NOTE: It is easier to get UI address from Apache configuration than - # from hiera, because hiera key lma::infrastructure_alerting::nagios_ui is a - # hash which was a bad idea. - ui_address=$(grep -v $wsgi_address /etc/apache2-nagios/port.confs|grep ':'|grep -v -E '^#'|awk '{print $2}') - if [ $NAGIOS_PORT == "443" ]; then - run_cmd "curl -S -k -i https://${ui_address}" "${diag_output}/nagios_ui_test" - else - run_cmd "curl -S -i http://${ui_address}" "${diag_output}/nagios_ui_test" - fi - if [ $? -ne 0 ]; then - log_err "Fail to reach Nagios UI ($ui_address)" - fi -} - -function diag_pacemaker { - log_info "** Pacemaker" - diag_output="${DIAG_DIR}/diag.pacemaker" - mkdir -p "$diag_output" - run_cmd "crm status" "${diag_output}/status" - run_cmd "crm configure show" "${diag_output}/configuration" - tail_file /var/log/pacemaker.log -} - -function diag_system { - log_info "** System" - - seconds=10 - diag_output="${DIAG_DIR}/diag.system" - mkdir -p "$diag_output" - run_cmd hostname "${diag_output}/hostname" - run_cmd uptime $diag_output/uptime - run_cmd "dmesg | tail -n 100" $diag_output/dmesg - run_cmd "vmstat 1 $seconds" $diag_output/vmstat - run_cmd "mpstat -P ALL 1 $seconds" $diag_output/mpstat - run_cmd "pidstat 1 $seconds" $diag_output/pidstat - run_cmd "iostat -xz 1 $seconds" $diag_output/iostat - run_cmd lshw $diag_output/lshw - run_cmd "df -h" $diag_output/df - run_cmd "crontab -l" $diag_output/crontab - copy_file /proc/cpuinfo - - if which "iptables-save" >/dev/null; then - run_cmd iptables-save $diag_output/iptables - fi - - find "/etc/hiera" -name '*.yaml' | while read f; do - copy_file "$f" - done - copy_file /etc/hiera.yaml - - ls -l /etc/fuel/plugins > "${DIAG_DIR}/fuel_plugins" - - tail_file /var/log/puppet.log - run_cmd 'grep -E "MODULAR|fuel-plugin-" /var/log/puppet.log' $diag_output/puppet_tasks.list - - run_cmd "netstat -nalp" $diag_output/netstat - run_cmd "ip route" $diag_output/ip_route - run_cmd "ip link" $diag_output/ip_link - run_cmd "ip address" $diag_output/ip_address - run_cmd "ip netns" $diag_output/ip_netns - for netns in $(ip netns 2>/dev/null); do - run_cmd "ip netns exec $netns ip route" "$diag_output/netns_${netns}_ip_route" - run_cmd "ip netns exec $netns ip link" "$diag_output/netns_${netns}_ip_link" - run_cmd "ip netns exec $netns ip address" "$diag_output/netns_${netns}_ip_address" - done - if which "brctl" >/dev/null; then - run_cmd "brctl show" $diag_output/brctl_show - fi -} - -if has_collector; then - diag_collector -fi -if has_pacemaker; then - diag_pacemaker -fi -if has_collectd; then - diag_collectd -fi -if has_influxdb; then - diag_influxdb -fi -if has_elasticsearch; then - diag_elasticsearch -fi -if has_nagios; then - diag_nagios -fi - -if [ -d /etc/haproxy ]; then - copy_file /etc/haproxy -fi - -diag_system - -exit 0 diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/parser/functions/get_afd_filters.rb b/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/parser/functions/get_afd_filters.rb deleted file mode 100644 index 8cb7745c8..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/parser/functions/get_afd_filters.rb +++ /dev/null @@ -1,170 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# -# Returns a hash describing the AFD filter resources for the given inputs. -# -# ARG0: Hash table mapping AFD profiles to alarms -# ARG1: Array of alarm definitions -# ARG2: Array of AFD profiles -# ARG3: Type of AFD (either 'node' or 'service') -# ARG4: Hash table mapping metric names to the place where there are collected. -# -# Ex: -# -# ARG0: -# {"rabbitmq"=>{"apply_to_node" => "controller", "members" => {"queue"=> {"alarms" => ["rabbitmq-queue-warning"]}}}, -# "apache"=>{"apply_to_node" => "controller", "members" => {"worker"=> {"alarms" => ["apache-warning"]}}}, -# "memcached"=>{"apply_to_node"=>"controller", "members" => {"all"=> {"alarms" => ["memcached-warning"]}}}, -# "haproxy"=>{"apply_to_node" => "controller", "members" => {"alive"=> {"alarms" => ["haproxy-warning"]}}}} -# -# ARG1: -# -# [ -# {"name"=>"rabbitmq-queue-warning", -# "description"=>"Number of message in queues too high", -# "severity"=>"warning", -# "trigger"=> -# {"logical_operator"=>"or", -# "rules"=> -# [{"metric"=>"rabbitmq_messages", -# "relational_operator"=>">=", -# "threshold"=>200, -# "window"=>120, -# "periods"=>0, -# "function"=>"avg"}]}}, -# {"name"=>"apache-warning", -# "description"=>"", -# "severity"=>"warning", -# "trigger"=> -# {"logical_operator"=>"or", -# "rules"=> -# [{"metric"=>"apache_idle_workers", -# "relational_operator"=>"=", -# "threshold"=>0, -# "window"=>60, -# "periods"=>0, -# "function"=>"min"}, -# {"metric"=>"apache_status", -# "relational_operator"=>"=", -# "threshold"=>0, -# "window"=>60, -# "periods"=>0, -# "function"=>"min"}]}} -# ] -# -# ARG2: ["controller", "compute"] -# -# ARG3: type (node|service) -# -# ARG4: {"openstack_nova_total_free_vcpus" => {"collected_on": "aggregator"}} -# -# Results -> { -# 'rabbitmq_queue' => { -# 'type' => 'service', -# 'cluster_name' => 'rabbitmq', -# 'logical_name' => 'queue', -# 'alarms' => ['rabbitmq-queue-warning'], -# 'alarms_definitions' => {...}, -# 'message_matcher' => "Fields[name] == 'rabbitmq_messages'" -# 'enable_notification' => true, -# 'activate_alerting' => true, -# }, -# 'apache_worker' => { -# 'type' => 'service', -# 'cluster_name' => 'apache', -# 'logical_name' => 'worker', -# 'alarms' => ['apache-warning'], -# 'alarms_definitions' => {...}, -# 'message_matcher' => "Fields[name] == 'apache_idle_workers' || Fields[name] == 'apache_status'" -# 'enable_notification' => true, -# 'activate_alerting' => true, -# } -# } - -module Puppet::Parser::Functions - newfunction(:get_afd_filters, :type => :rvalue) do |args| - - afd_alarms = args[0] - alarm_definitions = args[1] - afd_profiles = args[2] - type = args[3] - if not args[4] - metric_defs = {} - else - metric_defs = args[4] - end - afd_filters = {} - - afd_alarms.each do |cluster_name , afds| - if afds.has_key?('apply_to_node') - default_profile = afds['apply_to_node'] - else - default_profile = false - end - - default_activate_alerting=true - default_enable_notification=false - if afds.has_key?('alerting') - if afds['alerting'] == 'disabled' - default_activate_alerting=false - elsif afds['alerting'] == 'enabled_with_notification' - default_enable_notification = true - end - end - afds['members'].each do |afd_name, alarms| - metrics = Set.new([]) - matches = false - activate_alerting = default_activate_alerting - enable_notification = default_enable_notification - if alarms.has_key?('alerting') - if alarms['alerting'] == 'disabled' - activate_alerting=false - elsif alarms['alerting'] == 'enabled_with_notification' - enable_notification = true - end - end - alarms['alarms'].each do |a_name| - afd = alarm_definitions.select {|defi| defi['name'] == a_name} - next if afd.empty? # user mention an unknown alarm for this AFD - - afd[0]['trigger']['rules'].each do |r| - if metric_defs.has_key?(r['metric']) and metric_defs[r['metric']].has_key?('collected_on') and afd_profiles.include? metric_defs[r['metric']]['collected_on'] - matches = true - elsif afd_profiles.include?(default_profile) - matches = true - end - if matches - metrics << r['metric'] - end - end - end - if matches - message_matcher = metrics.collect{|x| "Fields[name] == \'#{x}\'" }.join(' || ') - afd_filters["#{cluster_name}_#{afd_name}"] = { - 'type' => type, - 'cluster_name' => cluster_name, - 'logical_name' => afd_name, - 'alarms' => alarms['alarms'], - 'alarms_definitions' => alarm_definitions, - 'message_matcher' => message_matcher, - 'activate_alerting' => activate_alerting, - 'enable_notification' => enable_notification, - } - end - end - end - return afd_filters - end -end diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/parser/functions/get_cluster_names.rb b/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/parser/functions/get_cluster_names.rb deleted file mode 100644 index 1d07b8af4..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/parser/functions/get_cluster_names.rb +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# -# Returns an array containing the AFD profiles associated to a MOS role. -# -# ARG0: Hash of arrays that contains relation between AFD profile and node's roles. -# ARG1: Array of node's roles -# -# Ex: -# -# ARG0: -# {"controller"=>["primary-controller", "controller"], -# "compute"=>["compute"], -# "storage"=>["cinder", "ceph-osd"], -# "influxdb"=>["influxdb-grafana"]} -# -# ARG1: ['primary-controller'] -# -# Results -> ['controller'] -# - -module Puppet::Parser::Functions - newfunction(:get_cluster_names, :type => :rvalue) do |args| - - data = args[0] - roles = args[1] - - raise Puppet::ParseError, "arg[0] isn't a hash" unless data.is_a?(Hash) - raise Puppet::ParseError, "arg[1] isn't an array" unless roles.is_a?(Array) - - cluster_names = Set.new([]) - - roles.each do |role| - data.each do |k,v| - cluster_names << k if v['roles'].include?(role) - end - end - - return cluster_names.to_a() - end -end diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/provider/hiera_custom_source/ruby.rb b/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/provider/hiera_custom_source/ruby.rb deleted file mode 100644 index e2d767f09..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/provider/hiera_custom_source/ruby.rb +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'yaml' - -HIERA_CONFIG = '/etc/hiera.yaml' - -Puppet::Type.type(:hiera_custom_source).provide(:ruby) do - desc "Support for Hiera source configuration" - - defaultfor :kernel => 'Linux' - - def sources - if @hiera.has_key?(:hierarchy) - return @hiera[:hierarchy] - elsif @hiera.has_key?('hierarchy') - return @hiera['hierarchy'] - else - raise Puppet::Error, "No 'hierarchy' key in the Hiera configuration" - end - end - - # Load the Hiera configuration - def load_hiera - @hiera = YAML.load_file(HIERA_CONFIG) - end - - # Save the current Hiera configuration - def save_hiera - File.open(HIERA_CONFIG, 'w') do |file| - file.puts @hiera.to_yaml - end - end - - def create - self.load_hiera - self.sources.insert(0, resource[:name]) - self.save_hiera - end - - def destroy - self.load_hiera - self.sources.select!{|x| x != resource[:name] } - self.save_hiera - end - - def exists? - self.load_hiera - return self.sources.any?{|x| x == resource[:name] } - end -end diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/type/hiera_custom_source.rb b/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/type/hiera_custom_source.rb deleted file mode 100644 index aa9745a42..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/lib/puppet/type/hiera_custom_source.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -Puppet::Type.newtype(:hiera_custom_source) do - desc 'Manage Hiera sources' - - ensurable - - newparam(:name) do - desc 'The path to the Hiera source' - isnamevar - end - -end diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/afds.pp b/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/afds.pp deleted file mode 100644 index 412a621bc..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/afds.pp +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -class fuel_lma_collector::afds ( - $roles = undef, - $node_profiles = undef, - $node_cluster_alarms = undef, - $service_cluster_alarms = undef, - $alarms = undef, - $metrics = {}, -){ - - validate_array($roles) - validate_hash($node_profiles) - validate_hash($node_cluster_alarms) - validate_hash($service_cluster_alarms) - validate_hash($metrics) - validate_array($alarms) - - $clusters_tmp = get_cluster_names($node_profiles, $roles) - if size($clusters_tmp) == 0 { - $clusters = ['default'] - } else { - $clusters = $clusters_tmp - } - - $node_afd_filters = get_afd_filters($node_cluster_alarms, - $alarms, - $clusters, - 'node', - $metrics) - - $service_afd_filters = get_afd_filters($service_cluster_alarms, - $alarms, - $clusters, - 'service', - $metrics) - - create_resources(lma_collector::afd_filter, $node_afd_filters) - create_resources(lma_collector::afd_filter, $service_afd_filters) -} diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/hiera_data.pp b/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/hiera_data.pp deleted file mode 100644 index da553364f..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/hiera_data.pp +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -define fuel_lma_collector::hiera_data ( - $content, - $ensure = present, -) { - $hiera_directory = '/etc/hiera/override' - - if $ensure == present { - $parsed_yaml = parseyaml($content) - - if ! $parsed_yaml { - # With stlib <= 4.9, parseyaml() will raise an exception if the generated - # YAML is invalid so the Puppet parse will never get to the fail() - # instruction. - fail('Invalid YAML content!') - } - validate_hash($parsed_yaml) - validate_hash($parsed_yaml['lma_collector']) - } - - if !defined(Package['ruby-deep-merge']){ - package {'ruby-deep-merge': - ensure => 'installed', - } - } - - if !defined(File[$hiera_directory]){ - file { $hiera_directory: - ensure => directory, - } - } - - file { "${hiera_directory}/${name}.yaml": - ensure => $ensure, - content => $content, - require => File[$hiera_directory], - } - - hiera_custom_source { "override/${name}": - ensure => $ensure - } -} diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/mod_status.pp b/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/mod_status.pp deleted file mode 100644 index 7984e2376..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/mod_status.pp +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Class: fuel_lma_collector::mod_status -# -# We don't use apache::mod_status because it requires to include the apache -# base class. And by doing this we would overwrite the Horizon configuration. - -class fuel_lma_collector::mod_status ( - $allow_from = $fuel_lma_collector::params::apache_allow_from, -) inherits fuel_lma_collector::params { - - include apache::params - include apache::service - - validate_array($allow_from) - - $lib_path = $::apache::params::lib_path - $status_conf = "${::apache::params::mod_dir}/status.conf" - $status_load = "${::apache::params::mod_dir}/status.load" - - if $::osfamily == 'debian' { - $status_conf_link = "${::apache::params::mod_enable_dir}/status.conf" - $status_load_link = "${::apache::params::mod_enable_dir}/status.load" - - file { $status_conf_link: - ensure => link, - target => $status_conf, - require => File[$status_conf], - } - - file { $status_load_link: - ensure => link, - target => $status_load, - require => File[$status_load], - notify => Class['apache::service'], - } - } - - # This template uses $allow_from and $lib_path - file { $status_conf: - ensure => file, - content => template('fuel_lma_collector/apache/status.conf.erb'), - require => File[$status_load], - notify => Class['apache::service'], - } - - file { $status_load: - ensure => file, - content => template('fuel_lma_collector/apache/status.load.erb'), - } - -} diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/params.pp b/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/params.pp deleted file mode 100644 index 58f7d506b..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/params.pp +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -class fuel_lma_collector::params { - $apache_allow_from = ['127.0.0.1','::1'] -} diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/tools.pp b/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/tools.pp deleted file mode 100644 index dd2e6bdcd..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/manifests/tools.pp +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. - -class fuel_lma_collector::tools { - - file { '/usr/local/bin/lma_diagnostics': - ensure => present, - source => 'puppet:///modules/fuel_lma_collector/diagnostics.sh', - mode => '0755', - owner => 'root', - group => 'root', - require => Package['sysstat'], - } - package {'sysstat': - ensure => installed, - } -} diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/metadata.json b/deployment_scripts/puppet/modules/fuel_lma_collector/metadata.json deleted file mode 100644 index c0d9d8510..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/metadata.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "mirantis-fuel_lma_collector", - "version": "1.0.0", - "author": "Simon Pasquier ", - "summary": "Puppet Fuel LMA Collector Module", - "license": "Apache-2.0", - "source": "https://git.openstack.org/cgit/openstack/fuel-plugin-lma-collector.git", - "project_page": "none", - "issues_url": "none", - "operatingsystem_support": [ - { - "operatingsystem": "Ubuntu", - "operatingsystemrelease": ["14.04"] - } - ], - "requirements": [ - {"name": "puppet", "version_requirement": "3.x"} - ], - "description": "Puppet module for configuring the LMA collector service in a Fuel deployment", - "dependencies": [ - {"name": "mirantis/lma_collector", "version_requirement": "1.x"}, - {"name": "puppetlabs/stdlib", "version_requirement": "4.x"} - ] -} diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/classes/fuel_lma_collector_afds_spec.rb b/deployment_scripts/puppet/modules/fuel_lma_collector/spec/classes/fuel_lma_collector_afds_spec.rb deleted file mode 100644 index f558afd3a..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/classes/fuel_lma_collector_afds_spec.rb +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'fuel_lma_collector::afds' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - let(:params) do - {:roles => ['primary-controller'], - :node_profiles => {'controller' => {'roles' => ['primary-controller']}}, - :node_cluster_alarms => { - 'controller' => - { - 'apply_to_node' => 'controller', - 'members' => { - 'cpu' => { - "alarms" => ['cpu_warning'] - } - } - } - }, - :service_cluster_alarms=> { - 'mysql' => { - 'apply_to_node' => 'controller', - 'members' => { - 'all' => { - "alarms" => ['db_warning'] - } - } - } - }, - :alarms => [ - {"name"=>"cpu_warning", - "description"=>"Fake alarm", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [{"metric"=>"fake_cpu", - "relational_operator"=>">=", - "threshold"=>200, - "window"=>120, - "periods"=>0, - "function"=>"avg"}]}}, - {"name"=>"db_warning", - "description"=>"Fake alarm", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [{"metric"=>"db-warning", - "relational_operator"=>">=", - "threshold"=>200, - "window"=>120, - "periods"=>0, - "function"=>"avg"}]}}]} - end - - it { is_expected.to contain_heka__filter__sandbox('afd_node_controller_cpu') } - it { is_expected.to contain_file('/usr/share/lma_collector_modules/lma_alarms_controller_cpu.lua') } - - it { is_expected.to contain_heka__filter__sandbox('afd_service_mysql_all') } - it { is_expected.to contain_file('/usr/share/lma_collector_modules/lma_alarms_mysql_all.lua') } - end - - describe 'with enabled false' do - let(:params) do - {:roles => ['primary-controller'], - :node_profiles => {'controller' => {'roles' => ['primary-controller']}}, - :node_cluster_alarms => { - 'controller' => { - 'apply_to_node' => 'controller', - 'members' => { - 'cpu' => { - "alarms" => ['cpu_warning'] - } - } - } - }, - :service_cluster_alarms => {}, - :alarms => [ - {"name"=>"cpu_warning", - "description"=>"Fake alarm", - "severity"=>"warning", - "enabled"=>"false", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [{"metric"=>"fake_cpu", - "relational_operator"=>">=", - "threshold"=>200, - "window"=>120, - "periods"=>0, - "function"=>"avg"}]}}]} - end - - it { is_expected.to contain_file('/usr/share/lma_collector_modules/lma_alarms_controller_cpu.lua').with_content(/local alarms = {\n}/) } - - end - - describe 'with profile per default' do - let(:params) do - {:roles => ['foo-role'], - :node_profiles => {'controller' => {'roles' => ['primary-controller']}}, - :node_cluster_alarms => { - 'others' => - { - 'apply_to_node' => 'default', - 'members' => { - 'cpu' => { - "alarms" => ['cpu_warning'] - } - } - } - }, - :service_cluster_alarms => { - }, - :alarms => [ - {"name"=>"cpu_warning", - "description"=>"Fake alarm", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [{"metric"=>"fake_cpu", - "relational_operator"=>">=", - "threshold"=>200, - "window"=>120, - "periods"=>0, - "function"=>"avg"}]}}, - ]} - end - - it { is_expected.to contain_heka__filter__sandbox('afd_node_others_cpu') } - it { is_expected.to contain_file('/usr/share/lma_collector_modules/lma_alarms_others_cpu.lua') } - - end -end diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/defines/fuel_lma_collector_hiera_data_spec.rb b/deployment_scripts/puppet/modules/fuel_lma_collector/spec/defines/fuel_lma_collector_hiera_data_spec.rb deleted file mode 100644 index 50028de41..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/defines/fuel_lma_collector_hiera_data_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' -require 'yaml' - -describe 'fuel_lma_collector::hiera_data' do - let(:title) { :foo } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with valid YAML' do - yaml =< yaml} - end - it { is_expected.to contain_file('/etc/hiera/override/foo.yaml') } - end - - describe 'with invalid YAML' do - yaml =< yaml} - end - it do - skip('needs stdlib >= 4.9.0') - is_expected.to raise_error(Psych::SyntaxError) - end - end - - describe 'with data which is not a hash' do - yaml =< yaml} - end - it { is_expected.to raise_error(Puppet::Error) } - end - - describe 'with missing key in YAML' do - yaml =< yaml} - end - it { is_expected.to raise_error(Puppet::Error) } - end -end diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/functions/get_afd_filters_spec.rb b/deployment_scripts/puppet/modules/fuel_lma_collector/spec/functions/get_afd_filters_spec.rb deleted file mode 100644 index 14dc3fe51..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/functions/get_afd_filters_spec.rb +++ /dev/null @@ -1,450 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -require 'spec_helper' - -describe 'get_afd_filters' do - - alarms_nodes = [ - {"name"=>"cpu-critical-controller", - "description"=>"The CPU usage is too high (controller node)", - "severity"=>"critical", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [ - {"metric"=>"cpu_idle", - "relational_operator"=>"<=", - "threshold"=>5, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - {"metric"=>"cpu_wait", - "relational_operator"=>">=", - "threshold"=>35, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - ]}}, - {"name"=>"cpu-warning-controller", - "description"=>"The CPU usage is high (controller node)", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [ - {"metric"=>"cpu_idle", - "relational_operator"=>"<=", - "threshold"=>15, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - {"metric"=>"cpu_wait", - "relational_operator"=>">=", - "threshold"=>25, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - ]}}, - {"name"=>"cpu-critical-compute", - "description"=>"The CPU usage is high (critical node)", - "severity"=>"critical", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [ - {"metric"=>"cpu_idle", - "relational_operator"=>"<=", - "threshold"=>30, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - ]}}, - {"name"=>"cpu-warning-compute", - "description"=>"The CPU usage is high (compute node)", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [ - {"metric"=>"cpu_idle", - "relational_operator"=>"<=", - "threshold"=>20, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - ]}}, - {"name"=>"fs-critical", - "description"=>"The FS usage is critical", - "severity"=>"critical", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [ - {"metric"=>"fs_percent_free", - "relational_operator"=>"<=", - "threshold"=>8, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - ]}}, - ] - - afds_nodes = { - "controller" => { - "apply_to_node" => "controller", - "alerting" => 'enabled', - "members" => { - "system" => { - "alerting" => 'enabled_with_notification', - "alarms" => ["cpu-critical-controller", "cpu-warning-controller"], - }, - "foo" => { - "alarms" => ["cpu-critical-controller", "cpu-warning-controller"], - } - }, - }, - "compute" => { - "apply_to_node" => "compute", - "alerting" => 'enabled_with_notification', - "members" => { - "system" => { - "alarms" => ["cpu-critical-compute", "cpu-warning-compute"], - }, - "fs" => { - "alarms" => ["fs-critical"], - } - }, - } - } - - describe 'For controller nodes' do - it { should run.with_params(afds_nodes, alarms_nodes, ['controller'], 'node') - .and_return( - {"controller_system"=> - {"type"=>"node", - "cluster_name"=>"controller", - "logical_name"=>"system", - "alarms"=>["cpu-critical-controller", "cpu-warning-controller"], - "alarms_definitions"=> alarms_nodes, - "message_matcher"=>"Fields[name] == 'cpu_idle' || Fields[name] == 'cpu_wait'", - "enable_notification" => true, - "activate_alerting" => true, - }, - "controller_foo"=> - {"type"=>"node", - "cluster_name"=>"controller", - "logical_name"=>"foo", - "alarms"=>["cpu-critical-controller", "cpu-warning-controller"], - "alarms_definitions"=> alarms_nodes, - "message_matcher"=>"Fields[name] == 'cpu_idle' || Fields[name] == 'cpu_wait'", - "enable_notification" => false, - "activate_alerting" => true, - } - }) - - } - end - describe 'For compute nodes' do - it { should run.with_params(afds_nodes, alarms_nodes, ['compute'], 'node') - .and_return( - {"compute_system"=> - {"type"=>"node", - "cluster_name"=>"compute", - "logical_name"=>"system", - "alarms"=>["cpu-critical-compute", "cpu-warning-compute"], - "alarms_definitions"=> alarms_nodes, - "message_matcher"=>"Fields[name] == 'cpu_idle'", - "activate_alerting" => true, - "enable_notification" => true, - }, - "compute_fs"=> - {"type"=>"node", - "cluster_name"=>"compute", - "logical_name"=>"fs", - "alarms"=>["fs-critical"], - "alarms_definitions"=> alarms_nodes, - "message_matcher"=>"Fields[name] == 'fs_percent_free'", - "activate_alerting" => true, - "enable_notification" => true, - } - }) - } - end - describe 'For compute and controller nodes' do - it { should run.with_params(afds_nodes, alarms_nodes, ['compute', 'controller'], 'node') - .and_return( - {"compute_system"=> - {"type"=>"node", - "cluster_name"=>"compute", - "logical_name"=>"system", - "alarms"=>["cpu-critical-compute", "cpu-warning-compute"], - "alarms_definitions"=> alarms_nodes, - "message_matcher"=>"Fields[name] == 'cpu_idle'", - "activate_alerting" => true, - "enable_notification" => true, - }, - "compute_fs"=> - {"type"=>"node", - "cluster_name"=>"compute", - "logical_name"=>"fs", - "alarms"=>["fs-critical"], - "alarms_definitions"=> alarms_nodes, - "message_matcher"=>"Fields[name] == 'fs_percent_free'", - "activate_alerting" => true, - "enable_notification" => true, - }, - "controller_system"=> - {"type"=>"node", - "cluster_name"=>"controller", - "logical_name"=>"system", - "alarms"=>["cpu-critical-controller", "cpu-warning-controller"], - "alarms_definitions"=> alarms_nodes, - "message_matcher"=>"Fields[name] == 'cpu_idle' || Fields[name] == 'cpu_wait'", - "activate_alerting" => true, - "enable_notification" => true, - }, - "controller_foo"=> - {"type"=>"node", - "cluster_name"=>"controller", - "logical_name"=>"foo", - "alarms"=>["cpu-critical-controller", "cpu-warning-controller"], - "alarms_definitions"=> alarms_nodes, - "message_matcher"=>"Fields[name] == 'cpu_idle' || Fields[name] == 'cpu_wait'", - "enable_notification" => false, - "activate_alerting" => true, - } - }) - } - end - - alarms_services = [ - {"name"=>"rabbitmq-queue-warning", - "description"=>"Number of message in queues too high", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [{"metric"=>"rabbitmq_messages", - "relational_operator"=>">=", - "threshold"=>200, - "window"=>120, - "periods"=>0, - "function"=>"avg"}]}}, - {"name"=>"apache-warning", - "description"=>"", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [{"metric"=>"apache_idle_workers", - "relational_operator"=>"=", - "threshold"=>0, - "window"=>60, - "periods"=>0, - "function"=>"min"}, - {"metric"=>"apache_status", - "relational_operator"=>"=", - "threshold"=>0, - "window"=>60, - "periods"=>0, - "function"=>"min"}]}} - ] - afds_services = { - "rabbitmq" => { - "apply_to_node" => "controller", - "alerting" => 'enabled', - "members" => { - "queue" => { - "alarms" => ["rabbitmq-queue-warning"] - } - }, - }, - "apache" => { - "apply_to_node" => "controller", - "alerting" => 'enabled', - "members" => { - "worker" => { - "alarms" => ['apache-warning'], - } - }, - }, - } - describe 'For services' do - it { should run.with_params(afds_services, alarms_services, ['controller'], 'service') - .and_return( - { - "rabbitmq_queue"=> - { - "type"=>"service", - "cluster_name"=>"rabbitmq", - "logical_name"=>"queue", - "alarms_definitions"=> alarms_services, - "alarms"=>["rabbitmq-queue-warning"], - "message_matcher"=>"Fields[name] == 'rabbitmq_messages'", - "activate_alerting" => true, - "enable_notification" => false, - }, - "apache_worker"=> - { - "type"=>"service", - "cluster_name"=>"apache", - "logical_name"=>"worker", - "alarms_definitions"=> alarms_services, - "alarms"=>["apache-warning"], - "message_matcher"=>"Fields[name] == 'apache_idle_workers' || Fields[name] == 'apache_status'", - "activate_alerting" => true, - "enable_notification" => false, - }} - - ) - } - end - describe 'For services with apply_to_node overriden by metric collected_on' do - alarms_services_o = [ - {"name"=>"free_vcpu_warning", - "description"=>"", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [{"metric"=>"free_vcpu", - "relational_operator"=>"<=", - "threshold"=>1, - "window"=>60, - "periods"=>0, - "function"=>"min"}, - ]}}, - {"name"=>"total_free_vcpu_warning", - "description"=>"", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [{"metric"=>"total_free_vcpu", - "relational_operator"=>"<=", - "threshold"=>10, - "window"=>60, - "periods"=>0, - "function"=>"min"}, - ]}}, - {"name"=>"cpu-critical-controller", - "description"=>"The CPU usage is high (critical node)", - "severity"=>"critical", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [ - {"metric"=>"cpu_idle", - "relational_operator"=>"<=", - "threshold"=>30, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - ]}}, - {"name"=>"cpu-warning-controller", - "description"=>"The CPU usage is high (controller node)", - "severity"=>"warning", - "trigger"=> - {"logical_operator"=>"or", - "rules"=> - [ - {"metric"=>"cpu_idle", - "relational_operator"=>"<=", - "threshold"=>20, - "window"=>120, - "periods"=>0, - "function"=>"avg"}, - ]}}, - - ] - afds_services_overriden = { - "nova-free-resources" => { - "apply_to_node" => "compute", - "alerting" => 'enabled', - "members" => { - "free-vcpu" => { - "alerting" => 'disabled', - "alarms" => ['free_vcpu_warning'], - } - }, - }, - "nova-total-free-resources" => { - "alerting" => 'enabled', - "members" => { - "total-free-vcpu" => { - "alarms" => ['total_free_vcpu_warning'], - } - }, - }, - "controller" => { - "apply_to_node" => "controller", - "alerting" => 'enabled_with_notification', - "members" => { - "system" => { - "alarms" => ["cpu-critical-controller", "cpu-warning-controller"], - } - }, - }, - } - metrics = { - "free_vcpu" => { - "collected_on" => "controller" - }, - "total_free_vcpu" => { - "collected_on" => "controller" - } - } - it { should run.with_params(afds_services_overriden, alarms_services_o, ['controller'], 'service', metrics) - .and_return( - { - "nova-free-resources_free-vcpu"=> - { - "type"=>"service", - "cluster_name"=>"nova-free-resources", - "logical_name"=>"free-vcpu", - "alarms_definitions"=> alarms_services_o, - "alarms"=>["free_vcpu_warning"], - "message_matcher"=>"Fields[name] == 'free_vcpu'", - "activate_alerting" => false, - "enable_notification" => false, - }, - "nova-total-free-resources_total-free-vcpu"=> - { - "type"=>"service", - "cluster_name"=>"nova-total-free-resources", - "logical_name"=>"total-free-vcpu", - "alarms_definitions"=> alarms_services_o, - "alarms"=>["total_free_vcpu_warning"], - "message_matcher"=>"Fields[name] == 'total_free_vcpu'", - "activate_alerting" => true, - "enable_notification" => false, - }, - "controller_system"=> - { - "type"=>"service", - "cluster_name"=>"controller", - "logical_name"=>"system", - "alarms"=>["cpu-critical-controller", "cpu-warning-controller"], - "alarms_definitions"=> alarms_services_o, - "message_matcher"=>"Fields[name] == 'cpu_idle'", - "enable_notification" => true, - "activate_alerting" => true, - } - } - ) - } - end -end - diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/spec.opts b/deployment_scripts/puppet/modules/fuel_lma_collector/spec/spec.opts deleted file mode 100644 index 91cd6427e..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/spec.opts +++ /dev/null @@ -1,6 +0,0 @@ ---format -s ---colour ---loadby -mtime ---backtrace diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/spec_helper.rb b/deployment_scripts/puppet/modules/fuel_lma_collector/spec/spec_helper.rb deleted file mode 100644 index d8df693e5..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/spec/spec_helper.rb +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'rspec-puppet' - -fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) - -RSpec.configure do |c| - c.module_path = File.join(fixture_path, 'modules') - c.manifest_dir = File.join(fixture_path, 'manifests') - c.environmentpath = File.join(Dir.pwd, 'spec') -end diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/alarming.yaml.erb b/deployment_scripts/puppet/modules/fuel_lma_collector/templates/alarming.yaml.erb deleted file mode 100644 index f4a1d139d..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/alarming.yaml.erb +++ /dev/null @@ -1,3691 +0,0 @@ ---- -lma_collector: - alarms: - - name: 'cpu-critical-controller' - description: 'The CPU usage is too high (controller node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - metric: cpu_wait - relational_operator: '>=' - threshold: 35 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-controller' - description: 'The CPU usage is high (controller node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 15 - window: 120 - periods: 0 - function: avg - - metric: cpu_wait - relational_operator: '>=' - threshold: 25 - window: 120 - periods: 0 - function: avg - - name: 'swap-usage-critical' - description: 'There is no more swap free space' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: swap_free - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: max - - name: 'swap-activity-warning' - description: 'The swap activity is high' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: swap_io_in - relational_operator: '>=' - threshold: 1048576 # 1 Mb/s - window: 120 - periods: 0 - function: avg - - metric: swap_io_out - relational_operator: '>=' - threshold: 1048576 # 1 Mb/s - window: 120 - periods: 0 - function: avg - - name: 'swap-usage-warning' - description: 'The swap free space is low' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: swap_percent_used - relational_operator: '>=' - threshold: 0.8 - window: 60 - periods: 0 - function: avg - - name: 'cpu-critical-compute' - description: 'The CPU usage is too high (compute node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 30 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-compute' - description: 'The CPU usage is high (compute node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 20 - window: 120 - periods: 0 - function: avg - - name: 'cpu-critical-rabbitmq' - description: 'The CPU usage is too high (RabbitMQ node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-rabbitmq' - description: 'The CPU usage is high (RabbitMQ node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 15 - window: 120 - periods: 0 - function: avg - - name: 'cpu-critical-mysql' - description: 'The CPU usage is too high (MySQL node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-mysql' - description: 'The CPU usage is high (MySQL node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 15 - window: 120 - periods: 0 - function: avg - - name: 'cpu-critical-storage' - description: 'The CPU usage is too high (storage node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 40 - window: 120 - periods: 0 - function: avg - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-storage' - description: 'The CPU usage is high (storage node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 30 - window: 120 - periods: 0 - function: avg - - metric: cpu_idle - relational_operator: '<=' - threshold: 15 - window: 120 - periods: 0 - function: avg - - name: 'cpu-critical-default' - description: 'The CPU usage is too high' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 35 - window: 120 - periods: 0 - function: avg - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - name: 'rabbitmq-disk-limit-critical' - description: 'RabbitMQ has reached the free disk threshold. All producers are blocked' - severity: 'critical' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_remaining_disk - relational_operator: '<=' - threshold: 0 - window: 20 - periods: 0 - function: min - - name: 'rabbitmq-disk-limit-warning' - description: 'RabbitMQ is getting close to the free disk threshold' - severity: 'warning' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_remaining_disk - relational_operator: '<=' - threshold: 104857600 # 100MB - window: 20 - periods: 0 - function: min - - name: 'rabbitmq-memory-limit-critical' - description: 'RabbitMQ has reached the memory threshold. All producers are blocked' - severity: 'critical' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_remaining_memory - relational_operator: '<=' - threshold: 0 - window: 20 - periods: 0 - function: min - - name: 'rabbitmq-memory-limit-warning' - description: 'RabbitMQ is getting close to the memory threshold' - severity: 'warning' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_remaining_memory - relational_operator: '<=' - threshold: 104857600 # 100MB - window: 20 - periods: 0 - function: min - - name: 'rabbitmq-queue-warning' - description: 'The number of outstanding messages is too high' - severity: 'warning' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_messages - relational_operator: '>=' - threshold: 200 - window: 120 - periods: 0 - function: avg - - name: 'rabbitmq-pacemaker-down' - description: 'The RabbitMQ cluster is down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - logical_operator: 'and' - rules: - - metric: pacemaker_resource_percent - fields: - resource: rabbitmq - status: up - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'rabbitmq-pacemaker-critical' - description: 'The RabbitMQ cluster is critical because less than half of the nodes are up' - severity: 'critical' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - logical_operator: 'and' - rules: - - metric: pacemaker_resource_percent - fields: - resource: rabbitmq - status: up - relational_operator: '<' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'rabbitmq-pacemaker-warning' - description: 'The RabbitMQ cluster is degraded because some RabbitMQ nodes are missing' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - logical_operator: 'and' - rules: - - metric: pacemaker_resource_percent - fields: - resource: rabbitmq - status: up - relational_operator: '<' - threshold: 100 - window: 60 - periods: 0 - function: last - - name: 'apache-warning' - description: 'There is no Apache idle workers available' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: apache_idle_workers - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: min - - name: 'apache-check' - description: 'Apache cannot be checked' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: apache_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'log-fs-warning' - description: "The log filesystem's free space is low" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/log' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'log-fs-critical' - description: "The log filesystem's free space is too low" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/log' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'root-fs-warning' - description: "The root filesystem's free space is low" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'root-fs-critical' - description: "The root filesystem's free space is too low" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'mysql-fs-warning' - description: "The MySQL filesystem's free space is low" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/mysql' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'mysql-fs-critical' - description: "The MySQL filesystem's free space is too low" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/mysql' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'nova-fs-warning' - description: "The filesystem's free space is low (compute node)" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/nova' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'nova-fs-critical' - description: "The filesystem's free space is too low (compute node)" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/nova' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'other-fs-warning' - description: "The filesystem's free space is low" - severity: 'warning' - enabled: 'true' - no_data_policy: 'okay' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '!= /var/lib/nova && != /var/log && != /var/lib/mysql && != / && !~ ceph%-%d+$' - group_by: [fs] - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'other-fs-critical' - description: "The filesystem's free space is too low" - severity: 'critical' - enabled: 'true' - no_data_policy: 'okay' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '!= /var/lib/nova && != /var/log && != /var/lib/mysql && != / && !~ ceph%-%d+$' - group_by: [fs] - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'osd-disk-critical' - description: "The filesystem's free space is too low (OSD disk)" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - # Real FS is /var/lib/ceph/osd/ceph-0 but Collectd substituted '/' by '-' - fs: '=~ ceph/%d+$' - group_by: [fs] - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'nova-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on nova-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'nova-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'nova-logs-error' - description: 'Too many errors have been detected in Nova logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'nova' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'heat-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on heat-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'heat-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'heat-logs-error' - description: 'Too many errors have been detected in Heat logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'heat' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'swift-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on swift-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'swift-api || object-storage' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'swift-logs-error' - description: 'Too many errors have been detected in Swift logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'swift' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'cinder-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on cinder-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'cinder-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'cinder-logs-error' - description: 'Too many errors have been detected in Cinder logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'cinder' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'glance-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on glance-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'glance-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'glance-logs-error' - description: 'Too many errors have been detected in Glance logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'glance' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'neutron-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on neutron-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'neutron-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'neutron-logs-error' - description: 'Too many errors have been detected in Neutron logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'neutron' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'keystone-response-time-duration' - description: 'Keystone API is too slow' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: openstack_keystone_http_response_times - fields: - http_method: '== GET || == POST' - http_status: '!= 5xx' - relational_operator: '>' - threshold: 0.3 - window: 60 - periods: 0 - value: upper_90 - function: max - - name: 'keystone-public-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on keystone-public-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'keystone-public-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'keystone-admin-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on keystone-admin-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'keystone-admin-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'horizon-web-http-errors' - description: 'Too many 5xx HTTP errors have been detected on horizon' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'horizon-web || horizon-https' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'keystone-logs-error' - description: 'Too many errors have been detected in Keystone logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'keystone' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'mysql-node-connected' - description: 'The MySQL service has lost connectivity with the other nodes' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: mysql_cluster_connected - relational_operator: '==' - threshold: 0 - window: 30 - periods: 1 - function: min - - name: 'mysql-node-ready' - description: "The MySQL service isn't ready to serve queries" - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: mysql_cluster_ready - relational_operator: '==' - threshold: 0 - window: 30 - periods: 1 - function: min - - name: 'ceph-health-critical' - description: 'Ceph health is critical' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: ceph_health - relational_operator: '==' - threshold: 3 # HEALTH_ERR - window: 60 - function: max - - name: 'ceph-health-warning' - description: 'Ceph health is warning' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: ceph_health - relational_operator: '==' - threshold: 2 # HEALTH_WARN - window: 60 - function: max - - name: 'ceph-capacity-critical' - description: 'Ceph free capacity is too low' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: ceph_pool_total_percent_free - relational_operator: '<' - threshold: 2 - window: 60 - function: max - - name: 'ceph-capacity-warning' - description: 'Ceph free capacity is low' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: ceph_pool_total_percent_free - relational_operator: '<' - threshold: 5 - window: 60 - function: max - - name: 'elasticsearch-health-critical' - description: 'Elasticsearch cluster health is critical' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: elasticsearch_cluster_health - relational_operator: '==' - threshold: 3 # red - window: 60 - function: min - - name: 'elasticsearch-health-warning' - description: 'Elasticsearch health is warning' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: elasticsearch_cluster_health - relational_operator: '==' - threshold: 2 # yellow - window: 60 - function: min - - name: 'elasticsearch-fs-warning' - description: "The filesystem's free space is low (Elasticsearch node)" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/opt/es/data' # Real FS is /opt/es-data but Collectd substituted '/' by '-' - relational_operator: '<' - threshold: 20 # The low watermark for disk usage is 85% by default - window: 60 - periods: 0 - function: min - - name: 'elasticsearch-fs-critical' - description: "The filesystem's free space is too low (Elasticsearch node)" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/opt/es/data' # Real FS is /opt/es-data but Collectd substituted '/' by '-' - relational_operator: '<' - threshold: 15 # The high watermark for disk usage is 90% by default - window: 60 - periods: 0 - function: min - - name: 'influxdb-fs-warning' - description: "The filesystem's free space is low (InfluxDB node)" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/influxdb' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'influxdb-fs-critical' - description: "The filesystem's free space is too low (InfluxDB node)" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/influxdb' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'haproxy-check' - description: "HAProxy cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'rabbitmq-check' - description: "RabbitMQ cannot be checked" - # This alarm's severity is warning because the effective status of the - # RabbitMQ cluster is computed by rabbitmq-pacemaker-* alarms. - # This alarm is still useful because it will report the node(s) on which - # RabbitMQ isn't running. - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: rabbitmq_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceph-mon-check' - description: "Ceph monitor cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: ceph_mon_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceph-osd-check' - description: "Ceph OSD cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: ceph_osd_check - relational_operator: '==' - threshold: 0 - window: 80 # The metric interval collection is 60s - periods: 0 - function: last - - name: 'pacemaker-check' - description: "Pacemaker cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: pacemaker_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'elasticsearch-check' - description: "Elasticsearch cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: elasticsearch_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'influxdb-check' - description: "InfluxDB cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: influxdb_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'libvirt-check' - description: "Libvirt cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: libvirt_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'memcached-check' - description: "memcached cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: memcached_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'mysql-check' - description: "MySQL cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: mysql_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'network-warning-dropped-rx' - description: "Some received packets have been dropped" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: if_dropped_rx - relational_operator: '>' - threshold: 100 - window: 60 - periods: 0 - function: avg - - name: 'network-critical-dropped-rx' - description: "Too many received packets have been dropped" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: if_dropped_rx - relational_operator: '>' - threshold: 1000 - window: 60 - periods: 0 - function: avg - - name: 'network-warning-dropped-tx' - description: "Some transmitted packets have been dropped" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: if_dropped_tx - relational_operator: '>' - threshold: 100 - window: 60 - periods: 0 - function: avg - - name: 'network-critical-dropped-tx' - description: "Too many transmitted packets have been dropped" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: if_dropped_tx - relational_operator: '>' - threshold: 1000 - function: avg - window: 60 - - name: 'instance-creation-time-warning' - description: "Instance creation takes too much time" - severity: 'warning' - no_data_policy: 'okay' # This is a sporadic metric - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_instance_creation_time - relational_operator: '>' - threshold: 20 - window: 600 - periods: 0 - function: avg - - name: 'hdd-errors-critical' - description: 'Errors on hard drive(s) have been detected' - severity: 'critical' - enabled: 'true' - no_data_policy: okay - trigger: - rules: - - metric: hdd_errors_rate - group_by: ['device'] - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: max - - name: 'total-nova-free-vcpu-warning' - description: 'There is none VCPU available for new instances' - severity: 'warning' - enabled: 'true' - no_data_policy: skip # the metric is only collected from the aggregator node - trigger: - rules: - - metric: openstack_nova_total_free_vcpus - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: max - - name: 'total-nova-free-memory-warning' - description: 'There is none memory available for new instances' - severity: 'warning' - enabled: 'true' - no_data_policy: skip # the metric is only collected from the aggregator node - trigger: - rules: - - metric: openstack_nova_total_free_ram - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: max - - name: 'nova-aggregates-free-memory-warning' - description: "The nova aggregates free memory percent is low" - severity: 'warning' - enabled: 'true' - no_data_policy: skip # the metric is only collected from the aggregator node - trigger: - rules: - - metric: openstack_nova_aggregate_free_ram_percent - group_by: [aggregate] - relational_operator: '<' - threshold: 10.0 - window: 60 - periods: 0 - function: min - - name: 'nova-aggregates-free-memory-critical' - description: "The nova aggregates free memory percent is too low" - severity: 'critical' - enabled: 'true' - no_data_policy: skip # the metric is only collected from the aggregator node - trigger: - rules: - - metric: openstack_nova_aggregate_free_ram_percent - group_by: [aggregate] - relational_operator: '<' - threshold: 1.0 - window: 60 - periods: 0 - function: min - - # Adds alarm on local check for OpenStack services endpoint - - name: 'cinder-api-local-endpoint' - description: 'Cinder API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'cinder-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-api-local-endpoint' - description: 'Glance API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'glance-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-api-local-endpoint' - description: 'Heat API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'heat-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-local-endpoint' - description: 'Heat CFN API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'heat-cfn-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-local-endpoint' - description: 'Keystone public API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'keystone-public-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-local-endpoint' - description: 'Neutron API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'neutron-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-api-local-endpoint' - description: 'Nova API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'nova-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-api-local-endpoint' - description: 'Swift API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'swift-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - # Following are the OpenStack service check API definitions and - # also InfluxDB API - - name: 'influxdb-api-check-failed' - description: 'Endpoint check for InfluxDB is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: http_check - fields: - service: 'influxdb-cluster' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-api-check-failed' - description: 'Endpoint check for nova-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'nova-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-check-failed' - description: 'Endpoint check for neutron-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'neutron-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-api-check-failed' - description: 'Endpoint check for cinder-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'cinder-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-v2-api-check-failed' - description: 'Endpoint check for cinder-v2-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'cinder-v2-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-api-check-failed' - description: 'Endpoint check for glance-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'glance-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-api-check-failed' - description: 'Endpoint check for heat-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'heat-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-check-failed' - description: 'Endpoint check for heat-cfn-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'heat-cfn-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-api-check-failed' - description: 'Endpoint check for swift-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'swift-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-s3-api-check-failed' - description: 'Endpoint check for swift-s3-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'swift-s3-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-check-failed' - description: 'Endpoint check for keystone-public-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'keystone-public-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceilometer-api-check-failed' - description: 'Endpoint check for ceilometer-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'ceilometer-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - # Following are the AFD generated to check API backends - # All backends are down - - name: 'elasticsearch-api-backends-all-down' - description: 'All Elasticsearch backends are down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'elasticsearch-rest' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'kibana-api-backends-all-down' - description: 'All API backends are down for Kibana' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'kibana' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'influxdb-api-backends-all-down' - description: 'All API backends are down for InfluxDB' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'influxdb' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'grafana-api-backends-all-down' - description: 'All API backends are down for Grafana' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'grafana' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-registry-api-backends-all-down' - description: 'All API backends are down for glance-registry-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'glance-registry-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-api-backends-all-down' - description: 'All API backends are down for nova-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-api-backends-all-down' - description: 'All API backends are down for cinder-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'cinder-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'object-storage-api-backends-all-down' - description: 'All API backends are down for object-storage' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'object-storage' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-backends-all-down' - description: 'All API backends are down for heat-cfn-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-cfn-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'horizon-web-api-backends-all-down' - description: 'All API backends are down for horizon-web' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'horizon-web || horizon-https' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-novncproxy-websocket-api-backends-all-down' - description: 'All API backends are down for nova-novncproxy-websocket' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-novncproxy-websocket' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-api-backends-all-down' - description: 'All API backends are down for heat-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-backends-all-down' - description: 'All API backends are down for keystone-public-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'keystone-public-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cloudwatch-api-backends-all-down' - description: 'All API backends are down for heat-cloudwatch-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-cloudwatch-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-metadata-api-backends-all-down' - description: 'All API backends are down for nova-metadata-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-metadata-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'mysqld-tcp-api-backends-all-down' - description: 'All API backends are down for mysqld-tcp' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'mysqld-tcp' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-admin-api-backends-all-down' - description: 'All API backends are down for keystone-admin-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'keystone-admin-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-api-backends-all-down' - description: 'All API backends are down for glance-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'glance-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-backends-all-down' - description: 'All API backends are down for neutron-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'neutron-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-api-backends-all-down' - description: 'All API backends are down for swift-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'swift-api || object-storage' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceilometer-api-backends-all-down' - description: 'All API backends are down for ceilometer-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'ceilometer-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - # At least one backend is down - - name: 'elasticsearch-api-backends-one-down' - description: 'At least one API backend is down for elasticsearch' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'elasticsearch-rest' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'kibana-api-backends-one-down' - description: 'At least one API backend is down for kibana' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'kibana' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'influxdb-api-backends-one-down' - description: 'At least one API backend is down for influxdb' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'influxdb' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'grafana-api-backends-one-down' - description: 'At least one API backend is down for grafana' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'grafana' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-registry-api-backends-one-down' - description: 'At least one API backend is down for glance-registry-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'glance-registry-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-api-backends-one-down' - description: 'At least one API backend is down for nova-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-api-backends-one-down' - description: 'At least one API backend is down for cinder-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'cinder-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'object-storage-api-backends-one-down' - description: 'At least one API backend is down for object-storage' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'object-storage' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-backends-one-down' - description: 'At least one API backend is down for heat-cfn-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-cfn-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'horizon-web-api-backends-one-down' - description: 'At least one API backend is down for horizon-web' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'horizon-web || horizon-https' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-novncproxy-websocket-api-backends-one-down' - description: 'At least one API backend is down for nova-novncproxy-websocket' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-novncproxy-websocket' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-api-backends-one-down' - description: 'At least one API backend is down for heat-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-backends-one-down' - description: 'At least one API backend is down for keystone-public-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'keystone-public-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cloudwatch-api-backends-one-down' - description: 'At least one API backend is down for heat-cloudwatch-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-cloudwatch-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-metadata-api-backends-one-down' - description: 'At least one API backend is down for nova-metadata-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-metadata-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'mysqld-tcp-api-backends-one-down' - description: 'At least one API backend is down for mysqld-tcp' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'mysqld-tcp' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-admin-api-backends-one-down' - description: 'At least one API backend is down for keystone-admin-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'keystone-admin-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-api-backends-one-down' - description: 'At least one API backend is down for glance-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'glance-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-backends-one-down' - description: 'At least one API backend is down for neutron-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'neutron-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-api-backends-one-down' - description: 'At least one API backend is down for swift-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'swift-api || object-storage' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceilometer-api-backends-one-down' - description: 'At least one API backend is down for ceilometer-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'ceilometer-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - # Less than 50% of backends are up - - name: 'elasticsearch-api-backends-majority-down' - description: 'Less than 50% of backends are up for elasticsearch' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'elasticsearch-rest' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'kibana-api-backends-majority-down' - description: 'Less than 50% of backends are up for kibana' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'kibana' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'influxdb-api-backends-majority-down' - description: 'Less than 50% of backends are up for influxdb' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'influxdb' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'grafana-api-backends-majority-down' - description: 'Less than 50% of backends are up for grafana' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'grafana' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'glance-registry-api-backends-majority-down' - description: 'Less than 50% of backends are up for glance-registry-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'glance-registry-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-api-backends-majority-down' - description: 'Less than 50% of backends are up for nova-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'nova-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'cinder-api-backends-majority-down' - description: 'Less than 50% of backends are up for cinder-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'cinder-api' - state: 'up' - - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'object-storage-api-backends-majority-down' - description: 'Less than 50% of backends are up for object-storage' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'object-storage' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-backends-majority-down' - description: 'Less than 50% of backends are up for heat-cfn-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'heat-cfn-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'horizon-web-api-backends-majority-down' - description: 'Less than 50% of backends are up for horizon-web' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'horizon-web || horizon-https' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-novncproxy-websocket-api-backends-majority-down' - description: 'Less than 50% of backends are up for nova-novncproxy-websocket' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'nova-novncproxy-websocket' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'heat-api-backends-majority-down' - description: 'Less than 50% of backends are up for heat-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'heat-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-backends-majority-down' - description: 'Less than 50% of backends are up for keystone-public-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'keystone-public-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'heat-cloudwatch-api-backends-majority-down' - description: 'Less than 50% of backends are up for heat-cloudwatch-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'heat-cloudwatch-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-metadata-api-backends-majority-down' - description: 'Less than 50% of backends are up for nova-metadata-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'nova-metadata-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'mysqld-tcp-api-backends-majority-down' - description: 'Less than 50% of backends are up for mysqld-tcp' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'mysqld-tcp' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'keystone-admin-api-backends-majority-down' - description: 'Less than 50% of backends are up for keystone-admin-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'keystone-admin-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'glance-api-backends-majority-down' - description: 'Less than 50% of backends are up for glance-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'glance-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-backends-majority-down' - description: 'Less than 50% of backends are up for neutron-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'neutron-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'swift-api-backends-majority-down' - description: 'Less than 50% of backends are up for swift-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'swift-api || object-storage' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'ceilometer-api-backends-majority-down' - description: 'Less than 50% of backends are up for ceilometer-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'ceilometer-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - # Following are the AFD generated to check workers - # All workers are down - - name: 'nova-scheduler-all-down' - description: 'All Nova schedulers are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'scheduler' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-cert-all-down' - description: 'All Nova certs are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'cert' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-consoleauth-all-down' - description: 'All Nova consoleauths are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'consoleauth' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-compute-all-down' - description: 'All Nova computes are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'compute' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-conductor-all-down' - description: 'All Nova conductors are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'conductor' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-scheduler-all-down' - description: 'All Cinder schedulers are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services - fields: - service: 'scheduler' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-volume-all-down' - description: 'All Cinder volumes are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services - fields: - service: 'volume' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-l3-all-down' - description: 'All Neutron L3 agents are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'l3' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-dhcp-all-down' - description: 'All Neutron DHCP agents are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'dhcp' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-metadata-all-down' - description: 'All Neutron metadata agents are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'metadata' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-openvswitch-all-down' - description: 'All Neutron openvswitch agents are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'openvswitch' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - # At least one backend is down - - name: 'nova-scheduler-one-down' - description: 'At least one Nova scheduler is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'scheduler' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-cert-one-down' - description: 'At least one Nova cert is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'cert' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-consoleauth-one-down' - description: 'At least one Nova consoleauth is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'consoleauth' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-compute-one-down' - description: 'At least one Nova compute is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'compute' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-conductor-one-down' - description: 'At least one Nova conductor is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'conductor' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-scheduler-one-down' - description: 'At least one Cinder scheduler is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services - fields: - service: 'scheduler' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-volume-one-down' - description: 'At least one Cinder volume is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services - fields: - service: 'volume' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-l3-one-down' - description: 'At least one L3 agent is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'l3' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-dhcp-one-down' - description: 'At least one DHCP agent is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'dhcp' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-metadata-one-down' - description: 'At least one metadata agents is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'metadata' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-openvswitch-one-down' - description: 'At least one openvswitch agents is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'openvswitch' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - # Less than 50% of service are up (compared to up and down). - - name: 'nova-scheduler-majority-down' - description: 'Less than 50% of Nova schedulers are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'scheduler' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-cert-majority-down' - description: 'Less than 50% of Nova certs are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'cert' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-consoleauth-majority-down' - description: 'Less than 50% of Nova consoleauths are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'consoleauth' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-compute-majority-down' - description: 'Less than 50% of Nova computes are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'compute' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-conductor-majority-down' - description: 'Less than 50% of Nova conductors are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'conductor' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'cinder-scheduler-majority-down' - description: 'Less than 50% of Cinder schedulers are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services_percent - fields: - service: 'scheduler' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'cinder-volume-majority-down' - description: 'Less than 50% of Cinder volumes are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services_percent - fields: - service: 'volume' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-l3-majority-down' - description: 'Less than 50% of Neutron L3 agents are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents_percent - fields: - service: 'l3' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-dhcp-majority-down' - description: 'Less than 50% of Neutron DHCP agents are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents_percent - fields: - service: 'dhcp' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-metadata-majority-down' - description: 'Less than 50% of Neutron metadata agents are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents_percent - fields: - service: 'metadata' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-openvswitch-majority-down' - description: 'Less than 50% of Neutron openvswitch agents are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents_percent - fields: - service: 'openvswitch' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - # Definition of the AFD node filters - node_cluster_alarms: - controller: - apply_to_node: controller - alerting: enabled - members: - cpu: - alarms: ['cpu-critical-controller', 'cpu-warning-controller'] - network-rx: - alarms: ['network-critical-dropped-rx', 'network-warning-dropped-rx'] - network-tx: - alarms: ['network-critical-dropped-tx', 'network-warning-dropped-tx'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - log-fs: - alarms: ['log-fs-critical', 'log-fs-warning'] - other-fs: - alarms: ['other-fs-critical', 'other-fs-warning'] - swap: - alarms: ['swap-usage-critical', 'swap-activity-warning', 'swap-usage-warning'] - hdd-errors: - alerting: enabled_with_notification - alarms: ['hdd-errors-critical'] -<% if @detach_rabbitmq_enabled -%> - rabbitmq-nodes: - apply_to_node: rabbitmq-nodes - alerting: enabled - members: - cpu: - alarms: ['cpu-critical-rabbitmq', 'cpu-warning-rabbitmq'] - network-rx: - alarms: ['network-critical-dropped-rx', 'network-warning-dropped-rx'] - network-tx: - alarms: ['network-critical-dropped-tx', 'network-warning-dropped-tx'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - other-fs: - alarms: ['other-fs-critical', 'other-fs-warning'] - swap: - alarms: ['swap-usage-critical', 'swap-activity-warning', 'swap-usage-warning'] - hdd-errors: - alerting: enabled_with_notification - alarms: ['hdd-errors-critical'] -<% end -%> - mysql-nodes: - apply_to_node: mysql-nodes - alerting: enabled - members: -<% if @detach_database_enabled -%> - cpu: - alarms: ['cpu-critical-mysql', 'cpu-warning-mysql'] - network-rx: - alarms: ['network-critical-dropped-rx', 'network-warning-dropped-rx'] - network-tx: - alarms: ['network-critical-dropped-tx', 'network-warning-dropped-tx'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - other-fs: - alarms: ['other-fs-critical', 'other-fs-warning'] - swap: - alarms: ['swap-usage-critical', 'swap-activity-warning', 'swap-usage-warning'] - hdd-errors: - alerting: enabled_with_notification - alarms: ['hdd-errors-critical'] -<% end -%> - mysql-fs: - alarms: ['mysql-fs-critical', 'mysql-fs-warning'] - compute: - apply_to_node: compute - alerting: enabled - members: - cpu: - alarms: ['cpu-critical-compute', 'cpu-warning-compute'] - network-rx: - alarms: ['network-critical-dropped-rx', 'network-warning-dropped-rx'] - network-tx: - alarms: ['network-critical-dropped-tx', 'network-warning-dropped-tx'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - nova-fs: - alarms: ['nova-fs-critical', 'nova-fs-warning'] - other-fs: - alarms: ['other-fs-critical', 'other-fs-warning'] - swap: - alarms: ['swap-usage-critical', 'swap-activity-warning', 'swap-usage-warning'] - hdd-errors: - alerting: enabled_with_notification - alarms: ['hdd-errors-critical'] - storage: - apply_to_node: storage - alerting: enabled - members: - cpu: - alarms: ['cpu-critical-storage', 'cpu-warning-storage'] - network-rx: - alarms: ['network-critical-dropped-rx', 'network-warning-dropped-rx'] - network-tx: - alarms: ['network-critical-dropped-tx', 'network-warning-dropped-tx'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - other-fs: - alarms: ['other-fs-critical', 'other-fs-warning'] - swap: - alarms: ['swap-usage-critical', 'swap-activity-warning', 'swap-usage-warning'] - hdd-errors: - alerting: enabled_with_notification - alarms: ['hdd-errors-critical'] -<% if @storage_options["volumes_ceph"] then -%> - osd-disk: - alarms: ['osd-disk-critical'] -<% end -%> - elasticsearch-nodes: - apply_to_node: elasticsearch-nodes - alerting: enabled - members: - cpu: - alarms: ['cpu-critical-default'] - network-rx: - alarms: ['network-critical-dropped-rx', 'network-warning-dropped-rx'] - network-tx: - alarms: ['network-critical-dropped-tx', 'network-warning-dropped-tx'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - data-fs: - alarms: ['elasticsearch-fs-critical', 'elasticsearch-fs-warning'] - swap: - alarms: ['swap-usage-critical', 'swap-activity-warning', 'swap-usage-warning'] - hdd-errors: - alerting: enabled_with_notification - alarms: ['hdd-errors-critical'] - influxdb-nodes: - apply_to_node: influxdb-nodes - alerting: enabled - members: - cpu: - alarms: ['cpu-critical-default'] - network-rx: - alarms: ['network-critical-dropped-rx', 'network-warning-dropped-rx'] - network-tx: - alarms: ['network-critical-dropped-tx', 'network-warning-dropped-tx'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - data-fs: - alarms: ['influxdb-fs-critical', 'influxdb-fs-warning'] - swap: - alarms: ['swap-usage-critical', 'swap-activity-warning', 'swap-usage-warning'] - hdd-errors: - alerting: enabled_with_notification - alarms: ['hdd-errors-critical'] - # This is the default members configured for all nodes with unknown roles - default: - apply_to_node: default - # Operator wants to receive alert notification for individual nodes - alerting: enabled_with_notification - members: - cpu: - alarms: ['cpu-critical-default'] - network-rx: - alarms: ['network-critical-dropped-rx', 'network-warning-dropped-rx'] - network-tx: - alarms: ['network-critical-dropped-tx', 'network-warning-dropped-tx'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - other-fs: - alarms: ['other-fs-critical', 'other-fs-warning'] - swap: - alarms: ['swap-usage-critical', 'swap-activity-warning', 'swap-usage-warning'] - hdd-errors: - alarms: ['hdd-errors-critical'] - - # Definition of the AFD service filters - service_cluster_alarms: - rabbitmq-cluster: - apply_to_node: rabbitmq-nodes - alerting: enabled - members: - pacemaker: - alarms: ['rabbitmq-pacemaker-down', 'rabbitmq-pacemaker-critical', 'rabbitmq-pacemaker-warning'] - queue: - alarms: ['rabbitmq-queue-warning'] - memory: - alarms: ['rabbitmq-memory-limit-critical', 'rabbitmq-memory-limit-warning'] - disk: - alarms: ['rabbitmq-disk-limit-critical', 'rabbitmq-disk-limit-warning'] - rabbitmq-service: - apply_to_node: rabbitmq-nodes - alerting: enabled - members: - check: - alarms: ['rabbitmq-check'] - mysql: - apply_to_node: mysql-nodes - alerting: enabled - members: - node-status: - alarms: ['mysql-node-connected', 'mysql-node-ready'] - check: - alarms: ['mysql-check'] - apache: - apply_to_node: controller - alerting: enabled - members: - worker: - alarms: ['apache-warning'] - check: - alarms: ['apache-check'] - nova-api: - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['nova-api-http-errors'] - backends: - alarms: - - 'nova-api-backends-all-down' - - 'nova-api-backends-majority-down' - - 'nova-api-backends-one-down' - nova-api-check: - alerting: enabled - members: - vip: - alarms: ['nova-api-check-failed'] - nova-metadata-api: - apply_to_node: controller - alerting: enabled - members: - backends: - alarms: - - 'nova-metadata-api-backends-all-down' - - 'nova-metadata-api-backends-majority-down' - - 'nova-metadata-api-backends-one-down' - nova-novncproxy-websocket: - apply_to_node: controller - alerting: enabled - members: - backends: - alarms: - - 'nova-novncproxy-websocket-api-backends-all-down' - - 'nova-novncproxy-websocket-api-backends-majority-down' - - 'nova-novncproxy-websocket-api-backends-one-down' - nova-api-endpoint: - apply_to_node: controller - alerting: enabled - members: - endpoint: - alarms: ['nova-api-local-endpoint'] - nova-logs: - apply_to_node: controller - alerting: enabled - members: - error: - alarms: ['nova-logs-error'] - nova-logs-compute: - apply_to_node: compute - alerting: enabled - members: - error: - alarms: ['nova-logs-error'] - nova-cert: - alerting: enabled - members: - workers: - alarms: - - 'nova-cert-all-down' - - 'nova-cert-majority-down' - - 'nova-cert-one-down' - nova-consoleauth: - alerting: enabled - members: - workers: - alarms: - - 'nova-consoleauth-all-down' - - 'nova-consoleauth-majority-down' - - 'nova-consoleauth-one-down' - nova-compute: - alerting: enabled - members: - workers: - alarms: - - 'nova-compute-all-down' - - 'nova-compute-majority-down' - - 'nova-compute-one-down' - nova-conductor: - alerting: enabled - members: - workers: - alarms: - - 'nova-conductor-all-down' - - 'nova-conductor-majority-down' - - 'nova-conductor-one-down' - nova-scheduler: - alerting: enabled - members: - workers: - alarms: - - 'nova-scheduler-all-down' - - 'nova-scheduler-majority-down' - - 'nova-scheduler-one-down' - heat-api: - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['heat-api-http-errors'] - backends: - alarms: - - 'heat-api-backends-all-down' - - 'heat-api-backends-majority-down' - - 'heat-api-backends-one-down' - heat-cfn-api: - apply_to_node: controller - alerting: enabled - members: - backends: - alarms: - - 'heat-cfn-api-backends-all-down' - - 'heat-cfn-api-backends-majority-down' - - 'heat-cfn-api-backends-one-down' - heat-cloudwatch-api: - apply_to_node: controller - alerting: enabled - members: - backends: - alarms: - - 'heat-cloudwatch-api-backends-all-down' - - 'heat-cloudwatch-api-backends-majority-down' - - 'heat-cloudwatch-api-backends-one-down' - heat-api-check: - alerting: enabled - members: - vip: - alarms: ['heat-api-check-failed'] - heat-cfn-api-check: - alerting: enabled - members: - vip: - alarms: ['heat-cfn-api-check-failed'] - heat-api-endpoint: - apply_to_node: controller - alerting: enabled - members: - endpoint: - alarms: ['heat-api-local-endpoint'] - heat-cfn-api-endpoint: - apply_to_node: controller - alerting: enabled - members: - endpoint: - alarms: ['heat-cfn-api-local-endpoint'] - heat-logs: - apply_to_node: controller - alerting: enabled - members: - error: - alarms: ['heat-logs-error'] -<% if not @storage_options["objects_ceph"] then -%> - swift-api: - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['swift-api-http-errors'] - backends: - alarms: - - 'swift-api-backends-all-down' - - 'swift-api-backends-majority-down' - - 'swift-api-backends-one-down' - swift-api-check: - alerting: enabled - members: - vip: - alarms: ['swift-api-check-failed'] - swift-api-endpoint: - apply_to_node: controller - alerting: enabled - members: - endpoint: - alarms: ['swift-api-local-endpoint'] - swift-s3-api-check: - alerting: enabled - members: - vip: - alarms: ['swift-s3-api-check-failed'] - swift-logs: - apply_to_node: controller - alerting: enabled - members: - error: - alarms: ['swift-logs-error'] -<% end -%> - cinder-api: - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['cinder-api-http-errors'] - backends: - alarms: - - 'cinder-api-backends-all-down' - - 'cinder-api-backends-majority-down' - - 'cinder-api-backends-one-down' - cinder-api-check: - alerting: enabled - members: - vip: - alarms: ['cinder-api-check-failed'] - cinder-v2-api-check: - alerting: enabled - members: - vip: - alarms: ['cinder-v2-api-check-failed'] - cinder-api-endpoint: - apply_to_node: controller - alerting: enabled - members: - endpoint: - alarms: ['cinder-api-local-endpoint'] - cinder-logs: - apply_to_node: controller - alerting: enabled - members: - error: - alarms: ['cinder-logs-error'] - cinder-scheduler: - alerting: enabled - members: - workers: - alarms: - - 'cinder-scheduler-all-down' - - 'cinder-scheduler-majority-down' - - 'cinder-scheduler-one-down' - cinder-volume: - alerting: enabled - members: - workers: - alarms: - - 'cinder-volume-all-down' - - 'cinder-volume-majority-down' - - 'cinder-volume-one-down' -<% if not @storage_options["volumes_ceph"] then -%> - cinder-volume-logs: - apply_to_node: storage - alerting: enabled - members: - error: - alarms: ['cinder-logs-error'] -<% end -%> - glance-api: - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['glance-api-http-errors'] - backends: - alarms: - - 'glance-api-backends-all-down' - - 'glance-api-backends-majority-down' - - 'glance-api-backends-one-down' - glance-registry-api: - apply_to_node: controller - alerting: enabled - members: - backends: - alarms: - - 'glance-registry-api-backends-all-down' - - 'glance-registry-api-backends-majority-down' - - 'glance-registry-api-backends-one-down' - glance-api-check: - alerting: enabled - members: - vip: - alarms: ['glance-api-check-failed'] - glance-api-endpoint: - apply_to_node: controller - alerting: enabled - members: - endpoint: - alarms: ['glance-api-local-endpoint'] - glance-logs: - apply_to_node: controller - alerting: enabled - members: - error: - alarms: ['glance-logs-error'] - neutron-api: - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['neutron-api-http-errors'] - backends: - alarms: - - 'neutron-api-backends-all-down' - - 'neutron-api-backends-majority-down' - - 'neutron-api-backends-one-down' - neutron-api-check: - alerting: enabled - members: - vip: - alarms: ['neutron-api-check-failed'] - neutron-api-endpoint: - apply_to_node: controller - alerting: enabled - members: - endpoint: - alarms: ['neutron-api-local-endpoint'] - neutron-logs: - apply_to_node: controller - alerting: enabled - members: - error: - alarms: ['neutron-logs-error'] - neutron-l3: - alerting: enabled - members: - workers: - alarms: - - 'neutron-l3-all-down' - - 'neutron-l3-majority-down' - - 'neutron-l3-one-down' - neutron-dhcp: - alerting: enabled - members: - workers: - alarms: - - 'neutron-dhcp-all-down' - - 'neutron-dhcp-majority-down' - - 'neutron-dhcp-one-down' - neutron-metadata: - alerting: enabled - members: - workers: - alarms: - - 'neutron-metadata-all-down' - - 'neutron-metadata-majority-down' - - 'neutron-metadata-one-down' - neutron-openvswitch: - alerting: enabled - members: - workers: - alarms: - - 'neutron-openvswitch-all-down' - - 'neutron-openvswitch-majority-down' - - 'neutron-openvswitch-one-down' - neutron-logs-compute: - apply_to_node: compute - alerting: enabled - members: - error: - alarms: ['neutron-logs-error'] - keystone-response-time: - apply_to_node: controller - alerting: enabled - members: - duration: - alarms: ['keystone-response-time-duration'] - keystone-public-api: - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['keystone-public-api-http-errors'] - backends: - alarms: - - 'keystone-public-api-backends-all-down' - - 'keystone-public-api-backends-majority-down' - - 'keystone-public-api-backends-one-down' - keystone-public-api-check: - alerting: enabled - members: - vip: - alarms: ['keystone-public-api-check-failed'] - keystone-public-api-endpoint: - apply_to_node: controller - alerting: enabled - members: - endpoint: - alarms: ['keystone-public-api-local-endpoint'] - keystone-logs: - apply_to_node: controller - alerting: enabled - members: - error: - alarms: ['keystone-logs-error'] - keystone-admin-api: - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['keystone-admin-api-http-errors'] - backends: - alarms: - - 'keystone-admin-api-backends-all-down' - - 'keystone-admin-api-backends-majority-down' - - 'keystone-admin-api-backends-one-down' -<% if @tls_enabled then -%> - horizon-https: -<% else -%> - horizon-web: -<% end -%> - apply_to_node: controller - alerting: enabled - members: - http_errors: - alarms: ['horizon-web-http-errors'] - backends: - alarms: - - 'horizon-web-api-backends-all-down' - - 'horizon-web-api-backends-majority-down' - - 'horizon-web-api-backends-one-down' - nova-instances: - #TODO(scroiset): apply on compute nodes - apply_to_node: controller - alerting: enabled - members: - creation-time: - alarms: ['instance-creation-time-warning'] - nova-free-vcpu: - alerting: enabled - members: - nova-free-vcpu: - alarms: ['total-nova-free-vcpu-warning'] - nova-free-memory: - alerting: enabled - members: - nova-free-memory: - alarms: ['total-nova-free-memory-warning'] - nova-aggregates-free-memory: - alarms: ['nova-aggregates-free-memory-critical', 'nova-aggregates-free-memory-warning'] - ceph-mon-cluster: - apply_to_node: ceph-mon - alerting: enabled - members: - health: - alarms: ['ceph-health-critical', 'ceph-health-warning'] - capacity: - alarms: ['ceph-capacity-critical', 'ceph-capacity-warning'] - ceph-mon-service: - apply_to_node: ceph-mon - alerting: enabled - members: - check: - alarms: ['ceph-mon-check'] -<% if @storage_options["volumes_ceph"] then -%> - ceph-osd-service: - apply_to_node: storage - alerting: enabled - members: - check: - alarms: ['ceph-osd-check'] -<% end -%> - elasticsearch-cluster: - apply_to_node: elasticsearch-nodes - alerting: enabled - members: - health: - alarms: ['elasticsearch-health-critical', 'elasticsearch-health-warning'] - elasticsearch-service: - apply_to_node: elasticsearch-nodes - alerting: enabled - members: - check: - alarms: ['elasticsearch-check'] - influxdb-service: - apply_to_node: influxdb-nodes - alerting: enabled - members: - check: - alarms: ['influxdb-check'] - influxdb-api-check: - alerting: enabled - members: - vip: - alarms: ['influxdb-api-check-failed'] - haproxy-openstack: - apply_to_node: controller - alerting: enabled - members: - check: - alarms: ['haproxy-check'] - pacemaker-service: - apply_to_node: controller - alerting: enabled - members: - check: - alarms: ['pacemaker-check'] - libvirt-service: - apply_to_node: compute - alerting: enabled - members: - check: - alarms: ['libvirt-check'] - memcached-service: - apply_to_node: controller - alerting: enabled - members: - check: - alarms: ['memcached-check'] - ceilometer-api-check: - alerting: enabled - members: - vip: - alarms: ['ceilometer-api-check-failed'] - mysqld-tcp: - apply_to_node: controller - alerting: enabled - members: - backends: - alarms: - - 'mysqld-tcp-api-backends-all-down' - - 'mysqld-tcp-api-backends-majority-down' - - 'mysqld-tcp-api-backends-one-down' diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/apache/status.conf.erb b/deployment_scripts/puppet/modules/fuel_lma_collector/templates/apache/status.conf.erb deleted file mode 100644 index f932be0a9..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/apache/status.conf.erb +++ /dev/null @@ -1,13 +0,0 @@ - - SetHandler server-status - Order deny,allow - Deny from all - Allow from <%= @allow_from.join(" ") %> - - -ExtendedStatus On - - - # Show Proxy LoadBalancer status in mod_status - ProxyStatus On - diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/apache/status.load.erb b/deployment_scripts/puppet/modules/fuel_lma_collector/templates/apache/status.load.erb deleted file mode 100644 index fb8f8a889..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/apache/status.load.erb +++ /dev/null @@ -1 +0,0 @@ -LoadModule status_module <%= @lib_path %>/mod_status.so diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/clusters.yaml.erb b/deployment_scripts/puppet/modules/fuel_lma_collector/templates/clusters.yaml.erb deleted file mode 100644 index 35be38436..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/clusters.yaml.erb +++ /dev/null @@ -1,976 +0,0 @@ ---- -lma_collector: - - # The GSE policies are applied to clusters and describe how the the GSE - # cluster filter computes the cluster's status. The LMA toolchain is - # pre-configured with a few set of policies but everything can be customized: - # thresholds can be modified, new policies can be defined, and so on. - # - # A policy consists of a list of rules which are evaluated against the - # current status of the cluster's members. When one of the rules matches, the - # cluster's status gets the value associated with the rule and the evaluation - # stops here. The last rule of the list is usually a catch-all rule that - # defines the default status in case no other rule matched. - # - # The declaration of a policy rule is similar to an alarm rule except that: - # - there are no 'metric', 'window' and 'period' parameters. - # - there are only 2 supported functions: - # - 'count' which returns the number of members that match the passed value(s) - # - 'percent' which returns the percentage of members that match the passed value(s) - # - # The following rule definition reads as "the cluster's status is critical if - # more than 50% of its members are either down or critical": - # - # - status: critical - # trigger: - # logical_operator: or - # rules: - # - function: percent - # arguments: [ down, critical ] - # relational_operator: '>' - # threshold: 50 - # - gse_policies: - # A policy defining that the cluster's status depends on the member with the - # highest severity, typically used for a cluster of services. - highest_severity: - - status: down - trigger: - logical_operator: or - rules: - - function: count - arguments: [ down ] - relational_operator: '>' - threshold: 0 - - status: critical - trigger: - logical_operator: or - rules: - - function: count - arguments: [ critical ] - relational_operator: '>' - threshold: 0 - - status: warning - trigger: - logical_operator: or - rules: - - function: count - arguments: [ warning ] - relational_operator: '>' - threshold: 0 - - status: okay - trigger: - logical_operator: or - rules: - - function: count - arguments: [ okay ] - relational_operator: '>' - threshold: 0 - - status: unknown - - # A policy which is typically used for clusters managed by Pacemaker - # with the no-quorum-policy set to 'stop'. - majority_of_members: - - status: down - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ down ] - relational_operator: '>' - threshold: 50 - - status: critical - trigger: - logical_operator: and - rules: - - function: percent - arguments: [ down, critical ] - relational_operator: '>' - threshold: 20 - - function: percent - arguments: [ okay ] - relational_operator: '<' - threshold: 50 - function: percent - - status: warning - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ okay ] - relational_operator: '<' - threshold: 50 - function: percent - - status: okay - - # A policy that is used to derive a cluster status based - # on the status okay or down status for its members. - availability_of_members: - - status: down - trigger: - logical_operator: or - rules: - - function: count - arguments: [ okay ] - relational_operator: '==' - threshold: 0 - - status: critical - trigger: - logical_operator: and - rules: - - function: count - arguments: [ okay ] - relational_operator: '==' - threshold: 1 - - function: count - arguments: [ critical, down ] - relational_operator: '>' - threshold: 1 - - status: warning - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ okay ] - relational_operator: '<' - threshold: 100 - - status: okay - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ okay ] - relational_operator: '==' - threshold: 100 - - status: unknown - - # A policy that is used to derive a cluster status based - # on the health status of its members. - status_of_members: - - status: down - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ down ] - relational_operator: '==' - threshold: 100 - - status: critical - trigger: - logical_operator: and - rules: - - function: count - arguments: [ okay, warning ] - relational_operator: '<=' - threshold: 1 - - function: count - arguments: [ critical, down, unknown ] - relational_operator: '>' - threshold: 0 - - status: warning - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ okay ] - relational_operator: '!=' - threshold: 100 - - status: okay - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ okay ] - relational_operator: '==' - threshold: 100 - - status: unknown - - # A policy that is typically used for storage or compute clusters - majority_of_node_members: - - status: down - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ down ] - relational_operator: '==' - threshold: 100 - - status: critical - trigger: - logical_operator: and - rules: - - function: percent - arguments: [ down, critical ] - relational_operator: '>=' - threshold: 50 - - status: warning - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ down, critical, warning, unknown ] - relational_operator: '>' - threshold: 0 - function: percent - - status: okay - - gse_cluster_service: - input_message_types: - - afd_service_metric - aggregator_flag: true - # the field in the input messages to identify the cluster - cluster_field: service - # the field in the input messages to identify the cluster's member - member_field: source - output_message_type: gse_service_cluster_metric - output_metric_name: cluster_service_status - interval: 10 - warm_up_period: 20 - alerting: enabled - clusters: - nova-logs: - policy: highest_severity - group_by: hostname - members: - - error - nova-logs-compute: - policy: highest_severity - group_by: hostname - members: - - error - heat-logs: - policy: highest_severity - group_by: hostname - members: - - error - cinder-logs: - policy: highest_severity - group_by: hostname - members: - - error - glance-logs: - policy: highest_severity - group_by: hostname - members: - - error - neutron-logs: - policy: highest_severity - group_by: hostname - members: - - error - neutron-logs-compute: - policy: highest_severity - group_by: hostname - members: - - error - keystone-logs: - policy: highest_severity - group_by: hostname - members: - - error - mysqld-tcp: - policy: highest_severity - group_by: member - members: - - backends - mysql: - policy: majority_of_members - group_by: hostname - members: - - node-status - - check - haproxy-openstack: - policy: availability_of_members - group_by: hostname - members: - - check - apache: - policy: availability_of_members - group_by: hostname - members: - - worker - - check - memcached-service: - policy: availability_of_members - group_by: hostname - members: - - check - rabbitmq-cluster: - policy: highest_severity - group_by: member - members: - - memory - - disk - - queue - - pacemaker - rabbitmq-service: - # A check failure on a single node doesn't mean that the whole cluster - # is down, this is why a 'hostname' group_by and 'majority_of_members' - # policy are used here. - policy: majority_of_members - group_by: hostname - members: - - check - nova-api: - policy: highest_severity - group_by: member - members: - - backends - - http_errors - nova-api-check: - policy: highest_severity - group_by: member - members: - - vip - nova-api-endpoint: - policy: availability_of_members - group_by: hostname - members: - - endpoint - nova-novncproxy-websocket: - policy: highest_severity - group_by: member - members: - - backends - nova-metadata-api: - policy: highest_severity - group_by: member - members: - - backends - nova-scheduler: - policy: highest_severity - group_by: member - members: - - workers - nova-cert: - policy: highest_severity - group_by: member - members: - - workers - nova-consoleauth: - policy: highest_severity - group_by: member - members: - - workers - nova-compute: - policy: highest_severity - group_by: member - members: - - workers - nova-conductor: - policy: highest_severity - group_by: member - members: - - workers - # The AFDs are emitted by all the controller nodes because all of them - # collect the openstack_nova_instance_creation_time metric. Hence the - # service is considered not okay when a majority of controllers report - # not okay. - nova-instances: - policy: majority_of_members - group_by: hostname - members: - - creation-time - cinder-api: - policy: highest_severity - group_by: member - members: - - backends - - http_errors - cinder-api-check: - policy: highest_severity - group_by: member - members: - - vip - cinder-v2-api-check: - policy: highest_severity - group_by: member - members: - # Cinder V2 backends are in fact the same as the Cinder backends - - vip - cinder-api-endpoint: - policy: availability_of_members - group_by: hostname - members: - - endpoint - cinder-scheduler: - policy: highest_severity - group_by: member - members: - - workers - cinder-volume: - policy: highest_severity - group_by: member - members: - - workers - neutron-api: - policy: highest_severity - group_by: member - members: - - backends - - http_errors - neutron-api-check: - policy: highest_severity - group_by: member - members: - - vip - neutron-api-endpoint: - policy: availability_of_members - group_by: hostname - members: - - endpoint - neutron-l3: - policy: highest_severity - group_by: member - members: - - workers - neutron-dhcp: - policy: highest_severity - group_by: member - members: - - workers - neutron-metadata: - policy: highest_severity - group_by: member - members: - - workers -<% if not @contrail_plugin then -%> - neutron-openvswitch: - policy: highest_severity - group_by: member - members: - - workers -<% end -%> - keystone-response-time: - policy: highest_severity - group_by: member - members: - - duration - keystone-public-api: - policy: highest_severity - group_by: member - members: - - backends - - http_errors - keystone-public-api-check: - policy: highest_severity - group_by: member - members: - - vip - keystone-public-api-endpoint: - policy: availability_of_members - group_by: hostname - members: - - endpoint - keystone-admin-api: - policy: highest_severity - group_by: member - members: - # TODO(pasquier-s): add a metric reporting the status of the keystone-admin-api vip - - backends - - http_errors - glance-api: - policy: highest_severity - group_by: member - members: - - backends - - http_errors - glance-api-check: - policy: highest_severity - group_by: member - members: - - vip - glance-api-endpoint: - policy: availability_of_members - group_by: hostname - members: - - endpoint - glance-registry-api: - policy: highest_severity - group_by: member - members: - - backends - heat-api: - policy: highest_severity - group_by: member - members: - - backends - - http_errors - heat-api-check: - policy: highest_severity - group_by: member - members: - - vip - heat-api-endpoint: - policy: availability_of_members - group_by: hostname - members: - - endpoint - heat-cfn-api: - policy: highest_severity - group_by: member - members: - - backends - heat-cfn-api-check: - policy: highest_severity - group_by: member - members: - - vip - heat-cfn-api-endpoint: - policy: availability_of_members - group_by: hostname - members: - - endpoint - heat-cloudwatch-api: - policy: highest_severity - group_by: member - members: - - backends -<% if @tls_enabled then -%> - horizon-https: -<% else -%> - horizon-web: -<% end -%> - policy: highest_severity - group_by: member - members: - - backends - - http_errors -<% if not @storage_options["objects_ceph"] then -%> - swift-api: - policy: highest_severity - group_by: member - members: - - backends - - http_errors - swift-api-check: - policy: highest_severity - group_by: member - members: - - vip - swift-s3-api-check: - policy: highest_severity - group_by: member - members: - # Swift S3 backends are in fact the same as the Swift backends - - vip - swift-api-endpoint: - policy: availability_of_members - group_by: hostname - members: - - endpoint -<% end -%> -<% if @ceilometer_enabled -%> - ceilometer-api: - policy: highest_severity - group_by: member - members: - - backends - ceilometer-api-check: - policy: highest_severity - group_by: member - members: - - vip -<% end -%> -<% if @storage_options["volumes_ceph"] then -%> - ceph-mon-cluster: - policy: highest_severity - group_by: member - members: - - health - - capacity - ceph-mon-service: - policy: availability_of_members - group_by: hostname - members: - - check - ceph-osd-service: - policy: availability_of_members - group_by: hostname - members: - - check -<% end -%> -<% if @monitor_elasticsearch -%> - elasticsearch-cluster: - policy: highest_severity - group_by: member - members: - - health - elasticsearch-service: - policy: availability_of_members - group_by: hostname - members: - - check -<% end -%> -<% if @monitor_influxdb -%> - influxdb-api-check: - policy: highest_severity - group_by: member - members: - - vip - influxdb-service: - policy: availability_of_members - group_by: hostname - members: - - check -<% end -%> - pacemaker-service: - policy: availability_of_members - group_by: hostname - members: - - check - libvirt-service: - policy: majority_of_node_members - group_by: hostname - members: - - check - nova-free-vcpu: - policy: highest_severity - group_by: member - members: - - nova-free-vcpu - nova-free-memory: - policy: highest_severity - group_by: member - members: - - nova-free-memory - - nova-aggregates-free-memory - - gse_cluster_node: - input_message_types: - - afd_node_metric - aggregator_flag: true - # the field in the input messages to identify the cluster - cluster_field: node_role - # the field in the input messages to identify the cluster's member - member_field: source - output_message_type: gse_node_cluster_metric - output_metric_name: cluster_node_status - interval: 10 - warm_up_period: 80 - alerting: enabled_with_notification - clusters: - controller: - policy: status_of_members - group_by: hostname - members: - - cpu - - network-rx - - network-tx - - root-fs - - log-fs - - other-fs - - swap - - hdd-errors -<% if @detach_rabbitmq_enabled -%> - rabbitmq-nodes: - policy: status_of_members - group_by: hostname - members: - - cpu - - network-rx - - network-tx - - root-fs - - other-fs - - swap - - hdd-errors -<% end -%> - mysql-nodes: - policy: status_of_members - group_by: hostname - members: -<% if @detach_database_enabled -%> - - cpu - - network-rx - - network-tx - - root-fs - - other-fs - - swap - - hdd-errors -<% end -%> - - mysql-fs - compute: - policy: majority_of_node_members - group_by: hostname - members: - - cpu - - network-rx - - network-tx - - root-fs - - nova-fs - - other-fs - - swap - - hdd-errors - storage: - policy: majority_of_node_members - group_by: hostname - members: - - cpu - - network-rx - - network-tx - - root-fs - - other-fs - - swap - - hdd-errors -<% if @storage_options["volumes_ceph"] then -%> - - osd-disk -<% end -%> -<% if @monitor_elasticsearch -%> - elasticsearch-nodes: - policy: status_of_members - group_by: hostname - members: - - data-fs - - root-fs - - cpu - - network-rx - - network-tx - - swap - - hdd-errors -<% end -%> -<% if @monitor_influxdb -%> - influxdb-nodes: - policy: status_of_members - group_by: hostname - members: - - data-fs - - root-fs - - cpu - - network-rx - - network-tx - - swap - - hdd-errors -<% end -%> - - gse_cluster_global: - input_message_types: - - gse_service_cluster_metric - - gse_node_cluster_metric - aggregator_flag: false - # the field in the input messages to identify the cluster's member - member_field: cluster_name - output_message_type: gse_cluster_metric - output_metric_name: cluster_status - interval: 10 - warm_up_period: 30 - alerting: enabled_with_notification - clusters: - mysql: - policy: highest_severity - group_by: member - members: - - mysqld-tcp - - mysql - haproxy-openstack: - policy: highest_severity - group_by: member - members: - - haproxy-openstack - apache: - policy: highest_severity - group_by: member - members: - - apache - memcached: - policy: highest_severity - group_by: member - members: - - memcached-service - rabbitmq: - policy: highest_severity - group_by: member - members: - - rabbitmq-cluster - - rabbitmq-service - nova-control-plane: - policy: highest_severity - group_by: member - members: - - nova-logs - - nova-api # backends and http errors - - nova-api-check # vip check - - nova-api-endpoint # local check - - nova-metadata-api # worker - - nova-scheduler # worker - - nova-conductor # worker - - nova-cert # worker - - nova-consoleauth # worker - - nova-novncproxy-websocket # worker - hints: - - cinder-control-plane - - glance - - keystone - - neutron-control-plane - - mysql - - rabbitmq - nova-data-plane: - policy: highest_severity - group_by: member - members: - - nova-logs-compute - - nova-compute - - nova-instances - - libvirt-service - - nova-free-vcpu - - nova-free-memory - - nova-aggregates-free-memory - hints: - - neutron-data-plane - cinder-control-plane: - policy: highest_severity - group_by: member - members: - - cinder-logs - - cinder-api - - cinder-api-check - - cinder-v2-api-check - - cinder-api-endpoint - - cinder-scheduler - hints: - - keystone - - mysql - - rabbitmq -<% if not @storage_options["volumes_ceph"] then -%> - cinder-data-plane: - policy: highest_severity - group_by: member - members: - - cinder-volume-logs - - cinder-volume -<% end -%> - neutron-control-plane: - policy: highest_severity - group_by: member - members: - - neutron-logs - - neutron-api - - neutron-api-check - - neutron-api-endpoint -<% if not @contrail_plugin then -%> - - neutron-l3 - - neutron-dhcp - - neutron-metadata - - neutron-openvswitch -<% end -%> - hints: - - keystone - - mysql - - rabbitmq - neutron-data-plane: - policy: highest_severity - group_by: member - members: - - neutron-logs-compute -<% if not @contrail_plugin then -%> - - neutron-openvswitch -<% end -%> - keystone: - policy: highest_severity - group_by: member - members: - - keystone-logs - - keystone-response-time - - keystone-public-api - - keystone-public-api-check - - keystone-public-api-endpoint - - keystone-admin-api - hints: - - mysql - - apache - glance: - policy: highest_severity - group_by: member - members: - - glance-logs - - glance-api - - glance-api-check - - glance-api-endpoint - - glance-registry-api - hints: - - keystone - - mysql - heat: - policy: highest_severity - group_by: member - members: - - heat-logs - - heat-api - - heat-api-check - - heat-api-endpoint - - heat-cfn-api - - heat-cfn-api-check - - heat-cfn-api-endpoint - - heat-cloudwatch-api - hints: - - cinder-control-plane - - glance - - keystone - - neutron-control-plane - - nova-control-plane - - mysql - - rabbitmq - horizon: - policy: highest_severity - group_by: member - members: -<% if @tls_enabled then -%> - - horizon-https -<% else -%> - - horizon-web -<% end -%> - hints: - - keystone - - apache -<% if not @storage_options["objects_ceph"] then -%> - swift: - policy: highest_severity - group_by: member - members: - - swift-api - - swift-api-check - - swift-s3-api-check - - swift-api-endpoint - hints: - - keystone -<% end -%> -<% if @ceilometer_enabled -%> - ceilometer: - policy: highest_severity - group_by: member - members: - - ceilometer-api - - ceilometer-api-check - hints: - - keystone - - rabbitmq -<% end -%> -<% if @storage_options["volumes_ceph"] then -%> - ceph: - policy: highest_severity - group_by: member - members: - - ceph-mon-cluster - - ceph-mon-service - - ceph-osd-service -<% end -%> -<% if @monitor_elasticsearch -%> - elasticsearch: - policy: highest_severity - group_by: member - members: - - elasticsearch-cluster - - elasticsearch-service -<% end -%> -<% if @monitor_influxdb -%> - influxdb: - policy: highest_severity - group_by: member - members: - - influxdb-api-check - - influxdb-service -<% end -%> - pacemaker: - policy: highest_severity - group_by: member - members: - - pacemaker-service diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/metrics.yaml.erb b/deployment_scripts/puppet/modules/fuel_lma_collector/templates/metrics.yaml.erb deleted file mode 100644 index 8ed3a3954..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/metrics.yaml.erb +++ /dev/null @@ -1,21 +0,0 @@ ---- -lma_collector: - metrics: - openstack_nova_total_free_vcpus: - collected_on: aggregator - openstack_nova_total_free_ram: - collected_on: aggregator - openstack_nova_aggregate_free_ram_percent: - collected_on: aggregator - http_check: - collected_on: aggregator - openstack_check_api: - collected_on: aggregator - openstack_nova_services: - collected_on: aggregator - openstack_cinder_services: - collected_on: aggregator - openstack_neutron_agents: - collected_on: aggregator - pacemaker_resource_percent: - collected_on: aggregator diff --git a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/node_profiles.yaml.erb b/deployment_scripts/puppet/modules/fuel_lma_collector/templates/node_profiles.yaml.erb deleted file mode 100644 index 56fb07d44..000000000 --- a/deployment_scripts/puppet/modules/fuel_lma_collector/templates/node_profiles.yaml.erb +++ /dev/null @@ -1,45 +0,0 @@ ---- -lma_collector: - # Fuel roles mapping to alarm evaluator key. - node_profiles: - controller: - roles: ['primary-controller', 'controller'] - description: 'The Controller nodes' - mysql-nodes: -<% if @detach_database_enabled -%> - roles: ['primary-standalone-database', 'standalone-database'] -<% else -%> - roles: ['primary-controller', 'controller'] -<% end -%> - description: 'The MySQL nodes' - rabbitmq-nodes: -<% if @detach_rabbitmq_enabled -%> - roles: ['primary-standalone-rabbitmq', 'standalone-rabbitmq'] -<% else -%> - roles: ['primary-controller', 'controller'] -<% end -%> - description: 'The RabbitMQ nodes' -<% if @storage_options["volumes_ceph"] then -%> - ceph-mon: - roles: ['primary-controller', 'controller'] - description: 'The Ceph monitor nodes' -<% end -%> - compute: - roles: ['compute'] - description: 'The Compute nodes' - storage: - roles: ['cinder', 'ceph-osd'] - description: 'The Storage nodes (either Cinder of Ceph-OSD)' - elasticsearch-nodes: - roles: ['primary-elasticsearch_kibana', 'elasticsearch_kibana'] - description: 'The Elasticsearch and Kibana nodes' - influxdb-nodes: - roles: ['primary-influxdb_grafana', 'influxdb_grafana'] - description: 'The InfluxDB and Grafana nodes' - aggregator: - roles: ['primary-controller', 'controller'] - description: 'The Aggregator nodes' - - default: - roles: [] - description: 'The default profile includes all nodes which are not falling into a definied profile' diff --git a/deployment_scripts/puppet/modules/heka/.fixtures.yml b/deployment_scripts/puppet/modules/heka/.fixtures.yml deleted file mode 100644 index 3625a0bff..000000000 --- a/deployment_scripts/puppet/modules/heka/.fixtures.yml +++ /dev/null @@ -1,7 +0,0 @@ -fixtures: - repositories: - stdlib: - repo: "git://github.com/puppetlabs/puppetlabs-stdlib" - ref: "4.7.0" - symlinks: - heka: "#{source_dir}" diff --git a/deployment_scripts/puppet/modules/heka/.gitignore b/deployment_scripts/puppet/modules/heka/.gitignore deleted file mode 100644 index b766602a0..000000000 --- a/deployment_scripts/puppet/modules/heka/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -spec/fixtures/modules/* -spec/fixtures/manifests/* -Gemfile.lock -.bundle diff --git a/deployment_scripts/puppet/modules/heka/Gemfile b/deployment_scripts/puppet/modules/heka/Gemfile deleted file mode 100644 index e8a2c49ed..000000000 --- a/deployment_scripts/puppet/modules/heka/Gemfile +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -source 'https://rubygems.org' - -group :development, :test do - gem 'rake' - gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.4.0' - gem 'rspec' - gem 'rspec-puppet' - gem 'rspec-puppet-facts' - # Newer puppetlabs_spec_helper depends on rubocop-rspec that requires ruby >= 2.2.0 - gem 'puppetlabs_spec_helper', '~> 1.1.1' - # puppet-lint >= 2.2.0 don't support Puppet 3.x anymore - gem 'puppet-lint', '~> 2.1.0' - gem 'metadata-json-lint' -end diff --git a/deployment_scripts/puppet/modules/heka/LICENSE b/deployment_scripts/puppet/modules/heka/LICENSE deleted file mode 100644 index e06d20818..000000000 --- a/deployment_scripts/puppet/modules/heka/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. - diff --git a/deployment_scripts/puppet/modules/heka/README.md b/deployment_scripts/puppet/modules/heka/README.md deleted file mode 100644 index 38e82aeba..000000000 --- a/deployment_scripts/puppet/modules/heka/README.md +++ /dev/null @@ -1,49 +0,0 @@ -Heka module for Puppet -====================== - -Description ------------ - -Puppet module for configuring Heka. - -Usage ------ - -To deploy the Heka service on a host. - -```puppet -# Configure the base heka service -class {'heka': -} -``` - -Limitations ------------ - -This module supports only Fuel-based deployments using Neutron. - -License -------- - -Licensed under the terms of the Apache License, version 2.0. - - -Limitations ------------ - -None - -License -------- - -Licensed under the terms of the Apache License, version 2.0. - -Contact -------- - -Simon Pasquier, - -Support -------- - -See the Contact section. diff --git a/deployment_scripts/puppet/modules/heka/Rakefile b/deployment_scripts/puppet/modules/heka/Rakefile deleted file mode 100644 index 678462cf7..000000000 --- a/deployment_scripts/puppet/modules/heka/Rakefile +++ /dev/null @@ -1,28 +0,0 @@ -require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-lint/tasks/puppet-lint' -require 'puppet-syntax/tasks/puppet-syntax' -require 'metadata-json-lint/rake_task' - -PuppetLint.configuration.fail_on_warnings = true -PuppetLint.configuration.send('disable_80chars') -PuppetLint.configuration.send('disable_class_inherits_from_params_class') -PuppetLint.configuration.send('disable_class_parameter_defaults') - -exclude_paths = [ - "pkg/**/*", - "vendor/**/*", - "spec/**/*", -] -Rake::Task[:lint].clear -PuppetLint::RakeTask.new :lint do |config| - config.ignore_paths = exclude_paths -end -PuppetSyntax.exclude_paths = exclude_paths - -desc "Run metadata_lint, lint, syntax, and spec tests." -task :test => [ - :metadata_lint, - :lint, - :syntax, - :spec, -] diff --git a/deployment_scripts/puppet/modules/heka/lib/puppet/parser/functions/validate_buffering.rb b/deployment_scripts/puppet/modules/heka/lib/puppet/parser/functions/validate_buffering.rb deleted file mode 100644 index 8f219b6c2..000000000 --- a/deployment_scripts/puppet/modules/heka/lib/puppet/parser/functions/validate_buffering.rb +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -module Puppet::Parser::Functions - newfunction(:validate_buffering, :doc => <<-'ENDHEREDOC') do |args| - Validate that the parameters used for buffering are consistent. - - The function takes 3 arguments: - - max_buffer_size - - max_file_size - - full_action - - In practice, max_buffer_size must be greater than max_file_size. - - The following values will pass: - - $max_buffer_size = 2048 - $max_file_size = 1024 - validate_buffering($max_buffer_size, $max_file_size, 'drop') - - The following values will fail: - - $max_buffer_size = 1024 - $max_file_size = 2048 - validate_buffering($max_buffer_size, $max_file_size, 'drop') - - $max_buffer_size = 2048 - $max_file_size = 1024 - validate_buffering($max_buffer_size, $max_file_size, 'foo') - - ENDHEREDOC - - unless args.length == 3 then - raise Puppet::ParseError, ("validate_buffering(): wrong number of arguments (#{args.length}; must be 3)") - end - - unless args[0].to_s =~ /^\d+$/ then - raise Puppet::ParseError, ("validate_buffering(): bad argument (#{args[0]}}; must be integer)") - end - max_buffer_size = args[0].to_i - - # When passing undef as args[1], it will be seen as the empty string and - # evaluated as 0 which means no limit - unless args[1].to_s =~ /^\d*$/ then - raise Puppet::ParseError, ("validate_buffering(): bad argument (#{args[0]}}; must be integer)") - end - max_file_size = args[1].to_i - max_file_size = 512 * 1024 * 1024 if max_file_size == 0 - - if max_buffer_size > 0 and max_buffer_size < max_file_size then - raise(Puppet::ParseError, "validate_buffering(): max_buffer_size (" + - "#{max_buffer_size}) should be greater than max_file_size (#{max_file_size})") - end - - unless ["drop", "shutdown", "block"].include?(args[2]) then - raise(Puppet::ParseError, "validate_buffering(): full_action (" + - "#{args[2]}) should be either drop, shutdown or block") - end - end -end diff --git a/deployment_scripts/puppet/modules/heka/manifests/decoder/multidecoder.pp b/deployment_scripts/puppet/modules/heka/manifests/decoder/multidecoder.pp deleted file mode 100644 index 52817b9c8..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/decoder/multidecoder.pp +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::decoder::multidecoder ( - $config_dir, - $subs = [], - $log_sub_errors = true, - $cascade_strategy = 'all', - $ensure = present, -) { - - include heka::params - - validate_array($subs) - validate_string($cascade_strategy) - validate_bool($log_sub_errors) - - if size($subs) < 1 { - fail('subs parameter must be greater than 0') - } - if $cascade_strategy != 'all' and $cascade_strategy != 'first-wins' { - fail('cascade_strategy parameter must be either \'all\' or \'first-wins\'') - } - - file { "${config_dir}/multidecoder-${title}.toml": - ensure => $ensure, - content => template('heka/decoder/multidecoder.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/decoder/sandbox.pp b/deployment_scripts/puppet/modules/heka/manifests/decoder/sandbox.pp deleted file mode 100644 index 8c9f1da97..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/decoder/sandbox.pp +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::decoder::sandbox ( - $config_dir, - $filename, - $config = {}, - $module_directory = undef, - $ensure = present, -) { - - include heka::params - - validate_hash($config) - - file { "${config_dir}/decoder-${title}.toml": - ensure => $ensure, - content => template('heka/decoder/sandbox.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/decoder/scribbler.pp b/deployment_scripts/puppet/modules/heka/manifests/decoder/scribbler.pp deleted file mode 100644 index 49639d4c6..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/decoder/scribbler.pp +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::decoder::scribbler ( - $config_dir, - $config = {}, - $ensure = present, -) { - - include heka::params - - validate_hash($config) - - file { "${config_dir}/scribbler-${title}.toml": - ensure => $ensure, - content => template('heka/decoder/scribbler.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} - diff --git a/deployment_scripts/puppet/modules/heka/manifests/encoder/es_json.pp b/deployment_scripts/puppet/modules/heka/manifests/encoder/es_json.pp deleted file mode 100644 index 908757cf0..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/encoder/es_json.pp +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::encoder::es_json ( - $config_dir, - $es_index_from_timestamp = false, - $index = undef, - $ensure = present, - $fields = undef, - $timestamp = '%Y-%m-%dT%H:%M:%S', -) { - - include heka::params - - if $fields != undef { - validate_array($fields) - } - - file { "${config_dir}/encoder-${title}.toml": - ensure => $ensure, - content => template('heka/encoder/es_json.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/encoder/payload.pp b/deployment_scripts/puppet/modules/heka/manifests/encoder/payload.pp deleted file mode 100644 index d3e1b4598..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/encoder/payload.pp +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::encoder::payload ( - $config_dir, - $append_newlines = false, - $prefix_ts = false, - $ensure = present, -) { - - include heka::params - - file { "${config_dir}/encoder-${title}.toml": - ensure => $ensure, - content => template('heka/encoder/payload.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} - diff --git a/deployment_scripts/puppet/modules/heka/manifests/encoder/sandbox.pp b/deployment_scripts/puppet/modules/heka/manifests/encoder/sandbox.pp deleted file mode 100644 index c4c294114..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/encoder/sandbox.pp +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::encoder::sandbox ( - $config_dir, - $filename, - $config = {}, - $module_directory = undef, - $ensure = present, -) { - - include heka::params - - validate_hash($config) - - file { "${config_dir}/encoder-${title}.toml": - ensure => $ensure, - content => template('heka/encoder/sandbox.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} - diff --git a/deployment_scripts/puppet/modules/heka/manifests/filter/sandbox.pp b/deployment_scripts/puppet/modules/heka/manifests/filter/sandbox.pp deleted file mode 100644 index 7dc5d7be0..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/filter/sandbox.pp +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::filter::sandbox ( - $config_dir, - $filename, - $preserve_data = false, - $message_matcher = 'FALSE', - $ticker_interval = undef, - $config = {}, - $module_directory = undef, - $ensure = present, -) { - - include heka::params - - validate_hash($config) - - file { "${config_dir}/filter-${title}.toml": - ensure => $ensure, - content => template('heka/filter/sandbox.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/init.pp b/deployment_scripts/puppet/modules/heka/manifests/init.pp deleted file mode 100644 index c0fcae66a..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/init.pp +++ /dev/null @@ -1,311 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# == Define: heka -# -# Install and configure the core of the Heka service. -# -# === Parameters -# -# [*config_dir*] -# The directory where to store the configuration (default: '/etc/hekad'). -# -# [*user*] -# The user to run the Heka service as (default: 'heka'). You may have to use -# 'root' on some systems for the Heka service to be able to access log files, -# run additional commands, ... -# -# [*additional_groups*] -# Additional groups to which the heka user should be added. -# -# [*hostname*] -# Hostname reported by the service in the messages (default: the host's FQDN). -# -# [*maxprocs*] -# The number of CPU cores (default: $processorcount). -# -# [*max_message_size*] -# The maxium Heka message size in bytes (default: undef to use default Heka value). -# -# [*max_process_inject*] -# The maximum number of messages that a sandbox filter's ProcessMessage -# function can inject in a single call (default: undef to use default Heka -# value). -# -# [*max_timer_inject*] -# The maximum number of messages that a sandbox filter's TimerEvent function -# can inject in a single call (default: undef to use default Heka value). -# -# [*poolsize*] -# The pool size of maximum messages that can exist (default: 100). -# -# [*internal_statistics*] -# Whether or not to dump Heka internal statistics to stdout at a regular -# interval (currently every hour). -# -# [*install_init_script*] -# Whether or not install the init script (Upstart or Systemd). This is typically -# used when the service is managed by Pacemaker for example. -# (default: true). -# -# [*version*] -# The package version to install. (default: 'latest'). -# -# === Examples -# -# class { 'heka': -# hostname => 'foobar' -# } -# -# === Authors -# -# Simon Pasquier -# -# === Copyright -# -# Copyright 2015 Mirantis Inc, unless otherwise noted. -# -define heka ( - $config_dir = undef, - $user = undef, - $additional_groups = undef, - $hostname = undef, - $maxprocs = undef, - $max_message_size = undef, - $max_process_inject = undef, - $max_timer_inject = undef, - $poolsize = undef, - $pre_script = undef, - $internal_statistics = undef, - $install_init_script = true, - $version = 'latest', -) { - - include heka::params - - if $poolsize { - validate_integer($poolsize) - } - - $service_name = $title - - if $user { - $heka_user = $user - } else { - $heka_user = $heka::params::user - } - - if $config_dir { - $_config_dir = $config_dir - } else { - $_config_dir = $heka::params::config_dir - } - - $run_as_root = $heka_user == 'root' - if $run_as_root { - $_run_as_root = $run_as_root - } else { - $_run_as_root = $heka::params::run_as_root - } - if $additional_groups { - $_additional_groups = $additional_groups - } else { - $_additional_groups = $heka::params::additional_groups - } - if $hostname { - $_hostname = $hostname - } else { - $_hostname = $heka::params::hostname - } - if $maxprocs { - $_maxprocs = $maxprocs - } else { - $_maxprocs = $heka::params::maxprocs - } - if $max_message_size { - $_max_message_size = $max_message_size - } else { - $_max_message_size = $heka::params::max_message_size - } - if $max_process_inject { - $_max_process_inject = $max_process_inject - } else { - $_max_process_inject = $heka::params::max_process_inject - } - if $max_timer_inject { - $_max_timer_inject = $max_timer_inject - } else { - $_max_timer_inject = $heka::params::max_timer_inject - } - - $hekad_wrapper = "/usr/local/bin/${service_name}_wrapper" - $base_dir = "/var/cache/${service_name}" - $log_file = "/var/log/${service_name}.log" - - if ! defined(Package[$heka::params::package_name]) { - package { $heka::params::package_name: - ensure => $version, - alias => 'heka', - } - - if $::osfamily == 'Debian' { - # Starting from Heka 0.10.0, the Debian package provides a SysV init - # script so we need to stop the service and remove the init script. - # If this script isn't removed, the user may accidentally stop *all* the - # running hekad processes by invoking '/etc/init.d/heka stop'. - exec { 'stop_heka_daemon': - command => '/etc/init.d/heka stop', - onlyif => '/usr/bin/test -f /etc/init.d/heka', - require => Package['heka'], - notify => Exec['disable_heka_daemon'] - } - - exec { 'disable_heka_daemon': - command => '/usr/sbin/update-rc.d heka disable', - refreshonly => true, - notify => Exec['remove_heka_service'], - } - - exec { 'remove_heka_service': - command => '/bin/rm -f /etc/init.d/heka', - refreshonly => true, - } - } - } - - # This Puppet User resource is used by other manifests even if the hekad - # process runs as 'root'. - if ! defined(User[$heka_user]) { - user { $heka_user: - shell => $heka::params::nologin_bin, - home => $base_dir, - system => true, - groups => $_additional_groups, - alias => 'heka', - before => Package['heka'], - } - } - - file { $base_dir: - ensure => directory, - owner => $heka_user, - group => $heka_user, - mode => '0750', - require => [User[$heka_user], Package['heka']], - } - - file { $_config_dir: - ensure => directory, - owner => $heka_user, - group => $heka_user, - mode => '0750', - require => [User[$heka_user], Package['heka']], - } - - file { $log_file: - ensure => present, - owner => $heka_user, - group => $heka_user, - mode => '0660', - require => [User[$heka_user], Package['heka']], - } - - $logrotate_conf = "/etc/logrotate_${service_name}.conf" - file { $logrotate_conf: - ensure => present, - content => template('heka/logrotate.conf.erb'), - owner => 'root', - group => 'root', - mode => '0644', - require => Package['heka'], - } - - $logrotate_bin = "/usr/local/bin/logrotate_${service_name}" - file { $logrotate_bin: - ensure => present, - owner => 'root', - group => 'root', - mode => '0755', - content => template('heka/logrotate.cron.erb'), - require => File[$logrotate_conf], - } - - cron { "${service_name} logrotate": - ensure => present, - command => $logrotate_bin, - minute => '*/30', - hour => '*', - month => '*', - monthday => '*', - require => File[$logrotate_bin], - } - - if $install_init_script { - file { $hekad_wrapper: - ensure => present, - owner => 'root', - group => 'root', - mode => '0755', - content => template('heka/hekad_wrapper.erb'), - require => Package['heka'], - } - - case $::osfamily { - 'Debian': { - file {"/etc/init/${service_name}.conf": - ensure => present, - content => template('heka/hekad.upstart.conf.erb'), - notify => Service[$service_name], - alias => "${service_name}_heka_init_script", - require => File[$hekad_wrapper], - } - } - - 'RedHat': { - file { "/etc/init.d/${service_name}": - ensure => present, - content => template('heka/hekad.initd.erb'), - mode => '0755', - notify => Service[$service_name], - alias => "${service_name}_heka_init_script", - require => File[$hekad_wrapper], - } - } - default: { - fail("${::osfamily} not supported") - } - } - } - - file { "${_config_dir}/global.toml": - ensure => present, - content => template('heka/global.toml.erb'), - mode => '0600', - owner => $heka_user, - group => $heka_user, - require => File[$_config_dir], - notify => Service[$service_name], - } - - if $internal_statistics { - cron { 'heka-internal-statistics': - ensure => present, - command => '/usr/bin/killall -SIGUSR1 hekad', - minute => '0', - hour => '*', - month => '*', - monthday => '*', - } - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/input/amqp.pp b/deployment_scripts/puppet/modules/heka/manifests/input/amqp.pp deleted file mode 100644 index 0c4f1230f..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/input/amqp.pp +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::input::amqp ( - $config_dir, - $decoder, - $user, - $password, - $host, - $port, - $exchange, - $queue, - $exchange_durability = false, - $exchange_auto_delete = false, - $queue_auto_delete = true, - $exchange_type = 'topic', - $routing_key = '*', - $can_exit = false, - $ensure = present, -) { - - include heka::params - - file { "${config_dir}/amqp-${title}.toml": - ensure => $ensure, - content => template('heka/input/amqp.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/input/httplisten.pp b/deployment_scripts/puppet/modules/heka/manifests/input/httplisten.pp deleted file mode 100644 index 2ecfeb79b..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/input/httplisten.pp +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::input::httplisten ( - $config_dir, - $decoder, - $address = '127.0.0.1', - $port = '80', - $ensure = present, -) { - - include heka::params - - file { "${config_dir}/httplisten-${title}.toml": - ensure => $ensure, - content => template('heka/input/httplisten.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/input/logstreamer.pp b/deployment_scripts/puppet/modules/heka/manifests/input/logstreamer.pp deleted file mode 100644 index 446c11edc..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/input/logstreamer.pp +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::input::logstreamer( - $config_dir, - $decoder, - $splitter = undef, - $log_directory = '/var/log', - $file_match = undef, - $differentiator = undef, - $priority = undef, - $ensure = present, -) { - - include heka::params - - if $differentiator and ('/' in $differentiator) { - fail('differentiator contains a slash character') - } - - file { "${config_dir}/logstreamer-${title}.toml": - ensure => $ensure, - content => template('heka/input/logstreamer.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/input/process.pp b/deployment_scripts/puppet/modules/heka/manifests/input/process.pp deleted file mode 100644 index 885d0c18e..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/input/process.pp +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::input::process ( - $config_dir, - $decoder, - $commands, - $splitter = false, - $ticker_interval = '60', - $stdout = true, - $stderr = false, - $ensure = present, -) { - - include heka::params - - file { "${config_dir}/process-${title}.toml": - ensure => $ensure, - content => template('heka/input/process.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/input/tcp.pp b/deployment_scripts/puppet/modules/heka/manifests/input/tcp.pp deleted file mode 100644 index 5871fb440..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/input/tcp.pp +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::input::tcp ( - $config_dir, - $address = '127.0.0.1', - $port = 5565, - $decoder = 'ProtobufDecoder', - $ensure = present, -) { - - include heka::params - - if $decoder == 'ProtobufDecoder' { - $decoder_instance = $decoder - } else { - $decoder_instance = "${decoder}_decoder" - } - - file { "${config_dir}/input-${title}.toml": - ensure => $ensure, - content => template('heka/input/tcp.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/output/dashboard.pp b/deployment_scripts/puppet/modules/heka/manifests/output/dashboard.pp deleted file mode 100644 index 47095f44a..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/output/dashboard.pp +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::output::dashboard ( - $config_dir, - $dashboard_address = '0.0.0.0', - $dashboard_port = '4352', - $ticker_interval = '30', - $ensure = present, -) { - - include heka::params - - file { "${config_dir}/output-${title}.toml": - ensure => $ensure, - content => template('heka/output/dashboard.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} - diff --git a/deployment_scripts/puppet/modules/heka/manifests/output/elasticsearch.pp b/deployment_scripts/puppet/modules/heka/manifests/output/elasticsearch.pp deleted file mode 100644 index 3341484cd..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/output/elasticsearch.pp +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::output::elasticsearch ( - $config_dir, - $server = undef, - $port = undef, - $encoder = $title, - $message_matcher = 'FALSE', - $flush_interval = 5, - $flush_count = 10, - $use_buffering = true, - $max_buffer_size = 1024 * 1024 * 1024, # 1GiB - $queue_full_action = 'block', - $max_file_size = undef, - $ensure = present, -) { - - include heka::params - - if $use_buffering { - validate_buffering($max_buffer_size, $max_file_size, $queue_full_action) - } - - file { "${config_dir}/output-${title}.toml": - ensure => $ensure, - content => template('heka/output/elasticsearch.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/output/http.pp b/deployment_scripts/puppet/modules/heka/manifests/output/http.pp deleted file mode 100644 index 55a83b9f8..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/output/http.pp +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::output::http ( - $config_dir, - $url, - $encoder = $title, - $message_matcher = 'FALSE', - $username = undef, - $password = undef, - $timeout = undef, - $method = 'POST', - $headers = {}, - $use_buffering = true, - $max_buffer_size = 1024 * 1024 * 1024, # 1GiB - $queue_full_action = 'drop', - $max_file_size = undef, - $ensure = present, -) { - - include heka::params - - validate_hash($headers) - if $use_buffering { - validate_buffering($max_buffer_size, $max_file_size, $queue_full_action) - } - - file { "${config_dir}/output-${title}.toml": - ensure => $ensure, - content => template('heka/output/http.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/output/sandbox.pp b/deployment_scripts/puppet/modules/heka/manifests/output/sandbox.pp deleted file mode 100644 index 136c09bd6..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/output/sandbox.pp +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::output::sandbox ( - $config_dir, - $filename, - $message_matcher = 'FALSE', - $config = {}, - $module_directory = undef, - $ensure = present, -) { - - include heka::params - - validate_hash($config) - - file { "${config_dir}/output-${title}.toml": - ensure => $ensure, - content => template('heka/output/sandbox.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/output/tcp.pp b/deployment_scripts/puppet/modules/heka/manifests/output/tcp.pp deleted file mode 100644 index afca822f8..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/output/tcp.pp +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::output::tcp ( - $config_dir, - $address = '127.0.0.1', - $port = 5565, - $message_matcher = 'FALSE', - $use_buffering = true, - $max_buffer_size = 1024 * 1024 * 1024, # 1GiB - $queue_full_action = 'drop', - $max_file_size = undef, - $ensure = present, -) { - - include heka::params - - if $use_buffering { - validate_buffering($max_buffer_size, $max_file_size, $queue_full_action) - } - - file { "${config_dir}/output-${title}.toml": - ensure => $ensure, - content => template('heka/output/tcp.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/params.pp b/deployment_scripts/puppet/modules/heka/manifests/params.pp deleted file mode 100644 index 9569ea0a6..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/params.pp +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class heka::params { - $package_name = 'heka' - $user = 'heka' - $additional_groups = [] - - $hostname = undef - $maxprocs = $::processorcount - $max_message_size = undef - $max_process_inject = undef - $max_timer_inject = undef - $internal_statistics = false - - $config_dir = '/etc/hekad' - $share_dir = '/usr/share/heka' - $lua_modules_dir = '/usr/share/heka/lua_modules' - - # required to read the log files - case $::osfamily { - 'Debian': { - $groups = ['syslog', 'adm'] - $nologin_bin = '/usr/sbin/nologin' - } - 'RedHat': { - $groups = ['adm'] - $nologin_bin = '/sbin/nologin' - } - default: { - fail("${::osfamily} not supported") - } - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/splitter/regex.pp b/deployment_scripts/puppet/modules/heka/manifests/splitter/regex.pp deleted file mode 100644 index 5f9f88999..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/splitter/regex.pp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::splitter::regex ( - $config_dir, - $delimiter, - $delimiter_eol = undef, - $ensure = present, -) { - - include heka::params - - file { "${config_dir}/splitter-${title}.toml": - ensure => $ensure, - content => template('heka/splitter/regex.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} diff --git a/deployment_scripts/puppet/modules/heka/manifests/splitter/token.pp b/deployment_scripts/puppet/modules/heka/manifests/splitter/token.pp deleted file mode 100644 index 7dc74abe5..000000000 --- a/deployment_scripts/puppet/modules/heka/manifests/splitter/token.pp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define heka::splitter::token ( - $config_dir, - $delimiter, - $ensure = present, -) { - - include heka::params - - file { "${config_dir}/splitter-${title}.toml": - ensure => $ensure, - content => template('heka/splitter/token.toml.erb'), - mode => '0600', - owner => $heka::params::user, - group => $heka::params::user, - } -} - diff --git a/deployment_scripts/puppet/modules/heka/metadata.json b/deployment_scripts/puppet/modules/heka/metadata.json deleted file mode 100644 index 9d60d6330..000000000 --- a/deployment_scripts/puppet/modules/heka/metadata.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "mirantis-heka", - "version": "1.0.0", - "author": "Simon Pasquier ", - "summary": "Puppet Heka Module", - "license": "Apache-2.0", - "source": "https://git.openstack.org/cgit/openstack/fuel-plugin-lma-collector.git", - "project_page": "none", - "issues_url": "none", - "operatingsystem_support": [ - { - "operatingsystem": "Ubuntu", - "operatingsystemrelease": ["14.04"] - } - ], - "requirements": [ - {"name": "puppet", "version_requirement": "3.x"} - ], - "description": "Puppet module for configuring Heka", - "dependencies": [ - {"name": "puppetlabs/stdlib", "version_requirement": "4.x"} - ] -} diff --git a/deployment_scripts/puppet/modules/heka/spec/defines/heka_decoder_sandbox_spec.rb b/deployment_scripts/puppet/modules/heka/spec/defines/heka_decoder_sandbox_spec.rb deleted file mode 100644 index 2fbd9e7e2..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/defines/heka_decoder_sandbox_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'heka::decoder::sandbox' do - let(:title) { :foo } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with title = foo' do - let(:params) {{:config_dir => '/etc/hekad', :filename => 'foo.lua'}} - it { is_expected.to contain_file('/etc/hekad/decoder-foo.toml').without_content(/module_directory/) } - end - - describe 'with title = foo and module_directory' do - let(:params) {{:config_dir => '/etc/hekad', :filename => 'foo.lua', :module_directory => '/tmp'}} - it { is_expected.to contain_file('/etc/hekad/decoder-foo.toml').with_content(/module_directory = "\/tmp;/) } - end - -end diff --git a/deployment_scripts/puppet/modules/heka/spec/defines/heka_encoder_es_json_spec.rb b/deployment_scripts/puppet/modules/heka/spec/defines/heka_encoder_es_json_spec.rb deleted file mode 100644 index c3ccfbf98..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/defines/heka_encoder_es_json_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'heka::encoder::es_json' do - let(:title) { :es } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with title = es' do - let(:params) {{:config_dir => '/etc/hekad', :index => 'bar'}} - it { is_expected.to contain_file('/etc/hekad/encoder-es.toml') } - end - describe 'with fields list' do - let(:params) {{:config_dir => '/etc/hekad', :index => 'bar', :fields => ['foo', 'bar']}} - it { is_expected.to contain_file('/etc/hekad/encoder-es.toml').with_content(/fields = \[ "bar", "foo" \]/) } - end -end - diff --git a/deployment_scripts/puppet/modules/heka/spec/defines/heka_encoder_sandbox_spec.rb b/deployment_scripts/puppet/modules/heka/spec/defines/heka_encoder_sandbox_spec.rb deleted file mode 100644 index e0dd349de..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/defines/heka_encoder_sandbox_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'heka::encoder::sandbox' do - let(:title) { :foo } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with title = foo' do - let(:params) {{:config_dir => '/etc/hekad', :filename => 'foo.lua'}} - it { is_expected.to contain_file('/etc/hekad/encoder-foo.toml').without_content(/module_directory/) } - end - - describe 'with title = foo and module_directory' do - let(:params) {{:config_dir => '/etc/hekad', :filename => 'foo.lua', :module_directory => '/tmp'}} - it { is_expected.to contain_file('/etc/hekad/encoder-foo.toml').with_content(/module_directory = "\/tmp;/) } - end - -end diff --git a/deployment_scripts/puppet/modules/heka/spec/defines/heka_filter_sandbox_spec.rb b/deployment_scripts/puppet/modules/heka/spec/defines/heka_filter_sandbox_spec.rb deleted file mode 100644 index fb6415db2..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/defines/heka_filter_sandbox_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'heka::filter::sandbox' do - let(:title) { :foo } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with title = foo' do - let(:params) {{:config_dir => '/etc/hekad', :filename => 'foo.lua'}} - it { is_expected.to contain_file('/etc/hekad/filter-foo.toml').without_content(/module_directory/) } - end - - describe 'with title = foo and module_directory' do - let(:params) {{:config_dir => '/etc/hekad', :filename => 'foo.lua', :module_directory => '/tmp'}} - it { is_expected.to contain_file('/etc/hekad/filter-foo.toml').with_content(/module_directory = "\/tmp;/) } - end - -end diff --git a/deployment_scripts/puppet/modules/heka/spec/defines/heka_input_logstream_spec.rb b/deployment_scripts/puppet/modules/heka/spec/defines/heka_input_logstream_spec.rb deleted file mode 100644 index 8df371cf5..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/defines/heka_input_logstream_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'heka::input::logstreamer' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with required params' do - let(:title) { :foo } - let(:params) do - {:config_dir => '/etc/heka', - :decoder => 'decoder'} - end - it { is_expected.to contain_file('/etc/heka/logstreamer-foo.toml') } - end - - describe 'differentiator including a slash' do - let(:title) { :foo } - let(:params) do - {:config_dir => '/etc/heka', - :decoder => 'decoder', :differentiator => '["test", "/"]'} - end - it { is_expected.to raise_error(Puppet::Error, /slash/) } - end -end diff --git a/deployment_scripts/puppet/modules/heka/spec/defines/heka_output_http_spec.rb b/deployment_scripts/puppet/modules/heka/spec/defines/heka_output_http_spec.rb deleted file mode 100644 index 85f97e5d9..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/defines/heka_output_http_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'heka::output::http' do - let(:title) { :foo } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with title = foo' do - let(:params) {{:config_dir => '/etc/hekad', :url => 'http://example.com/'}} - it { is_expected.to contain_file('/etc/hekad/output-foo.toml') } - end - - describe 'with title = foo and buffering' do - let(:params) {{:config_dir => '/etc/hekad', - :url => 'http://example.com/', - :use_buffering => true, - :max_file_size => 50000, - :max_buffer_size => 100000, - :queue_full_action => 'shutdown' - }} - it { is_expected.to contain_file('/etc/hekad/output-foo.toml') } - end -end diff --git a/deployment_scripts/puppet/modules/heka/spec/defines/heka_output_sandbox_spec.rb b/deployment_scripts/puppet/modules/heka/spec/defines/heka_output_sandbox_spec.rb deleted file mode 100644 index 579a7773f..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/defines/heka_output_sandbox_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'heka::output::sandbox' do - let(:title) { :foo } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with title = foo' do - let(:params) {{:config_dir => '/etc/hekad', :filename => 'foo.lua'}} - it { is_expected.to contain_file('/etc/hekad/output-foo.toml').without_content(/module_directory/) } - end - - describe 'with title = foo and module_directory' do - let(:params) {{:config_dir => '/etc/hekad', :filename => 'foo.lua', :module_directory => '/tmp'}} - it { is_expected.to contain_file('/etc/hekad/output-foo.toml').with_content(/module_directory = "\/tmp;/) } - end - -end diff --git a/deployment_scripts/puppet/modules/heka/spec/defines/heka_spec.rb b/deployment_scripts/puppet/modules/heka/spec/defines/heka_spec.rb deleted file mode 100644 index 3fada87af..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/defines/heka_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'heka' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - let(:title) { :log} - it { is_expected.to contain_user('heka') } - it { is_expected.to contain_file('/etc/init/log.conf') \ - .with_content(/--chuid heka/) } - end - - describe 'with user => "root"' do - let(:params) do - {:user => 'root'} - end - let(:title) { :foo} - - it { is_expected.to contain_user('root') } - it { is_expected.to contain_file('/etc/init/foo.conf') } - it { is_expected.not_to contain_file('/etc/init/foo.conf') \ - .with_content(/--chuid/) } - end -end diff --git a/deployment_scripts/puppet/modules/heka/spec/functions/validate_buffering_spec.rb b/deployment_scripts/puppet/modules/heka/spec/functions/validate_buffering_spec.rb deleted file mode 100644 index 0a42ad075..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/functions/validate_buffering_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'validate_buffering' do - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('foo', 'bar', 'drop').and_raise_error(Puppet::ParseError, /bad argument/i) } - it { is_expected.to run.with_params(1024, 2048, 'drop').and_raise_error(Puppet::ParseError, /should be greater/i) } - it { is_expected.to run.with_params(2048, 1024, 'foo').and_raise_error(Puppet::ParseError, /should be either/i) } - it { is_expected.to run.with_params(0, '', 'shutdown') } - it { is_expected.to run.with_params(2048, 1024, 'shutdown') } - it { is_expected.to run.with_params(1024*1024*1024, 0, 'block') } -end diff --git a/deployment_scripts/puppet/modules/heka/spec/spec.opts b/deployment_scripts/puppet/modules/heka/spec/spec.opts deleted file mode 100644 index 91cd6427e..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/spec.opts +++ /dev/null @@ -1,6 +0,0 @@ ---format -s ---colour ---loadby -mtime ---backtrace diff --git a/deployment_scripts/puppet/modules/heka/spec/spec_helper.rb b/deployment_scripts/puppet/modules/heka/spec/spec_helper.rb deleted file mode 100644 index d8df693e5..000000000 --- a/deployment_scripts/puppet/modules/heka/spec/spec_helper.rb +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'rspec-puppet' - -fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) - -RSpec.configure do |c| - c.module_path = File.join(fixture_path, 'modules') - c.manifest_dir = File.join(fixture_path, 'manifests') - c.environmentpath = File.join(Dir.pwd, 'spec') -end diff --git a/deployment_scripts/puppet/modules/heka/templates/decoder/multidecoder.toml.erb b/deployment_scripts/puppet/modules/heka/templates/decoder/multidecoder.toml.erb deleted file mode 100644 index 1da8c52cf..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/decoder/multidecoder.toml.erb +++ /dev/null @@ -1,5 +0,0 @@ -[<%= @title %>_decoder] -type = "MultiDecoder" -subs = [<%= @subs.sort.collect{|x| '"' + x + '"'}.join(',') %>] -cascade_strategy = "<%= @cascade_strategy %>" -log_sub_errors = <%= @log_sub_errors %> diff --git a/deployment_scripts/puppet/modules/heka/templates/decoder/sandbox.toml.erb b/deployment_scripts/puppet/modules/heka/templates/decoder/sandbox.toml.erb deleted file mode 100644 index 715265444..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/decoder/sandbox.toml.erb +++ /dev/null @@ -1,14 +0,0 @@ -[<%= @title %>_decoder] -type = "SandboxDecoder" -filename = "<%= @filename %>" -<% if @module_directory -%> -module_directory = "<%= @module_directory %>;/usr/share/heka/lua_modules" -<% end -%> - -<% if @config.size() > 0 %> -[<%= @title %>_decoder.config] -<% @config.each do |k,v| %> -<% next if v.nil? or v == :undef -%> - <%= k %> = <%= v.is_a?(String) ? "'#{v}'" : v %> -<% end %> -<% end %> diff --git a/deployment_scripts/puppet/modules/heka/templates/decoder/scribbler.toml.erb b/deployment_scripts/puppet/modules/heka/templates/decoder/scribbler.toml.erb deleted file mode 100644 index a9ca86fe1..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/decoder/scribbler.toml.erb +++ /dev/null @@ -1,8 +0,0 @@ -[<%= @title %>_decoder] -type = "ScribbleDecoder" - -[<%= @title %>_decoder.message_fields] -<% @config.sort.each do |k,v| %> -<% next if v.nil? or v == :undef -%> - <%= k %> = "<%= v %>" -<% end %> diff --git a/deployment_scripts/puppet/modules/heka/templates/encoder/es_json.toml.erb b/deployment_scripts/puppet/modules/heka/templates/encoder/es_json.toml.erb deleted file mode 100644 index 42bd44355..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/encoder/es_json.toml.erb +++ /dev/null @@ -1,8 +0,0 @@ -[<%= @title %>_encoder] -type = "ESJsonEncoder" -index = "<%= @index %>" -es_index_from_timestamp = <%= @es_index_from_timestamp %> -timestamp = "<%= @timestamp %>" -<% if @fields -%> -fields = [ <%= @fields.sort.collect{ |x| '"%s"' % x }.join(", ") %> ] -<% end -%> diff --git a/deployment_scripts/puppet/modules/heka/templates/encoder/payload.toml.erb b/deployment_scripts/puppet/modules/heka/templates/encoder/payload.toml.erb deleted file mode 100644 index 83962f728..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/encoder/payload.toml.erb +++ /dev/null @@ -1,4 +0,0 @@ -[<%= @title %>_encoder] -type = "PayloadEncoder" -append_newlines = <%= @append_newlines %> -prefix_ts = <%= @prefix_ts %> diff --git a/deployment_scripts/puppet/modules/heka/templates/encoder/sandbox.toml.erb b/deployment_scripts/puppet/modules/heka/templates/encoder/sandbox.toml.erb deleted file mode 100644 index 2f49a1cde..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/encoder/sandbox.toml.erb +++ /dev/null @@ -1,13 +0,0 @@ -[<%= @title %>_encoder] -type = "SandboxEncoder" -filename = "<%= @filename %>" -<% if @module_directory -%> -module_directory = "<%= @module_directory %>;/usr/share/heka/lua_modules" -<% end -%> -<% if @config.size() > 0 %> -[<%= @title %>_encoder.config] -<% @config.each do |k,v| -%> -<%- next if v.nil? or v == :undef -%> - <%= k %> = <%= v.is_a?(String) ? "'#{v}'" : v %> -<% end %> -<% end %> diff --git a/deployment_scripts/puppet/modules/heka/templates/filter/sandbox.toml.erb b/deployment_scripts/puppet/modules/heka/templates/filter/sandbox.toml.erb deleted file mode 100644 index bc0493155..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/filter/sandbox.toml.erb +++ /dev/null @@ -1,19 +0,0 @@ -[<%= @title %>_filter] -type = "SandboxFilter" -filename = "<%= @filename %>" -preserve_data = <%= @preserve_data %> -message_matcher = "<%= @message_matcher %>" -<% if @module_directory -%> -module_directory = "<%= @module_directory %>;/usr/share/heka/lua_modules" -<% end -%> -<% if @ticker_interval %> -ticker_interval = <%= @ticker_interval %> -<% end %> - -<% if @config.size() > 0 %> -[<%= @title %>_filter.config] -<% @config.each do |k,v| %> -<% next if v.nil? or v == :undef -%> - <%= k %> = <%= v.is_a?(String) ? "'#{v}'" : v %> -<% end %> -<% end %> diff --git a/deployment_scripts/puppet/modules/heka/templates/global.toml.erb b/deployment_scripts/puppet/modules/heka/templates/global.toml.erb deleted file mode 100644 index d3b75cef9..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/global.toml.erb +++ /dev/null @@ -1,18 +0,0 @@ -[hekad] -maxprocs=<%= @_maxprocs %> -base_dir="<%= @base_dir %>" -<% if @_hostname %> -hostname="<%= @_hostname %>" -<% end %> -<% if @_max_message_size -%> -max_message_size = <%= @_max_message_size %> -<% end -%> -<% if @_max_process_inject -%> -max_process_inject = <%= @_max_process_inject %> -<% end -%> -<% if @_max_timer_inject -%> -max_timer_inject = <%= @_max_timer_inject %> -<% end -%> -<% if @poolsize -%> -poolsize = <%= @poolsize %> -<% end -%> diff --git a/deployment_scripts/puppet/modules/heka/templates/hekad.initd.erb b/deployment_scripts/puppet/modules/heka/templates/hekad.initd.erb deleted file mode 100644 index 303fa4372..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/hekad.initd.erb +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/sh -# -# hekad <%= @service_name %> -# -# chkconfig: - 98 02 -# description: Starts and stops a single heka instance on this system -### END INIT INFO - -# -# Source function library. -# -if [ -f /etc/rc.d/init.d/functions ]; then - . /etc/rc.d/init.d/functions -fi - -exec="<%= @hekad_wrapper %>" -prog="<%= @service_name %>" -pidfile=/var/run/${prog}.pid - -[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog - -lockfile=/var/lock/subsys/$prog - -HEKA_USER=root - -start() { - [ -x $exec ] || exit 5 - [ -f $CONF_FILE ] || exit 6 -<% unless @_run_as_root -%> - touch <%= @log_file %> - chown <%= @heka_user %>:<%= @heka_user %> <%= @log_file %> -<% end -%> - echo -n $"Starting $prog: " - daemonize -p $pidfile -e <%= @log_file %> <%= @_run_as_root ? "" : "-u #{ @heka_user }" %> -l $lockfile $exec - retval=$? - [ $retval -eq 0 ] && success || failure - echo - [ $retval -eq 0 ] && touch $lockfile - return $retval -} - -stop() { - echo -n $"Stopping $prog: " - pkill -P $(cat $pidfile) - retval=$? - rm -f $pidfile - echo - [ $retval -eq 0 ] && rm -f $lockfile - return $retval -} - -restart() { - stop - start -} - -reload() { - restart -} - -force_reload() { - restart -} - -rh_status() { - # run checks to determine if the service is running or use generic status - status -p $pidfile $prog -} - -rh_status_q() { - rh_status >/dev/null 2>&1 -} - - -case "$1" in - start) - rh_status_q && exit 0 - $1 - ;; - stop) - rh_status_q || exit 0 - $1 - ;; - restart) - $1 - ;; - reload) - rh_status_q || exit 7 - $1 - ;; - force-reload) - force_reload - ;; - status) - rh_status - ;; - condrestart|try-restart) - rh_status_q || exit 0 - restart - ;; - *) - echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" - exit 2 -esac -exit $? diff --git a/deployment_scripts/puppet/modules/heka/templates/hekad.upstart.conf.erb b/deployment_scripts/puppet/modules/heka/templates/hekad.upstart.conf.erb deleted file mode 100644 index 8c3c291e8..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/hekad.upstart.conf.erb +++ /dev/null @@ -1,21 +0,0 @@ -# <%= @service_name %> - -description "<%= @service_name %>" - -start on runlevel [2345] -stop on runlevel [!2345] - -respawn - -<% unless @_run_as_root -%> -pre-start script - touch <%= @log_file %> - chown <%= @heka_user %>:<%= @heka_user %> <%= @log_file %> -end script -<% end -%> - -script - # https://bugs.launchpad.net/lma-toolchain/+bug/1543289 - ulimit -n 102400 - exec start-stop-daemon --start <%= @_run_as_root ? "" : " --chuid #{ @heka_user }" %> --exec <%= @hekad_wrapper %> 2>><%= @log_file %> -end script diff --git a/deployment_scripts/puppet/modules/heka/templates/hekad_wrapper.erb b/deployment_scripts/puppet/modules/heka/templates/hekad_wrapper.erb deleted file mode 100644 index 9a93d092c..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/hekad_wrapper.erb +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -HEKAD="/usr/bin/hekad" - -<% if @pre_script -%> -<%= @pre_script %> -<% end -%> - -exec $HEKAD -config=<%= @config_dir %> diff --git a/deployment_scripts/puppet/modules/heka/templates/input/amqp.toml.erb b/deployment_scripts/puppet/modules/heka/templates/input/amqp.toml.erb deleted file mode 100644 index d537ef278..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/input/amqp.toml.erb +++ /dev/null @@ -1,13 +0,0 @@ -[<%= @title %>_amqp] -type = "AMQPInput" -url = "amqp://<%= @user %>:<%= @password %>@<%= @host %>:<%= @port %>/" -exchange = "<%= @exchange %>" -exchange_type = "<%= @exchange_type %>" -exchange_durability = <%= @exchange_durability %> -exchange_auto_delete = <%= @exchange_auto_delete %> -queue_auto_delete = <%= @queue_auto_delete %> -queue = "<%= @queue %>" -routing_key = "<%= @routing_key %>" -decoder = "<%= @decoder %>_decoder" -splitter = "NullSplitter" -can_exit = <%= @can_exit %> diff --git a/deployment_scripts/puppet/modules/heka/templates/input/httplisten.toml.erb b/deployment_scripts/puppet/modules/heka/templates/input/httplisten.toml.erb deleted file mode 100644 index 97222b877..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/input/httplisten.toml.erb +++ /dev/null @@ -1,5 +0,0 @@ -[<%= @title %>_httplisten] -type="HttpListenInput" -address = "<%= @address %>:<%= @port %>" -decoder = "<%= @decoder %>_decoder" -splitter = "NullSplitter" diff --git a/deployment_scripts/puppet/modules/heka/templates/input/logstreamer.toml.erb b/deployment_scripts/puppet/modules/heka/templates/input/logstreamer.toml.erb deleted file mode 100644 index 1153a9a46..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/input/logstreamer.toml.erb +++ /dev/null @@ -1,12 +0,0 @@ -[<%= @title %>_logstreamer] -type = "LogstreamerInput" -log_directory = "<%= @log_directory %>" -file_match = '<%= @file_match %>' -<% if @differentiator -%> -differentiator = <%= @differentiator %> -<% end -%> -<% if @priority -%> -priority = <%= @priority %> -<% end -%> -decoder = "<%= @decoder %>_decoder" -splitter = "<%= @splitter ? "#{ @splitter }_splitter" : "TokenSplitter" %>" diff --git a/deployment_scripts/puppet/modules/heka/templates/input/process.toml.erb b/deployment_scripts/puppet/modules/heka/templates/input/process.toml.erb deleted file mode 100644 index 1aac8d136..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/input/process.toml.erb +++ /dev/null @@ -1,28 +0,0 @@ -[<%= @title %>_process] -type="ProcessInput" -ticker_interval = <%= @ticker_interval %> -decoder = "<%= @decoder %>_decoder" -<% if @stdout -%> -stdout = true -<% else %> -stdout = false -<% end %> -<% if @stderr -%> -stderr = true -<% else %> -stderr = false -<% end %> - -<% if @splitter -%> -splitter = "<%= @splitter %>_splitter" -<% else -%> -splitter = "NullSplitter" -<% end -%> - -<% @commands.each_with_index do |command, i| -%> - <% command.each do |cmd, args| -%> - [<%= @title %>_process.command.<%= i %>] - bin = "<%= cmd %>" - args = [ <%= args.collect{ |x| '"%s"' % x }.join(", ") %> ] - <%end%> -<% end %> diff --git a/deployment_scripts/puppet/modules/heka/templates/input/tcp.toml.erb b/deployment_scripts/puppet/modules/heka/templates/input/tcp.toml.erb deleted file mode 100644 index f3ef9030b..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/input/tcp.toml.erb +++ /dev/null @@ -1,5 +0,0 @@ -[<%= @title %>_tcpinput] -type="TcpInput" -address = "<%= @address %>:<%= @port %>" -decoder = "<%= @decoder_instance %>" -splitter = "HekaFramingSplitter" diff --git a/deployment_scripts/puppet/modules/heka/templates/logrotate.conf.erb b/deployment_scripts/puppet/modules/heka/templates/logrotate.conf.erb deleted file mode 100644 index a24a99600..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/logrotate.conf.erb +++ /dev/null @@ -1,22 +0,0 @@ -# managed by puppet -<%= @log_file %> { - # Heka cannot be told to close its log file and re-open it so we need to - # use the copytruncate option - copytruncate - compress - delaycompress - missingok - notifempty - # logrotate allows to use only year, month, day and unix epoch - dateext - dateformat -%Y%m%d-%s - # number of rotated files to keep - rotate 10 - # do not rotate files unless both size and time conditions are met - hourly - minsize 20M - # force rotate if filesize exceeded 100M - maxsize 100M - # this must map the /var/log directory group ownership - su root syslog -} diff --git a/deployment_scripts/puppet/modules/heka/templates/logrotate.cron.erb b/deployment_scripts/puppet/modules/heka/templates/logrotate.cron.erb deleted file mode 100644 index e9d0ca132..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/logrotate.cron.erb +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# managed by puppet - -test -x /usr/sbin/logrotate || exit 0 - -LOCK_FILE="/var/lock/logrotate.<%= @service_name %>.lock" - -lock() { - exec 903>$LOCK_FILE - flock -n 903 && return 0 || return 1 -} - -unlock() { - flock -u 903 -} - -fail() { - if [ -z "$1" ] - then - MESSAGE="WARNING logrotate failed, no reason provided" - else - MESSAGE=$1 - fi - /usr/bin/logger -t logrotate "<%= @service_name %> ${MESSAGE}" - unlock - exit 1 -} - -lock || fail "WARNING <%= @service_name %> logrotate flock failed, exiting" - - -TMP_FILE=$(/bin/mktemp) -nice ionice -c3 /usr/sbin/logrotate -s /var/lib/logrotate/<%= @service_name %>.status <%= @logrotate_conf %> >& $TMP_FILE -EXITVALUE=$? - -if [ -f /etc/redhat-release ] || [ -f /etc/centos-release ]; -then - # Due to bug in logrotate on centos/rhel, it always returns 0. Use grep for - # detect errors; exit code 1 is considered a success as no errors were - # found. - grep -q error $TMP_FILE - EXITVALUE=$? - EXPECTEDVALUE=1 -else - EXPECTEDVALUE=0 -fi -rm $TMP_FILE - -if [ "${EXITVALUE}" != "${EXPECTEDVALUE}" ]; then - fail "ALERT exited abnormally with [${EXITVALUE}] (${EXPECTEDVALUE} was expected)" -fi - -unlock -exit 0 diff --git a/deployment_scripts/puppet/modules/heka/templates/output/dashboard.toml.erb b/deployment_scripts/puppet/modules/heka/templates/output/dashboard.toml.erb deleted file mode 100644 index 3f45495b7..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/output/dashboard.toml.erb +++ /dev/null @@ -1,3 +0,0 @@ -[DashboardOutput] -address = "<%= @dashboard_address %>:<%= @dashboard_port %>" -ticker_interval = <%= @ticker_interval %> diff --git a/deployment_scripts/puppet/modules/heka/templates/output/elasticsearch.toml.erb b/deployment_scripts/puppet/modules/heka/templates/output/elasticsearch.toml.erb deleted file mode 100644 index 67e49d5e2..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/output/elasticsearch.toml.erb +++ /dev/null @@ -1,21 +0,0 @@ -[<%= @title %>_output] -type = "ElasticSearchOutput" -message_matcher = "<%= @message_matcher %>" -encoder = "<%= @encoder %>_encoder" - -<% # Heka expects milliseconds here -%> -flush_interval = <%= @flush_interval.to_i() * 1000 %> -flush_count = <%= @flush_count %> - -server = "http://<%= @server %>:<%= @port %>" - -use_buffering = <%= @use_buffering %> - -<% if @use_buffering -%> -[<%= @title %>_output.buffering] -max_buffer_size = <%= @max_buffer_size %> -<% if @max_file_size != :undef -%> -max_file_size = <%= @max_file_size %> -<% end -%> -full_action = "<%= @queue_full_action %>" -<% end -%> diff --git a/deployment_scripts/puppet/modules/heka/templates/output/http.toml.erb b/deployment_scripts/puppet/modules/heka/templates/output/http.toml.erb deleted file mode 100644 index 08bc9bb23..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/output/http.toml.erb +++ /dev/null @@ -1,32 +0,0 @@ -[<%= @title %>_output] -type = "HttpOutput" -message_matcher = "<%= @message_matcher %>" -encoder = "<%= @encoder %>_encoder" -address = "<%= @url %>" -<% if @username -%> -username = "<%= @username %>" -<% end -%> -<% if @password -%> -password = "<%= @password %>" -<% end -%> -<% unless @timeout.nil? -%> -http_timeout = <%= @timeout.to_i() * 1000 %> -<% end -%> -method = "<%= @method %>" -use_buffering = <%= @use_buffering %> - -<% if @use_buffering -%> -[<%= @title %>_output.buffering] -max_buffer_size = <%= @max_buffer_size %> -<% if @max_file_size != :undef -%> -max_file_size = <%= @max_file_size %> -<% end -%> -full_action = "<%= @queue_full_action %>" -<% end -%> - -<% if @headers.size() > 0 -%> - [<%= @title %>_output.headers] - <% @headers.keys().sort().each do |header| -%> - <%= header %> = ["<%= @headers[header] %>"] - <%end%> -<% end -%> diff --git a/deployment_scripts/puppet/modules/heka/templates/output/sandbox.toml.erb b/deployment_scripts/puppet/modules/heka/templates/output/sandbox.toml.erb deleted file mode 100644 index fe07b125e..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/output/sandbox.toml.erb +++ /dev/null @@ -1,16 +0,0 @@ -[<%= @title %>_output] -type = "SandboxOutput" -filename = "<%= @filename %>" -message_matcher = "<%= @message_matcher %>" -message_matcher = "<%= @message_matcher %>" -<% if @module_directory -%> -module_directory = "<%= @module_directory %>;/usr/share/heka/lua_modules" -<% end -%> - -<% if @config.size() > 0 %> -[<%= @title %>_output.config] -<% @config.each do |k,v| %> -<% next if v.nil? or v == :undef -%> - <%= k %> = <%= v.is_a?(String) ? "'#{v}'" : v %> -<% end %> -<% end %> diff --git a/deployment_scripts/puppet/modules/heka/templates/output/smtp.toml.erb b/deployment_scripts/puppet/modules/heka/templates/output/smtp.toml.erb deleted file mode 100644 index 9b51149ce..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/output/smtp.toml.erb +++ /dev/null @@ -1,16 +0,0 @@ -[<%= @title %>_output] -type = "SmtpOutput" -message_matcher = "<%= @message_matcher %>" -encoder = "<%= @encoder %>_encoder" -send_from = "<%= @send_from %>" -send_to = [<%= @send_to.sort().collect { |email| "'#{email}'"}.join(',') %>] -subject = "<%= @subject %>" -host = "<%= @host %>" -auth = "<%= @auth %>" -<% if @user and not @user.nil? and @password != ''%> -user = "<%= @user %>" -<% end %> -<% if @password and not @password.nil? and @password != '' %> -password = "<%= @password %>" -<% end %> -send_interval = <%= @send_interval %> diff --git a/deployment_scripts/puppet/modules/heka/templates/output/tcp.toml.erb b/deployment_scripts/puppet/modules/heka/templates/output/tcp.toml.erb deleted file mode 100644 index 3a3f7dfc0..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/output/tcp.toml.erb +++ /dev/null @@ -1,16 +0,0 @@ -[<%= @title %>_tcpoutput] -type="TcpOutput" -address = "<%= @address %>:<%= @port %>" -encoder = "ProtobufEncoder" -message_matcher = "<%= @message_matcher %>" - -use_buffering = <%= @use_buffering %> -<% if @use_buffering -%> -[<%= @title %>_tcpoutput.buffering] -max_buffer_size = <%= @max_buffer_size %> -<% if @max_file_size != :undef -%> -max_file_size = <%= @max_file_size %> -<% end -%> -full_action = "<%= @queue_full_action %>" -<% end -%> - diff --git a/deployment_scripts/puppet/modules/heka/templates/splitter/regex.toml.erb b/deployment_scripts/puppet/modules/heka/templates/splitter/regex.toml.erb deleted file mode 100644 index dfd5548e9..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/splitter/regex.toml.erb +++ /dev/null @@ -1,6 +0,0 @@ -[<%= @title %>_splitter] -type = "RegexSplitter" -delimiter = '<%= @delimiter %>' -<% unless @delimiter_eol.nil? -%> -delimiter_eol = <%= @delimiter_eol %> -<% end -%> diff --git a/deployment_scripts/puppet/modules/heka/templates/splitter/token.toml.erb b/deployment_scripts/puppet/modules/heka/templates/splitter/token.toml.erb deleted file mode 100644 index 239009dde..000000000 --- a/deployment_scripts/puppet/modules/heka/templates/splitter/token.toml.erb +++ /dev/null @@ -1,3 +0,0 @@ -[<%= @title %>_splitter] -type = "TokenSplitter" -delimiter = "<%= @delimiter %>" diff --git a/deployment_scripts/puppet/modules/heka/tests/init.pp b/deployment_scripts/puppet/modules/heka/tests/init.pp deleted file mode 100644 index cf391e877..000000000 --- a/deployment_scripts/puppet/modules/heka/tests/init.pp +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# The baseline for module testing used by Puppet Labs is that each manifest -# should have a corresponding test manifest that declares that class or defined -# type. -# -# Tests are then run by using puppet apply --noop (to check for compilation -# errors and view a log of events) or by fully applying the test in a virtual -# environment (to compare the resulting system state to the desired state). -# -# Learn more about module testing here: -# http://docs.puppetlabs.com/guides/tests_smoke.html -# -include heka diff --git a/deployment_scripts/puppet/modules/lma_collector/.fixtures.yml b/deployment_scripts/puppet/modules/lma_collector/.fixtures.yml deleted file mode 100644 index 7fa6b2625..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/.fixtures.yml +++ /dev/null @@ -1,17 +0,0 @@ -fixtures: - repositories: - stdlib: - repo: "git://github.com/puppetlabs/puppetlabs-stdlib" - ref: "4.7.0" - concat: - repo: "git://github.com/puppetlabs/puppetlabs-concat" - ref: "1.2.4" - collectd: - repo: "git://github.com/puppet-community/puppet-collectd" - ref: "v4.3.0" - apache: - repo: "git://github.com/puppetlabs/puppetlabs-apache" - ref: "1.4.0" - symlinks: - lma_collector: "#{source_dir}" - heka: "#{source_dir}/../heka" diff --git a/deployment_scripts/puppet/modules/lma_collector/.gitignore b/deployment_scripts/puppet/modules/lma_collector/.gitignore deleted file mode 100644 index 91a269438..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -spec/fixtures/modules/* -spec/fixtures/manifests/* -Gemfile.lock -tests/lua/mocks/date_time.lua -.bundle -tests/lua/mocks/inspect.lua -tests/lua/mocks/anomaly.lua -tests/lua/mocks/annotation.lua diff --git a/deployment_scripts/puppet/modules/lma_collector/Gemfile b/deployment_scripts/puppet/modules/lma_collector/Gemfile deleted file mode 100644 index e8a2c49ed..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/Gemfile +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -source 'https://rubygems.org' - -group :development, :test do - gem 'rake' - gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.4.0' - gem 'rspec' - gem 'rspec-puppet' - gem 'rspec-puppet-facts' - # Newer puppetlabs_spec_helper depends on rubocop-rspec that requires ruby >= 2.2.0 - gem 'puppetlabs_spec_helper', '~> 1.1.1' - # puppet-lint >= 2.2.0 don't support Puppet 3.x anymore - gem 'puppet-lint', '~> 2.1.0' - gem 'metadata-json-lint' -end diff --git a/deployment_scripts/puppet/modules/lma_collector/LICENSE b/deployment_scripts/puppet/modules/lma_collector/LICENSE deleted file mode 100644 index e06d20818..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. - diff --git a/deployment_scripts/puppet/modules/lma_collector/README.md b/deployment_scripts/puppet/modules/lma_collector/README.md deleted file mode 100644 index e7b12d41d..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/README.md +++ /dev/null @@ -1,1122 +0,0 @@ -# lma_collector - -## Overview - -The `lma_collector` module lets you use Puppet to configure and deploy -collectors of the LMA (Logging, Monitoring and Alerting) toolchain. - -The main components of an LMA collector are: - -* [Heka](http://hekad.readthedocs.org). Heka is used to process log, - notification and metric messages, and persist these messages into - Elasticsearch and InfluxDB. - -* [collectd](http://collectd.org/). collectd is used for collecting - performance statistics from various sources. - -The following versions of Heka and collectd are known to work for LMA: - -* Heka v0.10.0 (`heka_0.10.0_amd64.deb`) -* collectd v5.4.0 (`collectd_5.4.0-3ubuntu2_amd64.deb`) - -## Usage - -### Setup - -To install and configure the main components, declare the `lma_collector` -class and `lma_collector::heka` defines: - -```puppet -class { 'lma_collector': } - -lma_collector::heka { 'log_collector': - require => Class['lma_collector'], -} - -lma_collector::heka { 'metric_collector': - require => Class['lma_collector'], -} -``` - -This installs Heka and configures it with Heka plugins necessary for LMA. - -Here is another example where a custom Heka message field is specified: - -```puppet -class {'lma_collector': - tags => { - tag_A => 'some value' - } -} -``` - -### Collect system logs - -To make the Collector collect standard system logs from log files in `/var/log` -declare the `lma_collector::logs::system` class: - -```puppet -class { 'lma_collector::logs::system': } -``` - -### Collect OpenStack logs - -To make the collector collect logs created by an OpenStack service declare the -`lma_collector::logs::openstack` define. This is an example for the Nova logs: - -```puppet -lma_collector::logs::openstack { 'nova': } -``` - -This configures Heka to read the Nova logs from the log files located in -`/var/log/nova/`. - -For Swift a specific class should be declared. For example: - -```puppet -class { 'lma_collector::logs::swift': - file_match => 'swift-all\.log$', -} -``` - -For Keystone, in addition to declaring the `lma_collector::logs::openstack` -define, the `lma_collector::logs::keystone_wsgi` class should be declared -to read Keystone logs stored from Apache log files: - -```puppet -class { 'lma_collector::logs::keystone_wsgi': } -``` - -### Collect libvirt logs - -To make the collector collect logs created by libvirt declare the -`lma_collector::logs::libvirt` class: - -```puppet -class { 'lma_collector::logs::libvirt': } -``` - -### Collect MySQL logs - -To make the collector collect logs created by MySQL declare the -`lma_collector::logs::mysql` class: - -```puppet -class { 'lma_collector::logs::mysql': } -``` - -### Collect Open vSwitch logs - -To make the collector collect logs created by Open vSwitch declare the -`lma_collector::logs::ovs` class: - -```puppet -class { 'lma_collector::logs::ovs': } -``` - -### Collect Pacemaker logs - -To make the collector collect logs created by Pacemaker declare the -`lma_collector::logs::pacemaker` class: - -```puppet -class { 'lma_collector::logs::pacemaker': } -``` - -### Collect RabbitMQ logs - -To make the collector collect logs created by RabbitMQ declare the -`lma_collector::logs::rabbitmq` class: - -```puppet -class { 'lma_collector::logs::rabbitmq': } -``` - -### Derive HTTP metrics from logs - -To make the collector create HTTP metrics from OpenStack log messages that -include HTTP information (method, status, and response time) declare the -`lma_collector::logs::aggregated_http_metrics` class: - -```puppet -class { 'lma_collector::logs::aggregated_http_metrics': } -``` - -### Store logs into Elasticsearch - -To make the collector store the collected logs into Elasticsearch declare the -`lma_collector::elasticsearch` class: - -```puppet -class { 'lma_collector::elasticsearch': - server => 'example.com', -} -``` - -### Collect statistics (a.k.a. metrics) - -The `lma_collector::collectd::base` sets up collectd and the communication -channel between collectd and Heka. It also sets up a number of standard collect -plugins. - -Usage example: - -```puppet -class { 'lma_collector::collectd::base': - processes => ['influxdb', 'grafana-server', 'hekad', 'collectd'], - process_matches => [{name => 'elasticsearch', regex => 'java'}] - read_threads => 10, -} -``` - -### Collect OpenStack statistics - -To make the collector collect statistics for an OpenStack service declare -the `lma_collector::collectd::openstack` define: - -```puppet -lma_collector::collectd::openstack { 'nova': - user => 'user', - password => 'password', - tenant => 'tenant', - keystone_url => 'http://example.com/keystone', - polling_interval => 60, - pagination_limit => 500, -} -``` - -This define can be used for the following OpenStack services: nova, cinder, -glance, keystone, and neutron. - -Here is another example for neutron: - -```puppet -lma_collector::collectd::openstack { 'neutron': - user => 'user', - password => 'password', - tenant => 'tenant', - keystone_url => 'http://example.com/keystone', -} -``` - -### Collect OpenStack service statuses - -To make the collector collect statuses of OpenStack services declare the -`lma_collector::collectd::openstack_checks` class: - -```puppet -class { 'lma_collector::collectd::openstack_checks': - user => 'user', - password => 'password', - tenant => 'tenant', - keystone_url => 'http://example.com/keystone', -} -``` - -### Collectd OpenStack service worker statuses - -To make the collector collect statuses of workers of an OpenStack service -declare the `lma_collector::collectd::dbi_services` define: - -```puppet -lma_collector::collectd::dbi_services { 'nova': - dbname => 'nova', - username => 'nova', - password => 'nova', - report_interval => 60, - downtime_factor => 2, -} -``` - -This define can be used for the following OpenStack services: nova, cinder and -neutron. - -### Collect HAProxy statistics - -To make the collector collect statistics for HAProxy declare the -`lma_collector::collectd::haproxy` class: - -```puppet -class { 'lma_collector::collectd::haproxy': - socket => '/var/lib/haproxy/stats', - # mapping of proxy names to meaningful names to use in metrics names - proxy_names => { - 'keystone-1' => 'keystone-public-api', - 'keystone-2' => 'keystone-admin-api', - }, -} -``` - -### Collect RabbitMQ statistics - -To make the collector collect statistics for RabbitMQ declare the -`lma_collector::collectd::rabbitmq` class: - -```puppet -class { 'lma_collector::collectd::rabbitmq': -} -``` - -### Collect Memcached statistics - -To make the collector collect statistics for Memcached declare the -`lma_collector::collectd::memcached` class: - -```puppet -class {'lma_collector::collectd::memcached': - host => 'localhost', -} -``` - -### Collect Apache statistics - -To make the collector collect statistics for Apache declare the -`lma_collector::collectd::apache` class: - -```puppet -class { 'lma_collector::collectd::apache': -} -``` - -This will collectd Apache statistics from -`http://127.0.0.1/server-status?auto`. - -### Collect Nova Hypervisor statistics - -To make the collector collect statistics for the Nova hypervisors declare the -`lma_collector::collectd::hypervisor` class: - -```puppet -class { 'lma_collector::collectd::hypervisor': - user => 'user', - password => 'password', - tenant => 'tenant', - keystone_url => 'http://example.com/keystone', -} -``` - -### Collect Ceph statistics - -To make the collector collect statistics for Ceph declare the -`lma_collector::collectd::ceph_mon` class: - -```puppet -class { 'lma_collector::collectd::ceph_mon: -} -``` - -With this the collector will collect information on the Ceph cluster (health, -monitor count, quorum count, free space, ...) and the placement groups. - -### Collect Ceph OSD statistics - -To make the collector collect Ceph OSD (Object Storage Daemon) performance -statistics declare the `lma_collector::collectd::ceph_osd` class: - -```puppet -class { 'lma_collector::collectd::ceph_osd': -} -``` - -### Collect Pacemaker statistics - -To make the collector collect statistics for Pacemaker declare the -`lma_collector::collectd::pacemaker` class: - -```puppet -class { 'lma_collector::collectd::pacemaker': - resources => ['vip__public', 'vip__management'], -} -``` - -### Collect MySQL statistics - -To make the collector collect statistics for MySQL declare the -`lma_collector::collectd::mysql` class: - -```puppet -class { 'lma_collector::collectd::mysql': - username => 'mysql_username', - password => 'mysql_password', -} -``` - -### Collect OpenStack notifications - -To make the collector collect notifications emitted by the OpenStack services -declare the `lma_collector::notifications::input` class: - -```puppet -class { 'lma_collector::notifications::input': - topic => 'lma_notifications', - host => '127.0.0.1', - user => 'rabbit_user', - password => 'rabbit_password', -} -``` - -### Store metrics into InfluxDB - -To make the collector store the collected metrics into InfluxDB declare the -`lma_collector::influxdb` class: - -```puppet -class { 'lma_collector::influxdb': - database => 'lma', - user => 'lma', - password => 'secret', - server => 'example.com', -} -``` - -### Send AFD messages to Nagios - -To make the collector send AFD messages to Nagios declare the -`lma_collector::afd_nagios` define: - -```puppet -lma_collector::afd_nagios { 'node_afds': - url => 'http://nagios.example.com/cgi-bin/cmd.cgi', - user => 'nagiosadmin', - password => 'secret', -} -``` - -### Send GSE messages to Nagios - -To make the collector send GSE messages to Nagios declare the -`lma_collector::gse_nagios` define: - -```puppet -lma_collector::gse_nagios { 'global_clusters': - url => 'http://nagios.example.com/cgi-bin/cmd.cgi', - user => 'nagiosadmin', - password => 'secret', - message_type => 'gse_cluster_metric', - virtual_hostname => '00-global_clusters', - openstack_deployment_name => 'production', -} - -``` - -### Configure the aggregator mode - -To make the collector send AFD messages to the aggregator node declare the -`lma_collector::aggregator::client` class: - -```puppet -class { 'lma_collector::aggregator::client': - address => 'aggregator.example.com', -} -``` - -To make the collector act as an aggregator node for the other collectors -declare the `lma_collector::aggregator::server` class: - -```puppet -class { 'lma_collector::aggregator::server': -} -``` - -## Reference - -### Classes - -Public Classes: - -* [`lma_collector`](#class-lma_collector) -* [`lma_collector::elasticsearch`](#class-lma_collectorelasticsearch) -* [`lma_collector::logs::keystone_wsgi`](#class-lma_collectorlogskeystone_wsgi) -* [`lma_collector::logs::libvirt`](#class-lma_collectorlogslibvirt) -* [`lma_collector::logs::mysql`](#class-lma_collectorlogsmysql) -* [`lma_collector::logs::ovs`](#class-lma_collectorlogsovs) -* [`lma_collector::logs::pacemaker`](#class-lma_collectorlogspacemaker) -* [`lma_collector::logs::rabbitmq`](#class-lma_collectorlogsrabbitmq) -* [`lma_collector::logs::system`](#class-lma_collectorlogssystem) -* [`lma_collector::logs::swift`](#class-lma_collectorlogsswift) -* [`lma_collector::logs::aggregated_http_metrics`](#class-lma_collectorlogsaggregated_http_metrics) -* [`lma_collector::collectd::base`](#class-lma_collectorcollectdbase) -* [`lma_collector::collectd::haproxy`](#class-lma_collectorcollectdhaproxy) -* [`lma_collector::collectd::rabbitmq`](#class-lma_collectorcollectdrabbitmq) -* [`lma_collector::collectd::memcached`](#class-lma_collectorcollectdmemcached) -* [`lma_collector::collectd::openstack_checks`](#class-lma_collectorcollectdopenstack_checks) -* [`lma_collector::collectd::apache`](#class-lma_collectorcollectdapache) -* [`lma_collector::collectd::ceph_mon`](#define-lma_collectorcollectdceph_mon) -* [`lma_collector::collectd::ceph_osd`](#define-lma_collectorcollectdceph_osd) -* [`lma_collector::collectd::hypervisor`](#class-lma_collectorcollectdhypervisor) -* [`lma_collector::collectd::pacemaker`](#class-lma_collectorcollectdpacemaker) -* [`lma_collector::collectd::mysql`](#class-lma_collectorcollectdmysql) -* [`lma_collector::influxdb`](#class-lma_collectorinfluxdb) -* [`lma_collector::notifications::input`](#class-lma_collectornotificationsinput) -* [`lma_collector::notifications::metrics`](#class-lma_collectornotificationsmetrics) -* [`lma_collector::aggregator::client`](#class-lma_collectoraggregatorclient) -* [`lma_collector::aggregator::server`](#class-lma_collectoraggregatorserver) -* [`lma_collector::gse_policies`](#class-lma_collectorgse_policies) -* [`lma_collector::metrics::heka_monitoring`](#class-lma_collectormetricsheka_monitoring) - -Private Classes: - -* `lma_collector::params`: Provide defaults for the `lma_collector` module - parameters. - -### Defines - -* [`lma_collector::heka`](#define-lma_collectorheka) -* [`lma_collector::logs::openstack`](#define-lma_collectorlogsopenstack) -* [`lma_collector::collectd::openstack`](#define-lma_collectorcollectdopenstack) -* [`lma_collector::afd_filter`](#define-lma_collectorafd_filter) -* [`lma_collector::afd_nagios`](#define-lma_collectorafd_nagios) -* [`lma_collector::gse_cluster_filter`](#define-lma_collectorgse_cluster_filter) -* [`lma_collector::gse_nagios`](#define-lma_collectorgse_nagios) - -#### Class: `lma_collector` - -Install the common Lua modules used by LMA collectors. - -##### Parameters - -* `tags`: *Optional*. Fields added to Heka messages. Valid options: a hash. Default: `{}`. - -#### Class: `lma_collector::elasticsearch` - -Declare this class to make Heka serialize the log messages and send them to -Elasticsearch for indexing. - -##### Parameters - -* `server`: *Required*. Elasticsearch server name. Valid options: a string. -* `port`: *Required*. Elasticsearch service port. Valid options: an integer. -* `flush_interval`: *Optional*. Interval at which accumulated messages should - be bulk indexed into Elasticsearch, in seconds. Default: `5`. -* `flush_count`: *Optional*. Number of messages that, if processed, will - trigger them to be bulk indexed into Elasticsearch. Default: `10`. - -#### Class: `lma_collector::logs::keystone_wsgi` - -Declare this class to create an Heka `logstreamer` that reads Keystone Apache -logs from `/var/log/apache2/keystone_wsgi_*_access.log`. - -This class currently assumes the following log configuration in Apache: - -``` -CustomLog "/var/log/apache2/keystone_wsgi_main_access.log" "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" -``` - -for Keystone main and: - -``` -CustomLog "/var/log/apache2/keystone_wsgi_admin_access.log" "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" -``` - -for Keystone admin. - -The class correctly configures the Heka `logstreamer` for the case of -sequential rotating log files, i.e. log files with the following structure: - -``` -/var/log/apache2/keystone_wsgi_*_access.log -/var/log/apache2/keystone_wsgi_*_access.log.1 -/var/log/apache2/keystone_wsgi_*_access.log.2 -``` - -#### Class: `lma_collector::logs::libvirt` - -Declare this class to create an Heka `logstreamer` that reads libvirt logs -from `/var/log/libvirt/libvirtd.log`. - -#### Class: `lma_collector::logs::mysql` - -Declare this class to create an Heka `logstreamer` that reads MySQL logs from -`/var/log/mysql.log`. - -#### Class: `lma_collector::logs::ovs` - -Declare this class to create an Heka `logstreamer` that reads Open vSwitch logs -from log files located in the `/var/log/openvswitch/` directory. - -#### Class: `lma_collector::logs::pacemaker` - -Declare this class to create an Heka `logstreamer` that reads Pacemaker logs -from `/var/log/pacemaker.log`. - -#### Class: `lma_collector::logs::rabbitmq` - -Declare this class to create an Heka `logstreamer` that reads RabbitMQ logs -from log files located in the `/var/log/rabbitmq` directory. - -#### Class: `lma_collector::logs::system` - -Declare this class to create an Heka `logstreamer` that reads system logs. - -Logs are read from following files in `/var/log`: `daemon.log`, `cron.log`, -`haproxy.log`, `kern.log`, `auth.log`, `syslog`, `messages` and `debug`. This -class assumes that Rsyslog is used, with the `RSYSLOG_TraditionalFileFormat` -template. - -More specifically, the following syslog patterns are assumed: - -``` -<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%\n -``` - -or - -``` -'%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%\n' -``` - -#### Class: `lma_collector::logs::swift` - -Declare this class to create an Heka `logstreamer` that reads Swift logs from -a Syslog file. - -##### Parameters - -* `file_match`: *Required*. The log file name pattern. Example: - `'swift\.log$'`. Example for a sequential rotating file: - `'swift\.log\.?(?P\d*)$'`. See - http://hekad.readthedocs.org/en/latest/pluginconfig/logstreamer.html - for more information. -* `priority`: *Optional*. When using sequential logstreams, the priority - defines how to sort the log files in order from the slowest to newest. - Example: `'["^Seq"]'`. See - http://hekad.readthedocs.org/en/latest/pluginconfig/logstreamer.html - for more information. -* `log_directory`: *Optional*. The log directory. Default: `/var/log`. - -#### Class: `lma_collector::logs::aggregated_http_metrics` - -Declare this class to create an Heka filter that derives HTTP metrics from -OpenStack log messages that include HTTP information (method, status and -response time). Response times are aggregated over an interval and the -following statistics are produced: `min`,`max`,`sum`,`count`,`percentile`. - -The metric name is `openstack__http_response_times` where `` -is the OpenStack service name (e.g. "neutron"). - -##### Parameters - -* `hostname`: *Optional*. The hostname. Default: $::hostname factor. -* `interval`: *Optional*. Interval in second used to aggregate metrics. Default: 10. -* `max_timer_inject`: *Optional*. The maximum number of messages allowed to be injected by the sandbox. Default: 10. -* `bulk_size`: *Optional*. The number of metrics embedded by a bulk_metric. Default: 500. -* `percentile`: *Optional*. The percentile. Default: 90. - -#### Class: `lma_collector::collectd::base` - -Declare this class to set up collectd and the communication channel between -collectd and Heka. The declaration of this class also sets up a number of -standard collectd plugins, namely `logfile`, `cpu`, `disk`, `interface`, -`load`, `memory`, `processes`, `swap`, and `users`. - -##### Parameters - -* `processes`: *Optional*. The names of processes that the collectd - `processes` plugin will get statistics for. Valid options: an array of - strings. Default: `undef`. See - https://github.com/voxpupuli/puppet-collectd#class-collectdpluginprocesses - for more information. -* `process_matches`: *Optional*. Name/regex pairs specifying the processes that - the collectd `processes` plugin will get statistics for. Valid options: an - array of hashs with two properties, `name` and `regex`. See - https://github.com/voxpupuli/puppet-collectd#class-collectdpluginprocesses - for more information. -* `read_threads`: *Optional*. The number of threads used by collectd. Valid - options: an integer. Default: 5. -* `purge`: *Optional*. Purge the collectd configuration files. Default: - `false`. - -#### Class: `lma_collector::collectd::haproxy` - -Declare this class to configure collectd to collect HAProxy statistics. The -collectd plugin used is a Python script. - -##### Parameters - -* `socket`: *Required*. The path to HAProxy's `stats` Unix socket. E.g. - `/var/lib/haproxy/stats`. Valid options: a string. -* `proxy_ignore`: *Optional*. The list of proxy names to ignore, i.e. for which - no metrics will be created. Valid options: an array of strings. Default: - `[]`. -* `proxy_names`: *Optional*. A mapping of proxy names to meaningful names used - in metrics names. This is useful when there are meaningless proxy names such - as "keystone-1" in the HAProxy configuration. Valid options: a hash. Default: - `{}`. - -#### Class: `lma_collector::collectd::rabbitmq` - -Declare this class to configure collectd to collect RabbitMQ statistics. The -collectd plugin used is a Python script, which uses the `rabbitmqctl` command -to get statistics from RabbitMQ. - -##### Parameters - -* `queue`: *Optional*. Collect statistics for specific queue(s), a string that - starts and ends with a slash is interpreted as a regular expression - (backslash `\` must be escaped by writing `\\`). - Valid option: an array of string. Default: `[]`. - -#### Class: `lma_collector::collectd::memcached` - -Declare this class to configure collectd to collect Memcached statistics. -collectd's native `memcached` plugin is used to collect statistics and a -custom Python plugin is used to check the availability of Memcached server. - -##### Parameters - -* `host`: *Required*. The Memcached host. Valid options: a string. See - https://github.com/voxpupuli/puppet-collectd#class-collectdpluginmemcached. -* `Port`: *Optional. The Memcached port. Valid option: an integer. - Default: `11211`. - -#### Class: `lma_collector::collectd::openstack_checks` - -Declare this class to configure collectd to collect statuses of OpenStack -services. The collectd plugin used is a Python script. - -##### Parameters - -* `user`: *Required*. The user to use when querying the OpenStack endpoint. - Valid options: a string. -* `password`: *Required*. The password to use when querying the OpenStack - endpoint. Valid options: a string. -* `tenant`: *Required*. The tenant to use when querying the OpenStack endpoint. - Valid options: a string. -* `keystone_url`: *Required*. The Keystone endpoint URL to use. Valid options: - a string. -* `timeout`: *Optional*. Timeout in seconds beyond which the collector - considers that the endpoint doesn't respond. Valid options: an integer. - Default: 5. -* `pacemaker_master_resource`: *Optional*. Name of the pacemaker resource used - to determine if the collecting of statistics should be active. This is - a parameter for advanced users. For this to function the - [`lma_collector::collectd::pacemaker`](#class-lma_collectorcollectdpacemaker) - class should be declared, with its `master_resource` parameter set to the - same value as this parameter. Valid options: a string. Default: `undef`. - -#### Class: `lma_collector::collectd::apache` - -Declare this class to configure collectd to collect Apache statistics. -collectd's native `apache` plugin is used. The URL used is -`http://${host}/server-status?auto`, where `${host}` is replaced by the value -provided with the `host` parameter. - -##### Parameters - -* `host`: *Optional*. The Apache host. Valid options: a string. Default: - `'127.0.0.1'`. -* `port`: *Optional*. The Apache port. Valid options: a string. Default: `'80'`. - -#### Class: `lma_collector::collectd::hypervisor` - -Declare this class to configure collectd to collect statistics on Nova -hypervisors. The collectd plugin used is a Python script talking to the -Nova API. - -##### Parameters - -* `user`: *Required*. The user to use when querying the OpenStack endpoint. - Valid options: a string. -* `password`: *Required*. The password to use when querying the OpenStack - endpoint. Valid options: a string. -* `tenant`: *Required*. The tenant to use when querying the OpenStack endpoint. - Valid options: a string. -* `keystone_url`: *Required*. The Keystone endpoint URL to use. Valid options: - a string. -* `timeout`: *Optional*. Timeout in seconds beyond which the collector - considers that the endpoint doesn't respond. Valid options: an integer. - Default: 5. -* `pacemaker_master_resource`: *Optional*. Name of the pacemaker resource used - to determine if the collecting of statistics should be active. This is - a parameter for advanced users. For this to function the - [`lma_collector::collectd::pacemaker`](#class-lma_collectorcollectdpacemaker) - class should be declared, with its `master_resource` parameter set to the - same value as this parameter. Valid options: a string. Default: `undef`. - -#### Class: `lma_collector::collectd::pacemaker` - -Declare this class to configure collectd to collect statistics for Pacemaker -resources running on the node. The collectd plugin used is a Python script, -which uses Pacemaker's `crm_resource` command to get statistics from Pacemaker. - -##### Parameters - -* `resources`: *Required*. The Pacemaker resources to get statistics for. Valid - options: an hash of strings. -* `notify_resource`: *Optional*. If this is set, the collectd plugin generates - a collectd notification reporting the state of the Pacemaker resource - identified to by `master_resource`. Users of - [`lma_collector::collectd::openstack`](#define-lma_collectorcollectdopenstack), - [`lma_collector::collectd::openstack_checks`](#class-lma_collectorcollectdopenstackchecks) and - [`lma_collector::collectd::hypervisor`](#class-lma_collectorcollectdhypervisor) - with the `notify_resource` parameter needs to declare the - `lma_collector::collectd::pacemaker` class and use that parameter. - Valid options: a string. Default: `undef`. -* `hostname`: *Optional*. If this is set it will be used to identify the local - host in the Pacemaker cluster. If unset, collectd will use the value returned - by the Python socket.getfqdn() function. - Valid options: a string. Default: `undef`. - -#### Class: `lma_collector::collectd::mysql` - -Declare this class to configure collectd to collect statistics for the MySQL -instance local to the node. - -The collectd plugin used is the native collectd [MySQL -plugin](https://collectd.org/wiki/index.php/Plugin:MySQL). It is configured -with `'localhost'` as the `Host`, meaning that the local MySQL Unix socket will -be used to connect to MySQL. - -##### Parameters - -* `username`: *Required*. The database user to use to connect to the MySQL - database. Valid options: a string. -* `password`: *Required*. The database password to use to connect to the MySQL - database. Valid options: a string. -* `host`: *Optional*. The IP address to use to connect to the MySQL database. - Valid options: a string. Default: `localhost`. -* `socket`: *Optional*. The Unix socket to use to connect to the MySQL database. - Valid options: a string. Default: `undef`. - -#### Class: `lma_collector::collectd::ceph_mon` - -Declare this class to make collectd collect Ceph statistics. - -With this the collector will collect information on the Ceph cluster (health, -monitor count, quorum count, free space, ...) and the Placement Groups. - -The collectd plugin used is a Python script. That script uses the `ceph` -command internally. So for this plugin to work the `ceph` command should be -installed, and a valid configuration for accessing the Ceph cluster should be -in place. - -#### Class: `lma_collector::collectd::ceph_osd` - -Declare this class to make collectd collect Ceph OSD (Object Storage Daemon) -performance statistics of all the OSD daemons running on the host. - -The collectd plugin used is a Python script. That script uses the `ceph` -command internally, so that command should be installed. - -#### Class: `lma_collector::influxdb` - -Declare this class to make Heka serialize the metric messages and send them to -InfluxDB. - -##### Parameters - -* `database`: *Required*. InfluxDB database. Valid options: a string. -* `user`: *Required*. InfluxDB username. Valid options: a string. -* `password`: *Required*. InfluxDB password. Valid options: a string. -* `server`: *Required*. InfluxDB server name. Valid options: a string. -* `port`: *Required*. InfluxDB service port. Valid options: an integer. -* `tag_fields`: *Optional*. List of message fields to be stored as tags. Valid - options: an array. Default: `[]`. -* `time_precision`: *Optional*. Time precision. Valid options: a string. - Default: `ms`. -* `flush_count`: *Optional*. Maximum number of datapoints to send in a single - write request. Valid values: an integer. Default: `5000`. -* `flush_interval`: *Optional*. Maximum number of seconds to wait before - writing data to InfluxDB. Valid values: an integer. Default: `5`. - -#### Class: `lma_collector::notifications::input` - -Declare this class to make Heka collect the notifications emitted by the -OpenStack services on RabbitMQ. - -The OpenStack services should be configured to send their notifications to the -same topic exchange as the one this class is configured with. - -##### Parameters - -* `topic`: *Required*. The topic exchange from where to read the notifications. - Valid options: a string. -* `host`: *Required*. The address of the RabbitMQ host. Valid options: a - string. -* `port`: *Optional*. The port the RabbitMQ host listens on. Valid options: - an integer. Default: `5672`. -* `user`: *Required*. The user to use to connect to RabbitMQ. Valid options: a - string. -* `password`: *Required*. The password to use to connect to RabbitMQ. Valid - options: a string. - -#### Class: `lma_collector::notifications::metrics` - -Declare this class to make Heka emit metrics from the OpenStack notifications. - -#### Class: `lma_collector::aggregator::client` - -Declare this class to make Heka send the AFD messages to another Heka node -running the aggregator service. - -##### Parameters - -* `address`: *Required*. The address of the aggregator server. Valid options: a - string. -* `port`: *Optional*. The port the aggregator server listens on. Valid options: - an integer. Default: `5565`. - -#### Class: `lma_collector::aggregator::server` - -Declare this class to make Heka run the aggregator service. - -##### Parameters - -* `listen_address`: *Optional*. The address the aggregator service listens on. - Valid options: a string. Default: `127.0.0.1`. -* `port`: *Optional*. The port the aggregator service listens on. Valid options: - an integer. Default: `5565`. -* `http_check_port`: *Optional*. The HTTP port that an external service can use - to check the health of the aggregator service. Valid options: an integer. - Default: `undef`. - -#### Class: `lma_collector::gse_policies` - -Declare this class to configure the GSE cluster policies on the aggregator node. - -##### Parameters - -* `policies`: *Required*. Definition of the GSE cluster policies as described - in the [Cluster Policies](http://fuel-plugin-lma-collector.readthedocs.org/en/latest/alarms.html#cluster-policies) - documentation. Valid options: a hash. - -#### Class: `lma_collector::metrics::heka_monitoring` - -Declare this class to collect metrics for the Heka services themselves. - -##### Parameters - -* `dashboard_address`: *Optional*. The address Heka dashboards listen on. - Valid options: a string. Default: `127.0.0.1`. -* `metric_dashboard_port`: *Optional*. The port the Heka dashboard of - metric collector listens on. - Valid options: a string. Default: `4353`. -* `log_dashboard_port`: *Optional*. The port the Heka dashboard of - log collector listens on. - Valid options: a string. Default: `4352`. - -#### Define: `lma_collector::heka` - -Main Define. Install and configure the Log and Metric collector. -The title must be either `log_collector` or `metric_collector`. - -##### Parameters - -* `user`: *Optional*. User the Heka service is run as. You may have to use `'root'` on some systems for the Heka service to be able to access log files, run additional commands, ... Valid options: a string. Default: `'heka'`. -* `groups`: *Optional*. Additional groups to add to the user running the Heka service. Ignored if the Heka service is run as "root". Valid options: an array of strings. Default: `['syslog', 'adm']`. -* `poolsize`: *Optional*. The pool size of maximum messages that can exist (default: 100). -* `heka_monitoring`: *Optional*. Enable the hekad plugins monitoring by configuring - the Heka dashboard and a filter plugin. Valid options: boolean. Default: true. -* `install_init_script`: *Optional*. Whether or not install the init script (Upstart or Systemd). - This is typically used when the service is managed by Pacemaker for example. - Valid options: boolean. Default: true. -* `version`: *Optional*. The Heka version to install. Default: 'latest'. - -#### Define: `lma_collector::logs::openstack` - -Declare this type to create an Heka `logstreamer` that reads logs of an -OpenStack service. - -It works for "standard" OpenStack services that write their logs into log files -located in `/var/log/{service}`, where `{service}` is the service name. - -For example it works for Nova, Neutron, Cinder, Glance, Heat, Keysone, Horizon -and Murano. - -The define doesn't work for Swift, as Swift only writes its logs to Syslog. -See the specific [`lma_collector::logs::swift`](#class-lma_collectorlogsswift) -class for Swift. - -##### Parameters - -* `service_match`: *Optional*. The regular expression portion which matches the - log file names excluding the suffix `.log`. This is generally used to - explicitly specify the file name(s) within the directory. - Valid options: a regexp string supported by the [Go programming - language](https://golang.org/pkg/regexp/). Default: `.+`. - -#### Define: `lma_collector::collectd::openstack` - -Declare this define to make collectd collect statistics from an OpenStack -service endpoint. - -This define supports the following services: nova, cinder, glance, keystone and -neutron. - -The resource title should be set to the service name (e.g. `'nova'`). - -##### Parameters - -* `user`: *Required*. The user to use when querying the OpenStack endpoint. - Valid options: a string. -* `password`: *Required*. The password to use when querying the OpenStack - endpoint. Valid options: a string. -* `tenant`: *Required*. The tenant to use when querying the OpenStack endpoint. - Valid options: a string. -* `keystone_url`: *Required*. The Keystone endpoint URL to use. Valid options: - a string. -* `timeout`: *Optional*. Timeout in seconds beyond which the collector - considers that the endpoint doesn't respond. Valid options: an integer. - Default: 20. -* `max_retries`: *Optional*. Number of maximum retries when an error occurs - (including timeout). Valid options: an integer. - Default: 2. -* `pacemaker_master_resource`: *Optional*. Name of the pacemaker resource used - to determine if the collecting of statistics should be active. This is - a parameter for advanced users. For this to function the - [`lma_collector::collectd::pacemaker`](#class-lma_collectorcollectdpacemaker) - class should be declared, with its `master_resource` parameter set to the - same value as this parameter. Valid options: a string. Default: `undef`. -* `polling_interval`: *Optional*. The interval used to poll the resources. -* `pagination_limit`: *Optional*. The number of resource returned by request. - -#### Define `lma_collector::collectd::dbi_services` - -Declare this define to make collectd collect the statuses (`up`, `down` or -`disabled`) of the various workers of an OpenStack service. - -The collectd plugin used is DBI, which is a native collectd plugin. That plugin -uses SQL queries to the MySQL database. - -This define supports the following services: nova, cinder, and neutron. - -The resource title should be set to the service name (e.g. `'nova'`). - -##### Parameters - -* `dbname`: *Required*. The database name. Valid options: a string. -* `username`: *Required*. The database user. Valid options: a string. -* `password`: *Required*. The database password. Valid options: a string. -* `hostname`: *Optional*. The database hostname. Valid options: a string. - Default: `'localhost'`. -* `report_interval`: *Required*. The report interval in seconds used in the - service configuration. For example Nova's current default value is 10. - Valid options: an integer. -* `downtime_factor`: *Required*. The downtime factor used to determine when - consider a worker is down. A service is deemed "down" if no heartbeat has - been received since `downtime_factor * report_interval` seconds. Valid - options: an integer. - -#### Define `lma_collector::afd_filter` - -Declare this define to configure an [Anomaly and Fault Detection -filter](http://fuel-plugin-lma-collector.readthedocs.org/en/latest/alarms.html) -in Heka. - -##### Parameters - -* `type`: *Required*. Type of the AFD filter. Valid options: either `service` - for service AFD filters or `node` for node AFD filters. -* `cluster_name`: *Required*. Value of the `service` field (for service AFD - filters) or `node_role` (for node AFD filters) for the messages emitted by - the filter. Valid options: a string. -* `logical_name`: *Required*. Value of the `source` field for the messages - emitted by the filter. Valid options: a string. -* `alarms`: *Required*. List of alarm rules enabled for this filter. Valid - options: an array. -* `alarms_definitions`: *Required*. List of the alarm rules definitions. Valid - options: an array. -* `message_matcher`: *Required*. Message matcher for the Heka filter. Valid - options: a string. - -#### Define `lma_collector::afd_nagios` - -Declare this define to send [Anomaly and Fault Detection messages]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/alarms.html) -to Nagios as [passive check -results](https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/3/en/passivechecks.html). - -##### Parameters - -* `url`: *Required*. URL to the Nagios cgi.bin script. Valid options: a - string. -* `user`: *Optional*. Username used to authenticate to the Nagios web - interface. Valid options: a string. Default: `nagiosadmin`. -* `password`: *Optional*. Password used to authenticate to the Nagios web - interface. Valid options: a string. Default: empty string. -* `hostname`: *Optional*. It must match the hostname configured in Nagios. - Valid options: a string. Default: `$::hostname`. -* `service_template`: *Optional*. It must match the service description - configured in Nagios. Supports interpolation of message field values. Valid - options: a string. Default: `%{node_role}.%{source}`. -* `message_type`: *Optional*. Type of AFD messages to send to Nagios. Valid - options: a string. Default: `afd_node_metric`. - -#### Define `lma_collector::gse_cluster_filter` - -Declare this define to configure an [Global Status Evaluation filter]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/alarms.html) -in Heka. - -##### Parameters - -* `input_message_types`: *Required*. Message types that the GSE filter should - process. Valid options: an array. -* `aggregator_flag`: *Required*. Whether or not the GSE filter receives messages - emitted by the collectors or the aggregator itself. Valid options: a boolean. -* `member_field`: *Required*. Field in the input messages used by the GSE filter - to identify the cluster members. Valid options: a string. -* `output_message_type`: *Required*. Type of messages emitted by the GSE - filter. Valid options: a string. -* `output_metric_name`: *Required*. Metric name for the messages emitted by the - GSE filter. Valid options: a string. -* `interval`: *Optional*. Interval (in seconds) at which the GSE filter emits - its metric messages. Valid options: an integer. Default: 10. -* `cluster_field`: *Optional*. Field in the input message used by the GSE - filter to associate the AFD/GSE metrics to the clusters. Valid options: a - string. Default: undef. -* `clusters`: *Optional*. List of clusters that the plugin manages. See the [GSE - configuration](http://fuel-plugin-lma-collector.readthedocs.org/en/latest/alarms.html) - documentation for details. Valid options: a hash. Default: {}. -* `warm_up_period`: *Optional*. Number of seconds after a (re)start that the - GSE plugin will wait before emitting its metric messages. Valid options: an - integer. Default: undef. -* `alerting`: *Optional*. Whether or not the alerting is disabled or enabled - with or without notifications. - Valid options: one of the string 'disabled', 'enabled' or 'enabled_with_notification'. - Default: 'enabled_with_notification'. - -#### Define `lma_collector::gse_nagios` - -Declare this define to send [Global Status Evaluation messages]( -http://fuel-plugin-lma-collector.readthedocs.org/en/latest/alarms.html) -to Nagios as [passive check -results](https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/3/en/passivechecks.html). - -##### Parameters - -* `url`: *Required*. URL to the Nagios cgi.bin script. Valid options: a - string. -* `user`: *Optional*. Username used to authenticate to the Nagios web - interface. Valid options: a string. Default: `nagiosadmin`. -* `password`: *Optional*. Password used to authenticate to the Nagios web - interface. Valid options: a string. Default: empty string. -* `service_template`: *Optional*. It must match the service description - configured in Nagios. Supports interpolation of message field values. Valid - options: a string. Default: `%{cluster_name}`. -* `message_type`: *Required*. Type of GSE messages to send to Nagios. Valid - options: a string. -* `virtual_hostname`: *Required*. The host configured in Nagios to receive the - GSE checks must be named "${virtual_hostname}-env${openstack_deployment_name}". - Valid options: a string. -* `openstack_deployment_name`: *Optional*. Additional label to identify the - environment. Valid options: a string. Default: empty string. - -Limitations ------------ - - -License -------- - -Licensed under the terms of the Apache License, version 2.0. - -Contact -------- - -Simon Pasquier, - -Support -------- - -See the Contact section. diff --git a/deployment_scripts/puppet/modules/lma_collector/Rakefile b/deployment_scripts/puppet/modules/lma_collector/Rakefile deleted file mode 100644 index ad531700f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/Rakefile +++ /dev/null @@ -1,130 +0,0 @@ -require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-lint/tasks/puppet-lint' -require 'puppet-syntax/tasks/puppet-syntax' -require 'metadata-json-lint/rake_task' - -PuppetLint.configuration.fail_on_warnings = true -PuppetLint.configuration.send('disable_80chars') -PuppetLint.configuration.send('disable_class_inherits_from_params_class') -PuppetLint.configuration.send('disable_class_parameter_defaults') -PuppetLint.configuration.send('disable_variable_contains_dash') - -exclude_paths = [ - "pkg/**/*", - "vendor/**/*", - "spec/**/*", -] - -Rake::Task[:lint].clear -PuppetLint::RakeTask.new :lint do |config| - config.ignore_paths = exclude_paths -end -PuppetSyntax.exclude_paths = exclude_paths - -desc "Run metadata_lint, lint, syntax, and spec tests." -task :test => [ - :metadata_lint, - :lint, - :syntax, - :spec -] - -# Check for the presence of Lua 5.1 -lua_version = %x( lua5.1 -v 2>&1 ) -lua_present = $?.to_i == 0 ? (lua_version =~ /^Lua 5\.1/) : false -if lua_present then - task :test => :lua_tests -end - -LUA_TESTS = Rake::FileList.new("tests/**/test_*.lua") -desc "Run Lua unit tests." -task :lua_tests => [:lua_libraries, :lib_cbuf] do |t| - verbose(false) do - sh "lua5.1", "-e", "require('lpeg')" do |ok, res| - if ! ok then - raise "Please install the Lua LPEG package by running: apt-get install lua-lpeg" - end - end - end - LUA_TESTS.each do |f| - sh "lua5.1", f - end - Rake::Task[:remove_cbuf_library].invoke -end - -# Need to pull date_time.lua from the lua_sandbox repository because some tests -# depend on it indirectly -task :lua_libraries => ['tests/lua/mocks/date_time.lua', 'tests/lua/mocks/inspect.lua', - 'tests/lua/mocks/anomaly.lua', 'tests/lua/mocks/annotation.lua'] - -file 'tests/lua/mocks/annotation.lua' do |t| - verbose(false) do - sh "curl", "-s", "-o", t.name, "https://raw.githubusercontent.com/mozilla-services/heka/versions/0.10/sandbox/lua/modules/annotation.lua" do |ok, res| - if ! ok then - raise "Fail to download annotation.lua from lua_sandbox repository!" - end - end - end -end - -file 'tests/lua/mocks/anomaly.lua' do |t| - verbose(false) do - sh "curl", "-s", "-o", t.name, "https://raw.githubusercontent.com/mozilla-services/heka/versions/0.10/sandbox/lua/modules/anomaly.lua" do |ok, res| - if ! ok then - raise "Fail to download anomaly.lua from lua_sandbox repository!" - end - end - end -end - -file 'tests/lua/mocks/date_time.lua' do |t| - verbose(false) do - sh "curl", "-s", "-o", t.name, "https://raw.githubusercontent.com/mozilla-services/lua_sandbox/97331863d3e05d25131b786e3e9199e805b9b4ba/modules/date_time.lua" do |ok, res| - if ! ok then - raise "Fail to download date_time.lua from lua_sandbox repository!" - end - end - end -end - -file 'tests/lua/mocks/inspect.lua' do |t| - verbose(false) do - sh "curl", "-s", "-o", t.name, "https://raw.githubusercontent.com/kikito/inspect.lua/master/inspect.lua" do |ok, res| - if ! ok then - raise "Fail to download inspect.lua from gitub repository!" - end - end - end -end - -task :lib_cbuf => ['./circular_buffer.so'] - -cbuf_commit = 'bb6dd9f88f148813315b5a660b7e2ba47f958b31' -cbuf_tarball_url = "https://github.com/mozilla-services/lua_circular_buffer/archive/#{ cbuf_commit }.tar.gz" - -file './circular_buffer.so' do |t| - tmp_directory = File.join('/tmp', "lua_circular_buffer-#{ cbuf_commit }") - cbuf_shared_library = File.join(tmp_directory, 'release', 'circular_buffer.so') - unless File.exists?(cbuf_shared_library) then - # Download the archive from Github and build the library - sh "rm -rf #{ tmp_directory } && wget -qO - #{ cbuf_tarball_url } | tar -zxvf - -C /tmp" do |ok, res| - unless ok then - raise "Failed to download the lua_circular_buffer archive!" - end - end - - sh "cd #{ tmp_directory } && mkdir release && cd release && cmake -DCMAKE_BUILD_TYPE=release .. && make" do |ok, res| - unless ok then - raise "Failed to compile circular_buffer.so!" - end - end - end - - FileUtils.cp(cbuf_shared_library, '.') -end - -task :remove_cbuf_library do |t| - verbose(false) do - sh 'rm -f ./circular_buffer.so' - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/build_ceph_perf_types.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/build_ceph_perf_types.py deleted file mode 100755 index b7c0eb0f2..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/build_ceph_perf_types.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -import json -import os -import subprocess -import sys - - -class CephPerfCollectionSchema(object): - - def __init__(self, collection, schema): - self.collection = collection - self.schema = schema - - def __str__(self): - def sanitize(s): - return s.replace('::', '_').replace('-', '_').lower() - - return '\n'.join(['%s_%s value:GAUGE:U:U' % (sanitize(self.collection), - sanitize(k)) - for k in sorted(self.schema.iterkeys())]) - - -class CephPerfSchema(object): - - def __init__(self, socket_path): - self.socket_path = socket_path - - @staticmethod - def run_command(cmd): - try: - proc = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - (stdout, stderr) = proc.communicate() - stdout = stdout.rstrip('\n') - except Exception as e: - print("Cannot execute command '%s': %s" % (cmd, str(e))) - raise e - - return json.loads(stdout) - - def ceph_version(self): - cmd = ['/usr/bin/ceph', '--admin-daemon', self.socket_path, 'version'] - return self.run_command(cmd).get('version') - - def itertypes(self): - cmd = ['/usr/bin/ceph', '--admin-daemon', self.socket_path, 'perf', - 'schema'] - - for collection, schema in self.run_command(cmd).iteritems(): - yield CephPerfCollectionSchema(collection, schema) - - -def main(): - script_name = os.path.basename(sys.argv[0]) - if len(sys.argv) < 2 or len(sys.argv) > 3: - print("usage: %s [namespace]" % script_name) - else: - schema = CephPerfSchema(sys.argv[1]) - collection = sys.argv[2] if len(sys.argv) == 3 else None - print("# File generated automatically by the %s script" % script_name) - print("# Ceph version: %s" % schema.ceph_version()) - for item in schema.itertypes(): - if collection is None or item.collection == collection: - print(item) - -if __name__ == '__main__': - main() diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_osd_perf.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_osd_perf.py deleted file mode 100644 index 391961193..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_osd_perf.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. - -import collectd -import glob -import re - -import collectd_base as base - -INTERVAL = 60 -RE_OSD_ID = re.compile(".*?osd\.(\d+)\.asok$") - - -class CephOSDPerfPlugin(base.CephBase): - """Collect OSD performance counters of OSD daemons running on the host.""" - - # Collect only metrics from the 'osd' namespace - PREFIXES = ('osd') - - def __init__(self, *args, **kwargs): - super(CephOSDPerfPlugin, self).__init__(*args, **kwargs) - self.plugin = 'ceph_osd_perf' - self.socket_glob = None - - def config_callback(self, conf): - super(CephOSDPerfPlugin, self).config_callback(conf) - for node in conf.children: - if node.key == "AdminSocket": - self.socket_glob = node.values[0] - - if not self.socket_glob: - raise Exception("AdminSocket not defined") - - @staticmethod - def convert_to_collectd_value(value): - # See for details - # https://www.mail-archive.com/ceph-users@lists.ceph.com/msg18705.html - if isinstance(value, dict): - if value['avgcount'] > 0: - return value['sum'] / value['avgcount'] - else: - return 0.0 - else: - return value - - @staticmethod - def convert_to_collectd_type(*args): - return '_'.join([s.replace('::', '_').replace('-', '_').lower() for s - in args]) - - def itermetrics(self): - check_errors = [] - checked = 0 - for socket_name in glob.glob(self.socket_glob): - m = RE_OSD_ID.match(socket_name) - if not m: - continue - - osd_id = m.group(1) - perf_dump = self.execute_to_json('ceph --admin-daemon %s perf dump' - % socket_name) - if not perf_dump: - check_errors.append(osd_id) - continue - - checked += 1 - for prefix, stats in perf_dump.iteritems(): - if prefix not in self.PREFIXES or not stats: - continue - - for k in sorted(stats.iterkeys()): - yield { - 'type': self.convert_to_collectd_type(prefix, k), - 'type_instance': osd_id, - 'values': self.convert_to_collectd_value(stats[k]) - } - - if check_errors: - raise base.CheckException( - "Fail to run 'ceph perf dump' for OSD(s): {}".format( - ', '.join(check_errors))) - - if checked == 0: - raise base.CheckException( - 'Could not find any OSD socket in {}'.format(self.socket_glob) - ) - - -plugin = CephOSDPerfPlugin(collectd, 'ceph_osd') - - -def init_callback(): - plugin.restore_sigchld() - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_init(init_callback) -collectd.register_config(config_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_osd_stats.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_osd_stats.py deleted file mode 100644 index cf5711c09..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_osd_stats.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. - -import collectd - -import collectd_base as base - -INTERVAL = 60 - - -class CephOSDStatsPlugin(base.CephBase): - """ Collect per OSD stats about store size and commit latency.""" - - def __init__(self, *args, **kwargs): - super(CephOSDStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = 'ceph_osd' - - def itermetrics(self): - osd_stats = self.execute_to_json('ceph pg dump osds --format json') - if not osd_stats: - raise base.CheckException("Fail to execute 'pg dump osds'") - - for osd in osd_stats: - osd_id = osd['osd'] - - yield { - 'type_instance': osd_id, - 'type': 'osd_space', - 'values': [osd['kb_used'] * 1000, osd['kb'] * 1000], - } - - yield { - 'type_instance': osd_id, - 'type': 'osd_latency', - 'values': [osd['fs_perf_stat']['apply_latency_ms'], - osd['fs_perf_stat']['commit_latency_ms']], - } - -plugin = CephOSDStatsPlugin(collectd, 'ceph_mon') - - -def init_callback(): - plugin.restore_sigchld() - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_init(init_callback) -collectd.register_config(config_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_pg_mon_status.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_pg_mon_status.py deleted file mode 100644 index c2bf47e78..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_pg_mon_status.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. - -import collectd - -import collectd_base as base - -INTERVAL = 30 -HEALTH_MAP = { - 'HEALTH_OK': 1, - 'HEALTH_WARN': 2, - 'HEALTH_ERR': 3, -} - - -class CephMonPlugin(base.CephBase): - """ Collect states and metrics about ceph cluster and placement groups.""" - - def __init__(self, *args, **kwargs): - super(CephMonPlugin, self).__init__(*args, **kwargs) - self.plugin = 'ceph_mon' - - def itermetrics(self): - status = self.execute_to_json('ceph -s --format json') - if not status: - raise base.CheckException("Fail to execute 'ceph -s'") - - yield { - 'type': 'health', - 'values': HEALTH_MAP[status['health']['overall_status']], - } - - if 'mons' in status['monmap']: - monitor_nb = len(status['monmap']['mons']) - else: - monitor_nb = 0 - yield { - 'type': 'monitor_count', - 'values': monitor_nb - } - - yield { - 'type': 'quorum_count', - 'values': len(status.get('quorum', [])) - } - - pgmap = status['pgmap'] - yield { - 'type': 'pg_bytes', - 'values': [pgmap['bytes_used'], pgmap['bytes_avail'], - pgmap['bytes_total']], - } - yield { - 'type': 'pg_data_bytes', - 'values': pgmap['data_bytes'] - } - yield { - 'type': 'pg_count', - 'values': pgmap['num_pgs'] - } - - for state in pgmap['pgs_by_state']: - yield { - 'type': 'pg_state_count', - 'type_instance': state['state_name'], - 'values': state['count'] - } - -plugin = CephMonPlugin(collectd, 'ceph_mon') - - -def init_callback(): - plugin.restore_sigchld() - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_init(init_callback) -collectd.register_config(config_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_pool_osd.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_pool_osd.py deleted file mode 100644 index e5a504441..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/ceph_pool_osd.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. - -import collectd - -import collectd_base as base - -INTERVAL = 60 - - -class CephPoolPlugin(base.CephBase): - """ Collect Ceph pool metrics and OSD daemons state""" - - def __init__(self, *args, **kwargs): - super(CephPoolPlugin, self).__init__(*args, **kwargs) - self.plugin = 'ceph_pool' - - def itermetrics(self): - df = self.execute_to_json('ceph df --format json') - if not df: - raise base.CheckException("Fail to run 'ceph df'") - - objects_count = 0 - for pool in df['pools']: - objects_count += pool['stats'].get('objects', 0) - for m in ('bytes_used', 'max_avail', 'objects'): - yield { - 'type': 'pool_%s' % m, - 'type_instance': pool['name'], - 'values': pool['stats'].get(m, 0), - } - - yield { - 'type': 'objects_count', - 'values': objects_count - } - yield { - 'type': 'pool_count', - 'values': len(df['pools']) - } - - if 'total_bytes' in df['stats']: - # compatibility with 0.84+ - total = df['stats']['total_bytes'] - used = df['stats']['total_used_bytes'] - avail = df['stats']['total_avail_bytes'] - else: - # compatibility with <0.84 - total = df['stats']['total_space'] * 1024 - used = df['stats']['total_used'] * 1024 - avail = df['stats']['total_avail'] * 1024 - - yield { - 'type': 'pool_total_bytes', - 'values': [used, avail, total] - } - yield { - 'type': 'pool_total_percent', - 'values': [100.0 * used / total, 100.0 * avail / total] - } - - stats = self.execute_to_json('ceph osd pool stats --format json') - if not stats: - raise base.CheckException("Fail to run 'ceph osd pool stats'") - - for pool in stats: - client_io_rate = pool.get('client_io_rate', {}) - yield { - 'type': 'pool_bytes_rate', - 'type_instance': pool['pool_name'], - 'values': [client_io_rate.get('read_bytes_sec', 0), - client_io_rate.get('write_bytes_sec', 0)] - } - yield { - 'type': 'pool_ops_rate', - 'type_instance': pool['pool_name'], - 'values': client_io_rate.get('op_per_sec', 0) - } - - osd = self.execute_to_json('ceph osd dump --format json') - if not osd: - raise base.CheckException("Fail to run 'ceph osd dump'") - - for pool in osd['pools']: - for name in ('size', 'pg_num', 'pg_placement_num'): - yield { - 'type': 'pool_%s' % name, - 'type_instance': pool['pool_name'], - 'values': pool[name] - } - - _up, _down, _in, _out = (0, 0, 0, 0) - for osd in osd['osds']: - if osd['up'] == 1: - _up += 1 - else: - _down += 1 - if osd['in'] == 1: - _in += 1 - else: - _out += 1 - - yield { - 'type': 'osd_count', - 'values': [_up, _down, _in, _out] - } - -plugin = CephPoolPlugin(collectd, 'ceph_mon') - - -def init_callback(): - plugin.restore_sigchld() - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_init(init_callback) -collectd.register_config(config_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/check_local_endpoint.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/check_local_endpoint.py deleted file mode 100644 index e01715fa5..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/check_local_endpoint.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -import collectd -import collectd_base as base -import http_check - - -NAME = 'check_local_endpoint' - - -class CheckLocalEndpoint(http_check.HTTPCheckPlugin): - - def __init__(self, *args, **kwargs): - super(CheckLocalEndpoint, self).__init__(*args, **kwargs) - self.plugin = NAME - -plugin = CheckLocalEndpoint(collectd) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, base.INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/check_openstack_api.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/check_openstack_api.py deleted file mode 100644 index f77520805..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/check_openstack_api.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for checking the status of OpenStack API services -import collectd - -import collectd_openstack as openstack - -from urlparse import urlparse - -PLUGIN_NAME = 'check_openstack_api' -INTERVAL = openstack.INTERVAL - - -class APICheckPlugin(openstack.CollectdPlugin): - """Class to check the status of OpenStack API services.""" - - # TODO(all): sahara, murano - CHECK_MAP = { - 'keystone': { - 'path': '/', 'expect': [300], 'name': 'keystone-public-api'}, - 'heat': {'path': '/', 'expect': [300], 'name': 'heat-api'}, - 'heat-cfn': {'path': '/', 'expect': [300], 'name': 'heat-cfn-api'}, - 'glance': {'path': '/', 'expect': [300], 'name': 'glance-api'}, - # Since Mitaka, Cinder returns 300 instead of 200 in previous releases - 'cinder': {'path': '/', 'expect': [200, 300], 'name': 'cinder-api'}, - 'cinderv2': { - 'path': '/', 'expect': [200, 300], 'name': 'cinder-v2-api'}, - 'neutron': {'path': '/', 'expect': [200], 'name': 'neutron-api'}, - 'nova': {'path': '/', 'expect': [200], 'name': 'nova-api'}, - # Ceilometer requires authentication for all paths - 'ceilometer': { - 'path': 'v2/capabilities', 'expect': [200], 'auth': True, - 'name': 'ceilometer-api'}, - 'swift': {'path': 'healthcheck', 'expect': [200], 'name': 'swift-api'}, - 'swift_s3': { - 'path': 'healthcheck', 'expect': [200], 'name': 'swift-s3-api'}, - } - - def __init__(self, *args, **kwargs): - super(APICheckPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - - def _service_url(self, endpoint, path): - url = urlparse(endpoint) - u = '%s://%s' % (url.scheme, url.netloc) - if path != '/': - u = '%s/%s' % (u, path) - return u - - def check_api(self): - """ Check the status of all the API services. - - Yields a list of dict items with 'service', 'status' (either OK, - FAIL or UNKNOWN) and 'region' keys. - """ - catalog = self.service_catalog - for service in catalog: - name = service['name'] - if name not in self.CHECK_MAP: - self.logger.notice( - "No check found for service '%s', skipping it" % name) - status = self.UNKNOWN - check = {} - else: - check = self.CHECK_MAP[name] - url = self._service_url(service['url'], check['path']) - r = self.raw_get(url, token_required=check.get('auth', False)) - - if r is None or r.status_code not in check['expect']: - def _status(ret): - return 'N/A' if r is None else r.status_code - - self.logger.notice( - "Service %s check failed " - "(returned '%s' but expected '%s')" % ( - name, _status(r), check['expect']) - ) - status = self.FAIL - else: - status = self.OK - - yield { - 'service': check.get('name', name), - 'status': status, - 'region': service['region'] - } - - def itermetrics(self): - for item in self.check_api(): - if item['status'] != self.UNKNOWN: - # skip if status is UNKNOWN - yield { - 'plugin_instance': item['service'], - 'values': item['status'], - 'meta': {'region': item['region']}, - } - - -plugin = APICheckPlugin(collectd, PLUGIN_NAME) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_apache_check.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_apache_check.py deleted file mode 100644 index 790a60f3b..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_apache_check.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -import collectd -import collectd_base as base -import requests - -NAME = 'apache' - - -class ApacheCheckPlugin(base.Base): - - def __init__(self, *args, **kwargs): - super(ApacheCheckPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.url = None - - def config_callback(self, conf): - super(ApacheCheckPlugin, self).config_callback(conf) - - for node in conf.children: - if node.key == 'Url': - self.url = node.values[0] - - if self.url is None: - self.logger.error("{}: Missing Url parameter".format(NAME)) - - def read_callback(self): - try: - requests.get(self.url, timeout=5) - self.dispatch_check_metric(self.OK) - except Exception as err: - msg = "{}: Failed to check service: {}".format(NAME, err) - self.logger.error(msg) - self.dispatch_check_metric(self.FAIL, msg) - - -plugin = ApacheCheckPlugin(collectd) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_base.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_base.py deleted file mode 100644 index 0b6646a9e..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_base.py +++ /dev/null @@ -1,344 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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 functools import wraps -import json -import signal -import subprocess -import threading -import time -import traceback - - -INTERVAL = 10 - - -class CheckException(Exception): - pass - - -# A decorator that will call the decorated function only when the plugin has -# detected that it is currently active. -def read_callback_wrapper(f): - @wraps(f) - def wrapper(self, *args, **kwargs): - if self.do_collect_data: - f(self, *args, **kwargs) - - return wrapper - - -class Base(object): - """Base class for writing Python plugins.""" - - FAIL = 0 - OK = 1 - UNKNOWN = 2 - - MAX_IDENTIFIER_LENGTH = 63 - - def __init__(self, collectd, service_name=None, local_check=True, - disable_check_metric=False): - self.debug = False - self.timeout = 5 - self.max_retries = 3 - self.logger = collectd - self.collectd = collectd - self.plugin = None - self.plugin_instance = '' - # attributes controlling whether the plugin is in collect mode or not - self.depends_on_resource = None - self.do_collect_data = True - - self.service_name = service_name - self.local_check = local_check - self.disable_check_metric = disable_check_metric - - def config_callback(self, conf): - for node in conf.children: - if node.key == "Debug": - if node.values[0].lower() == 'true': - self.debug = True - elif node.key == "Timeout": - self.timeout = int(node.values[0]) - elif node.key == 'MaxRetries': - self.max_retries = int(node.values[0]) - elif node.key == 'DependsOnResource': - self.depends_on_resource = node.values[0] - elif node.key == 'DisableCheckMetric': - if node.values[0].lower() == 'true': - self.disable_check_metric = True - - @read_callback_wrapper - def conditional_read_callback(self): - self.read_callback() - - def read_callback(self): - try: - for metric in self.itermetrics(): - self.dispatch_metric(metric) - except CheckException as e: - msg = '{}: {}'.format(self.plugin, e) - self.logger.warning(msg) - self.dispatch_check_metric(self.FAIL, msg) - except Exception as e: - msg = '{}: Failed to get metrics: {}'.format(self.plugin, e) - self.logger.error('{}: {}'.format(msg, traceback.format_exc())) - self.dispatch_check_metric(self.FAIL, msg) - else: - self.dispatch_check_metric(self.OK) - - def dispatch_check_metric(self, value, failure=None): - """Send a check metric reporting whether or not the plugin succeeded - - """ - if self.disable_check_metric: - return - - metric = { - 'meta': {'service_check': self.service_name or self.plugin, - 'local_check': self.local_check}, - 'values': value, - } - - if failure is not None: - metric['meta']['failure'] = failure - - self.dispatch_metric(metric) - - def itermetrics(self): - """Iterate over the collected metrics - - This class must be implemented by the subclass and should yield dict - objects that represent the collected values. Each dict has 6 keys: - - 'values', a scalar number or a list of numbers if the type - defines several datasources. - - 'type_instance' (optional) - - 'plugin_instance' (optional) - - 'type' (optional, default='gauge') - - 'meta' (optional) - - 'hostname' (optional) - - For example: - - {'type_instance':'foo', 'values': 1} - {'type_instance':'bar', 'type': 'DERIVE', 'values': 1} - {'type_instance':'bar', 'type': 'DERIVE', 'values': 1, - 'meta': {'tagA': 'valA'}} - {'type': 'dropped_bytes', 'values': [1,2]} - """ - raise NotImplemented("Must be implemented by the subclass!") - - def dispatch_metric(self, metric): - values = metric['values'] - if not isinstance(values, list) and not isinstance(values, tuple): - values = (values,) - - type_instance = str(metric.get('type_instance', '')) - if len(type_instance) > self.MAX_IDENTIFIER_LENGTH: - self.logger.warning( - '%s: Identifier "%s..." too long (length: %d, max limit: %d)' % - (self.plugin, type_instance[:24], len(type_instance), - self.MAX_IDENTIFIER_LENGTH)) - - plugin_instance = metric.get('plugin_instance', self.plugin_instance) - v = self.collectd.Values( - plugin=self.plugin, - host=metric.get('hostname', ''), - type=metric.get('type', 'gauge'), - plugin_instance=plugin_instance, - type_instance=type_instance, - values=values, - # w/a for https://github.com/collectd/collectd/issues/716 - meta=metric.get('meta', {'0': True}) - ) - v.dispatch() - - def execute(self, cmd, shell=True, cwd=None, log_error=True): - """Executes a program with arguments. - - Args: - cmd: a list of program arguments where the first item is the - program name. - shell: whether to use the shell as the program to execute (default= - True). - cwd: the directory to change to before running the program - (default=None). - log_error: whether to log an error when the command returned a - non-zero status code (default=True). - - Returns: - A tuple containing the return code, the standard output and the - standard error if the program has been executed. - - (0, "foobar\n", "") - - (-1, None, None) if the program couldn't be executed at all. - """ - start_time = time.time() - try: - proc = subprocess.Popen( - cmd, - cwd=cwd, - shell=shell, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - (stdout, stderr) = proc.communicate() - stdout = stdout.rstrip('\n') - except Exception as e: - self.logger.error("Cannot execute command '%s': %s : %s" % - (cmd, str(e), traceback.format_exc())) - return (-1, None, None) - - returncode = proc.returncode - - if returncode != 0 and log_error: - self.logger.error("Command '%s' failed (return code %d): %s" % - (cmd, returncode, stderr)) - if self.debug: - elapsedtime = time.time() - start_time - self.logger.info("Command '%s' returned %s in %0.3fs" % - (cmd, returncode, elapsedtime)) - - return (returncode, stdout, stderr) - - def execute_to_json(self, *args, **kwargs): - """Executes a program and decodes the output as a JSON string. - - See execute(). - - Returns: - A Python object or - None if the execution of the program or JSON decoding fails. - """ - (retcode, out, err) = self.execute(*args, **kwargs) - if retcode == 0: - try: - return json.loads(out) - except ValueError as e: - self.logger.error("{}: document: '{}'".format(e, out)) - - @staticmethod - def restore_sigchld(): - """Restores the SIGCHLD handler. - - This should be provided to collectd as the init callback by plugins - that execute external programs and want to check the return code. - - Note that it will BREAK the exec plugin!!! - - See contrib/python/getsigchld.py in the collectd project for details. - """ - signal.signal(signal.SIGCHLD, signal.SIG_DFL) - - def notification_callback(self, notification): - if not self.depends_on_resource: - return - - try: - data = json.loads(notification.message) - except ValueError: - return - - if 'value' not in data: - self.logger.warning( - "%s: missing 'value' in notification" % - self.__class__.__name__) - elif 'resource' not in data: - self.logger.warning( - "%s: missing 'resource' in notification" % - self.__class__.__name__) - elif data['resource'] == self.depends_on_resource: - do_collect_data = data['value'] > 0 - if self.do_collect_data != do_collect_data: - # log only the transitions - self.logger.notice("%s: do_collect_data=%s" % - (self.__class__.__name__, do_collect_data)) - self.do_collect_data = do_collect_data - - -class CephBase(Base): - - def __init__(self, *args, **kwargs): - super(CephBase, self).__init__(*args, **kwargs) - self.cluster = 'ceph' - - def config_callback(self, conf): - super(CephBase, self).config_callback(conf) - - for node in conf.children: - if node.key == "Cluster": - self.cluster = node.values[0] - self.plugin_instance = self.cluster - - -class AsyncPoller(threading.Thread): - """Execute an independant thread to execute a function periodically - - Args: - collectd: used for logging - polling_function: a function to execute periodically - interval: the interval in second - name: (optional) the name of the thread - reset_on_read: (default False) if True, all results returned by the - polling_function() are accumulated until they are - read. - """ - - def __init__(self, collectd, polling_function, interval, name=None, - reset_on_read=False): - super(AsyncPoller, self).__init__(name=name) - self.collectd = collectd - self.polling_function = polling_function - self.interval = interval - self._results = [] - self._reset_on_read = reset_on_read - - def run(self): - self.collectd.info('Starting thread {}'.format(self.name)) - while True: - try: - started_at = time.time() - - self.results = self.polling_function() - tosleep = self.interval - (time.time() - started_at) - if tosleep > 0: - time.sleep(tosleep) - else: - self.collectd.warning( - 'Polling took more than {}s for {}'.format( - self.interval, self.name - ) - ) - - except Exception as e: - self.results = [] - self.collectd.error('{} fails: {}'.format(self.name, e)) - time.sleep(10) - - @property - def results(self): - r = self._results - if self._reset_on_read: - self._results = [] - return r - - @results.setter - def results(self, value): - if self._reset_on_read: - self._results.extend(value) - else: - self._results = value diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_fake.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_fake.py deleted file mode 100644 index f3ff34ea8..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_fake.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. - -import logging -import os - - -log_level = logging.INFO -if os.getenv('COLLECTD_DEBUG', '') == '1': - log_level = logging.DEBUG -logging.basicConfig(level=log_level) - - -class Values(object): - - def __init__(self, type=None, values=None, plugin_instance=None, - type_instance=None, plugin=None, host=None, time=None, - meta=None, interval=None): - self._type = type - self._values = values - self._plugin_instance = plugin_instance - self._type_instance = type_instance - self._plugin = plugin - self._host = host - self._time = time - self._meta = meta - self._interval = interval - - def dispatch(self, type=None, values=None, plugin_instance=None, - type_instance=None, plugin=None, host=None, time=None, - meta=None, interval=None): - info("plugin={plugin} plugin_instance={plugin_instance} " - "type={type} type_instance={type_instance} " - "values={values} meta={meta}".format( - plugin=plugin or self._plugin, - plugin_instance=plugin_instance or self._plugin_instance, - type=type or self._type, - type_instance=type_instance or self._type_instance, - values=values or self._values, - meta=meta or self._meta, - )) - - -def error(msg): - logging.error(msg) - - -def warning(msg): - logging.warning(msg) - - -def notice(msg): - logging.notice(msg) - - -def info(msg): - logging.info(msg) - - -def debug(msg): - logging.debug(msg) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_libvirt_check.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_libvirt_check.py deleted file mode 100644 index d0df216cc..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_libvirt_check.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -import collectd -import libvirt - -import collectd_base as base - -NAME = 'libvirt' -URI = 'qemu:///system' - - -class LibvirtCheckPlugin(base.Base): - - def __init__(self, *args, **kwargs): - super(LibvirtCheckPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.uri = URI - - def config_callback(self, conf): - super(LibvirtCheckPlugin, self).config_callback(conf) - - for node in conf.children: - if node.key == 'Uri': - self.uri = node.values[0] - - def read_callback(self): - try: - cnx = libvirt.openReadOnly(self.uri) - cnx.numOfDefinedDomains() - self.dispatch_check_metric(self.OK) - except libvirt.libvirtError as e: - msg = 'Fail to query libvirt ({}): {}'.format(self.uri, e) - self.dispatch_check_metric(self.FAIL, msg) - - -plugin = LibvirtCheckPlugin(collectd) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_memcached_check.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_memcached_check.py deleted file mode 100644 index 5d0dd26a2..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_memcached_check.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -import collectd - -import collectd_base as base - -from pymemcache.client import base as memcache - -NAME = 'memcached' - - -class MemcachedCheckPlugin(base.Base): - - def __init__(self, *args, **kwargs): - super(MemcachedCheckPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.host = None - self.port = 11211 - - def config_callback(self, conf): - super(MemcachedCheckPlugin, self).config_callback(conf) - - for node in conf.children: - if node.key == 'Host': - self.host = node.values[0] - if node.key == 'Port': - # Must coerce to integer to avoid getting a float value. - self.port = int(node.values[0]) - - if self.host is None: - self.logger.error('Missing Host parameter') - - def read_callback(self): - try: - - mc = memcache.Client((self.host, self.port)) - mc.get('__get_non_existent_key__') - self.dispatch_check_metric(self.OK) - except Exception as e: - msg = 'Fail to query memcached ({}:{}): {}'.format(self.host, - self.port, - e) - self.logger.error(msg) - self.dispatch_check_metric(self.FAIL, msg) - - -plugin = MemcachedCheckPlugin(collectd) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_mysql_check.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_mysql_check.py deleted file mode 100644 index 3f598960a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_mysql_check.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -import collectd - -import collectd_base as base -import os.path -import pymysql - -NAME = 'mysql' - - -class MySQLCheckPlugin(base.Base): - - def __init__(self, *args, **kwargs): - super(MySQLCheckPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.host = None - self.socket = None - self.port = '3306' - self.sql = 'SELECT VERSION()' - self.username = None - self.password = None - self.database = None - - def config_callback(self, conf): - super(MySQLCheckPlugin, self).config_callback(conf) - - for node in conf.children: - if node.key == 'Socket': - self.socket = node.values[0] - if node.key == 'Host': - self.host = node.values[0] - if node.key == 'Port': - self.port = int(node.values[0]) - if node.key == 'Username': - self.username = node.values[0] - if node.key == 'Password': - self.password = node.values[0] - if node.key == 'Database': # Optional - self.database = node.values[0] - if node.key == 'SQL': - self.sql = node.values[0] - - if not self.socket and not self.host: - # Try to find MySQL socket - for sock in ('/var/run/mysqld/mysqld.sock', - '/run/mysqld/mysqld.sock'): - if os.path.exists(sock): - self.socket = sock - self.logger.info('Use socket {} as a fallback'.format( - sock)) - break - - if not self.socket: - self.logger.error('Missing parameter: Host or Socket') - - if self.socket: - # The hostname must be set to localhost to work with socket - self.host = 'localhost' - self.logger.info('Use Socket={}'.format(self.socket)) - - if not self.username: - self.logger.warning('Missing parameter Username') - - def read_callback(self): - cnx = None - try: - cnx = pymysql.connect(host=self.host, - port=self.port, - unix_socket=self.socket, - user=self.username, - password=self.password, - db=self.database, - connect_timeout=3) - - with cnx.cursor() as cursor: - cursor.execute(self.sql) - cursor.fetchone() - self.dispatch_check_metric(self.OK) - except Exception as e: - msg = 'Fail to query MySQL "{}": {}'.format(self.sql, e) - self.logger.error(msg) - self.dispatch_check_metric(self.FAIL, msg) - - finally: - if cnx is not None: - cnx.close() - - -plugin = MySQLCheckPlugin(collectd) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_openstack.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_openstack.py deleted file mode 100644 index ec3b05662..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_openstack.py +++ /dev/null @@ -1,409 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. - -import datetime -import dateutil.parser -import dateutil.tz -import requests -import simplejson as json - -import collectd_base as base - -from collections import defaultdict - -# By default, query OpenStack API endpoints every 50 seconds. We choose a value -# less than the default group by interval (which is 60 seconds) to avoid gaps -# in the Grafana graphs. -INTERVAL = 50 - - -class KeystoneException(Exception): - pass - - -class OSClient(object): - """ Base class for querying the OpenStack API endpoints. - - It uses the Keystone service catalog to discover the API endpoints. - """ - EXPIRATION_TOKEN_DELTA = datetime.timedelta(0, 30) - - def __init__(self, username, password, tenant, keystone_url, timeout, - logger, max_retries): - self.logger = logger - self.username = username - self.password = password - self.tenant_name = tenant - self.keystone_url = keystone_url - self.service_catalog = [] - self.tenant_id = None - self.timeout = timeout - self.token = None - self.valid_until = None - - # Note: prior to urllib3 v1.9, retries are made on failed connections - # but not on timeout and backoff time is not supported. - # (at this time we ship requests 2.2.1 and urllib3 1.6.1 or 1.7.1) - self.session = requests.Session() - self.session.mount( - 'http://', requests.adapters.HTTPAdapter(max_retries=max_retries)) - self.session.mount( - 'https://', requests.adapters.HTTPAdapter(max_retries=max_retries)) - - def is_valid_token(self): - now = datetime.datetime.now(tz=dateutil.tz.tzutc()) - return self.token and self.valid_until and self.valid_until > now - - def clear_token(self): - self.token = None - self.valid_until = None - - def get_token(self): - self.clear_token() - data = json.dumps({ - "auth": - { - 'tenantName': self.tenant_name, - 'passwordCredentials': - { - 'username': self.username, - 'password': self.password - } - } - }) - self.logger.info("Trying to get token from '%s'" % self.keystone_url) - r = self.make_request('post', - '%s/tokens' % self.keystone_url, data=data, - token_required=False) - if not r: - raise KeystoneException("Cannot get a valid token from %s" % - self.keystone_url) - - if r.status_code < 200 or r.status_code > 299: - raise KeystoneException("%s responded with code %d" % - (self.keystone_url, r.status_code)) - - data = r.json() - self.logger.debug("Got response from Keystone: '%s'" % data) - self.token = data['access']['token']['id'] - self.tenant_id = data['access']['token']['tenant']['id'] - self.valid_until = dateutil.parser.parse( - data['access']['token']['expires']) - self.EXPIRATION_TOKEN_DELTA - self.service_catalog = [] - for item in data['access']['serviceCatalog']: - endpoint = item['endpoints'][0] - if 'internalURL' not in endpoint and 'publicURL' not in endpoint: - self.logger.warning( - "Service '{}' skipped because no URL can be found".format( - item['name'])) - continue - self.service_catalog.append({ - 'name': item['name'], - 'region': endpoint['region'], - 'service_type': item['type'], - 'url': endpoint.get('internalURL', endpoint.get('publicURL')), - 'admin_url': endpoint['adminURL'], - }) - - self.logger.debug("Got token '%s'" % self.token) - return self.token - - def make_request(self, verb, url, data=None, token_required=True, - params=None): - kwargs = { - 'url': url, - 'timeout': self.timeout, - 'headers': {'Content-type': 'application/json'} - } - if token_required and not self.is_valid_token() and \ - not self.get_token(): - self.logger.error("Aborting request, no valid token") - return - elif token_required: - kwargs['headers']['X-Auth-Token'] = self.token - - if data is not None: - kwargs['data'] = data - - if params is not None: - kwargs['params'] = params - - func = getattr(self.session, verb.lower()) - - try: - r = func(**kwargs) - except Exception as e: - self.logger.error("Got exception for '%s': '%s'" % - (kwargs['url'], e)) - return - - self.logger.info("%s responded with status code %d" % - (kwargs['url'], r.status_code)) - if r.status_code == 401: - # Clear token in case it is revoked or invalid - self.clear_token() - - return r - - -class CollectdPlugin(base.Base): - - def __init__(self, *args, **kwargs): - super(CollectdPlugin, self).__init__(*args, **kwargs) - # The timeout/max_retries are defined according to the observations on - # 200 nodes environments with 600 VMs. See #1554502 for details. - self.timeout = 20 - self.max_retries = 2 - self.os_client = None - self.extra_config = {} - self._threads = {} - self.pagination_limit = None - self.polling_interval = 60 - self._last_run = None - self.changes_since = False - - def _build_url(self, service, resource): - s = (self.get_service(service) or {}) - url = s.get('url') - # v3 API must be used in order to obtain tenants in multi-domain envs - if service == 'keystone' and (resource in ['projects', - 'users', 'roles']): - url = url.replace('v2.0', 'v3') - - if url: - if url[-1] != '/': - url += '/' - url = "%s%s" % (url, resource) - else: - self.logger.error("Service '%s' not found in catalog" % service) - return url - - def raw_get(self, url, token_required=False): - return self.os_client.make_request('get', url, - token_required=token_required) - - def iter_workers(self, service): - """ Return the list of workers and their state - - Here is an example of returned dictionnary: - { - 'host': 'node.example.com', - 'service': 'nova-compute', - 'state': 'up' - } - - where 'state' can be 'up', 'down' or 'disabled' - """ - - if service == 'neutron': - endpoint = 'v2.0/agents' - entry = 'agents' - else: - endpoint = 'os-services' - entry = 'services' - - ost_services_r = self.get(service, endpoint) - - msg = "Cannot get state of {} workers".format(service) - if ost_services_r is None: - self.logger.warning(msg) - elif ost_services_r.status_code != 200: - msg = "{}: Got {} ({})".format( - msg, ost_services_r.status_code, ost_services_r.content) - self.logger.warning(msg) - else: - try: - r_json = ost_services_r.json() - except ValueError: - r_json = {} - - if entry not in r_json: - msg = "{}: couldn't find '{}' key".format(msg, entry) - self.logger.warning(msg) - else: - for val in r_json[entry]: - data = {'host': val['host'], 'service': val['binary']} - - if service == 'neutron': - if not val['admin_state_up']: - data['state'] = 'disabled' - else: - data['state'] = 'up' if val['alive'] else 'down' - else: - if val['status'] == 'disabled': - data['state'] = 'disabled' - elif val['state'] == 'up' or val['state'] == 'down': - data['state'] = val['state'] - else: - msg = "Unknown state for {} workers:{}".format( - service, val['state']) - self.logger.warning(msg) - continue - - yield data - - def get(self, service, resource, params=None): - url = self._build_url(service, resource) - if not url: - return - self.logger.info('GET({}) {}'.format(url, params)) - return self.os_client.make_request('get', url, params=params) - - @property - def service_catalog(self): - if not self.os_client.service_catalog: - # In case the service catalog is empty (eg Keystone was down when - # collectd started), we should try to get a new token - self.os_client.get_token() - return self.os_client.service_catalog - - def get_service(self, service_name): - return next((x for x in self.service_catalog - if x['name'] == service_name), None) - - def config_callback(self, config): - super(CollectdPlugin, self).config_callback(config) - for node in config.children: - if node.key == 'Username': - username = node.values[0] - elif node.key == 'Password': - password = node.values[0] - elif node.key == 'Tenant': - tenant_name = node.values[0] - elif node.key == 'KeystoneUrl': - keystone_url = node.values[0] - elif node.key == 'PaginationLimit': - self.pagination_limit = int(node.values[0]) - elif node.key == 'PollingInterval': - self.polling_interval = int(node.values[0]) - - self.os_client = OSClient(username, password, tenant_name, - keystone_url, self.timeout, self.logger, - self.max_retries) - - def get_objects(self, project, object_name, api_version='', - params=None, detail=False, since=False): - """ Return a list of OpenStack objects - - The API version is not always included in the URL endpoint - registered in Keystone (eg Glance). In this case, use the - api_version parameter to specify which version should be used. - - """ - self.changes_since = since - if params is None: - params = {} - - if api_version: - resource = '%s/%s' % (api_version, object_name) - else: - resource = '%s' % (object_name) - - if detail: - resource = '{}/detail'.format(resource) - - opts = {} - if self.pagination_limit: - opts['limit'] = self.pagination_limit - - opts.update(params) - - def openstack_api_poller(): - _objects = [] - _opts = {} - _opts.update(opts) - - if self.changes_since and self._last_run: - _opts['changes-since'] = self._last_run.isoformat() - - # Keep track of the initial request time - last_run = datetime.datetime.now(tz=dateutil.tz.tzutc()) - has_failure = False - - while True: - r = self.get(project, resource, params=_opts) - if not r or object_name not in r.json(): - has_failure = True - if r is None: - err = '' - else: - err = r.text - self.collectd.warning('Could not find {}: {} {}'.format( - project, object_name, err - )) - # Avoid to provide incomplete data by reseting current - # set. - _objects = [] - break - - resp = r.json() - bulk_objs = resp.get(object_name) - if not bulk_objs: - # emtpy list - break - - _objects.extend(bulk_objs) - - if self.pagination_limit is None: - break - - links = resp.get('{}_links'.format(object_name), []) - has_next = len( - [i for i in links if i.get('rel') == 'next']) > 0 or \ - resp.get('next') - if has_next: - _opts['marker'] = bulk_objs[-1]['id'] - else: - break - - if not has_failure: - self._last_run = last_run - - return _objects - - poller_id = '{}:{}'.format(project, resource) - if poller_id not in self._threads: - t = base.AsyncPoller(self.collectd, - openstack_api_poller, - self.polling_interval, - poller_id, self.changes_since) - t.start() - self._threads[poller_id] = t - - t = self._threads[poller_id] - if not t.is_alive(): - self.logger.warning("Unexpected end of the thread {}".format( - t.name)) - del self._threads[poller_id] - return [] - - return t.results - - def count_objects_group_by(self, - list_object, - group_by_func, - count_func=None): - - """ Count the number of items grouped by arbitrary criteria.""" - - counts = defaultdict(int) - for obj in list_object: - s = group_by_func(obj) - try: - counts[s] += count_func(obj) if count_func else 1 - except TypeError: - # Ignore when count_func() doesn't return a number - pass - return counts diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_pacemaker.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_pacemaker.py deleted file mode 100644 index e8cb7b238..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/collectd_pacemaker.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -import collectd -from collections import Counter -from collections import defaultdict -from sets import Set -import socket -import xml.etree.ElementTree as ET - -import collectd_base as base - -NAME = 'pacemaker' -CRM_MON_BINARY = '/usr/sbin/crm_mon' - -# Node status -OFFLINE_STATUS = 0 -MAINTENANCE_STATUS = 1 -ONLINE_STATUS = 2 - - -class CrmMonitorPlugin(base.Base): - - def __init__(self, *args, **kwargs): - super(CrmMonitorPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.crm_mon_binary = CRM_MON_BINARY - self.hostname = socket.getfqdn() - self.notify_resource = None - self.resources = {} - self.history = {} - - def config_callback(self, conf): - super(CrmMonitorPlugin, self).config_callback(conf) - - for node in conf.children: - if node.key == 'Hostname': - self.hostname = node.values[0] - elif node.key == 'CrmMonBinary': - self.crm_mon_binary = node.values[0] - elif node.key == 'Resource': - self.resources[node.values[0]] = node.values[-1] - elif node.key == 'NotifyResource': - self.notify_resource = node.values[0] - - def itermetrics(self): - def str_to_bool(v): - return str(v).lower() == 'true' - - def str_to_boolint(v): - if str_to_bool(v): - return 1 - else: - return 0 - - def shorten_hostname(v): - return v.split('.')[0] - - def same_hostname(v): - if v is not None and v.get('name') == self.hostname: - return 1 - return 0 - - retcode, out, err = self.execute( - [self.crm_mon_binary, '--as-xml', '-r', '-f'], shell=False) - if retcode != 0: - raise base.CheckException( - "Failed to execute crm_mon '{}'".format(err)) - - try: - root = ET.fromstring(out) - except ET.ParseError: - raise base.CheckException( - "Failed to parse XML '{}'".format(out[:64])) - - if self.notify_resource: - # Notify the other collectd plugins whether the resource runs - # locally or not - node = root.find('resources/resource[@id="{}"]/node'.format( - self.notify_resource)) - self.collectd.Notification( - type='gauge', - message='{{"resource":"{}","value":{}}}'.format( - self.notify_resource, same_hostname(node)), - severity=self.collectd.NOTIF_OKAY - ).dispatch() - # The metric needs to be emitted too for the Lua plugins executed - # by the metric_collector service - yield { - 'type_instance': 'local_resource_active', - 'values': same_hostname(node), - 'meta': {'resource': self.notify_resource, - 'host': shorten_hostname(self.hostname)} - } - - summary = root.find('summary') - current_dc = summary.find('current_dc') - # The metric needs to be emitted for the alarms that leverage the other - # metrics emitted by the plugin - yield { - 'type_instance': 'local_dc_active', - 'values': same_hostname(current_dc), - 'meta': {'host': shorten_hostname(self.hostname)} - } - - if current_dc.get('name') != self.hostname: - # The other metrics are only collected from the cluster's DC - return - - # Report global cluster metrics - yield { - 'type_instance': 'dc', - 'values': str_to_boolint(current_dc.get('present', 'false')) - } - - yield { - 'type_instance': 'quorum_status', - 'values': str_to_boolint(current_dc.get('with_quorum', 'false')) - } - yield { - 'type_instance': 'configured_nodes', - 'values': int(summary.find('nodes_configured').get('number')) - } - yield { - 'type_instance': 'configured_resources', - 'values': int(summary.find('resources_configured').get('number')) - } - - # Report node status metrics - cluster_nodes = [] - aggregated_nodes_status = {'online': 0, 'offline': 0, 'maintenance': 0} - nodes_total = 0 - for node in root.find('nodes').iter('node'): - nodes_total += 1 - hostname = shorten_hostname(node.get('name')) - cluster_nodes.append(node.get('name')) - if str_to_bool(node.get('online')): - if str_to_bool(node.get('maintenance')): - aggregated_nodes_status['maintenance'] += 1 - yield { - 'type_instance': 'node_status', - 'values': MAINTENANCE_STATUS, - 'meta': {'status': 'maintenance', 'host': hostname} - } - else: - aggregated_nodes_status['online'] += 1 - yield { - 'type_instance': 'node_status', - 'values': ONLINE_STATUS, - 'meta': {'status': 'online', 'host': hostname} - } - else: - aggregated_nodes_status['offline'] += 1 - yield { - 'type_instance': 'node_status', - 'values': OFFLINE_STATUS, - 'meta': {'status': 'offline', 'host': hostname} - } - - for status, cnt in aggregated_nodes_status.items(): - yield { - 'type_instance': 'nodes_count', - 'values': cnt, - 'meta': {'status': status} - } - yield { - 'type_instance': 'nodes_percent', - 'values': 100.0 * cnt / nodes_total, - 'meta': {'status': status} - } - - # Report the number of resources per status - # Clone resources can run on multipe nodes while "simple" resources run - # only one node at the same time - aggregated_resources = defaultdict(Counter) - resources = root.find('resources') - for resource_id, resource_name in self.resources.iteritems(): - resource_elts = [] - simple_resource = None - clone_resource = resources.find( - 'clone/resource[@id="{}"]/..'.format(resource_id)) - if not clone_resource: - simple_resource = resources.find('resource[@id="{}"]'.format( - resource_id)) - if simple_resource: - resource_elts = [simple_resource] - else: - resource_elts = clone_resource.findall('resource') - - if not resource_elts: - self.logger.error("{}: Couldn't find resource '{}'".format( - self.plugin, resource_id)) - continue - - total = 0 - for item in resource_elts: - total += 1 - if (item.get('role') in ('Slave', 'Master') and - not str_to_bool(item.get('failed'))): - # Multi-master resource - aggregated_resources[resource_name]['up'] += 1 - elif item.get('role') == 'Started': - aggregated_resources[resource_name]['up'] += 1 - else: - aggregated_resources[resource_name]['down'] += 1 - - if simple_resource: - # Report on which node the "simple" resource is running - for node in cluster_nodes: - yield { - 'type_instance': 'local_resource_active', - 'values': str_to_boolint( - node == simple_resource.find('node').get('name')), - 'meta': {'resource': resource_name, - 'host': shorten_hostname(node)} - } - - for status in ('up', 'down'): - cnt = aggregated_resources[resource_name][status] - yield { - 'type_instance': 'resource_count', - 'values': cnt, - 'meta': {'status': status, 'resource': resource_name} - } - yield { - 'type_instance': 'resource_percent', - 'values': 100.0 * cnt / total, - 'meta': {'status': status, 'resource': resource_name} - } - - # Collect operations' history metrics for the monitored resources - # - # The reported count for the resource's operations is an approximate - # value because crm_mon doesn't provide the exact number. To estimate - # the number of operations applied to a resource, the plugin keeps a - # copy of call_ids and compares it with the current value. - - history = root.find('node_history') - if history is None: - return - - for node in history.iter('node'): - hostname = shorten_hostname(node.get('name')) - if hostname not in self.history: - self.history[hostname] = {} - - for resource_id, resource_name in self.resources.iteritems(): - if resource_id not in self.history[hostname]: - self.history[hostname][resource_id] = { - 'fail_count': 0, - 'ops_count': 0, - 'call_ids': Set([]) - } - v = self.history[hostname][resource_id] - - res_history = node.find('resource_history[@id="{}"]'.format( - resource_id)) - if res_history: - # For simple resources, the resource_history element only - # exists for the node that runs the resource - v['fail_count'] += int(res_history.get('fail-count', 0)) - call_ids = Set([ - i.get('call') for i in res_history.findall( - 'operation_history')]) - if call_ids: - v['ops_count'] += len(call_ids - v['call_ids']) - v['call_ids'] = call_ids - - yield { - 'type_instance': 'resource_failures', - 'values': v['fail_count'], - 'meta': {'resource': resource_name, 'host': hostname} - } - yield { - 'type_instance': 'resource_operations', - 'values': v['ops_count'], - 'meta': {'resource': resource_name, 'host': hostname} - } - - -plugin = CrmMonitorPlugin(collectd) - - -def init_callback(): - plugin.restore_sigchld() - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/elasticsearch_cluster.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/elasticsearch_cluster.py deleted file mode 100644 index 5947f6210..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/elasticsearch_cluster.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -import collectd -import requests - -import collectd_base as base - -NAME = 'elasticsearch_cluster' -HEALTH_MAP = { - 'green': 1, - 'yellow': 2, - 'red': 3, -} -METRICS = ['number_of_nodes', 'active_primary_shards', 'active_primary_shards', - 'active_shards', 'relocating_shards', 'unassigned_shards', - 'number_of_pending_tasks', 'initializing_shards'] - - -class ElasticsearchClusterHealthPlugin(base.Base): - def __init__(self, *args, **kwargs): - super(ElasticsearchClusterHealthPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.address = '127.0.0.1' - self.port = 9200 - self.session = requests.Session() - self.url = None - self.session.mount( - 'http://', - requests.adapters.HTTPAdapter(max_retries=self.max_retries) - ) - - def config_callback(self, conf): - super(ElasticsearchClusterHealthPlugin, self).config_callback(conf) - - for node in conf.children: - if node.key == 'Address': - self.address = node.values[0] - if node.key == 'Port': - self.port = node.values[0] - - self.url = "http://{address}:{port}/_cluster/health".format( - **{ - 'address': self.address, - 'port': int(self.port), - }) - - def itermetrics(self): - try: - r = self.session.get(self.url) - except Exception as e: - msg = "Got exception for '{}': {}".format(self.url, e) - raise base.CheckException(msg) - - if r.status_code != 200: - msg = "{} responded with code {}".format( - self.url, r.status_code) - raise base.CheckException(msg) - - data = r.json() - self.logger.debug("Got response from Elasticsearch: '%s'" % data) - - yield { - 'type_instance': 'health', - 'values': HEALTH_MAP[data['status']] - } - - for metric in METRICS: - value = data.get(metric) - if value is None: - # Depending on the Elasticsearch version, not all metrics are - # available - self.logger.info("Couldn't find {} metric".format(metric)) - continue - yield { - 'type_instance': metric, - 'values': value - } - -plugin = ElasticsearchClusterHealthPlugin(collectd, 'elasticsearch') - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/haproxy.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/haproxy.py deleted file mode 100644 index 2299d6ec7..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/haproxy.py +++ /dev/null @@ -1,318 +0,0 @@ -# haproxy-collectd-plugin - haproxy.py -# -# Original Author: Michael Leinartas -# Substantial additions by Mirantis -# Description: This is a collectd plugin which runs under the Python plugin to -# collect metrics from haproxy. -# Plugin structure and logging func taken from -# https://github.com/phrawzty/rabbitmq-collectd-plugin - -# Copyright (c) 2011 Michael Leinartas -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -import collectd -import csv -import itertools -import socket - -import collectd_base as base - -from collections import defaultdict - -NAME = 'haproxy' -RECV_SIZE = 1024 -SERVER_METRICS = { - 'CurrConns': ('connections', 'gauge'), - 'CurrSslConns': ('ssl_connections', 'gauge'), - 'PipesUsed': ('pipes_used', 'gauge'), - 'PipesFree': ('pipes_free', 'gauge'), - 'Run_queue': ('run_queue', 'gauge'), - 'Tasks': ('tasks', 'gauge'), - 'Uptime_sec': ('uptime', 'gauge'), -} -FRONTEND_METRIC_TYPES = { - 'bin': ('bytes_in', 'gauge'), - 'bout': ('bytes_out', 'gauge'), - 'dresp': ('denied_responses', 'gauge'), - 'dreq': ('denied_requests', 'gauge'), - 'ereq': ('error_requests', 'gauge'), - 'hrsp_1xx': ('response_1xx', 'gauge'), - 'hrsp_2xx': ('response_2xx', 'gauge'), - 'hrsp_3xx': ('response_3xx', 'gauge'), - 'hrsp_4xx': ('response_4xx', 'gauge'), - 'hrsp_5xx': ('response_5xx', 'gauge'), - 'hrsp_other': ('response_other', 'gauge'), - 'stot': ('session_total', 'gauge'), - 'scur': ('session_current', 'gauge'), -} -BACKEND_METRIC_TYPES = { - 'bin': ('bytes_in', 'gauge'), - 'bout': ('bytes_out', 'gauge'), - 'downtime': ('downtime', 'gauge'), - 'dresp': ('denied_responses', 'gauge'), - 'dreq': ('denied_requests', 'gauge'), - 'econ': ('error_connection', 'gauge'), - 'eresp': ('error_responses', 'gauge'), - 'hrsp_1xx': ('response_1xx', 'gauge'), - 'hrsp_2xx': ('response_2xx', 'gauge'), - 'hrsp_3xx': ('response_3xx', 'gauge'), - 'hrsp_4xx': ('response_4xx', 'gauge'), - 'hrsp_5xx': ('response_5xx', 'gauge'), - 'hrsp_other': ('response_other', 'gauge'), - 'qcur': ('queue_current', 'gauge'), - 'stot': ('session_total', 'gauge'), - 'scur': ('session_current', 'gauge'), - 'wredis': ('redistributed', 'gauge'), - 'wretr': ('retries', 'gauge'), - 'status': ('status', 'gauge'), -} - -STATUS_MAP = { - 'DOWN': 0, - 'UP': 1, -} - -FRONTEND_TYPE = '0' -BACKEND_TYPE = '1' -BACKEND_SERVER_TYPE = '2' - -HAPROXY_SOCKET = '/var/lib/haproxy/stats' -DEFAULT_PROXY_MONITORS = ['server', 'frontend', 'backend', 'backend_server'] - - -class HAProxySocket(object): - def __init__(self, socket_file): - self.socket_file = socket_file - - def connect(self): - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(self.socket_file) - return s - - def communicate(self, command): - '''Send a command to the socket and return a response (raw string).''' - - s = self.connect() - if not command.endswith('\n'): - command += '\n' - s.send(command) - result = '' - buf = '' - buf = s.recv(RECV_SIZE) - while buf: - result += buf - buf = s.recv(RECV_SIZE) - s.close() - return result - - def get_server_info(self): - result = {} - output = self.communicate('show info') - for line in output.splitlines(): - try: - key, val = line.split(':') - except ValueError: - continue - result[key.strip()] = val.strip() - return result - - def get_server_stats(self): - output = self.communicate('show stat') - # sanitize and make a list of lines - output = output.lstrip('# ').strip() - output = [l.strip(',') for l in output.splitlines()] - csvreader = csv.DictReader(output) - result = [d.copy() for d in csvreader] - return result - - -class HAProxyPlugin(base.Base): - def __init__(self, *args, **kwargs): - super(HAProxyPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.names_mapping = {} - self.proxy_monitors = [] - self.proxy_ignore = [] - self.socket = HAPROXY_SOCKET - - def get_proxy_name(self, pxname): - if pxname not in self.names_mapping: - self.logger.info('Mapping missing for "%s"' % pxname) - return self.names_mapping.get(pxname, pxname) - - def itermetrics(self): - haproxy = HAProxySocket(self.socket) - - # Collect server statistics - if 'server' in self.proxy_monitors: - try: - stats = haproxy.get_server_info() - except socket.error: - msg = "Unable to connect to HAProxy socket at {}".format( - self.socket) - raise base.CheckException(msg) - else: - for k, v in stats.iteritems(): - if k not in SERVER_METRICS: - continue - type_instance = SERVER_METRICS[k][0] - type_ = SERVER_METRICS[k][1] - yield { - 'type_instance': type_instance, - 'type': type_, - 'values': int(v), - } - - try: - stats = haproxy.get_server_stats() - except socket.error: - msg = "Unable to connect to HAProxy socket at {}".format( - self.socket) - raise base.CheckException(msg) - - def match(x): - if x['pxname'] in self.proxy_ignore: - return False - return (x['svname'].lower() in self.proxy_monitors or - x['pxname'].lower() in self.proxy_monitors or - ('backend_server' in self.proxy_monitors and - x['type'] == BACKEND_SERVER_TYPE)) - stats = filter(match, stats) - for stat in stats: - stat['pxname'] = self.get_proxy_name(stat['pxname']) - - # Collect statistics for the frontends and the backends - for stat in itertools.ifilter(lambda x: x['type'] == FRONTEND_TYPE or - x['type'] == BACKEND_TYPE, stats): - if stat['type'] == FRONTEND_TYPE: - metrics = FRONTEND_METRIC_TYPES - side = 'frontend' - else: - metrics = BACKEND_METRIC_TYPES - side = 'backend' - for k, metric in metrics.iteritems(): - if k not in stat: - self.logger.warning("Can't find {} metric".format(k)) - continue - value = stat[k] - - metric_name = '{}_{}'.format(side, metric[0]) - meta = { - side: stat['pxname'] - } - - if metric[0] == 'status': - value = STATUS_MAP[value] - else: - value = int(value) if value else 0 - - yield { - 'type_instance': metric_name, - 'type': metric[1], - 'values': value, - 'meta': meta - } - - # Count the number of servers per backend and state - backend_server_states = {} - for stat in itertools.ifilter(lambda x: - x['type'] == BACKEND_SERVER_TYPE, stats): - pxname = stat['pxname'] - if pxname not in backend_server_states: - backend_server_states[pxname] = defaultdict(int) - - # The status field for a server has the following syntax when a - # transition occurs with HAproxy >=1.6: "DOWN 17/30" or "UP 1/3". - status = stat['status'].split(' ')[0] - - # We only pick up the UP and DOWN status while it can be one of - # NOLB/MAINT/MAINT(via)... - if status in STATUS_MAP: - backend_server_states[pxname][status] += 1 - backend_server_states[pxname]['_count'] += 1 - # Emit metric for the backend server - yield { - 'type_instance': 'backend_server', - 'values': STATUS_MAP[status], - 'meta': { - 'backend': pxname, - 'state': status.lower(), - 'server': stat['svname'], - } - } - - for pxname, states in backend_server_states.iteritems(): - for s in STATUS_MAP.keys(): - val = states.get(s, 0) - yield { - 'type_instance': 'backend_servers', - 'values': val, - 'meta': { - 'backend': pxname, - 'state': s.lower() - } - } - - if backend_server_states[pxname]['_count'] == 0: - prct = 0 - else: - prct = (100.0 * val) / \ - backend_server_states[pxname]['_count'] - yield { - 'type_instance': 'backend_servers_percent', - 'values': prct, - 'meta': { - 'backend': pxname, - 'state': s.lower() - } - } - - def config_callback(self, conf): - for node in conf.children: - if node.key == "ProxyMonitor": - self.proxy_monitors.append(node.values[0]) - elif node.key == "ProxyIgnore": - self.proxy_ignore.append(node.values[0]) - elif node.key == "Socket": - self.socket = node.values[0] - elif node.key == "Mapping": - self.names_mapping[node.values[0]] = node.values[1] - else: - self.logger.warning('Unknown config key: %s' % node.key) - - if not self.proxy_monitors: - self.proxy_monitors += DEFAULT_PROXY_MONITORS - self.proxy_monitors = [p.lower() for p in self.proxy_monitors] - - -plugin = HAProxyPlugin(collectd) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/http_check.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/http_check.py deleted file mode 100644 index 774d88939..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/http_check.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -try: - import collectd -except ImportError: - import collectd_fake as collectd - -import requests - -import collectd_base as base - - -NAME = 'http_check' - - -class HTTPCheckPlugin(base.Base): - - def __init__(self, *args, **kwargs): - super(HTTPCheckPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.session = requests.Session() - self.session.mount( - 'http://', - requests.adapters.HTTPAdapter(max_retries=self.max_retries) - ) - self.session.mount( - 'https://', - requests.adapters.HTTPAdapter(max_retries=self.max_retries) - ) - self.urls = {} - self.expected_codes = {} - - def config_callback(self, config): - super(HTTPCheckPlugin, self).config_callback(config) - for node in config.children: - if node.key == "Url": - self.urls[node.values[0]] = node.values[1] - elif node.key == 'ExpectedCode': - self.expected_codes[node.values[0]] = int(node.values[1]) - - def itermetrics(self): - for name, url in self.urls.items(): - try: - r = self.session.get(url, timeout=self.timeout) - except Exception as e: - self.logger.warning("Got exception for '{}': {}".format( - url, e) - ) - yield {'type_instance': name, 'values': self.FAIL} - else: - - expected_code = self.expected_codes.get(name, 200) - if r.status_code != expected_code: - self.logger.warning( - ("{} ({}) responded with code {} " - "while {} is expected").format(name, url, - r.status_code, - expected_code)) - yield {'type_instance': name, 'values': self.FAIL} - else: - self.logger.debug( - "Got response from {}: '{}'".format(url, r.content)) - yield {'type_instance': name, 'values': self.OK} - - -plugin = HTTPCheckPlugin(collectd, disable_check_metric=True) - - -if __name__ == '__main__': - plugin.urls['google_ok'] = 'https://www.google.com' - plugin.urls['google_fail'] = 'https://www.google.com/not_found' - plugin.expected_codes['google_ok'] = 200 - plugin.expected_codes['github_fail'] = 200 - plugin.read_callback() -else: - def config_callback(conf): - plugin.config_callback(conf) - - def notification_callback(notification): - plugin.notification_callback(notification) - - def read_callback(): - plugin.conditional_read_callback() - - collectd.register_config(config_callback) - collectd.register_notification(notification_callback) - collectd.register_read(read_callback, base.INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/hypervisor_stats.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/hypervisor_stats.py deleted file mode 100644 index b4f32dbd3..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/hypervisor_stats.py +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting hypervisor statistics from Nova -import collectd - -import collectd_openstack as openstack - -PLUGIN_NAME = 'hypervisor_stats' -INTERVAL = openstack.INTERVAL - - -class HypervisorStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Nova hypervisors.""" - VALUE_MAP = { - 'current_workload': 'running_tasks', - 'running_vms': 'running_instances', - 'local_gb_used': 'used_disk_GB', - 'free_disk_gb': 'free_disk_GB', - 'memory_mb_used': 'used_ram_MB', - 'free_ram_mb': 'free_ram_MB', - 'vcpus_used': 'used_vcpus', - } - - def __init__(self, *args, **kwargs): - super(HypervisorStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - - def config_callback(self, config): - super(HypervisorStatsPlugin, self).config_callback(config) - for node in config.children: - if node.key == 'CpuAllocationRatio': - self.extra_config['cpu_ratio'] = float(node.values[0]) - if 'cpu_ratio' not in self.extra_config: - self.logger.warning('CpuAllocationRatio parameter not set') - - def itermetrics(self): - nova_aggregates = {} - r = self.get('nova', 'os-aggregates') - if not r: - self.logger.warning("Could not get nova aggregates") - else: - aggregates_list = r.json().get('aggregates', []) - for agg in aggregates_list: - nova_aggregates[agg['name']] = { - 'id': agg['id'], - 'hosts': [h.split('.')[0] for h in agg['hosts']], - 'metrics': {'free_vcpus': 0}, - } - nova_aggregates[agg['name']]['metrics'].update( - {v: 0 for v in self.VALUE_MAP.values()} - ) - - r = self.get('nova', 'os-hypervisors/detail') - if not r: - self.logger.warning("Could not get hypervisor statistics") - return - - total_stats = {v: 0 for v in self.VALUE_MAP.values()} - total_stats['free_vcpus'] = 0 - hypervisor_stats = r.json().get('hypervisors', []) - for stats in hypervisor_stats: - # remove domain name and keep only the hostname portion - host = stats['hypervisor_hostname'].split('.')[0] - for k, v in self.VALUE_MAP.iteritems(): - m_val = stats.get(k, 0) - yield { - 'type_instance': v, - 'values': m_val, - 'meta': {'host': host}, - } - total_stats[v] += m_val - for agg in nova_aggregates.keys(): - agg_hosts = nova_aggregates[agg]['hosts'] - if host in agg_hosts: - nova_aggregates[agg]['metrics'][v] += m_val - if 'cpu_ratio' in self.extra_config: - m_vcpus = stats.get('vcpus', 0) - m_vcpus_used = stats.get('vcpus_used', 0) - free = (int(self.extra_config['cpu_ratio'] * - m_vcpus)) - m_vcpus_used - yield { - 'type_instance': 'free_vcpus', - 'values': free, - 'meta': {'host': host}, - } - total_stats['free_vcpus'] += free - for agg in nova_aggregates.keys(): - agg_hosts = nova_aggregates[agg]['hosts'] - if host in agg_hosts: - free = ((int(self.extra_config['cpu_ratio'] * - m_vcpus)) - - m_vcpus_used) - nova_aggregates[agg]['metrics']['free_vcpus'] += free - - # Dispatch the aggregate metrics - for agg in nova_aggregates.keys(): - agg_id = nova_aggregates[agg]['id'] - agg_total_free_ram = ( - nova_aggregates[agg]['metrics']['free_ram_MB'] + - nova_aggregates[agg]['metrics']['used_ram_MB'] - ) - # Only emit metric when value is > 0 - # If this is not the case, (for instance when no host - # in aggregate), this requires the corresponding alarms to - # have a 'skip' no_data_policy, so as not to be triggered - if agg_total_free_ram > 0: - nova_aggregates[agg]['metrics']['free_ram_percent'] = round( - (100.0 * nova_aggregates[agg]['metrics']['free_ram_MB']) / - agg_total_free_ram, - 2) - for k, v in nova_aggregates[agg]['metrics'].iteritems(): - yield { - 'type_instance': 'aggregate_{}'.format(k), - 'values': v, - 'meta': { - 'aggregate': agg, - 'aggregate_id': agg_id, - } - } - # Dispatch the global metrics - for k, v in total_stats.iteritems(): - yield { - 'type_instance': 'total_{}'.format(k), - 'values': v, - } - -plugin = HypervisorStatsPlugin(collectd, PLUGIN_NAME, - disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/influxdb.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/influxdb.py deleted file mode 100644 index 4b7426b01..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/influxdb.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/python -# Copyright 2016 Mirantis, Inc. -# -# 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. - -import collectd -import requests - -import collectd_base as base - -NAME = 'influxdb' -METRICS_BY_NAME = { - 'cluster': { - 'writeShardPointsReq': ('cluster_write_shard_points_requests', - 'gauge'), - 'writeShardReq': ('cluster_write_shard_requests', 'gauge')}, - - 'httpd': { - 'authFail': ('httpd_failed_auths', 'gauge'), - 'pingReq': ('httpd_ping_requests', 'gauge'), - 'pointsWrittenOK': ('httpd_write_points_ok', 'gauge'), - 'queryReq': ('httpd_query_requests', 'gauge'), - 'queryRespBytes': ('httpd_query_response_bytes', 'gauge'), - 'req': ('httpd_requests', 'gauge'), - 'writeReq': ('httpd_write_requests', 'gauge'), - 'writeReqBytes': ('httpd_write_request_bytes', 'gauge')}, - - 'write': { - 'pointReq': ('write_point_requests', 'gauge'), - 'pointReqLocal': ('write_point_local_requests', 'gauge'), - 'pointReqRemote': ('write_point_remote_requests', 'gauge'), - 'req': ('write_requests', 'gauge'), - 'subWriteOk': ('write_sub_ok', 'gauge'), - 'writeOk': ('write_ok', 'gauge')}, - - 'runtime': { - 'Alloc': ('memory_alloc', 'gauge'), - 'TotalAlloc': ('memory_total_alloc', 'gauge'), - 'Sys': ('memory_system', 'gauge'), - 'Lookups': ('memory_lookups', 'gauge'), - 'Mallocs': ('memory_mallocs', 'gauge'), - 'Frees': ('memory_frees', 'gauge'), - 'HeapIdle': ('heap_idle', 'gauge'), - 'HeapInUse': ('heap_in_use', 'gauge'), - 'HeapObjects': ('heap_objects', 'gauge'), - 'HeapReleased': ('heap_released', 'gauge'), - 'HeapSys': ('heap_system', 'gauge'), - 'NumGC': ('garbage_collections', 'gauge'), - 'NumGoroutine': ('go_routines', 'gauge')} -} - - -class InfluxDBClusterPlugin(base.Base): - def __init__(self, *args, **kwargs): - super(InfluxDBClusterPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.session = requests.Session() - self.address = "localhost" - self.port = "8086" - self.session.mount( - 'http://', - requests.adapters.HTTPAdapter(max_retries=3) - ) - - def config_callback(self, conf): - super(InfluxDBClusterPlugin, self).config_callback(conf) - - for node in conf.children: - if node.key == 'Username': - username = node.values[0] - elif node.key == 'Password': - password = node.values[0] - elif node.key == 'Address': - self.address = node.values[0] - elif node.key == 'Port': - self.port = node.values[0] - - if username is None or password is None: - self.logger.error("Username and Password parameters are required") - else: - self.session.auth = (username, password) - - def itermetrics(self): - - payload = {'q': 'show stats'} - url = "http://{}:{}/query".format(self.address, self.port) - - try: - r = self.session.get(url, params=payload) - except Exception as e: - msg = "Got {0} when getting stats from {1}".format(e, url) - raise base.CheckException(msg) - - if r.status_code != 200: - msg = "Got response {0} from {0}".format(r.status_code, url) - raise base.CheckException(msg) - - data = r.json() - try: - series_list = data['results'][0]['series'] - except: - self.logger.error("Failed to retrieve series for InfluxDB cluster") - return - - for serie in series_list: - metrics_list = METRICS_BY_NAME.get(serie['name'], None) - if not metrics_list: - continue - for i in range(len(serie['columns'])): - metric_name = serie['columns'][i] - if metric_name in metrics_list: - yield { - 'type_instance': metrics_list[metric_name][0], - 'type': metrics_list[metric_name][1], - 'values': [serie['values'][0][i]], - } - - -plugin = InfluxDBClusterPlugin(collectd) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_cinder.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_cinder.py deleted file mode 100644 index 38ebab4bd..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_cinder.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting statistics from Cinder -import collectd - -import collectd_openstack as openstack - -PLUGIN_NAME = 'cinder' -INTERVAL = openstack.INTERVAL - - -class CinderStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Cinder objects. - - number of volumes broken down by state - total size of volumes usable and in error state - """ - - def __init__(self, *args, **kwargs): - super(CinderStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - self.pagination_limit = 500 - - def itermetrics(self): - - volumes_details = self.get_objects('cinderv2', 'volumes', - params={'all_tenants': 1}, - detail=True) - - def groupby(d): - return d.get('status', 'unknown').lower() - - def count_size_bytes(d): - return d.get('size', 0) * 10 ** 9 - - status = self.count_objects_group_by(volumes_details, - group_by_func=groupby) - for s, nb in status.iteritems(): - yield { - 'plugin_instance': 'volumes', - 'type_instance': s, - 'values': nb - } - - sizes = self.count_objects_group_by(volumes_details, - group_by_func=groupby, - count_func=count_size_bytes) - for n, size in sizes.iteritems(): - yield { - 'plugin_instance': 'volumes_size', - 'type_instance': n, - 'values': size - } - - snaps_details = self.get_objects('cinderv2', 'snapshots', - params={'all_tenants': 1}) - status_snaps = self.count_objects_group_by(snaps_details, - group_by_func=groupby) - for s, nb in status_snaps.iteritems(): - yield { - 'plugin_instance': 'snapshots', - 'type_instance': s, - 'values': nb - } - - sizes = self.count_objects_group_by(snaps_details, - group_by_func=groupby, - count_func=count_size_bytes) - for n, size in sizes.iteritems(): - yield { - 'plugin_instance': 'snapshots_size', - 'type_instance': n, - 'values': size - } - - -plugin = CinderStatsPlugin(collectd, PLUGIN_NAME, disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_cinder_services.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_cinder_services.py deleted file mode 100644 index 56d5ad7b7..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_cinder_services.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/python -# Copyright 2017 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting statistics from Cinder -import collectd -from collections import Counter -from collections import defaultdict -import re - -import collectd_openstack as openstack - -PLUGIN_NAME = 'cinder' -INTERVAL = openstack.INTERVAL - - -class CinderServiceStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Cinder services. - - state of workers broken down by state - """ - - states = {'up': 0, 'down': 1, 'disabled': 2} - cinder_re = re.compile('^cinder-') - - def __init__(self, *args, **kwargs): - super(CinderServiceStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - - def itermetrics(self): - - # Get information of the state per service - # State can be: 'up', 'down' or 'disabled' - aggregated_workers = defaultdict(Counter) - - for worker in self.iter_workers('cinder'): - host = worker['host'].split('.')[0] - service = self.cinder_re.sub('', worker['service']) - state = worker['state'] - - aggregated_workers[service][state] += 1 - yield { - 'plugin_instance': 'cinder_service', - 'values': self.states[state], - 'meta': {'host': host, 'service': service, 'state': state}, - } - - for service in aggregated_workers: - totalw = sum(aggregated_workers[service].values()) - - for state in self.states: - prct = (100.0 * aggregated_workers[service][state]) / totalw - yield { - 'plugin_instance': 'cinder_services_percent', - 'values': prct, - 'meta': {'state': state, 'service': service} - } - yield { - 'plugin_instance': 'cinder_services', - 'values': aggregated_workers[service][state], - 'meta': {'state': state, 'service': service}, - } - - -plugin = CinderServiceStatsPlugin(collectd, PLUGIN_NAME, - disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_glance.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_glance.py deleted file mode 100644 index 4886967dc..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_glance.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting resource statistics from Glance -import collectd - -import collectd_openstack as openstack - -PLUGIN_NAME = 'glance' -INTERVAL = openstack.INTERVAL - - -class GlanceStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Glance service. - - number of image broken down by state - total size of images usable and in error state - """ - - def __init__(self, *args, **kwargs): - super(GlanceStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - self.pagination_limit = 25 - - def itermetrics(self): - - def is_snap(d): - return d.get('image_type') == 'snapshot' - - def groupby(d): - p = d['visibility'] - status = d.get('status', 'unknown').lower() - if is_snap(d): - return 'snapshots.%s.%s' % (p, status) - return 'images.%s.%s' % (p, status) - - images_details = self.get_objects('glance', 'images', - api_version='v2', - params={}, - detail=False) - status = self.count_objects_group_by(images_details, - group_by_func=groupby) - for s, nb in status.iteritems(): - (name, visibility, status) = s.split('.') - yield { - 'type_instance': name, - 'values': nb, - 'meta': {'visibility': visibility, 'status': status} - } - - # sizes - def count_size_bytes(d): - return d.get('size', 0) - - def groupby_size(d): - p = d['visibility'] - status = d.get('status', 'unknown').lower() - if is_snap(d): - return 'snapshots_size.%s.%s' % (p, status) - return 'images_size.%s.%s' % (p, status) - - sizes = self.count_objects_group_by(images_details, - group_by_func=groupby_size, - count_func=count_size_bytes) - for s, nb in sizes.iteritems(): - (name, visibility, status) = s.split('.') - yield { - 'type_instance': name, - 'values': nb, - 'meta': {'visibility': visibility, 'status': status}, - } - -plugin = GlanceStatsPlugin(collectd, PLUGIN_NAME, disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_keystone.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_keystone.py deleted file mode 100644 index cbd4e4d8e..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_keystone.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting statistics from Keystone -import collectd - -import collectd_openstack as openstack - -PLUGIN_NAME = 'keystone' -INTERVAL = openstack.INTERVAL - - -class KeystoneStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Keystone service. - - number of tenants, users broken down by state - number of roles - """ - - def __init__(self, *args, **kwargs): - super(KeystoneStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - - def itermetrics(self): - - def groupby(d): - return 'enabled' if d.get('enabled') else 'disabled' - - # tenants - r = self.get('keystone', 'projects') - if not r: - self.logger.warning('Could not find Keystone tenants') - return - tenants_details = r.json().get('projects', []) - status = self.count_objects_group_by(tenants_details, - group_by_func=groupby) - for s, nb in status.iteritems(): - yield { - 'type_instance': 'tenants', - 'values': nb, - 'meta': {'state': s}, - } - - # users - r = self.get('keystone', 'users') - if not r: - self.logger.warning('Could not find Keystone users') - return - users_details = r.json().get('users', []) - status = self.count_objects_group_by(users_details, - group_by_func=groupby) - for s, nb in status.iteritems(): - yield { - 'type_instance': 'users', - 'values': nb, - 'meta': {'state': s}, - } - - # roles - r = self.get('keystone', 'roles') - if not r: - self.logger.warning('Could not find Keystone roles') - return - roles = r.json().get('roles', []) - yield { - 'type_instance': 'roles', - 'values': len(roles), - } - -plugin = KeystoneStatsPlugin(collectd, PLUGIN_NAME, - disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron.py deleted file mode 100644 index a9ccff02f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting resource statistics from Neutron -import collectd - -import collectd_openstack as openstack - -PLUGIN_NAME = 'neutron' -INTERVAL = openstack.INTERVAL - - -class NeutronStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Neutron objects. - - number of networks broken down by status - number of subnets - number of ports broken down by owner and status - number of routers broken down by status - number of floating IP addresses broken down by free/associated - """ - - def __init__(self, *args, **kwargs): - super(NeutronStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - self.pagination_limit = 100 - - def itermetrics(self): - - def groupby_network(x): - return "networks.%s" % x.get('status', 'unknown').lower() - - def groupby_router(x): - return "routers.%s" % x.get('status', 'unknown').lower() - - def groupby_port(x): - owner = x.get('device_owner', 'none') - if owner.startswith('network:'): - owner = owner.replace('network:', '') - elif owner.startswith('compute:'): - # The part after 'compute:' is the name of the Nova AZ - owner = 'compute' - else: - owner = 'none' - status = x.get('status', 'unknown').lower() - return "ports.%s.%s" % (owner, status) - - def groupby_floating(x): - if x.get('port_id', None): - status = 'associated' - else: - status = 'free' - return "floatingips.%s" % status - - # Networks - networks = self.get_objects('neutron', 'networks', api_version='v2.0', - params={'fields': ['id', 'status']}) - status = self.count_objects_group_by(networks, - group_by_func=groupby_network) - for s, nb in status.iteritems(): - yield {'type_instance': s, 'values': nb} - yield {'type_instance': 'networks', 'values': len(networks)} - - # Subnets - subnets = self.get_objects('neutron', 'subnets', api_version='v2.0', - params={'fields': ['id', 'status']}) - yield {'type_instance': 'subnets', 'values': len(subnets)} - - # Ports - ports = self.get_objects('neutron', 'ports', api_version='v2.0', - params={'fields': ['id', 'status', - 'device_owner']}) - status = self.count_objects_group_by(ports, - group_by_func=groupby_port) - for s, nb in status.iteritems(): - yield {'type_instance': s, 'values': nb} - yield {'type_instance': 'ports', 'values': len(ports)} - - # Routers - routers = self.get_objects('neutron', 'routers', api_version='v2.0', - params={'fields': ['id', 'status']}) - status = self.count_objects_group_by(routers, - group_by_func=groupby_router) - for s, nb in status.iteritems(): - yield {'type_instance': s, 'values': nb} - yield {'type_instance': 'routers', 'values': len(routers)} - - # Floating IP addresses - floatingips = self.get_objects('neutron', 'floatingips', - api_version='v2.0', - params={'fields': ['id', 'status', - 'port_id']}) - status = self.count_objects_group_by(floatingips, - group_by_func=groupby_floating) - for s, nb in status.iteritems(): - yield {'type_instance': s, 'values': nb} - yield {'type_instance': 'floatingips', 'values': len(routers)} - - -plugin = NeutronStatsPlugin(collectd, PLUGIN_NAME, disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron_agents.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron_agents.py deleted file mode 100644 index 3ae5ed750..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron_agents.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting resource statistics from Neutron -import collectd -from collections import Counter -from collections import defaultdict -import re - -import collectd_openstack as openstack - -PLUGIN_NAME = 'neutron' -INTERVAL = openstack.INTERVAL - - -class NeutronAgentStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Neutron agents. - - state of agents - """ - - neutron_re = re.compile('^neutron-') - agent_re = re.compile('-agent$') - states = {'up': 0, 'down': 1, 'disabled': 2} - - def __init__(self, *args, **kwargs): - super(NeutronAgentStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - - def itermetrics(self): - - # Get information of the state per agent - # State can be up or down - aggregated_agents = defaultdict(Counter) - - for agent in self.iter_workers('neutron'): - host = agent['host'].split('.')[0] - service = self.agent_re.sub( - '', self.neutron_re.sub('', agent['service'])) - state = agent['state'] - - aggregated_agents[service][state] += 1 - - yield { - 'type_instance': 'neutron_agent', - 'values': self.states[state], - 'meta': {'host': host, 'service': service, 'state': state} - } - - for service in aggregated_agents: - totala = sum(aggregated_agents[service].values()) - - for state in self.states: - prct = (100.0 * aggregated_agents[service][state]) / totala - yield { - 'type_instance': 'neutron_agents_percent', - 'values': prct, - 'meta': {'service': service, 'state': state}, - } - yield { - 'type_instance': 'neutron_agents', - 'values': aggregated_agents[service][state], - 'meta': {'service': service, 'state': state}, - } - - -plugin = NeutronAgentStatsPlugin(collectd, PLUGIN_NAME, - disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_nova.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_nova.py deleted file mode 100644 index 084e7b1c4..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_nova.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting statistics from Nova -import collectd - -import collectd_openstack as openstack -from itertools import groupby - - -PLUGIN_NAME = 'nova' -INTERVAL = openstack.INTERVAL - - -class NovaInstanceStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Nova instances. - - Number of instances broken down by state - """ - def __init__(self, *args, **kwargs): - super(NovaInstanceStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - self.pagination_limit = 500 - self._cache = {} - - def itermetrics(self): - server_details = self.get_objects('nova', 'servers', - params={'all_tenants': 1}, - detail=True, since=True) - - for server in server_details: - _id = server.get('id') - status = server.get('status', 'unknown').lower() - if status == 'deleted': - try: - self.logger.debug( - 'remove deleted instance {} from cache'.format(_id)) - del self._cache[_id] - except KeyError: - self.logger.warning( - 'cannot find instance in cache {}'.format(_id)) - else: - self._cache[_id] = status - - servers = sorted(self._cache.values()) - for status, g in groupby(servers): - yield { - 'plugin_instance': 'instances', - 'values': len(list(g)), - 'type_instance': status, - } - - -plugin = NovaInstanceStatsPlugin(collectd, PLUGIN_NAME, - disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_nova_services.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_nova_services.py deleted file mode 100644 index c9f84eb58..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_nova_services.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/python -# Copyright 2017 Mirantis, Inc. -# -# 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. -# -# Collectd plugin for getting statistics from Nova -import collectd -from collections import Counter -from collections import defaultdict -import re - -import collectd_openstack as openstack - -PLUGIN_NAME = 'nova' -INTERVAL = openstack.INTERVAL - - -class NovaServiceStatsPlugin(openstack.CollectdPlugin): - """ Class to report the statistics on Nova services. - - status per service broken down by state - """ - - states = {'up': 0, 'down': 1, 'disabled': 2} - nova_re = re.compile('^nova-') - - def __init__(self, *args, **kwargs): - super(NovaServiceStatsPlugin, self).__init__(*args, **kwargs) - self.plugin = PLUGIN_NAME - self.interval = INTERVAL - - def itermetrics(self): - - # Get information of the state per service - # State can be: 'up', 'down' or 'disabled' - aggregated_workers = defaultdict(Counter) - - for worker in self.iter_workers('nova'): - host = worker['host'].split('.')[0] - service = self.nova_re.sub('', worker['service']) - state = worker['state'] - - aggregated_workers[service][state] += 1 - yield { - 'plugin_instance': 'nova_service', - 'values': self.states[state], - 'meta': {'host': host, 'service': service, 'state': state} - } - - for service in set(aggregated_workers.keys()).union( - ('compute', 'scheduler', 'conductor', 'cert', 'consoleauth')): - - total = sum(aggregated_workers[service].values()) - - for state in self.states: - prct = 0 - if total > 0: - prct = (100.0 * aggregated_workers[service][state]) / total - - yield { - 'plugin_instance': 'nova_services_percent', - 'values': prct, - 'meta': {'state': state, 'service': service}, - } - yield { - 'plugin_instance': 'nova_services', - 'values': aggregated_workers[service][state], - 'meta': {'state': state, 'service': service}, - } - - -plugin = NovaServiceStatsPlugin(collectd, PLUGIN_NAME, - disable_check_metric=True) - - -def config_callback(conf): - plugin.config_callback(conf) - - -def notification_callback(notification): - plugin.notification_callback(notification) - - -def read_callback(): - plugin.conditional_read_callback() - -collectd.register_config(config_callback) -collectd.register_notification(notification_callback) -collectd.register_read(read_callback, INTERVAL) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/rabbitmq_info.py b/deployment_scripts/puppet/modules/lma_collector/files/collectd/rabbitmq_info.py deleted file mode 100644 index d78b6cb4a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/rabbitmq_info.py +++ /dev/null @@ -1,133 +0,0 @@ -# Name: rabbitmq-collectd-plugin - rabbitmq_info.py -# Description: This plugin uses Collectd's Python plugin to obtain RabbitMQ -# metrics. -# -# Copyright 2015 Mirantis, Inc. -# -# 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. - -import collectd - -import collectd_base as base -import requests - -NAME = 'rabbitmq_info' -# Override in config by specifying 'Host'. -HOST = '127.0.0.1' -# Override in config by specifying 'Port'. -PORT = '15672' - - -class RabbitMqPlugin(base.Base): - - def __init__(self, *args, **kwargs): - super(RabbitMqPlugin, self).__init__(*args, **kwargs) - self.plugin = NAME - self.username = None - self.password = None - self.host = HOST - self.port = PORT - self.session = None - - def config_callback(self, conf): - super(RabbitMqPlugin, self).config_callback(conf) - - for node in conf.children: - if node.key == 'Username': - self.username = node.values[0] - if node.key == 'Password': - self.password = node.values[0] - if node.key == 'Host': - self.host = node.values[0] - if node.key == 'Port': - self.port = node.values[0] - - if not (self.username and self.password): - self.logger.error('Missing Username and Password parameters') - - self.session = requests.Session() - self.session.auth = (self.username, self.password) - self.session.mount( - 'http://', - requests.adapters.HTTPAdapter(max_retries=self.max_retries) - ) - url = "http://{}:{}".format(self.host, self.port) - self.api_nodes_url = "{}/api/nodes".format(url) - self.api_overview_url = "{}/api/overview".format(url) - - def itermetrics(self): - stats = {} - try: - r = self.session.get(self.api_overview_url, timeout=self.timeout) - overview = r.json() - except Exception as e: - msg = "Got exception for '{}': {}".format(self.api_overview_url, e) - raise base.CheckException(msg) - - if r.status_code != 200: - msg = "{} responded with code {}".format( - self.api_overview_url, r.status_code) - raise base.CheckException(msg) - - objects = overview.get('object_totals', {}) - stats['queues'] = objects.get('queues', 0) - stats['consumers'] = objects.get('consumers', 0) - stats['connections'] = objects.get('connections', 0) - stats['exchanges'] = objects.get('exchanges', 0) - stats['channels'] = objects.get('channels', 0) - stats['messages'] = overview.get('queue_totals', {}).get('messages', 0) - stats['running_nodes'] = len(overview.get('contexts', [])) - - for k, v in stats.iteritems(): - yield {'type_instance': k, 'values': v} - - stats = {} - nodename = overview['node'] - try: - r = self.session.get("{}/{}".format(self.api_nodes_url, nodename), - timeout=self.timeout) - node = r.json() - except Exception as e: - msg = "Got exception for '{}': {}".format(self.api_nodes_url, e) - raise base.CheckException(msg) - - if r.status_code != 200: - msg = "{} responded with code {}".format( - self.api_nodes_url, r.status_code) - self.logger.error(msg) - raise base.CheckException(msg) - - stats['disk_free_limit'] = node['disk_free_limit'] - stats['disk_free'] = node['disk_free'] - stats['remaining_disk'] = node['disk_free'] - node['disk_free_limit'] - - stats['used_memory'] = node['mem_used'] - stats['vm_memory_limit'] = node['mem_limit'] - stats['remaining_memory'] = node['mem_limit'] - node['mem_used'] - - for k, v in stats.iteritems(): - yield {'type_instance': k, 'values': v} - - -plugin = RabbitMqPlugin(collectd, 'rabbitmq') - - -def config_callback(conf): - plugin.config_callback(conf) - - -def read_callback(): - plugin.read_callback() - -collectd.register_config(config_callback) -collectd.register_read(read_callback) diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/types/ceph.db b/deployment_scripts/puppet/modules/lma_collector/files/collectd/types/ceph.db deleted file mode 100644 index 24ee88a4c..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/types/ceph.db +++ /dev/null @@ -1,46 +0,0 @@ -# For all types, plugin_instance contains the Ceph cluster name - -# cluster health metrics -health value:GAUGE:1:3 -monitor_count value:GAUGE:0:U -quorum_count value:GAUGE:0:U -# number of placement groups per state, type_instance is the PG's state -pg_state_count value:GAUGE:0:U -# total number of objects -objects_count value:GAUGE:0:U -# total number of placement groups -pg_count value:GAUGE:0:U -# used, free and total amount of bytes -pg_bytes used:GAUGE:0:U free:GAUGE:0:U total:GAUGE:0:U -# amount of data bytes -pg_data_bytes value:GAUGE:0:U - -# number of bytes used in the pool, type_instance is the pool name -pool_bytes_used value:GAUGE:0:U -# max number of bytes available in the pool, type_instance is the pool name -pool_max_avail value:GAUGE:0:U -# number of objects in the pool, type_instance is the pool name -pool_objects value:GAUGE:0:U -# number of pools -pool_count value:GAUGE:0:U -# used, free and total amount of bytes for all pools -pool_total_bytes used:GAUGE:0:U free:GAUGE:0:U total:GAUGE:0:U -# percentage of used, free and total space for all pools -pool_total_percent used:GAUGE:0:101 free:GAUGE:0:101 -# number of bytes received and transmitted by second, type_instance is the pool name -pool_bytes_rate rx:GAUGE:0:U tx:GAUGE:0:U -# number of operations per second, type_instance is the pool name -pool_ops_rate value:GAUGE:0:U -# number of objects, type_instance is the pool name -pool_pg_num value:GAUGE:0:U -# number of placement groups, type_instance is the pool name -pool_pg_placement_num value:GAUGE:0:U -# size of the pool, type_instance is the pool name -pool_size value:GAUGE:0:U - -# number of OSDs per state -osd_count up:GAUGE:0:U down:GAUGE:0:U in:GAUGE:0:U out:GAUGE:0:U -# amount of used and total space in bytes, type_instance is the OSD identifier -osd_space used:GAUGE:0:U total:GAUGE:0:U -# apply and commit latencies in milliseconds, type_instance is the OSD identifier -osd_latency apply:GAUGE:0:U commit:GAUGE:0:U diff --git a/deployment_scripts/puppet/modules/lma_collector/files/collectd/types/ceph_perf.db b/deployment_scripts/puppet/modules/lma_collector/files/collectd/types/ceph_perf.db deleted file mode 100644 index c557bb0c3..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/collectd/types/ceph_perf.db +++ /dev/null @@ -1,74 +0,0 @@ -# File generated automatically by the build_ceph_perf_types.py script -# Ceph versions: 0.80.9, 0.94.5 -osd_agent_evict value:GAUGE:U:U -osd_agent_flush value:GAUGE:U:U -osd_agent_skip value:GAUGE:U:U -osd_agent_wake value:GAUGE:U:U -osd_buffer_bytes value:GAUGE:U:U -osd_copyfrom value:GAUGE:U:U -osd_heartbeat_from_peers value:GAUGE:U:U -osd_heartbeat_to_peers value:GAUGE:U:U -osd_loadavg value:GAUGE:U:U -osd_map_message_epoch_dups value:GAUGE:U:U -osd_map_message_epochs value:GAUGE:U:U -osd_map_messages value:GAUGE:U:U -osd_messages_delayed_for_map value:GAUGE:U:U -osd_numpg value:GAUGE:U:U -osd_numpg_primary value:GAUGE:U:U -osd_numpg_replica value:GAUGE:U:U -osd_numpg_stray value:GAUGE:U:U -osd_object_ctx_cache_hit value:GAUGE:U:U -osd_object_ctx_cache_total value:GAUGE:U:U -osd_op value:GAUGE:U:U -osd_op_in_bytes value:GAUGE:U:U -osd_op_latency value:GAUGE:U:U -osd_op_out_bytes value:GAUGE:U:U -osd_op_process_latency value:GAUGE:U:U -osd_op_r value:GAUGE:U:U -osd_op_r_latency value:GAUGE:U:U -osd_op_r_out_bytes value:GAUGE:U:U -osd_op_r_process_latency value:GAUGE:U:U -osd_op_rw value:GAUGE:U:U -osd_op_rw_in_bytes value:GAUGE:U:U -osd_op_rw_latency value:GAUGE:U:U -osd_op_rw_out_bytes value:GAUGE:U:U -osd_op_rw_process_latency value:GAUGE:U:U -osd_op_rw_rlat value:GAUGE:U:U -osd_op_w value:GAUGE:U:U -osd_op_w_in_bytes value:GAUGE:U:U -osd_op_w_latency value:GAUGE:U:U -osd_op_w_process_latency value:GAUGE:U:U -osd_op_w_rlat value:GAUGE:U:U -osd_op_wip value:GAUGE:U:U -osd_opq value:GAUGE:U:U -osd_pull value:GAUGE:U:U -osd_push value:GAUGE:U:U -osd_push_in value:GAUGE:U:U -osd_push_in_bytes value:GAUGE:U:U -osd_push_out_bytes value:GAUGE:U:U -osd_recovery_ops value:GAUGE:U:U -osd_stat_bytes value:GAUGE:U:U -osd_stat_bytes_avail value:GAUGE:U:U -osd_stat_bytes_used value:GAUGE:U:U -osd_subop value:GAUGE:U:U -osd_subop_in_bytes value:GAUGE:U:U -osd_subop_latency value:GAUGE:U:U -osd_subop_pull value:GAUGE:U:U -osd_subop_pull_latency value:GAUGE:U:U -osd_subop_push value:GAUGE:U:U -osd_subop_push_in_bytes value:GAUGE:U:U -osd_subop_push_latency value:GAUGE:U:U -osd_subop_w value:GAUGE:U:U -osd_subop_w_in_bytes value:GAUGE:U:U -osd_subop_w_latency value:GAUGE:U:U -osd_tier_clean value:GAUGE:U:U -osd_tier_delay value:GAUGE:U:U -osd_tier_dirty value:GAUGE:U:U -osd_tier_evict value:GAUGE:U:U -osd_tier_flush value:GAUGE:U:U -osd_tier_flush_fail value:GAUGE:U:U -osd_tier_promote value:GAUGE:U:U -osd_tier_proxy_read value:GAUGE:U:U -osd_tier_try_flush value:GAUGE:U:U -osd_tier_try_flush_fail value:GAUGE:U:U -osd_tier_whiteout value:GAUGE:U:U diff --git a/deployment_scripts/puppet/modules/lma_collector/files/ocf-lma_collector b/deployment_scripts/puppet/modules/lma_collector/files/ocf-lma_collector deleted file mode 100755 index b7d9973e2..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/ocf-lma_collector +++ /dev/null @@ -1,337 +0,0 @@ -#!/bin/bash -# Copyright 2016 Mirantis, Inc. -# -# 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. -# -# See usage() function below for more details ... -# -# OCF instance parameters: -# OCF_RESKEY_binary -# OCF_RESKEY_config -# OCF_RESKEY_log_file -# OCF_RESKEY_user -# OCF_RESKEY_watchdog_file -# OCF_RESKEY_watchdog_timeout -####################################################################### -# Initialization: - -: "${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}" -. "${OCF_FUNCTIONS_DIR}/ocf-shellfuncs" - -####################################################################### - -# Fill in some defaults if no values are specified - -OCF_RESKEY_binary_default="/usr/bin/hekad" -OCF_RESKEY_user_default="root" -OCF_RESKEY_watchdog_file_default= -OCF_RESKEY_watchdog_timeout_default=20 - -: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} -: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} -: ${OCF_RESKEY_watchdog_file=${OCF_RESKEY_watchdog_file_default}} -: ${OCF_RESKEY_watchdog_timeout=${OCF_RESKEY_watchdog_timeout_default}} - -####################################################################### - -usage() { - cat < - - -1.0 - - -Manages the LMA collector daemon as a Pacemaker Resource. - -Manages Log or Metric collector - - - - -Name of the collector service. - -Collector service name - - - - - -Path of the LMA collector binary file that will be run. - -LMA collector binary file - - - - - -Path to the LMA collector configuration file or directory - -LMA collector configuration - - - - - -Path to the LMA collector log file - -LMA collector log file - - - - - -User running the LMA collector process - -LMA collector user - - - - - -The file to monitor that the process is up and running - -LMA collector watchdog file - - - - - -How much time the watchdog file can be left unmodified before claiming that -the process is unresponsive. - -LMA collector watchdog timeout - - - - - - - - - - - - - - -END -} - -####################################################################### -# Functions invoked by resource manager actions - -service_validate() { - local rc - - PID_FILE="${HA_RSCTMP}/${__SCRIPT_NAME}/${OCF_RESKEY_service_name}.pid" - - check_binary "$OCF_RESKEY_binary" - - if [[ ! -f $OCF_RESKEY_config && ! -d $OCF_RESKEY_config ]]; then - ocf_log err "Config $OCF_RESKEY_config doesn't exist" - return "$OCF_ERR_GENERIC" - fi - - getent passwd "$OCF_RESKEY_user" >/dev/null 2>&1 - rc=$? - if [ $rc -ne 0 ]; then - ocf_log err "User $OCF_RESKEY_user doesn't exist" - return "$OCF_ERR_GENERIC" - fi - - true -} - -service_status() { - local rc - local pid - - # check and make PID file dir - local PID_DIR - PID_DIR=$( dirname "${PID_FILE}" ) - if [ ! -d "${PID_DIR}" ] ; then - ocf_log debug "Create pid file dir: ${PID_DIR} and chown to ${OCF_RESKEY_user}" - mkdir -p "${PID_DIR}" - chown -R "${OCF_RESKEY_user}" "${PID_DIR}" - chmod 755 "${PID_DIR}" - fi - - if [ ! -f "$PID_FILE" ]; then - ocf_log info "LMA collector is not running" - return "$OCF_NOT_RUNNING" - else - pid=$(cat "$PID_FILE") - fi - - if [ -n "${pid}" ]; then - ocf_run -warn kill -s 0 "$pid" - rc=$? - if [ $rc -ne 0 ]; then - ocf_log info "Old PID file found, but LMA collector process isn't running" - return "$OCF_NOT_RUNNING" - fi - else - ocf_log err "PID file ${PID_FILE} is empty!" - return "$OCF_ERR_GENERIC" - fi - - if [ ! -z "$OCF_RESKEY_watchdog_file" ]; then - if [ ! -f "$OCF_RESKEY_watchdog_file" ]; then - ocf_log info "${OCF_RESKEY_watchdog_file} is missing" - return "$OCF_NOT_RUNNING" - else - now=$(date '+%s') - last_access=$(stat -c %Y "${OCF_RESKEY_watchdog_file}") - if [ $(( now - last_access )) -gt "${OCF_RESKEY_watchdog_timeout}" ]; then - ocf_log err "File ${OCF_RESKEY_watchdog_file} not modified since ${OCF_RESKEY_watchdog_timeout} seconds" - return "$OCF_NOT_RUNNING" - fi - fi - else - ocf_log debug "Skip watchdog check since watchdog_file parameter is not set" - fi - - return "$OCF_SUCCESS" -} - -service_monitor() { - local rc - service_status - rc=$? - return $rc -} - -service_start() { - local rc - - service_monitor - rc=$? - if [ $rc -eq "$OCF_SUCCESS" ]; then - ocf_log info "${OCF_RESKEY_service_name} is already running" - return "$OCF_SUCCESS" - fi - - # See https://bugs.launchpad.net/lma-toolchain/+bug/1543289 - ulimit -n 102400 - - su "${OCF_RESKEY_user}" -s /bin/sh -c "${OCF_RESKEY_binary} \ --config=${OCF_RESKEY_config} >> $OCF_RESKEY_log_file 2>&1"' & echo $!' > "$PID_FILE" - - # Spin waiting for the server to come up - while true; do - service_monitor - rc=$? - [ $rc -eq "$OCF_SUCCESS" ] && break - if [ $rc -ne "$OCF_NOT_RUNNING" ]; then - ocf_log err "${OCF_RESKEY_service_name} start failed" - exit "$OCF_ERR_GENERIC" - fi - sleep 3 - done - - ocf_log info "${OCF_RESKEY_service_name} started" - return "$OCF_SUCCESS" -} - -service_stop() { - local rc - local pid - - service_monitor - rc=$? - if [ $rc -eq "$OCF_NOT_RUNNING" ]; then - ocf_log info "${OCF_RESKEY_service_name} is already stopped" - return "$OCF_SUCCESS" - fi - - # Try SIGTERM - pid=$(cat "$PID_FILE") - ocf_run kill -s TERM "$pid" - rc=$? - if [ $rc -ne 0 ]; then - ocf_log err "${OCF_RESKEY_service_name} couldn't be stopped" - exit "$OCF_ERR_GENERIC" - fi - - # stop waiting - shutdown_timeout=15 - if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then - shutdown_timeout=$(( (OCF_RESKEY_CRM_meta_timeout/1000)-5 )) - fi - count=0 - while [ $count -lt $shutdown_timeout ]; do - service_monitor - rc=$? - if [ $rc -eq "$OCF_NOT_RUNNING" ]; then - break - fi - count=$(( count + 1)) - sleep 1 - ocf_log debug "${OCF_RESKEY_service_name} still hasn't stopped yet. Waiting ..." - done - - service_monitor - rc=$? - if [ "${rc}" -ne "${OCF_NOT_RUNNING}" ]; then - # SIGTERM didn't help either, try SIGKILL - ocf_log info "${OCF_RESKEY_service_name} failed to stop after ${shutdown_timeout}s using SIGTERM. Trying SIGKILL ..." - ocf_run kill -s KILL "${pid}" - fi - - ocf_log info "${OCF_RESKEY_service_name} stopped" - - ocf_log debug "Delete pid file: ${PID_FILE} with content $(cat "${PID_FILE}")" - rm -f "${PID_FILE}" - - return "${OCF_SUCCESS}" -} - -####################################################################### - -case "$1" in - meta-data) meta_data - exit "$OCF_SUCCESS";; - usage|help) usage - exit "$OCF_SUCCESS";; -esac - -# Anything except meta-data and help must pass validation -service_validate || exit $? - -# What kind of method was invoked? -case "$1" in - start) service_start;; - stop) service_stop;; - status) service_status;; - monitor) service_monitor;; - validate-all) ;; - *) usage - exit "$OCF_ERR_UNIMPLEMENTED";; -esac diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/accumulator.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/accumulator.lua deleted file mode 100644 index 9b01a8fc2..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/accumulator.lua +++ /dev/null @@ -1,63 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. -local time = os.time -local string = string -local table = table -local setmetatable = setmetatable -local ipairs = ipairs -local pairs = pairs -local tostring = tostring -local type = type - -local Accumulator = {} -Accumulator.__index = Accumulator - -setfenv(1, Accumulator) -- Remove external access to contain everything in the module - --- Create a new Accumulator --- --- flush_count: the maximum number of items to accumulate before flushing --- flush_interval: the maximum number of seconds to wait before flushing --- callback: the function to call back when flushing the accumulator, it will --- receive the table of accumulated items as parameter. -function Accumulator.new(flush_count, flush_interval, callback) - local a = {} - setmetatable(a, Accumulator) - a.flush_count = flush_count - a.flush_interval = flush_interval - a.flush_cb = callback - a.last_flush = time() * 1e9 - a.buffer = {} - return a -end - --- Flush the buffer if flush_count or flush_interval are met --- --- ns: the current timestamp in nanosecond (optional) -function Accumulator:flush(ns) - local now = ns or time() * 1e9 - if #self.buffer > self.flush_count or now - self.last_flush > self.flush_interval then - self.flush_cb(self.buffer) - self.buffer = {} - self.last_flush = now - end -end - --- Append an item to the buffer and flush the buffer if needed -function Accumulator:append(item) - self.buffer[#self.buffer+1] = item - self:flush() -end - -return Accumulator diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd.lua deleted file mode 100644 index 9e864df58..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd.lua +++ /dev/null @@ -1,185 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local cjson = require 'cjson' -local string = require 'string' - -local lma = require 'lma_utils' -local consts = require 'gse_constants' - -local read_message = read_message -local assert = assert -local ipairs = ipairs -local pairs = pairs -local pcall = pcall -local table = table - -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - -function get_entity_name(field) - return read_message(string.format('Fields[%s]', field)) -end - -function get_status() - return read_message('Fields[value]') -end - -function extract_alarms() - local ok, payload = pcall(cjson.decode, read_message('Payload')) - if not ok or not payload.alarms then - return nil - end - return payload.alarms -end - --- return a human-readable message from an alarm table --- for instance: "CPU load too high (WARNING, rule='last(load_midterm)>=5', current=7)" -function get_alarm_for_human(alarm) - local metric - local fields = {} - for name, value in pairs(alarm.fields) do - fields[#fields+1] = name .. '="' .. value .. '"' - end - if #fields > 0 then - metric = string.format('%s[%s]', alarm.metric, table.concat(fields, ',')) - else - metric = alarm.metric - end - - local host = '' - if alarm.hostname then - host = string.format(', host=%s', alarm.hostname) - end - - return string.format( - "%s (%s, rule='%s(%s)%s%s', current=%.2f%s)", - alarm.message, - alarm.severity, - alarm['function'], - metric, - alarm.operator, - alarm.threshold, - alarm.value, - host - ) -end - -function alarms_for_human(alarms) - local alarm_messages = {} - local hint_messages = {} - - for _, v in ipairs(alarms) do - if v.tags and v.tags.dependency_level and v.tags.dependency_level == 'hint' then - hint_messages[#hint_messages+1] = get_alarm_for_human(v) - else - alarm_messages[#alarm_messages+1] = get_alarm_for_human(v) - end - end - - if #hint_messages > 0 then - alarm_messages[#alarm_messages+1] = "Other related alarms:" - end - for _, v in ipairs(hint_messages) do - alarm_messages[#alarm_messages+1] = v - end - - return alarm_messages -end - -local alarms = {} - --- append an alarm to the list of pending alarms --- the list is sent when inject_afd_metric is called -function add_to_alarms(status, fn, metric, fields, tags, operator, value, threshold, window, periods, message) - local severity = consts.status_label(status) - assert(severity) - alarms[#alarms+1] = { - severity=severity, - ['function']=fn, - metric=metric, - fields=fields or {}, - tags=tags or {}, - operator=operator, - value=value, - threshold=threshold, - window=window or 0, - periods=periods or 0, - message=message - } -end - -function get_alarms() - return alarms -end - -function reset_alarms() - alarms = {} -end - --- inject an AFD event into the Heka pipeline -function inject_afd_metric(msg_type, msg_tag_name, msg_tag_value, metric_name, - value, hostname, interval, source, to_alerting) - local payload - - if #alarms > 0 then - payload = lma.safe_json_encode({alarms=alarms}) - reset_alarms() - if not payload then - return - end - else - -- because cjson encodes empty tables as objects instead of arrays - payload = '{"alarms":[]}' - end - - local no_alerting - if to_alerting ~= nil and to_alerting == false then - no_alerting = true - end - - local msg = { - Type = msg_type, - Payload = payload, - Fields = { - name=metric_name, - value=value, - hostname=hostname, - interval=interval, - source=source, - tag_fields={msg_tag_name, 'source', 'hostname'}, - no_alerting = no_alerting, - } - } - msg.Fields[msg_tag_name] = msg_tag_value, - lma.inject_tags(msg) - lma.safe_inject_message(msg) -end - --- inject an AFD service event into the Heka pipeline -function inject_afd_service_metric(service, value, hostname, interval, source) - inject_afd_metric('afd_service_metric', - 'service', - service, - 'service_status', - value, hostname, interval, source) -end - -MATCH = 1 -NO_MATCH = 2 -NO_DATA = 3 -MISSING_DATA = 4 - - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_alarm.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_alarm.lua deleted file mode 100644 index 4fd660f0a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_alarm.lua +++ /dev/null @@ -1,216 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local assert = assert -local ipairs = ipairs -local pairs = pairs -local string = string -local setmetatable = setmetatable - --- LMA libs -local utils = require 'lma_utils' -local table_utils = require 'table_utils' -local consts = require 'gse_constants' -local afd = require 'afd' -local Rule = require 'afd_rule' - -local SEVERITIES = { - warning = consts.WARN, - critical = consts.CRIT, - down = consts.DOWN, - unknown = consts.UNKW, - okay = consts.OKAY, -} - -local Alarm = {} -Alarm.__index = Alarm - -setfenv(1, Alarm) -- Remove external access to contain everything in the module - -function Alarm.new(alarm) - local a = {} - setmetatable(a, Alarm) - a._metrics_list = nil - a.name = alarm.name - a.description = alarm.description - if alarm.trigger.logical_operator then - a.logical_operator = string.lower(alarm.trigger.logical_operator) - else - a.logical_operator = 'or' - end - a.severity_str = string.upper(alarm.severity) - a.severity = SEVERITIES[string.lower(alarm.severity)] - assert(a.severity ~= nil) - - a.skip_when_no_data = false - if alarm.no_data_policy then - if string.lower(alarm.no_data_policy) == 'skip' then - a.skip_when_no_data = true - else - a.no_data_severity = SEVERITIES[string.lower(alarm.no_data_policy)] - end - else - a.no_data_severity = consts.UNKW - end - assert(a.skip_when_no_data or a.no_data_severity ~= nil) - - a.rules = {} - a.initial_wait = 0 - for _, rule in ipairs(alarm.trigger.rules) do - local r = Rule.new(rule) - a.rules[#a.rules+1] = r - local wait = r.window * r.periods - if wait > a.initial_wait then - a.initial_wait = wait * 1e9 - end - end - a.start_time_ns = 0 - - return a -end - --- return the Set of metrics used by the alarm -function Alarm:get_metrics() - if not self._metrics_list then - self._metrics_list = {} - for _, rule in ipairs(self.rules) do - if not table_utils.item_find(rule.metric, metrics) then - self._metrics_list[#self._metrics_list+1] = rule.metric - end - end - end - return self._metrics_list -end - --- return a list of field names used for the metric --- (can have duplicate names) -function Alarm:get_metric_fields(metric_name) - local fields = {} - for _, rule in ipairs(self.rules) do - if rule.metric == metric_name then - for k, _ in pairs(rule.fields) do - fields[#fields+1] = k - end - for _, g in ipairs(rule.group_by) do - fields[#fields+1] = g - end - end - end - return fields -end - -function Alarm:has_metric(metric) - return table_utils.item_find(metric, self:get_metrics()) -end - --- dispatch datapoint in datastores -function Alarm:add_value(ts, metric, value, fields) - local data - for id, rule in pairs(self.rules) do - if rule.metric == metric then - rule:add_value(ts, value, fields) - end - end -end - --- return: state of alarm and a list of alarm details. --- --- with alarm list when state != OKAY: --- { --- { --- value = , --- fields = , --- message = , --- }, --- } -function Alarm:evaluate(ns) - local state = consts.OKAY - local matches = 0 - local all_alerts = {} - local function add_alarm(rule, value, message, fields) - all_alerts[#all_alerts+1] = { - severity = self.severity_str, - ['function'] = rule.fct, - metric = rule.metric, - operator = rule.relational_operator, - threshold = rule.threshold, - window = rule.window, - periods = rule.periods, - value = value, - fields = fields, - message = message - } - end - local one_unknown = false - local msg - - for _, rule in ipairs(self.rules) do - local eval, context_list = rule:evaluate(ns) - if eval == afd.MATCH then - matches = matches + 1 - msg = self.description - elseif eval == afd.MISSING_DATA then - msg = 'No datapoint have been received over the last ' .. rule.observation_window .. ' seconds' - one_unknown = true - elseif eval == afd.NO_DATA then - msg = 'No datapoint have been received ever' - one_unknown = true - end - for _, context in ipairs(context_list) do - add_alarm(rule, context.value, msg, - context.fields) - end - end - - if self.logical_operator == 'and' then - if one_unknown then - if self.skip_when_no_data then - state = nil - else - state = self.no_data_severity - end - elseif #self.rules == matches then - state = self.severity - end - elseif self.logical_operator == 'or' then - if matches > 0 then - state = self.severity - elseif one_unknown then - if self.skip_when_no_data then - state = nil - else - state = self.no_data_severity - end - end - end - - if state == nil or state == consts.OKAY then - all_alerts = {} - end - return state, all_alerts -end - -function Alarm:set_start_time(ns) - self.start_time_ns = ns -end - -function Alarm:is_evaluation_time(ns) - local delta = ns - self.start_time_ns - if delta >= self.initial_wait then - return true - end - return false -end - -return Alarm diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_alarms.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_alarms.lua deleted file mode 100644 index 74dc3289c..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_alarms.lua +++ /dev/null @@ -1,120 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local pairs = pairs -local ipairs = ipairs -local lma = require 'lma_utils' -local table_utils = require 'table_utils' -local consts = require 'gse_constants' -local gse_utils = require 'gse_utils' -local Alarm = require 'afd_alarm' - -local all_alarms = {} - -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - --- return a list of field names required for the metric -function get_metric_fields(metric_name) - local fields = {} - for name, alarm in pairs(all_alarms) do - local mf = alarm:get_metric_fields(metric_name) - if mf then - for _, field in pairs(mf) do - if not table_utils.item_find(field, fields) then - fields[#fields+1] = field - end - end - end - end - return fields -end - --- return list of alarms interested by a metric -function get_interested_alarms(metric) - local interested_alarms = {} - for _, alarm in pairs(all_alarms) do - if alarm:has_metric(metric) then - - interested_alarms[#interested_alarms+1] = alarm - end - end - return interested_alarms -end - -function add_value(ts, metric, value, fields) - local interested_alarms = get_interested_alarms(metric) - for _, alarm in ipairs (interested_alarms) do - alarm:add_value(ts, metric, value, fields) - end -end - -function reset_alarms() - all_alarms = {} -end - -function evaluate(ns) - local global_state - local all_alerts = {} - for _, alarm in pairs(all_alarms) do - if alarm:is_evaluation_time(ns) then - local state, alerts = alarm:evaluate(ns) - global_state = gse_utils.max_status(state, global_state) - for _, a in ipairs(alerts) do - all_alerts[#all_alerts+1] = { state=state, alert=a } - end - -- raise the first triggered alarm except for OKAY/UNKW states - if global_state ~= consts.UNKW and global_state ~= consts.OKAY then - break - end - end - end - return global_state, all_alerts -end - -function get_alarms() - return all_alarms -end -function get_alarm(alarm_name) - for _, a in ipairs(all_alarms) do - if a.name == alarm_name then - return a - end - end -end - -function load_alarm(alarm) - local A = Alarm.new(alarm) - all_alarms[#all_alarms+1] = A -end - -function load_alarms(alarms) - for _, alarm in ipairs(alarms) do - load_alarm(alarm) - end -end - -local started = false -function set_start_time(ns) - for _, alarm in ipairs(all_alarms) do - alarm:set_start_time(ns) - end - started = true -end - -function is_started() - return started -end - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_rule.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_rule.lua deleted file mode 100644 index 680ea618f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/afd_rule.lua +++ /dev/null @@ -1,324 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local anomaly = require('anomaly') -local circular_buffer = require('circular_buffer') -local setmetatable = setmetatable -local ipairs = ipairs -local pairs = pairs -local math = require 'math' -local string = string -local table = table -local assert = assert -local type = type - --- LMA libs -local utils = require 'lma_utils' -local table_utils = require 'table_utils' -local consts = require 'gse_constants' -local gse_utils = require 'gse_utils' -local afd = require 'afd' -local matching = require 'value_matching' - -local MIN_WINDOW = 10 -local MIN_PERIOD = 1 -local SECONDS_PER_ROW = 5 - -local Rule = {} -Rule.__index = Rule - -setfenv(1, Rule) -- Remove external access to contain everything in the module - -function Rule.new(rule) - local r = {} - setmetatable(r, Rule) - - local win = MIN_WINDOW - if rule.window and rule.window + 0 > 0 then - win = rule.window + 0 - end - r.window = win - local periods = MIN_PERIOD - if rule.periods and rule.periods + 0 > 0 then - periods = rule.periods + 0 - end - r.periods = periods - r.relational_operator = rule.relational_operator - r.metric = rule.metric - r.fields = rule.fields or {} - - -- build field matching - r.field_matchers = {} - for f, expression in pairs(r.fields) do - r.field_matchers[f] = matching.new(expression) - end - - r.fct = rule['function'] - r.threshold = rule.threshold + 0 - r.value_index = rule.value or nil -- Can be nil - - -- build unique rule id - local arr = {r.metric, r.fct, r.window, r.periods} - for f, v in table_utils.orderedPairs(r.fields or {}) do - arr[#arr+1] = string.format('(%s=%s)', f, v) - end - r.rule_id = table.concat(arr, '/') - - r.group_by = rule.group_by or {} - - if r.fct == 'roc' then - -- We use the name of the metric as the payload_name. - -- - -- The ROC algorithm needs the following parameters: - -- - the number of intervals in the analysis window - -- - the number of intervals in the historical analysis window - -- - the threshold - -- - -- r.window is an interval in seconds. So to get the number of - -- intervals we divide r.window by the number of seconds per row. - -- - -- r.periods represents the number of windows that we want to use for - -- the historical analysis. As we tell the ROC algorithm to use all - -- remaining buffer for the historical window we need to allocate - -- r.periods * (r.window / SECONDS_PER_ROW) for the historical - -- analysis and 2 additional periods for the previous and current - -- analysis windows. - -- - local cfg_str = string.format('roc("%s",1,%s,0,%s,false,false)', - r.metric, - math.ceil(r.window/SECONDS_PER_ROW), - r.threshold) - r.roc_cfg = anomaly.parse_config(cfg_str) - r.cbuf_size = math.ceil(r.window / SECONDS_PER_ROW) * (r.periods + 2) - else - r.roc_cfg = nil - r.cbuf_size = math.ceil(r.window * r.periods / SECONDS_PER_ROW) - end - r.ids_datastore = {} - r.datastore = {} - r.observation_window = math.ceil(r.window * r.periods) - - return r -end - -function Rule:get_datastore_id(fields) - if #self.group_by == 0 or fields == nil then - return self.rule_id - end - - local arr = {} - arr[#arr + 1] = self.rule_id - for _, g in ipairs(self.group_by) do - arr[#arr + 1] = fields[g] - end - return table.concat(arr, '/') -end - -function Rule:fields_accepted(fields) - if not fields then - fields = {} - end - local matched_fields = 0 - local no_match_on_fields = true - for f, expression in pairs(self.field_matchers) do - no_match_on_fields = false - for k, v in pairs(fields) do - if k == f then - if expression:matches(v) then - matched_fields = matched_fields + 1 - else - return false - end - end - end - end - return no_match_on_fields or matched_fields > 0 -end - -function Rule:get_circular_buffer() - local cbuf - if self.fct == 'avg' then - cbuf = circular_buffer.new(self.cbuf_size, 2, SECONDS_PER_ROW) - cbuf:set_header(1, self.metric, 'sum', 'sum') - cbuf:set_header(2, self.metric, 'count', 'sum') - elseif self.fct == 'min' or self.fct == 'max' then - cbuf = circular_buffer.new(self.cbuf_size, 1, SECONDS_PER_ROW) - cbuf:set_header(1, self.metric, self.fct) - else - cbuf = circular_buffer.new(self.cbuf_size, 1, SECONDS_PER_ROW) - cbuf:set_header(1, self.metric) - end - return cbuf -end - --- store datapoints in cbuf, create the cbuf if not exists. --- value can be a table where the index to choose is referenced by self.value_index -function Rule:add_value(ts, value, fields) - if not self:fields_accepted(fields) then - return - end - if type(value) == 'table' then - value = value[self.value_index] - end - if value == nil then - return - end - - local data - local uniq_field_id = self:get_datastore_id(fields) - if not self.datastore[uniq_field_id] then - self.datastore[uniq_field_id] = { - fields = self.fields, - cbuf = self:get_circular_buffer() - } - if #self.group_by > 0 then - self.datastore[uniq_field_id].fields = fields - end - - self:add_datastore(uniq_field_id) - end - data = self.datastore[uniq_field_id] - - if self.fct == 'avg' then - data.cbuf:add(ts, 1, value) - data.cbuf:add(ts, 2, 1) - else - data.cbuf:set(ts, 1, value) - end -end - -function Rule:add_datastore(id) - if not table_utils.item_find(id, self.ids_datastore) then - self.ids_datastore[#self.ids_datastore+1] = id - end -end - -function Rule:compare_threshold(value) - return gse_utils.compare_threshold(value, self.relational_operator, self.threshold) -end - -local function isnumber(value) - return value ~= nil and not (value ~= value) -end - -local available_functions = {last=true, avg=true, max=true, min=true, sum=true, - variance=true, sd=true, diff=true, roc=true} - --- evaluate the rule against datapoints --- return a list: match (bool or string), context ({value=v, fields=list of field table}) --- --- examples: --- true, { {value=100, fields={{queue='nova'}, {queue='neutron'}}, ..} --- false, { {value=10, fields={}}, ..} --- with 2 special cases: --- - never receive one datapoint --- 'nodata', {} --- - no more datapoint received for a metric --- 'missing', {value=-1, fields={}} --- There is a drawback with the 'missing' state and could leads to emit false positive --- state. For example when the monitored thing has been renamed/deleted, --- it's normal to don't receive datapoint anymore .. for example a filesystem. -function Rule:evaluate(ns) - local fields = {} - local one_match, one_no_match, one_missing_data = false, false, false - for _, id in ipairs(self.ids_datastore) do - local data = self.datastore[id] - if data then - local cbuf_time = data.cbuf:current_time() - -- if we didn't receive datapoint within the observation window this means - -- we don't receive anymore data and cannot compute the rule. - if ns - cbuf_time > self.observation_window * 1e9 then - one_missing_data = true - fields[#fields+1] = {value = -1, fields = data.fields} - else - assert(available_functions[self.fct]) - local result - - if self.fct == 'roc' then - local anomaly_detected, _ = anomaly.detect(ns, self.metric, data.cbuf, self.roc_cfg) - if anomaly_detected then - one_match = true - fields[#fields+1] = {value=-1, fields=data.fields} - else - one_no_match = true - end - elseif self.fct == 'avg' then - local total - total = data.cbuf:compute('sum', 1) - local count = data.cbuf:compute('sum', 2) - result = total/count - elseif self.fct == 'last' then - local last - local t = ns - while (not isnumber(last)) and t >= ns - self.observation_window * 1e9 do - last = data.cbuf:get(t, 1) - t = t - SECONDS_PER_ROW * 1e9 - end - if isnumber(last) then - result = last - else - one_missing_data = true - fields[#fields+1] = {value = -1, fields = data.fields} - end - elseif self.fct == 'diff' then - local first, last - - local t = ns - while (not isnumber(last)) and t >= ns - self.observation_window * 1e9 do - last = data.cbuf:get(t, 1) - t = t - SECONDS_PER_ROW * 1e9 - end - - if isnumber(last) then - t = ns - self.observation_window * 1e9 - while (not isnumber(first)) and t <= ns do - first = data.cbuf:get(t, 1) - t = t + SECONDS_PER_ROW * 1e9 - end - end - - if not isnumber(last) or not isnumber(first) then - one_missing_data = true - fields[#fields+1] = {value = -1, fields = data.fields} - else - result = last - first - end - else - result = data.cbuf:compute(self.fct, 1) - end - - if result then - local m = self:compare_threshold(result) - if m then - one_match = true - fields[#fields+1] = {value=result, fields=data.fields} - else - one_no_match = true - end - end - end - end - end - if one_match then - return afd.MATCH, fields - elseif one_missing_data then - return afd.MISSING_DATA, fields - elseif one_no_match then - return afd.NO_MATCH, {} - else - return afd.NO_DATA, {{value=-1, fields=self.fields}} - end -end - -return Rule diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse.lua deleted file mode 100644 index 16bb95046..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse.lua +++ /dev/null @@ -1,164 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local consts = require 'gse_constants' -local string = require 'string' -local table = require 'table' -local GseCluster = require 'gse_cluster' -local lma = require 'lma_utils' -local table_utils = require 'table_utils' - -local pairs = pairs -local ipairs = ipairs -local assert = assert -local type = type -local read_message = read_message - -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - --- Hash of GseCluster instances organized by name -local clusters = {} --- Reverse index table to map cluster's members to clusters -local reverse_cluster_index = {} --- Array of cluster names ordered by dependency -local ordered_clusters = {} - -function add_cluster(cluster_id, members, hints, group_by, policy_rules) - assert(type(members) == 'table') - assert(type(hints) == 'table') - assert(type(policy_rules) == 'table') - - local cluster = GseCluster.new(members, hints, group_by, policy_rules) - clusters[cluster_id] = cluster - - -- update the reverse index - for _, member in ipairs(members) do - if not reverse_cluster_index[member] then - reverse_cluster_index[member] = {} - end - local reverse_table = reverse_cluster_index[member] - if not table_utils.item_find(cluster_id, reverse_table) then - reverse_table[#reverse_table+1] = cluster_id - end - end - - if not table_utils.item_find(cluster_id, ordered_clusters) then - local after_index = 1 - for current_pos, id in ipairs(ordered_clusters) do - if table_utils.item_find(id, cluster.hints) then - after_index = current_pos + 1 - end - end - - local index = after_index - for _, item in pairs(clusters) do - for _, hint in pairs(item.hints) do - if hint == cluster_id then - local pos = table_utils.item_pos(hint, cluster_orderings) - if pos and pos <= index then - index = pos - elseif index > after_index then - error('circular dependency between clusters!') - end - end - end - end - table.insert(ordered_clusters, index, cluster_id) - end -end - -function get_ordered_clusters() - return ordered_clusters -end - -function cluster_exists(cluster_id) - return clusters[cluster_id] ~= nil -end - --- return the list of clusters which depends on a given member -function find_cluster_memberships(member_id) - return reverse_cluster_index[member_id] or {} -end - --- store the status of a cluster's member and its current alarms -function set_member_status(cluster_id, member, value, alarms, hostname) - local cluster = clusters[cluster_id] - if cluster then - cluster:update_fact(member, hostname, value, alarms) - end -end - --- The cluster status depends on the status of its members. --- The status of the related clusters (defined by cluster.hints) doesn't modify --- the overall status but their alarms are returned. -function resolve_status(cluster_id) - local cluster = clusters[cluster_id] - assert(cluster) - - cluster:refresh_status() - local alarms = table_utils.deepcopy(cluster.alarms) - - if cluster.status ~= consts.OKAY then - -- add hints if the cluster isn't healthy - for _, other_id in ipairs(cluster.hints or {}) do - for _, v in pairs(cluster:subtract_alarms(clusters[other_id])) do - alarms[#alarms+1] = table_utils.deepcopy(v) - alarms[#alarms].tags['dependency_name'] = other_id - alarms[#alarms].tags['dependency_level'] = 'hint' - end - end - end - - return cluster.status, alarms -end - --- compute the cluster metric and inject it into the Heka pipeline --- the metric's value is computed using the status of its members -function inject_cluster_metric(msg_type, cluster_name, metric_name, interval, source, to_alerting) - local payload - local status, alarms = resolve_status(cluster_name) - - if #alarms > 0 then - payload = lma.safe_json_encode({alarms=alarms}) - if not payload then - return - end - else - -- because cjson encodes empty tables as objects instead of arrays - payload = '{"alarms":[]}' - end - - local no_alerting - if to_alerting ~= nil and to_alerting == false then - no_alerting = true - end - - local msg = { - Type = msg_type, - Payload = payload, - Fields = { - name=metric_name, - value=status, - cluster_name=cluster_name, - tag_fields={'cluster_name'}, - interval=interval, - source=source, - no_alerting=no_alerting, - } - } - lma.inject_tags(msg) - lma.safe_inject_message(msg) -end - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_cluster.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_cluster.lua deleted file mode 100644 index cce94f4c6..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_cluster.lua +++ /dev/null @@ -1,154 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local consts = require 'gse_constants' -local gse_utils = require 'gse_utils' -local table_utils = require 'table_utils' - -local ipairs = ipairs -local pairs = pairs -local setmetatable = setmetatable -local assert = assert -local type = type - -local GseCluster = {} -GseCluster.__index = GseCluster - -setfenv(1, GseCluster) -- Remove external access to contain everything in the module - -local VALID_STATUSES = { - [consts.OKAY]=true, - [consts.WARN]=true, - [consts.CRIT]=true, - [consts.DOWN]=true, - [consts.UNKW]=true -} - -function GseCluster.new(members, hints, group_by, policy_rules) - assert(type(members) == 'table') - assert(type(hints) == 'table') - assert(type(policy_rules) == 'table') - - local cluster = {} - setmetatable(cluster, GseCluster) - - cluster.members = members - cluster.hints = hints - cluster.policy_rules = policy_rules - -- when group_by is 'hostname', facts are stored by hostname then member - -- when group_by is 'member', facts are stored by member only - -- otherwise facts are stored by member then hostname - if group_by == 'hostname' or group_by == 'member' then - cluster.group_by = group_by - else - cluster.group_by = 'none' - end - cluster.status = consts.UNKW - cluster.facts = {} - cluster.alarms = {} - cluster.member_index = {} - for _, v in ipairs(members) do - cluster.member_index[v] = true - end - - return cluster -end - -function GseCluster:has_member(member) - return self.member_index[member] -end - --- Update the facts table for a cluster's member -function GseCluster:update_fact(member, hostname, value, alarms) - assert(VALID_STATUSES[value]) - assert(type(alarms) == 'table') - - local key1, key2 = member, hostname - if self.group_by == 'hostname' then - key1 = hostname - key2 = member - elseif self.group_by == 'member' then - key2 = '__anyhost__' - end - - if not self.facts[key1] then - self.facts[key1] = {} - end - self.facts[key1][key2] = { - status=value, - alarms=table_utils.deepcopy(alarms), - member=member - } - if self.group_by == 'hostname' then - -- store the hostname for later reference in the alarms - self.facts[key1][key2].hostname = hostname - end -end - --- Compute the status and alarms of the cluster according to the current facts --- and the cluster's policy -function GseCluster:refresh_status() - local alarms = {} - local status_breakdown = {} - - self.status = consts.UNKW - self.alarms = {} - - for group_key, _ in table_utils.orderedPairs(self.facts) do - local group_status = consts.UNKW - for sub_key, fact in table_utils.orderedPairs(self.facts[group_key]) do - group_status = gse_utils.max_status(group_status, fact.status) - if fact.status ~= consts.OKAY then - for _, v in ipairs(fact.alarms) do - alarms[#alarms+1] = table_utils.deepcopy(v) - if not alarms[#alarms]['tags'] then - alarms[#alarms]['tags'] = {} - end - alarms[#alarms].tags['dependency_name'] = fact.member - alarms[#alarms].tags['dependency_level'] = 'direct' - if fact.hostname then - alarms[#alarms].hostname = fact.hostname - end - end - end - end - status_breakdown[group_status] = (status_breakdown[group_status] or 0) + 1 - end - for _, policy_rule in ipairs(self.policy_rules) do - if policy_rule:evaluate(status_breakdown) then - self.status = policy_rule.status - break - end - end - if self.status ~= consts.OKAY then - self.alarms = alarms - end - - return self.status -end - --- Return the alarms from another cluster which aren't already known by this --- cluster -function GseCluster:subtract_alarms(cluster) - local subset = {} - if cluster then - for _, alarm in ipairs(cluster.alarms) do - if alarm.tags and alarm.tags['dependency_name'] and not self:has_member(alarm.tags['dependency_name']) then - subset[#subset+1] = alarm - end - end - end - return subset -end - -return GseCluster diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_constants.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_constants.lua deleted file mode 100644 index 2a328e62f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_constants.lua +++ /dev/null @@ -1,39 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - --- The status values were chosen to match with the Grafana constraints: --- OKAY => green --- WARN & UNKW => orange --- CRIT & DOWN => red -OKAY=0 -WARN=1 -UNKW=2 -CRIT=3 -DOWN=4 - -local STATUS_LABELS = { - [OKAY]='OKAY', - [WARN]='WARN', - [UNKW]='UNKNOWN', - [CRIT]='CRITICAL', - [DOWN]='DOWN' -} - -function status_label(v) - return STATUS_LABELS[v] -end - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_policy.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_policy.lua deleted file mode 100644 index 6c7e52c4b..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_policy.lua +++ /dev/null @@ -1,109 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local consts = require 'gse_constants' -local gse_utils = require 'gse_utils' - -local assert = assert -local ipairs = ipairs -local pairs = pairs -local setmetatable = setmetatable -local string = string -local tonumber = tonumber - -local GsePolicy = {} -GsePolicy.__index = GsePolicy - -setfenv(1, GsePolicy) -- Remove external access to contain everything in the module - -local SEVERITIES = { - okay=consts.OKAY, - warning=consts.WARN, - unknown=consts.UNKW, - critical=consts.CRIT, - down=consts.DOWN -} - -function GsePolicy.new(policy) - local p = {} - setmetatable(p, GsePolicy) - - p.status = SEVERITIES[string.lower(policy.status)] - assert(p.status) - - p.require_percent = false - p.rules = {} - if policy.trigger then - p.logical_op = string.lower(policy.trigger.logical_operator or 'or') - for _, r in ipairs(policy.trigger.rules or {}) do - assert(r['function'] == 'count' or r['function'] == 'percent') - if r['function'] == 'percent' then - p.require_percent = true - end - local rule = { - ['function']=r['function'], - relational_op=r.relational_operator, - threshold=tonumber(r.threshold), - arguments={} - } - for _, v in ipairs(r.arguments) do - assert(SEVERITIES[v]) - rule.arguments[#rule.arguments+1] = SEVERITIES[v] - end - p.rules[#p.rules+1] = rule - end - end - - return p -end - --- return true or false depending on whether the facts match the policy -function GsePolicy:evaluate(facts) - local total = 0 - - if #self.rules == 0 then - return true - end - - if self.require_percent then - for _, v in pairs(facts) do - total = total + v - end - end - - local one_match = false - for _, r in ipairs(self.rules) do - local value = 0 - for _, status in ipairs(r.arguments) do - if facts[status] then - value = value + facts[status] - end - end - if r['function'] == 'percent' then - value = value * 100 / total - end - - if gse_utils.compare_threshold(value, r.relational_op, r.threshold) then - one_match = true - if self.logical_op == 'or' then - return true - end - elseif self.logical_op == 'and' then - return false - end - end - - return one_match -end - -return GsePolicy diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_utils.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_utils.lua deleted file mode 100644 index dd82aa255..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/gse_utils.lua +++ /dev/null @@ -1,58 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local consts = require 'gse_constants' - -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - -local STATUS_WEIGHTS = { - [consts.UNKW]=0, - [consts.OKAY]=1, - [consts.WARN]=2, - [consts.CRIT]=3, - [consts.DOWN]=4 -} - -function max_status(val1, val2) - if not val1 then - return val2 - elseif not val2 then - return val1 - elseif STATUS_WEIGHTS[val1] > STATUS_WEIGHTS[val2] then - return val1 - else - return val2 - end -end - -function compare_threshold(value, op, threshold) - local rule_matches = false - if op == '==' or op == 'eq' then - rule_matches = value == threshold - elseif op == '!=' or op == 'ne' then - rule_matches = value ~= threshold - elseif op == '>=' or op == 'gte' then - rule_matches = value >= threshold - elseif op == '>' or op == 'gt' then - rule_matches = value > threshold - elseif op == '<=' or op == 'lte' then - rule_matches = value <= threshold - elseif op == '<' or op == 'lt' then - rule_matches = value < threshold - end - return rule_matches -end - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/influxdb.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/influxdb.lua deleted file mode 100644 index d9c359d8a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/influxdb.lua +++ /dev/null @@ -1,114 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. -local string = string -local table = table -local setmetatable = setmetatable -local ipairs = ipairs -local pairs = pairs -local tostring = tostring -local type = type - -local utils = require 'lma_utils' - -local InfluxEncoder = {} -InfluxEncoder.__index = InfluxEncoder - -setfenv(1, InfluxEncoder) -- Remove external access to contain everything in the module - -local function escape_string(str) - return tostring(str):gsub("([ ,])", "\\%1") -end - -local function encode_scalar_value(value) - if type(value) == "number" then - -- Always send numbers as formatted floats, so InfluxDB will accept - -- them if they happen to change from ints to floats between - -- points in time. Forcing them to always be floats avoids this. - return string.format("%.6f", value) - elseif type(value) == "string" then - -- string values need to be double quoted - return '"' .. value:gsub('"', '\\"') .. '"' - elseif type(value) == "boolean" then - return '"' .. tostring(value) .. '"' - end -end - -local function encode_value(value) - if type(value) == "table" then - local values = {} - for k,v in pairs(value) do - table.insert( - values, - string.format("%s=%s", escape_string(k), encode_scalar_value(v)) - ) - end - return table.concat(values, ',') - else - return "value=" .. encode_scalar_value(value) - end -end - --- Create a new InfluxDB encoder --- --- time_precision: "s", "m", "ms", "us" or "ns" (default: "ns") -function InfluxEncoder.new(time_precision) - local e = {} - setmetatable(e, InfluxEncoder) - e.time_precision = time_precision or 'ns' - return e -end - --- Encode a single datapoint using the InfluxDB line protocol --- --- timestamp: the timestamp in nanosecond --- name: the measurement's name --- value: a scalar value or a list of key-value pairs --- tags: a list of key-value pairs encoded as InfluxDB tags -function InfluxEncoder:encode_datapoint(timestamp, name, value, tags) - if timestamp == nil or type(name) ~= 'string' or value == nil or type(tags or {}) ~= 'table' then - -- fail silently if any input parameter is invalid - return "" - end - - local ts = timestamp - if self.time_precision ~= 'ns' then - ts = utils.message_timestamp(self.time_precision, ts) - end - - local tags_array = {} - for k,v in pairs(tags or {}) do - if k ~= '' and v ~= '' then - -- empty tag name and value aren't allowed by InfluxDB - table.insert(tags_array, escape_string(k) .. '=' .. escape_string(v)) - end - end - - if #tags_array > 0 then - -- for performance reasons, it is recommended to always send the tags - -- in the same order. - table.sort(tags_array) - return string.format("%s,%s %s %d", - escape_string(name), - table.concat(tags_array, ','), - encode_value(value), - ts) - else - return string.format("%s %s %d", - escape_string(name), - encode_value(value), - ts) - end -end - -return InfluxEncoder diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/lma_utils.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/lma_utils.lua deleted file mode 100644 index 556148810..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/lma_utils.lua +++ /dev/null @@ -1,313 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local cjson = require 'cjson' -local string = require 'string' -local extra = require 'extra_fields' -local patt = require 'patterns' -local math = require 'math' - -local pairs = pairs -local inject_message = inject_message -local inject_payload = inject_payload -local read_message = read_message -local pcall = pcall -local type = type - -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - -severity_to_label_map = { - [0] = 'EMERGENCY', - [1] = 'ALERT', - [2] = 'CRITICAL', - [3] = 'ERROR', - [4] = 'WARNING', - [5] = 'NOTICE', - [6] = 'INFO', - [7] = 'DEBUG', -} - -label_to_severity_map = { - EMERGENCY = 0, - ALERT = 1, - CRITICAL = 2, - ERROR = 3, - WARNING = 4, - NOTICE = 5, - INFO= 6, - DEBUG = 7, -} - -metric_type = { - COUNTER = "counter", - GAUGE = "gauge", - DERIVE = "derive", -} - -local default_severity = 7 - -local bulk_datapoints = {} - --- Add a datapoint to the bulk metric message --- The 'value' parameter can be a table to support multi-value metric -function add_to_bulk_metric(name, value, tags) - bulk_datapoints[#bulk_datapoints+1] = { - name = name, - tags = tags or {}, - } - if type(value) == 'table' then - bulk_datapoints[#bulk_datapoints].values = value - else - bulk_datapoints[#bulk_datapoints].value = value - end -end - --- Send the bulk metric message to the Heka pipeline -function inject_bulk_metric(ts, hostname, source, m_type) - if #bulk_datapoints == 0 then - return - end - - local payload = safe_json_encode(bulk_datapoints) - if not payload then - -- Reset the table otherwise it may grow infinitely and the sandbox - -- will eventually be killed by Heka. - -- See https://bugs.launchpad.net/lma-toolchain/+bug/1545743 - bulk_datapoints = {} - return - end - - local msg = { - Hostname = hostname, - Timestamp = ts, - Payload = payload, - Type = 'bulk_metric', -- prepended with 'heka.sandbox' - Severity = label_to_severity_map.INFO, - Fields = { - hostname = hostname, - source = source, - type = m_type or metric_type['GAUGE'] - } - } - -- reset the local table storing the datapoints - bulk_datapoints = {} - - inject_tags(msg) - return safe_inject_message(msg) -end - --- Encode a Lua variable as JSON without raising an exception if the encoding --- fails for some reason (for instance, the encoded buffer exceeds the sandbox --- limit) -function safe_json_encode(v) - local ok, data = pcall(cjson.encode, v) - - if not ok then - return - end - - return data -end - --- Call inject_payload() wrapped by pcall() -function safe_inject_payload(payload_type, payload_name, data) - local ok, err_msg = pcall(inject_payload, payload_type, payload_name, data) - if not ok then - return -1, err_msg - else - return 0 - end -end - --- Call inject_message() wrapped by pcall() -function safe_inject_message(msg) - local ok, err_msg = pcall(inject_message, msg) - if not ok then - return -1, err_msg - else - return 0 - end -end - --- Parse a Syslog-based payload and update the Heka message --- Return true if successful, false otherwise -function parse_syslog_message(grammar, payload, msg) - -- capture everything after the first backslash because syslog_grammar will - -- drop it - local extra_msg = string.match(payload, '^[^\n]+\n(.+)\n$') - - local fields = grammar:match(payload) - if not fields then - return false - end - - msg.Timestamp = fields.timestamp - fields.timestamp = nil - - msg.Hostname = fields.hostname - fields.hostname = nil - - msg.Pid = fields.syslogtag.pid or 0 - fields.programname = fields.syslogtag.programname - fields.syslogtag = nil - - if fields.pri then - msg.Severity = fields.pri.severity - fields.syslogfacility = fields.pri.facility - fields.pri = nil - else - msg.Severity = fields.syslogseverity or fields["syslogseverity-text"] - or fields.syslogpriority or fields["syslogpriority-text"] - or default_severity - fields.syslogseverity = nil - fields["syslogseverity-text"] = nil - fields.syslogpriority = nil - fields["syslogpriority-text"] = nil - end - fields.severity_label = severity_to_label_map[msg.Severity] - - if extra_msg ~= nil then - msg.Payload = fields.msg .. "\n" .. extra_msg - else - msg.Payload = fields.msg - end - fields.msg = nil - - msg.Fields = fields - - inject_tags(msg) - - return true -end - --- Inject tags into the Heka message -function inject_tags(msg) - for k,v in pairs(extra.tags) do - if msg.Fields[k] == nil then - msg.Fields[k] = v - end - end -end - --- Convert a datetime string to the RFC3339 format --- it supports a variety of datetime formats. --- Return the string unmodified if the datetime couldn't be parsed -function format_datetime (raw_datetime) - local datetime - local t = patt.TimestampTable:match(raw_datetime) - if t then - local frac = 0 - local offset_sign = '+' - local offset_hour = 0 - local offset_min = 0 - if t.sec_frac then frac = t.sec_frac end - if t.offset_sign then offset_sign = t.offset_sign end - if t.offset_hour then offset_hour = t.offset_hour end - if t.offset_min then offset_min = t.offset_min end - datetime = string.format("%04d-%02d-%02dT%02d:%02d:%02d.%06d%s%02d:%02d", - t.year, t.month, t.day, t.hour, t.min, t.sec, frac*1e6, offset_sign, - offset_hour, offset_min) - end - return datetime -end - -function chomp(s) - return string.gsub(s, "\n$", "") -end - -function truncate(str, max_length, delimiter) - if string.len(str) <= max_length then - return str - end - - local pos = 1 - while true do - local next_pos1, next_pos2 = string.find(str, delimiter, pos) - if not next_pos1 or next_pos1 - 1 > max_length then - pos = pos - string.len(delimiter) - 1 - if pos < 1 then - pos = max_length - end - break - end - pos = next_pos2 + 1 - end - - return string.sub(str, 1, pos) -end - --- Convert a nanosecond timestamp to a lower precision timestamp. --- Arguments: --- timestamp_precision: one of 'us', 'ms', 's', 'm' or 'h'. --- timestamp: a timestamp in nanosecond, if not provided the message Timestamp is used. -function message_timestamp(timestamp_precision, timestamp) - -- Default is to divide ns to ms - local timestamp_divisor = 1e6 - -- Divide ns to s - if timestamp_precision == "s" then - timestamp_divisor = 1e9 - -- Divide ns to us - elseif timestamp_precision == "us" then - timestamp_divisor = 1e3 - -- Divide ns to m - elseif timestamp_precision == "m" then - timestamp_divisor = 1e9 * 60 - -- Divide ns to h - elseif timestamp_precision == "h" then - timestamp_divisor = 1e9 * 60 * 60 - end - if timestamp == nil then - timestamp = read_message("Timestamp") - end - return math.floor(timestamp / timestamp_divisor) -end - --- Extract the metric value(s) from the message. --- The value can be either a scalar value or a table for mulitvalue metrics. --- Returns true plus the value or if it fails, returns false plus the error message. -function get_values_from_metric() - if read_message('Fields[value_fields]') then - value = {} - local i = 0 - local val - while true do - local f = read_message("Fields[value_fields]", 0, i) - if not f then - break - end - val = read_message(string.format('Fields[%s]', f)) - if val ~= nil then - value[f] = val - i = i + 1 - end - end - if i == 0 then - return false, 'Fields[value_fields] does not list any valid field' - end - else - value = read_message("Fields[value]") - if not value then - return false, 'Fields[value] is missing' - end - end - - return true, value -end - --- convert a nanosecond value to second -function convert_to_sec(ns) - return math.floor(ns/1e9) -end - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/patterns.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/patterns.lua deleted file mode 100644 index bcb58c7ac..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/patterns.lua +++ /dev/null @@ -1,147 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local table = require 'table' -local dt = require "date_time" -local l = require 'lpeg' -l.locale(l) - -local tonumber = tonumber - -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - -function format_uuid(t) - return table.concat(t, '-') -end - -function anywhere (patt) - return l.P { - patt + 1 * l.V(1) - } -end - -sp = l.space -colon = l.P":" -dash = l.P"-" -dot = l.P'.' -quote = l.P'"' - -local x4digit = l.xdigit * l.xdigit * l.xdigit * l.xdigit -local uuid_dash = l.C(x4digit * x4digit * dash * x4digit * dash * x4digit * dash * x4digit * dash * x4digit * x4digit * x4digit) -local uuid_nodash = l.Ct(l.C(x4digit * x4digit) * l.C(x4digit) * l.C(x4digit) * l.C(x4digit) * l.C(x4digit * x4digit * x4digit)) / format_uuid - --- Return a UUID string in canonical format (eg with dashes) -Uuid = uuid_nodash + uuid_dash - --- Parse a datetime string and return a table with the following keys --- year (string) --- month (string) --- day (string) --- hour (string) --- min (string) --- sec (string) --- sec_frac (number less than 1, can be nil) --- offset_sign ('-' or '+', can be nil) --- offset_hour (number, can be nil) --- offset_min (number, can be nil) --- --- The datetime string can be formatted as --- 'YYYY-MM-DD( |T)HH:MM:SS(.ssssss)?(offset indicator)?' -TimestampTable = l.Ct(dt.rfc3339_full_date * (sp + l.P"T") * dt.rfc3339_partial_time * (dt.rfc3339_time_offset + dt.timezone_offset)^-1) - --- Returns the parsed datetime converted to nanosec -Timestamp = TimestampTable / dt.time_to_ns - -programname = (l.R("az", "AZ", "09") + l.P"." + dash + l.P"_")^1 -Pid = l.digit^1 -SeverityLabel = l.P"CRITICAL" + l.P"ERROR" + l.P"WARNING" + l.P"INFO" + l.P"AUDIT" + l.P"DEBUG" + l.P"TRACE" -Message = l.P(1)^0 - --- Capture for OpenStack logs producing four values: Timestamp, Pid, --- SeverityLabel, PythonModule and Message. --- --- OpenStack log messages are of this form: --- 2015-11-30 08:38:59.306 3434 INFO oslo_service.periodic_task [-] Blabla... --- --- [-] is the "request" part, it can take multiple forms. See below. -openstack = l.Ct(l.Cg(Timestamp, "Timestamp")* sp * l.Cg(Pid, "Pid") * sp * - l.Cg(SeverityLabel, "SeverityLabel") * sp * l.Cg(programname, "PythonModule") * - sp * l.Cg(Message, "Message")) - --- Capture for OpenStack request context producing three values: RequestId, --- UserId and TenantId. --- --- Notes: --- --- OpenStack logs include a request context, enclosed between square brackets. --- It takes one of these forms: --- --- [-] --- [req-0fd2a9ba-448d-40f5-995e-33e32ac5a6ba - - - - -] --- [req-4db318af-54c9-466d-b365-fe17fe4adeed 8206d40abcc3452d8a9c1ea629b4a8d0 112245730b1f4858ab62e3673e1ee9e2 - - -] --- --- In the 1st case the capture produces nil. --- In the 2nd case the capture produces one value: RequestId. --- In the 3rd case the capture produces three values: RequestId, UserId, TenantId. --- --- The request id may be formatted as 'req-xxx' or 'xxx' depending on the project. --- The user id and tenant id may not be present depending on the OpenStack release. -openstack_request_context = (l.P(1) - "[" )^0 * "[" * l.P"req-"^-1 * - l.Ct(l.Cg(Uuid, "RequestId") * sp * ((l.Cg(Uuid, "UserId") * sp * - l.Cg(Uuid, "TenantId")) + l.P(1)^0)) - "]" - -local http_method = l.Cg(l.R"AZ"^3, "http_method") -local url = l.Cg( (1 - sp)^1, "http_url") -local http_version = l.Cg(l.digit * dot * l.digit, "http_version") - --- Pattern for the " HTTP/" format found --- found in both OpenStack and Apache log files. --- Example : OPTIONS /example.com HTTP/1.0 -http_request = http_method * sp * url * sp * l.P'HTTP/' * http_version - --- Patterns for HTTP status, HTTP response size and HTTP response time in --- OpenLayers logs. --- --- Notes: --- Nova changes the default log format of eventlet.wsgi (see nova/wsgi.py) and --- prefixes the HTTP status, response size and response time values with --- respectively "status: ", "len: " and "time: ". --- Other OpenStack services just rely on the default log format. --- TODO(pasquier-s): build the LPEG grammar based on the log_format parameter --- passed to eventlet.wsgi.server similar to what the build_rsyslog_grammar --- function does for RSyslog. -local openstack_http_status = l.P"status: "^-1 * l.Cg(l.digit^3 / tonumber, "http_status") -local openstack_response_size = l.P"len: "^-1 * l.Cg(l.digit^1 / tonumber, "http_response_size") -local openstack_response_time = l.P"time: "^-1 * l.Cg(l.digit^1 * dot^0 * l.digit^0 / tonumber, "http_response_time") - --- Capture for OpenStack HTTP producing six values: http_method, http_url, --- http_version, http_status, http_response_size and http_response_time. -openstack_http = anywhere(l.Ct( - quote * http_request * quote * sp^1 * - openstack_http_status * sp^1 * openstack_response_size * sp^1 * - openstack_response_time -)) - --- Capture for IP addresses producing one value: ip_address. -ip_address = anywhere(l.Ct( - l.Cg(l.digit^-3 * dot * l.digit^-3 * dot * l.digit^-3 * dot * l.digit^-3, "ip_address") -)) - --- Pattern used to match the beginning of a Python Traceback. -traceback = l.P'Traceback (most recent call last):' - --- Pattern used to match a number -Number = l.P"-"^-1 * l.xdigit^1 * (l.S(".,") * l.xdigit^1 )^-1 / tonumber - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/table_utils.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/table_utils.lua deleted file mode 100644 index ba5fb93b0..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/table_utils.lua +++ /dev/null @@ -1,109 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local table = require 'table' -local pairs = pairs -local ipairs = ipairs -local type = type - -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - --- return a clone of the passed table -function deepcopy(t) - if type(t) == 'table' then - local copy = {} - for k, v in pairs(t) do - copy[k] = deepcopy(v) - end - return copy - end - return t -end - --- return the position (index) of an item in a list, nil if not found -function item_pos(item, list) - if type(list) == 'table' then - for i, v in ipairs(list) do - if v == item then - return i - end - end - end -end - --- return true if an item is present in the list, false otherwise -function item_find(item, list) - return item_pos(item, list) ~= nil -end - --- from http://lua-users.org/wiki/SortedIteration -function __genOrderedIndex( t ) - local orderedIndex = {} - for key in pairs(t) do - table.insert( orderedIndex, key ) - end - table.sort( orderedIndex ) - return orderedIndex -end - -function orderedNext(t, state) - -- Equivalent of the next function, but returns the keys in the alphabetic - -- order. We use a temporary ordered key table that is stored in the - -- table being iterated. - - key = nil - if state == nil then - -- the first time, generate the index - t.__orderedIndex = __genOrderedIndex( t ) - key = t.__orderedIndex[1] - else - -- fetch the next value - for i = 1,table.getn(t.__orderedIndex) do - if t.__orderedIndex[i] == state then - key = t.__orderedIndex[i+1] - end - end - end - - if key then - return key, t[key] - end - - -- no more value to return, cleanup - t.__orderedIndex = nil - return -end - -function orderedPairs(t) - -- Equivalent of the pairs() function on tables. Allows to iterate - -- in order - return orderedNext, t, nil -end - --- Shallow comparison between two tables. --- Return true if the two tables have the same keys with identical --- values, otherwise false. -function table_equal(t1, t2) - -- all key-value pairs in t1 must be in t2 - for k, v in pairs(t1) do - if t2[k] ~= v then return false end - end - -- there must not be other keys in t2 - for k, v in pairs(t2) do - if t1[k] == nil then return false end - end - return true -end - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/value_matching.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/value_matching.lua deleted file mode 100644 index 152425ee9..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/common/value_matching.lua +++ /dev/null @@ -1,171 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. - -local l = require "lpeg" -l.locale(l) -local pcall = pcall -local string = require 'string' - -local patterns = require 'patterns' -local error = error -local setmetatable = setmetatable -local tonumber = tonumber - -local C = l.C -local P = l.P -local S = l.S -local V = l.V -local Ct = l.Ct -local Cc = l.Cc - -local Optional_space = patterns.sp^0 -local Only_spaces = patterns.sp^1 * -1 - -local function space(pat) - return Optional_space * pat * Optional_space -end - -local EQ = P'==' -local NEQ = P'!=' -local GT = P'>' -local LT = P'<' -local GTE = P'>=' -local LTE = P'<=' -local MATCH = P'=~' -local NO_MATCH = P'!~' - -local OR = P'||' -local AND = P'&&' - -local function get_operator(op) - if op == '' then - return '==' - end - return op -end - -local numerical_operator = (EQ + NEQ + LTE + GTE + GT + LT )^-1 / get_operator -local sub_numerical_expression = space(numerical_operator) * patterns.Number * Optional_space -local is_plain_numeric = (sub_numerical_expression * ((OR^1 + AND^1) * sub_numerical_expression)^0) * -1 - -local quoted_string = (P'"' * C((P(1) - (P'"'))^1) * P'"' + C((P(1) - patterns.sp)^1)) -local string_operator = (EQ + NEQ + MATCH + NO_MATCH)^-1 / get_operator -local sub_string_expression = space(string_operator) * quoted_string * Optional_space -local is_plain_string = (sub_string_expression * ((OR^1 + AND^1) * sub_string_expression)^0) * -1 - -local numerical_expression = P { - 'OR'; - AND = Ct(Cc('and') * V'SUB' * space(AND) * V'AND' + V'SUB'), - OR = Ct(Cc('or') * V'AND' * space(OR) * V'OR' + V'AND'), - SUB = Ct(sub_numerical_expression) -} * -1 - -local string_expression = P { - 'OR'; - AND = Ct(Cc('and') * V'SUB' * space(AND) * V'AND' + V'SUB'), - OR = Ct(Cc('or') * V'AND' * space(OR) * V'OR' + V'AND'), - SUB = Ct(sub_string_expression) -} * -1 - -local is_complex = patterns.anywhere(EQ + NEQ + LTE + GTE + GT + LT + MATCH + NO_MATCH + OR + AND) - -local function eval_tree(tree, value) - local match = false - - if type(tree[1]) == 'table' then - match = eval_tree(tree[1], value) - else - local operator = tree[1] - if operator == 'and' or operator == 'or' then - match = eval_tree(tree[2], value) - for i=3, #tree, 1 do - local m = eval_tree(tree[i], value) - if operator == 'or' then - match = match or m - else - match = match and m - end - end - else - local matcher = tree[2] - if operator == '==' then - return value == matcher - elseif operator == '!=' then - return value ~= matcher - elseif operator == '>' then - return value > matcher - elseif operator == '<' then - return value < matcher - elseif operator == '>=' then - return value >= matcher - elseif operator == '<=' then - return value <= matcher - elseif operator == '=~' then - local ok, m = pcall(string.find, value, matcher) - return ok and m ~= nil - elseif operator == '!~' then - local ok, m = pcall(string.find, value, matcher) - return ok and m == nil - end - end - end - return match -end - -local MatchExpression = {} -MatchExpression.__index = MatchExpression - -setfenv(1, MatchExpression) -- Remove external access to contain everything in the module - -function MatchExpression.new(expression) - local r = {} - setmetatable(r, MatchExpression) - if is_complex:match(expression) then - r.is_plain_numeric_exp = is_plain_numeric:match(expression) ~= nil - - if r.is_plain_numeric_exp then - r.tree = numerical_expression:match(expression) - elseif is_plain_string:match(expression) ~= nil then - r.tree = string_expression:match(expression) - end - if r.tree == nil then - error('Invalid expression: ' .. expression) - end - else - if expression == '' or Only_spaces:match(expression) then - error('Expression is empty') - end - r.is_simple_equality_matching = true - end - r.expression = expression - - return r -end - -function MatchExpression:matches(value) - if self.is_simple_equality_matching then - return self.expression == value or - tonumber(self.expression) == value or - tonumber(value) == self.expression - end - if self.is_plain_numeric_exp then - value = tonumber(value) - if value == nil then - return false - end - end - return eval_tree(self.tree, value) -end - -return MatchExpression diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/ceilometer.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/ceilometer.lua deleted file mode 100644 index 01564af6e..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/ceilometer.lua +++ /dev/null @@ -1,135 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. -require "string" -require "cjson" -require 'table' -require 'math' - -local patt = require 'patterns' -local utils = require 'lma_utils' -local l = require 'lpeg' -l.locale(l) - -function normalize_uuid(uuid) - return patt.Uuid:match(uuid) -end - --- the metadata_fields parameter is a list of words separated by space -local fields_grammar = l.Ct((l.C((l.P(1) - l.P" ")^1) * l.P" "^0)^0) -local metadata_fields = fields_grammar:match( - read_config("metadata_fields") or "" -) - -local decode_resources = read_config('decode_resources') or false - -local sample_msg = { - Timestamp = nil, - -- This message type has the same structure than 'bulk_metric'. - Type = "ceilometer_samples", - Payload = nil -} - -local resource_msg = { - Timestamp = nil, - Type = "ceilometer_resource", - Fields = nil, -} - -function inject_metadata(metadata, tags) - local value - for _, field in ipairs(metadata_fields) do - value = metadata[field] - if value ~= nil and type(value) ~= 'table' then - tags["metadata." .. field] = value - end - end -end - -function add_resource_to_payload(sample, payload) - - local resource_data = { - timestamp = sample.timestamp, - resource_id = sample.resource_id, - source = sample.source or "", - metadata = sample.resource_metadata, - user_id = sample.user_id, - project_id = sample.project_id, - meter = { - [sample.counter_name] = { - type = sample.counter_type, - unit = sample.counter_unit - } - } - } - payload[sample.resource_id] = resource_data -end - - -function add_sample_to_payload(sample, payload) - local sample_data = { - name='sample', - timestamp = patt.Timestamp:match(sample.timestamp), - values = { - value = sample.counter_volume, - message_id = sample.message_id, - recorded_at = sample.recorded_at, - timestamp = sample.timestamp, - message_signature = sample.signature, - type = sample.counter_type, - unit = sample.counter_unit - } - } - local tags = { - meter = sample.counter_name, - resource_id = sample.resource_id, - project_id = sample.project_id , - user_id = sample.user_id, - source = sample.source - } - - inject_metadata(sample.resource_metadata or {}, tags) - sample_data["tags"] = tags - table.insert(payload, sample_data) -end - -function process_message () - local data = read_message("Payload") - local ok, message = pcall(cjson.decode, data) - if not ok then - return -1, "Cannot decode Payload" - end - local ok, message_body = pcall(cjson.decode, message["oslo.message"]) - if not ok then - return -1, "Cannot decode Payload[oslo.message]" - end - local sample_payload = {} - local resource_payload = {} - for _, sample in ipairs(message_body["payload"]) do - add_sample_to_payload(sample, sample_payload) - if decode_resources then - add_resource_to_payload(sample, resource_payload) - end - end - sample_msg.Payload = cjson.encode(sample_payload) - sample_msg.Timestamp = patt.Timestamp:match(message_body.timestamp) - utils.safe_inject_message(sample_msg) - - if decode_resources then - resource_msg.Payload = cjson.encode(resource_payload) - resource_msg.Timestamp = patt.Timestamp:match(message_body.timestamp) - utils.safe_inject_message(resource_msg) - end - - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/collectd.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/collectd.lua deleted file mode 100644 index 6c3415b57..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/collectd.lua +++ /dev/null @@ -1,452 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require "string" -require "cjson" - -local utils = require 'lma_utils' - -local sep = '_' - -local processes_map = { - ps_code = 'memory_code', - ps_count = '', - ps_cputime = 'cputime', - ps_data = 'memory_data', - ps_disk_octets = 'disk_bytes', - ps_disk_ops = 'disk_ops', - ps_pagefaults = 'pagefaults', - ps_rss = 'memory_rss', - ps_stacksize = 'stacksize', - ps_vm = 'memory_virtual', -} - --- The following table keeps a list of metrics from plugin where the --- Fields[hostname] shouldn't be set by default. -local hostname_free = { - ceph_mon = true, - ceph_pool = true, - check_openstack_api = true, - cinder = true, - glance = true, - http_check = true, - hypervisor_stats = true, - keystone = true, - neutron = true, - nova = true, - pacemaker = true, -} - --- this is needed for the libvirt metrics because in that case, collectd sends --- the instance's ID instead of the hostname in the 'host' attribute -local hostname = read_config('hostname') or error('hostname must be specified') -local swap_size = (read_config('swap_size') or 0) + 0 - -function replace_dot_by_sep (str) - return string.gsub(str, '%.', sep) -end - -function process_message () - local ok, samples = pcall(cjson.decode, read_message("Payload")) - if not ok then - -- TODO: log error - return -1 - end - - for _, sample in ipairs(samples) do - local metric_prefix = sample['type'] - if sample['type_instance'] ~= "" then - metric_prefix = metric_prefix .. sep .. sample['type_instance'] - end - - local metric_source = sample['plugin'] - - for i, value in ipairs(sample['values']) do - local skip_it = false - local metric_name = metric_prefix - if sample['dsnames'][i] ~= "value" then - metric_name = metric_name .. sep .. sample['dsnames'][i] - end - - local msg = { - Timestamp = sample['time'] * 1e9, -- Heka expects nanoseconds - Hostname = sample['host'], - Logger = "collectd", - Payload = utils.safe_json_encode(sample) or '', - Severity = 6, - Type = "metric", - Fields = { - interval = sample['interval'], - source = metric_source, - type = sample['dstypes'][i], - value = value, - tag_fields = {}, - } - } - - -- Check if Fields[hostname] should be added or not to the metric message - if not hostname_free[metric_source] then - msg['Fields']['hostname'] = sample['host'] - end - - -- Normalize metric name, unfortunately collectd plugins aren't - -- always consistent on metric namespaces so we need a few if/else - -- statements to cover all cases. - if sample['meta'] and sample['meta']['service_check'] then - msg['Fields']['name'] = sample['meta']['service_check'] .. sep .. 'check' - msg['Fields']['details'] = sample['meta']['failure'] - if sample['meta']['local_check'] then - -- if the check is local to the node, add the hostname - msg['Fields']['hostname'] = sample['host'] - end - elseif metric_source == 'df' then - local entity - if sample['type'] == 'df_inodes' then - entity = 'inodes' - elseif sample['type'] == 'percent_inodes' then - entity = 'inodes_percent' - elseif sample['type'] == 'percent_bytes' then - entity = 'space_percent' - else -- sample['type'] == 'df_complex' - entity = 'space' - end - - local mount = sample['plugin_instance'] - if mount == 'root' then - mount = '/' - else - mount = '/' .. mount:gsub('-', '/') - end - - msg['Fields']['name'] = 'fs' .. sep .. entity .. sep .. sample['type_instance'] - msg['Fields']['fs'] = mount - table.insert(msg['Fields']['tag_fields'], 'fs') - elseif metric_source == 'disk' then - msg['Fields']['name'] = metric_name - msg['Fields']['device'] = sample['plugin_instance'] - table.insert(msg['Fields']['tag_fields'], 'device') - elseif metric_source == 'cpu' then - msg['Fields']['name'] = 'cpu' .. sep .. sample['type_instance'] - msg['Fields']['cpu_number'] = sample['plugin_instance'] - table.insert(msg['Fields']['tag_fields'], 'cpu_number') - elseif metric_source == 'netlink' then - local netlink_metric = sample['type'] - if netlink_metric == 'if_rx_errors' then - netlink_metric = 'if_errors_rx' - elseif netlink_metric == 'if_tx_errors' then - netlink_metric = 'if_errors_tx' - end - - -- Netlink plugin can send one or two values. Use dsnames only when needed. - if sample['dsnames'][i] ~= 'value' then - netlink_metric = netlink_metric .. sep .. sample['dsnames'][i] - end - -- and type of errors is set in type_instance - if sample['type_instance'] ~= '' then - netlink_metric = netlink_metric .. sep .. sample['type_instance'] - end - msg['Fields']['name'] = netlink_metric - msg['Fields']['interface'] = sample['plugin_instance'] - table.insert(msg['Fields']['tag_fields'], 'interface') - elseif metric_source == 'processes' then - if processes_map[sample['type']] then - -- metrics related to a specific process - msg['Fields']['service'] = sample['plugin_instance'] - table.insert(msg['Fields']['tag_fields'], 'service') - msg['Fields']['name'] = 'lma_components' - if processes_map[sample['type']] ~= '' then - msg['Fields']['name'] = msg['Fields']['name'] .. sep .. processes_map[sample['type']] - end - if sample['dsnames'][i] ~= 'value' then - msg['Fields']['name'] = msg['Fields']['name'] .. sep .. sample['dsnames'][i] - end - - -- For ps_cputime, convert it to a percentage: collectd is - -- sending us the number of microseconds allocated to the - -- process as a rate so within 1 second. - if sample['type'] == 'ps_cputime' then - msg['Fields']['value'] = 100 * value / 1e6 - end - else - -- metrics related to all processes - msg['Fields']['name'] = 'processes' - if sample['type'] == 'ps_state' then - msg['Fields']['name'] = msg['Fields']['name'] .. sep .. 'count' - msg['Fields']['state'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'state') - else - msg['Fields']['name'] = msg['Fields']['name'] .. sep .. sample['type'] - end - end - elseif metric_source == 'dbi' and sample['plugin_instance'] == 'mysql_status' then - msg['Fields']['name'] = 'mysql' .. sep .. replace_dot_by_sep(sample['type_instance']) - elseif metric_source == 'mysql' then - if sample['type'] == 'threads' then - msg['Fields']['name'] = 'mysql_' .. metric_name - elseif sample['type'] == 'mysql_commands' then - msg['Fields']['name'] = sample['type'] - msg['Fields']['statement'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'statement') - elseif sample['type'] == 'mysql_handler' then - msg['Fields']['name'] = sample['type'] - msg['Fields']['handler'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'handler') - else - msg['Fields']['name'] = metric_name - end - elseif metric_source == 'check_openstack_api' then - -- For OpenStack API metrics, plugin_instance = - msg['Fields']['name'] = 'openstack_check_api' - msg['Fields']['service'] = sample['plugin_instance'] - table.insert(msg['Fields']['tag_fields'], 'service') - if sample['meta'] then - msg['Fields']['os_region'] = sample['meta']['region'] - end - elseif metric_source == 'hypervisor_stats' then - -- Metrics from the OpenStack hypervisor metrics where - -- type_instance = which can end by _MB or _GB - msg['Fields']['name'] = 'openstack' .. sep .. 'nova' .. sep - local name, unit - name, unit = string.match(sample['type_instance'], '^(.+)_(.B)$') - if name then - msg['Fields']['name'] = msg['Fields']['name'] .. name - msg.Fields['value'] = {value = msg.Fields['value'], representation = unit} - else - msg['Fields']['name'] = msg['Fields']['name'] .. sample['type_instance'] - end - if sample['meta'] and sample['meta']['host'] then - msg['Fields']['hostname'] = sample['meta']['host'] - end - if sample['meta'] and sample['meta']['aggregate'] then - msg['Fields']['aggregate'] = sample['meta']['aggregate'] - table.insert(msg['Fields']['tag_fields'], 'aggregate') - end - if sample['meta'] and sample['meta']['aggregate_id'] then - msg['Fields']['aggregate_id'] = sample['meta']['aggregate_id'] - table.insert(msg['Fields']['tag_fields'], 'aggregate_id') - end - elseif metric_source == 'rabbitmq_info' then - msg['Fields']['name'] = 'rabbitmq' .. sep .. sample['type_instance'] - if sample['meta'] and sample['meta']['queue'] then - msg['Fields']['queue'] = sample['meta']['queue'] - table.insert(msg['Fields']['tag_fields'], 'queue') - end - elseif metric_source == 'nova' then - if sample['plugin_instance'] == 'nova_services' or - sample['plugin_instance'] == 'nova_services_percent' or - sample['plugin_instance'] == 'nova_service' then - msg['Fields']['name'] = 'openstack_' .. sample['plugin_instance'] - msg['Fields']['service'] = sample['meta']['service'] - msg['Fields']['state'] = sample['meta']['state'] - table.insert(msg['Fields']['tag_fields'], 'service') - table.insert(msg['Fields']['tag_fields'], 'state') - if sample['plugin_instance'] == 'nova_service' then - msg['Fields']['hostname'] = sample['meta']['host'] - end - else - msg['Fields']['name'] = 'openstack' .. sep .. 'nova' .. sep .. replace_dot_by_sep(sample['plugin_instance']) - msg['Fields']['state'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'state') - end - elseif metric_source == 'cinder' then - if sample['plugin_instance'] == 'cinder_services' or - sample['plugin_instance'] == 'cinder_services_percent' or - sample['plugin_instance'] == 'cinder_service' then - msg['Fields']['name'] = 'openstack_' .. sample['plugin_instance'] - msg['Fields']['service'] = sample['meta']['service'] - msg['Fields']['state'] = sample['meta']['state'] - table.insert(msg['Fields']['tag_fields'], 'service') - table.insert(msg['Fields']['tag_fields'], 'state') - if sample['plugin_instance'] == 'cinder_service' then - msg['Fields']['hostname'] = sample['meta']['host'] - end - else - msg['Fields']['name'] = 'openstack' .. sep .. 'cinder' .. sep .. replace_dot_by_sep(sample['plugin_instance']) - msg['Fields']['state'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'state') - end - elseif metric_source == 'glance' then - msg['Fields']['name'] = 'openstack' .. sep .. 'glance' .. sep .. sample['type_instance'] - msg['Fields']['state'] = sample['meta']['status'] - msg['Fields']['visibility'] = sample['meta']['visibility'] - table.insert(msg['Fields']['tag_fields'], 'state') - table.insert(msg['Fields']['tag_fields'], 'visibility') - elseif metric_source == 'keystone' then - msg['Fields']['name'] = 'openstack' .. sep .. 'keystone' .. sep .. sample['type_instance'] - if sample['meta']['state'] then - msg['Fields']['state'] = sample['meta']['state'] - table.insert(msg['Fields']['tag_fields'], 'state') - end - elseif metric_source == 'neutron' then - if sample['type_instance'] == 'networks' or sample['type_instance'] == 'ports' or sample['type_instance'] == 'routers' or sample['type_instance'] == 'floatingips' then - skip_it = true - elseif sample['type_instance'] == 'subnets' then - msg['Fields']['name'] = 'openstack' .. sep .. 'neutron' .. sep .. 'subnets' - elseif sample['type_instance'] == 'neutron_agents' or - sample['type_instance'] == 'neutron_agents_percent' or - sample['type_instance'] == 'neutron_agent' then - msg['Fields']['name'] = 'openstack_' .. sample['type_instance'] - msg['Fields']['service'] = sample['meta']['service'] - msg['Fields']['state'] = sample['meta']['state'] - table.insert(msg['Fields']['tag_fields'], 'service') - table.insert(msg['Fields']['tag_fields'], 'state') - if sample['type_instance'] == 'neutron_agent' then - msg['Fields']['hostname'] = sample['meta']['host'] - end - elseif string.match(sample['type_instance'], '^ports') then - local resource, owner, state = string.match(sample['type_instance'], '^([^.]+)%.([^.]+)%.(.+)$') - msg['Fields']['name'] = 'openstack' .. sep .. 'neutron' .. sep .. replace_dot_by_sep(resource) - msg['Fields']['owner'] = owner - msg['Fields']['state'] = state - table.insert(msg['Fields']['tag_fields'], 'owner') - table.insert(msg['Fields']['tag_fields'], 'state') - else - local resource, state = string.match(sample['type_instance'], '^([^.]+)%.(.+)$') - msg['Fields']['name'] = 'openstack' .. sep .. 'neutron' .. sep .. replace_dot_by_sep(resource) - msg['Fields']['state'] = state - table.insert(msg['Fields']['tag_fields'], 'state') - end - elseif metric_source == 'memcached' then - msg['Fields']['name'] = 'memcached' .. sep .. string.gsub(metric_name, 'memcached_', '') - elseif metric_source == 'haproxy' then - msg['Fields']['name'] = 'haproxy' .. sep .. sample['type_instance'] - if sample['meta'] then - if sample['meta']['backend'] then - msg['Fields']['backend'] = sample['meta']['backend'] - table.insert(msg['Fields']['tag_fields'], 'backend') - if sample['meta']['state'] then - msg['Fields']['state'] = sample['meta']['state'] - table.insert(msg['Fields']['tag_fields'], 'state') - end - if sample['meta']['server'] then - msg['Fields']['server'] = sample['meta']['server'] - table.insert(msg['Fields']['tag_fields'], 'server') - end - elseif sample['meta']['frontend'] then - msg['Fields']['frontend'] = sample['meta']['frontend'] - table.insert(msg['Fields']['tag_fields'], 'frontend') - end - end - elseif metric_source == 'apache' then - metric_name = string.gsub(metric_name, 'apache_', '') - msg['Fields']['name'] = 'apache' .. sep .. string.gsub(metric_name, 'scoreboard', 'workers') - elseif metric_source == 'ceph_osd_perf' then - msg['Fields']['name'] = 'ceph_perf' .. sep .. sample['type'] - - msg['Fields']['cluster'] = sample['plugin_instance'] - msg['Fields']['osd'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'cluster') - table.insert(msg['Fields']['tag_fields'], 'osd') - elseif metric_source:match('^ceph') then - msg['Fields']['name'] = 'ceph' .. sep .. sample['type'] - if sample['dsnames'][i] ~= 'value' then - msg['Fields']['name'] = msg['Fields']['name'] .. sep .. sample['dsnames'][i] - end - - msg['Fields']['cluster'] = sample['plugin_instance'] - table.insert(msg['Fields']['tag_fields'], 'cluster') - - if sample['type_instance'] ~= '' then - local additional_tag - if string.match(sample['type'], '^pool_') then - additional_tag = 'pool' - elseif string.match(sample['type'], '^pg_state') then - additional_tag = 'state' - elseif string.match(sample['type'], '^osd_') then - additional_tag = 'osd' - end - if additional_tag then - msg['Fields'][additional_tag] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], additional_tag) - end - end - elseif metric_source == 'pacemaker' then - if sample['meta'] and sample['meta']['host'] then - msg['Fields']['hostname'] = sample['meta']['host'] - end - - msg['Fields']['name'] = metric_source .. sep .. sample['type_instance'] - - -- add dimension fields - for _, v in ipairs({'status', 'resource'}) do - if sample['meta'] and sample['meta'][v] then - msg['Fields'][v] = sample['meta'][v] - table.insert(msg['Fields']['tag_fields'], v) - end - end - elseif metric_source == 'users' then - -- 'users' is a reserved name for InfluxDB v0.9 - msg['Fields']['name'] = 'logged_users' - elseif metric_source == 'libvirt' then - -- collectd sends the instance's ID in the 'host' field - msg['Fields']['instance_id'] = sample['host'] - table.insert(msg['Fields']['tag_fields'], 'instance_id') - msg['Fields']['hostname'] = hostname - msg['Hostname'] = hostname - - if string.match(sample['type'], '^disk_') then - msg['Fields']['name'] = 'virt' .. sep .. sample['type'] .. sep .. sample['dsnames'][i] - msg['Fields']['device'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'device') - elseif string.match(sample['type'], '^if_') then - msg['Fields']['name'] = 'virt' .. sep .. sample['type'] .. sep .. sample['dsnames'][i] - msg['Fields']['interface'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'interface') - elseif sample['type'] == 'virt_cpu_total' then - msg['Fields']['name'] = 'virt_cpu_time' - elseif sample['type'] == 'virt_vcpu' then - msg['Fields']['name'] = 'virt_vcpu_time' - msg['Fields']['vcpu_number'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'vcpu_number') - else - msg['Fields']['name'] = 'virt' .. sep .. metric_name - end - elseif metric_source == 'elasticsearch_cluster' or metric_source == 'influxdb' then - msg['Fields']['name'] = metric_source .. sep .. sample['type_instance'] - elseif metric_source == 'http_check' then - msg['Fields']['name'] = metric_source - msg['Fields']['service'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'service') - elseif metric_source == 'check_local_endpoint' then - msg['Fields']['name'] = 'openstack_check_local_api' - msg['Fields']['service'] = sample['type_instance'] - table.insert(msg['Fields']['tag_fields'], 'service') - else - msg['Fields']['name'] = replace_dot_by_sep(metric_name) - end - - if not skip_it then - if msg['Fields']['hostname'] then - table.insert(msg['Fields']['tag_fields'], 'hostname') - end - utils.inject_tags(msg) - -- Before injecting the message we need to check that tag_fields is not an - -- empty table otherwise the protobuf encoder fails to encode the table. - if #msg['Fields']['tag_fields'] == 0 then - msg['Fields']['tag_fields'] = nil - end - utils.safe_inject_message(msg) - if metric_source == 'swap' and metric_name == 'swap_used' and swap_size > 0 then - -- collectd 5.4.0 doesn't report the used swap in - -- percentage, this is why the metric is computed and - -- injected by this plugin. - msg['Fields']['name'] = 'swap_percent_used' - msg['Fields']['value'] = value / swap_size - utils.safe_inject_message(msg) - end - end - end - end - - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/generic_syslog.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/generic_syslog.lua deleted file mode 100644 index 48e526288..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/generic_syslog.lua +++ /dev/null @@ -1,50 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require "string" - -local syslog = require "syslog" -local utils = require 'lma_utils' - -local msg = { - Timestamp = nil, - Type = 'log', - Hostname = nil, - Payload = nil, - Pid = nil, - Fields = nil, - Severity = nil, -} - -local syslog_pattern = read_config("syslog_pattern") or error("syslog_pattern configuration must be specified") -local syslog_grammar = syslog.build_rsyslog_grammar(syslog_pattern) - --- This grammar is intended for log messages that are generated before RSYSLOG --- is fully configured -local fallback_syslog_pattern = read_config("fallback_syslog_pattern") -local fallback_syslog_grammar -if fallback_syslog_pattern then - fallback_syslog_grammar = syslog.build_rsyslog_grammar(fallback_syslog_pattern) -end - -function process_message () - local log = read_message("Payload") - - if utils.parse_syslog_message(syslog_grammar, log, msg) or - (fallback_syslog_grammar and utils.parse_syslog_message(fallback_syslog_grammar, log, msg)) then - msg.Logger = string.gsub(read_message('Logger'), '%.log$', '') - return utils.safe_inject_message(msg) - end - - return -1 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/keystone_wsgi_log.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/keystone_wsgi_log.lua deleted file mode 100644 index a3c970bb5..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/keystone_wsgi_log.lua +++ /dev/null @@ -1,73 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local l = require 'lpeg' -l.locale(l) - -local common_log_format = require 'common_log_format' -local patt = require 'patterns' -local utils = require 'lma_utils' - -local msg = { - Timestamp = nil, - Type = 'log', - Hostname = nil, - Payload = nil, - Pid = nil, - Fields = nil, - Severity = 6, -} - -local severity_label = utils.severity_to_label_map[msg.Severity] - -local apache_log_pattern = read_config("apache_log_pattern") or error( - "apache_log_pattern configuration must be specificed") -local apache_grammar = common_log_format.build_apache_grammar(apache_log_pattern) -local request_grammar = l.Ct(patt.http_request) - -function process_message () - - -- logger is either "keystone-wsgi-main" or "keystone-wsgi-admin" - local logger = read_message("Logger") - - local log = read_message("Payload") - - local m - - m = apache_grammar:match(log) - if m then - msg.Logger = 'openstack.keystone' - msg.Payload = log - msg.Timestamp = m.time - - msg.Fields = {} - msg.Fields.http_status = m.status - msg.Fields.http_response_time = m.request_time.value / 1e6 -- us to sec - msg.Fields.programname = logger - msg.Fields.severity_label = severity_label - - local request = m.request - m = request_grammar:match(request) - if m then - msg.Fields.http_method = m.http_method - msg.Fields.http_url = m.http_url - msg.Fields.http_version = m.http_version - end - - utils.inject_tags(msg) - return utils.safe_inject_message(msg) - end - - return -1, string.format("Failed to parse %s log: %s", logger, string.sub(log, 1, 64)) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/libvirt_log.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/libvirt_log.lua deleted file mode 100644 index a191b8fd7..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/libvirt_log.lua +++ /dev/null @@ -1,63 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local l = require 'lpeg' -l.locale(l) - -local string = require 'string' -local patt = require 'patterns' -local utils = require 'lma_utils' - -local msg = { - Timestamp = nil, - Type = 'log', - Hostname = nil, - Payload = nil, - Pid = nil, - Fields = nil, - Severity = nil, -} - --- libvirt message logs are formatted like this: --- --- 2015-03-26 17:24:52.126+0000: : : Message - -local timestamp = l.Cg(patt.Timestamp, "Timestamp") -local pid = l.Cg(patt.Pid, "Pid") -local severity = l.Cg(l.P"debug" + "info" + "warning" + "error", "Severity") -local message = l.Cg(patt.Message, "Message") - -local grammar = l.Ct(timestamp * ": " * pid * ": " * severity * " : " * message) - -function process_message () - local log = read_message("Payload") - - local m = grammar:match(log) - if not m then - return -1 - end - - m.Severity = string.upper(m.Severity) - - msg.Timestamp = m.Timestamp - msg.Pid = m.Pid - msg.Payload = m.Message - msg.Severity = utils.label_to_severity_map[m.Severity] - - msg.Fields = {} - msg.Fields.severity_label = m.Severity - msg.Fields.programname = 'libvirt' - utils.inject_tags(msg) - - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/metric.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/metric.lua deleted file mode 100644 index 0994a0098..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/metric.lua +++ /dev/null @@ -1,90 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. - -require "cjson" -require "string" - -local l = require 'lpeg' -l.locale(l) - -local loggers_pattern = l.Ct( (l.C((l.P(1) - l.space)^1) * l.space^0)^1 * -1) -local loggers_list = loggers_pattern:match(read_config('deserialize_bulk_metric_for_loggers') or '') - -local loggers = {} -for _, logger in ipairs(loggers_list) do - loggers[logger] = true -end - -local utils = require 'lma_utils' - -function process_message () - local msg = decode_message(read_message("raw")) - if string.match(msg.Type, 'bulk_metric$') and loggers[msg.Logger] ~= nil then - - local ok, metrics = pcall(cjson.decode, msg.Payload) - if not ok then - return -1, metrics - end - - local new_msg = { - Timestamp = msg.Timestamp, - Hostname = msg.Hostname, - Severity = msg.Severity, - Logger = msg.Logger, - Type = nil, - Payload = '', - Fields = {}, - } - for _, metric in ipairs(metrics) do - local fields = {} - local metric_type - if metric.value then - metric_type = 'metric' - fields['value'] = metric.value - else - metric_type = 'multivalue_metric' - local value_fields = {} - for k, v in pairs(metric.values) do - fields[k] = v - table.insert(value_fields, k) - end - fields['value_fields'] = value_fields - end - local tag_fields = {} - for t, v in pairs(metric.tags or {}) do - fields[t] = v - table.insert(tag_fields, t) - end - fields['tag_fields'] = tag_fields - fields['name'] = metric.name - fields['hostname'] = msg.Hostname - - new_msg.Type = metric_type - new_msg.Fields = fields - - utils.inject_tags(new_msg) - ok, err = utils.safe_inject_message(new_msg) - if ok ~= 0 then - return -1, err - end - end - else -- simple metric - utils.inject_tags(msg) - ok, err = utils.safe_inject_message(msg) - if ok ~= 0 then - return -1, err - end - end - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/mysql_log.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/mysql_log.lua deleted file mode 100644 index 689aa163f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/mysql_log.lua +++ /dev/null @@ -1,57 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require "string" -local l = require 'lpeg' -l.locale(l) - -local syslog = require "syslog" -local patt = require 'patterns' -local utils = require 'lma_utils' - -local msg = { - Timestamp = nil, - Type = 'log', - Hostname = nil, - Payload = nil, - Pid = nil, - Fields = nil, - Severity = nil, -} - -local syslog_pattern = read_config("syslog_pattern") or error("syslog_pattern configuration must be specified") - -local sp = l.space -local colon = l.P":" - -local syslog_grammar = syslog.build_rsyslog_grammar(syslog_pattern) - --- mysqld logs are cranky,the date is YYMMMDD, the hours have no leading zero and the "real" severity level is enclosed by square brackets... -local mysql_grammar = l.Ct(l.digit^-6 * sp^1 * l.digit^-2 * colon * l.digit^-2 * colon * l.digit^-2 * sp^1 * l.P"[" * l.Cg(l.R("az", "AZ")^0 / string.upper, "SeverityLabel") * l.P"]" * sp^1 * l.Cg(patt.Message, "Message")) - - -function process_message () - local log = read_message("Payload") - - if not utils.parse_syslog_message(syslog_grammar, log, msg) then - return -1 - end - - local m = mysql_grammar:match(msg.Payload) - if m then - msg.Fields.severity_label = m.SeverityLabel - msg.Payload = m.Message - end - - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/noop.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/noop.lua deleted file mode 100644 index be9a9ddc7..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/noop.lua +++ /dev/null @@ -1,28 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local msg_type = read_config('msg_type') or error('msg_type must be defined') - -local msg = { - Type = msg_type, - Severity = 7, -- debug - Payload = nil, - Fields = nil, -} - -function process_message () - inject_message(msg) - - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/notification.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/notification.lua deleted file mode 100644 index 3f10e0d05..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/notification.lua +++ /dev/null @@ -1,191 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require "string" -require "cjson" - -local patt = require 'patterns' -local utils = require 'lma_utils' - --- Mapping table from event_type prefixes to notification loggers -local logger_map = { - --cinder - volume = 'cinder', - snapshot = 'cinder', - -- glance - image = 'glance', - -- heat - orchestration = 'heat', - -- keystone - identity = 'keystone', - -- nova - compute = 'nova', - compute_task = 'nova', - scheduler = 'nova', - keypair = 'nova', - -- neutron - floatingip = 'neutron', - security_group = 'neutron', - security_group_rule = 'neutron', - network = 'neutron', - port = 'neutron', - router = 'neutron', - subnet = 'neutron', - -- sahara - sahara = 'sahara', -} - --- Mapping table between the attributes in the notification's payload and the --- fields in the Heka message -local payload_fields = { - -- all - tenant_id = 'tenant_id', - user_id = 'user_id', - display_name = 'display_name', - -- nova - vcpus = 'vcpus', - availability_zone = 'availability_zone', - instance_id = 'instance_id', - instance_type = 'instance_type', - image_name = 'image_name', - memory_mb = 'memory_mb', - disk_gb = 'disk_gb', - state = 'state', - old_state = 'old_state', - old_task_state = 'old_task_state', - new_task_state = 'new_task_state', - created_at = 'created_at', - launched_at = 'launched_at', - deleted_at = 'deleted_at', - terminated_at = 'terminated_at', - -- neutron - network_id = 'network_id', - subnet_id = 'subnet_id', - port_id = 'port_id', - -- cinder - volume_id = 'volume_id', - size = 'size', - status = 'state', - replication_status = 'replication_status', -} - -function normalize_uuid(uuid) - return patt.Uuid:match(uuid) -end - --- Mapping table defining transformation functions to be applied, keys are the --- attributes in the notification's payload and values are Lua functions -local transform_functions = { - created_at = utils.format_datetime, - launched_at = utils.format_datetime, - deleted_at = utils.format_datetime, - terminated_at = utils.format_datetime, - user_id = normalize_uuid, - tenant_id = normalize_uuid, - instance_id = normalize_uuid, - network_id = normalize_uuid, - subnet_id = normalize_uuid, - port_id = normalize_uuid, - volume_id = normalize_uuid, -} - -local include_full_notification = read_config("include_full_notification") or false - -function process_cadf_event(notif, msg) - local cadf_event = notif.payload - - msg.Type = 'audit' - msg.Logger = notif.publisher_id - msg.Severity = utils.label_to_severity_map[notif.priority] - msg.Timestamp = patt.Timestamp:match(cadf_event.eventTime) - - msg.Fields.action = cadf_event.action - -- notif.event_type can be 'http.request' or 'http.response' - msg.Fields.notification_type = notif.event_type - -- cadf_event.eventType can be 'activity', 'monitor', ... - msg.Fields.event_type = cadf_event.eventType - msg.Fields.outcome = cadf_event.outcome - msg.Fields.severity_label = notif.priority -end - -function process_notification(notif, msg) - local openstack_notif = notif.payload - - msg.Type = 'notification' - msg.Logger = logger_map[string.match(notif.event_type, '([^.]+)')] - msg.Severity = utils.label_to_severity_map[notif.priority] - msg.Timestamp = patt.Timestamp:match(notif.timestamp) - - msg.Fields.publisher, msg.Hostname = string.match(notif.publisher_id, '([^.]+)%.([%w_-]+)') - if openstack_notif.host ~= nil then - msg.Hostname = string.match(openstack_notif.host, '([%w_-]+)') - end - - msg.Fields.event_type = notif.event_type - msg.Fields.severity_label = notif.priority - msg.Fields.hostname = msg.Hostname - - for k, v in pairs(payload_fields) do - local val = openstack_notif[k] - if val ~= nil then - local name = payload_fields[k] or k - local transform = transform_functions[k] - if transform ~= nil then - msg.Fields[name] = transform(val) - else - msg.Fields[name] = val - end - end - end -end - -function process_message() - local msg = {Fields={}} - local data = read_message("Payload") - local ok, notif = pcall(cjson.decode, data) - if not ok then - return -1, string.format("Failed to parse notification: %s: '%s'", notif, string.sub(data or 'N/A', 1, 64)) - end - - local oslo_version = notif['oslo.version'] - if oslo_version then - -- messagingv2 notifications - ok, notif = pcall(cjson.decode, notif['oslo.message']) - if not ok then - return -1, string.format("Failed to parse v%s notification: %s: '%s'", oslo_version, notif, string.sub(data or 'N/A', 1, 64)) - end - end - - if include_full_notification then - msg.Payload = data - else - msg.Payload = utils.safe_json_encode(notif.payload) or '{}' - end - - local ok, error_msg - if notif.payload.eventType and notif.payload.eventTime then - -- Payload of CADF event notifications always contain at least - -- eventType and eventTime fields - -- http://docs.openstack.org/developer/pycadf/specification/events.html - ok, error_msg = pcall(process_cadf_event, notif, msg) - else - ok, error_msg = pcall(process_notification, notif, msg) - end - - if not ok then - return -1, error_msg - end - - utils.inject_tags(msg) - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/openstack_log.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/openstack_log.lua deleted file mode 100644 index 9199bd4e4..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/openstack_log.lua +++ /dev/null @@ -1,143 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require "string" -require "table" -local l = require 'lpeg' -l.locale(l) - -local patt = require 'patterns' -local utils = require 'lma_utils' -local table_utils = require 'table_utils' - -local msg = { - Timestamp = nil, - Type = 'log', - Hostname = nil, - Payload = nil, - Pid = nil, - Fields = nil, - Severity = nil, -} - --- traceback_lines is a reference to a table used to accumulate lines of --- a Traceback. traceback_key represent the key of the Traceback lines --- being accumulated in traceback_lines. This is used to know when to --- stop accumulating and inject the Heka message. -local traceback_key = nil -local traceback_lines = nil - -function prepare_message (service, timestamp, pid, severity_label, - python_module, programname, payload) - msg.Logger = 'openstack.' .. service - msg.Timestamp = timestamp - msg.Payload = payload - msg.Pid = pid - msg.Severity = utils.label_to_severity_map[severity_label] or 7 - msg.Fields = {} - msg.Fields.severity_label = severity_label - msg.Fields.python_module = python_module - msg.Fields.programname = programname - msg.Payload = payload -end - --- OpenStack log messages are of this form: --- 2015-11-30 08:38:59.306 3434 INFO oslo_service.periodic_task [-] Blabla... --- --- [-] is the "request" part, it can take multiple forms. - -function process_message () - - -- Logger is of form "_" (e.g. "nova_nova-api", - -- "neutron_l3-agent"). - local logger = read_message("Logger") - local service, program = string.match(logger, '([^_]+)_(.+)') - - local log = read_message("Payload") - local m - - m = patt.openstack:match(log) - if not m then - return -1, string.format("Failed to parse %s log: %s", logger, string.sub(log, 1, 64)) - end - - local key = { - Timestamp = m.Timestamp, - Pid = m.Pid, - SeverityLabel = m.SeverityLabel, - PythonModule = m.PythonModule, - service = service, - program = program, - } - - if traceback_key ~= nil then - -- If traceback_key is not nil then it means we've started accumulated - -- lines of a Python traceback. We keep accumulating the traceback - -- lines util we get a different log key. - if table_utils.table_equal(traceback_key, key) then - table.insert(traceback_lines, m.Message) - return 0 - else - prepare_message(traceback_key.service, traceback_key.Timestamp, - traceback_key.Pid, traceback_key.SeverityLabel, - traceback_key.PythonModule, traceback_key.program, - table.concat(traceback_lines, '')) - traceback_key = nil - traceback_lines = nil - utils.inject_tags(msg) - -- Ignore safe_inject_message status code here to still get a - -- chance to inject the current log message. - utils.safe_inject_message(msg) - end - end - - if patt.traceback:match(m.Message) then - -- Python traceback detected, begin accumulating the lines making - -- up the traceback. - traceback_key = key - traceback_lines = {} - table.insert(traceback_lines, m.Message) - return 0 - end - - prepare_message(service, m.Timestamp, m.Pid, m.SeverityLabel, m.PythonModule, - program, m.Message) - - m = patt.openstack_request_context:match(msg.Payload) - if m then - msg.Fields.request_id = m.RequestId - if m.UserId then - msg.Fields.user_id = m.UserId - end - if m.TenantId then - msg.Fields.tenant_id = m.TenantId - end - end - - m = patt.openstack_http:match(msg.Payload) - if m then - msg.Fields.http_method = m.http_method - msg.Fields.http_status = m.http_status - msg.Fields.http_url = m.http_url - msg.Fields.http_version = m.http_version - msg.Fields.http_response_size = m.http_response_size - msg.Fields.http_response_time = m.http_response_time - m = patt.ip_address:match(msg.Payload) - if m then - msg.Fields.http_client_ip_address = m.ip_address - end - end - - utils.inject_tags(msg) - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/ovs_log.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/ovs_log.lua deleted file mode 100644 index 47b88ebf2..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/ovs_log.lua +++ /dev/null @@ -1,62 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local l = require 'lpeg' -l.locale(l) - -local syslog = require "syslog" -local patt = require 'patterns' -local utils = require 'lma_utils' - -local msg = { - Timestamp = nil, - Type = 'log', - Hostname = nil, - Paload = nil, - Logger = 'ovs', - Pid = nil, - Fields = nil, - Severity = nil, -} - -local pipe = l.P'|' - -local function_name = l.Cg((l.R("az", "AZ", "09") + l.P"." + l.P"-" + l.P"_" + l.P"(" + l.P")")^1, 'function_name') -local pid = l.Cg(patt.Pid, "Pid") -local timestamp = l.Cg(patt.Timestamp, "Timestamp") -local severity = l.Cg(syslog.severity, 'Severity') -local message = l.Cg(l.P(1 - l.P"\n")^0, "Message") - -local ovs_grammar = l.Ct(timestamp * pipe * pid * pipe * function_name * pipe * severity * pipe * message) - -function process_message () - local log = read_message("Payload") - local logger = read_message("Logger") - local m - - msg.Fields = {} - m = ovs_grammar:match(log) - if not m then - return -1 - end - msg.Timestamp = m.Timestamp - msg.Payload = m.function_name .. ': ' .. m.Message - msg.Pid = m.Pid - msg.Severity = m.Severity or 5 - msg.Fields.severity_label = utils.severity_to_label_map[m.Severity] - msg.Fields.programname = logger - - utils.inject_tags(msg) - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/pacemaker_log.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/pacemaker_log.lua deleted file mode 100644 index 1286e890b..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/pacemaker_log.lua +++ /dev/null @@ -1,75 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require "string" -local l = require 'lpeg' -l.locale(l) - -local dt = require "date_time" -local patt = require "patterns" -local syslog = require "syslog" -local utils = require 'lma_utils' - -local msg = { - Timestamp = nil, - Type = 'log', - Hostname = nil, - Payload = nil, - Pid = nil, - Fields = nil, - Severity = nil, -} - -local syslog_pattern = read_config("syslog_pattern") or error("syslog_pattern configuration must be specified") -local syslog_grammar = syslog.build_rsyslog_grammar(syslog_pattern) - --- This grammar is intended for debug and info messages which aren't emitted --- through Syslog. For example: --- Apr 29 13:23:46 [13545] node-32.domain.tld pacemakerd: INFO: get_cluster_type: Detected an active 'corosync' cluster -local sp = l.space -local colon = l.P":" - -local timestamp = l.Cg(dt.rfc3164_timestamp / dt.time_to_ns, "Timestamp") -local pid = l.Cg(patt.Pid, "Pid") -local severity = l.Cg((l.R"AZ" + l.R"az")^1 / string.upper, "SeverityLabel") -local programname = l.Cg(patt.programname, "programname") -local message = l.Cg(patt.Message, "Message") - -local fallback_grammar = l.Ct(timestamp * sp^1 * l.P'[' * pid * l.P']' * sp^1 * - (l.P(1) - sp)^0 * sp^1 * programname * colon * sp^1 * severity * colon * - sp^1 * message) - -function process_message () - local log = read_message("Payload") - - if utils.parse_syslog_message(syslog_grammar, log, msg) then - return utils.safe_inject_message(msg) - else - local m = fallback_grammar:match(log) - if m then - msg.Timestamp = m.Timestamp - msg.Payload = m.Message - msg.Pid = m.Pid - msg.Severity = utils.label_to_severity_map[m.SeverityLabel] or 7 - - msg.Fields = {} - msg.Fields.severity_label = utils.severity_to_label_map[msg.Severity] - msg.Fields.programname = m.programname - utils.inject_tags(msg) - - return utils.safe_inject_message(msg) - end - end - - return -1 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/pacemaker_resources.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/pacemaker_resources.lua deleted file mode 100644 index ae569657f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/pacemaker_resources.lua +++ /dev/null @@ -1,47 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require 'string' -local l = require 'lpeg' -local utils = require 'lma_utils' -l.locale(l) - -local msg = { - Timestamp = nil, - Type = "metric", - Payload = nil, - Severity = 6, -- INFO - Fields = nil -} - -local word = (l.R("az", "AZ", "09") + l.P"." + l.P"_" + l.P"-")^1 -local grammar = l.Ct(l.Cg(word, 'resource') * " " * l.Cg(l.xdigit, 'active')) - -function process_message () - local data = read_message("Payload") - local m = grammar:match(data) - if not m then - return -1 - end - msg.Timestamp = read_message("Timestamp") - msg.Payload = data - msg.Fields = {} - msg.Fields.source = 'pacemaker' - msg.Fields.type = utils.metric_type['GAUGE'] - msg.Fields.hostname = read_message('Hostname') - utils.inject_tags(msg) - - msg.Fields.name= string.format('pacemaker.resource.%s.active', m.resource) - msg.Fields.value = tonumber(m.active) - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/rabbitmq.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/rabbitmq.lua deleted file mode 100644 index 846a5f6da..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/decoders/rabbitmq.lua +++ /dev/null @@ -1,71 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local dt = require "date_time" -local l = require 'lpeg' -l.locale(l) - -local patt = require 'patterns' -local utils = require 'lma_utils' - -local msg = { - Timestamp = nil, - Type = 'log', - Hostname = nil, - Payload = nil, - Pid = nil, - Fields = nil, - Severity = nil, -} - --- RabbitMQ message logs are formatted like this: --- =ERROR REPORT==== 2-Jan-2015::09:17:22 === --- Blabla --- Blabla --- -local message = l.Cg(patt.Message / utils.chomp, "Message") --- The token before 'REPORT' isn't standardized so it can be a valid severity --- level as 'INFO' or 'ERROR' but also 'CRASH' or 'SUPERVISOR'. -local severity = l.Cg(l.R"AZ"^1, "SeverityLabel") -local day = l.R"13" * l.R"09" + l.R"19" -local datetime = l.Cg(day, "day") * patt.dash * dt.date_mabbr * patt.dash * dt.date_fullyear * - "::" * dt.rfc3339_partial_time -local timestamp = l.Cg(l.Ct(datetime)/ dt.time_to_ns, "Timestamp") - -local grammar = l.Ct("=" * severity * " REPORT==== " * timestamp * " ===" * l.P'\n' * message) - -function process_message () - local log = read_message("Payload") - - local m = grammar:match(log) - if not m then - return -1 - end - - msg.Timestamp = m.Timestamp - msg.Payload = m.Message - if utils.label_to_severity_map[m.SeverityLabel] then - msg.Severity = utils.label_to_severity_map[m.SeverityLabel] - elseif m.SeverityLabel == 'CRASH' then - msg.Severity = 2 -- CRITICAL - else - msg.Severity = 5 -- NOTICE - end - - msg.Fields = {} - msg.Fields.severity_label = utils.severity_to_label_map[msg.Severity] - msg.Fields.programname = 'rabbitmq' - utils.inject_tags(msg) - - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/es_ceilometer_resources.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/es_ceilometer_resources.lua deleted file mode 100644 index 860ba03ba..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/es_ceilometer_resources.lua +++ /dev/null @@ -1,66 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. -require "string" -require "cjson" -local elasticsearch = require "elasticsearch" - -local index = read_config("index") or "index" -local type_name = read_config("type_name") or "message" - -function process_message() - local ns - local resources = cjson.decode(read_message("Payload")) - for resource_id, resource in pairs(resources) do - local update = cjson.encode({update = {_index = index, _type = type_name, - _id = resource_id}}) - local body = { - script = 'ctx._source.meters += meter;' .. - 'ctx._source.user_id = user_id;' .. - 'ctx._source.project_id = project_id;' .. - 'ctx._source.source = source; ' .. - 'ctx._source.metadata = ' .. - 'ctx._source.last_sample_timestamp <= timestamp ? ' .. - 'metadata : ctx._source.metadata;' .. - 'ctx._source.last_sample_timestamp = ' .. - 'ctx._source.last_sample_timestamp < timestamp ?' .. - 'timestamp : ctx._source.last_sample_timestamp;' .. - 'ctx._source.first_sample_timestamp = ' .. - 'ctx._source.first_sample_timestamp > timestamp ?' .. - 'timestamp : ctx._source.first_sample_timestamp;', - params = { - meter = resource.meter, - metadata = resource.metadata, - timestamp = resource.timestamp, - user_id = resource.user_id or '', - project_id = resource.project_id or '', - source = resource.source or '', - }, - upsert = { - first_sample_timestamp = resource.timestamp, - last_sample_timestamp = resource.timestamp, - project_id = resource.project_id or '', - user_id = resource.user_id or '', - source = resource.source or '', - metadata = resource.metadata, - meters = resource.meter - } - } - body = cjson.encode(body) - - add_to_payload(update, "\n", body, "\n") - end - - inject_payload() - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/status_nagios.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/status_nagios.lua deleted file mode 100644 index ad4c5407a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/status_nagios.lua +++ /dev/null @@ -1,87 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require 'table' -require 'string' - -local afd = require 'afd' -local consts = require 'gse_constants' -local lma = require 'lma_utils' -local interp = require "msg_interpolate" - -local host = read_config('nagios_host') -local service_template = read_config('service_template') or error('service_template is required!') --- Nagios CGI cannot accept 'plugin_output' parameter greater than 1024 bytes --- See bug #1517917 for details. --- With the 'cmd.cgi' re-implementation for the command PROCESS_SERVICE_CHECK_RESULT, --- this limit can be increased to 3KB. See blueprint scalable-nagios-api. -local truncate_size = (read_config('truncate_size') or 3072) + 0 -local data = { - cmd_typ = '30', - cmd_mod = '2', - host = host, - service = nil, - plugin_state = nil, - plugin_output = nil, - performance_data = '', -} -local nagios_break_line = '\\n' --- mapping GSE statuses to Nagios states -local nagios_state_map = { - [consts.OKAY]=0, - [consts.WARN]=1, - [consts.UNKW]=3, - [consts.CRIT]=2, - [consts.DOWN]=2 -} - -function url_encode(str) - if (str) then - str = string.gsub (str, "([^%w %-%_%.%~])", - function (c) return string.format ("%%%02X", string.byte(c)) end) - str = string.gsub (str, " ", "+") - end - return str -end - -function process_message() - local service_name = interp.interpolate_from_msg(service_template) - local status = afd.get_status() - local alarms = afd.alarms_for_human(afd.extract_alarms()) - - if not service_name or not nagios_state_map[status] or not alarms then - return -1 - end - - data['service'] = service_name - data['plugin_state'] = nagios_state_map[status] - - local details = { - string.format('%s %s', service_name, consts.status_label(status)) - } - if #alarms == 0 then - details[#details+1] = 'no details' - else - for _, alarm in ipairs(alarms) do - details[#details+1] = alarm - end - end - data['plugin_output'] = lma.truncate(table.concat(details, nagios_break_line), truncate_size, nagios_break_line) - - local params = {} - for k, v in pairs(data) do - params[#params+1] = string.format("%s=%s", k, url_encode(v)) - end - - return lma.safe_inject_payload('txt', 'nagios', table.concat(params, '&')) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/status_smtp.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/status_smtp.lua deleted file mode 100644 index 3bfad7f8e..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/encoders/status_smtp.lua +++ /dev/null @@ -1,79 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -require 'table' -require 'string' - -local afd = require 'afd' -local consts = require 'gse_constants' -local lma = require 'lma_utils' - -local statuses = {} - -local concat_string = '\n' - -function process_message() - local previous - local text - local cluster = afd.get_entity_name('cluster_name') - local msg_type = read_message("Type") - local status = afd.get_status() - local alarms = afd.extract_alarms() - - if not cluster or not status or not alarms then - return -1 - end - local key = string.format('%s.%s', msg_type, cluster) - if not statuses[key] then - statuses[key] = {} - end - previous = statuses[key] - - local text - if #alarms == 0 then - text = 'no detail' - else - text = table.concat(afd.alarms_for_human(alarms), concat_string) - end - - local title - if not previous.status and status == consts.OKAY then - -- don't send a email when we detect a new cluster which is OKAY - return 0 - elseif not previous.status then - title = string.format('%s status is %s', - cluster, - consts.status_label(status)) - elseif status ~= previous.status then - title = string.format('%s status %s -> %s', - cluster, - consts.status_label(previous.status), - consts.status_label(status)) --- TODO(scroiset): avoid spam --- This code has the same issue than annotations, see filters/influxdb_annotation.lua --- elseif previous.text ~= text then --- title = string.format('%s status remains %s', --- cluster, --- consts.status_label(status)) - else - -- nothing has changed since the last message - return 0 - end - - -- store the last status and text for future messages - previous.status = status - previous.text = text - - return lma.safe_inject_payload('txt', '', table.concat({title, text}, concat_string)) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/afd.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/afd.lua deleted file mode 100644 index bf1032261..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/afd.lua +++ /dev/null @@ -1,99 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local string = require 'string' - -local utils = require 'lma_utils' -local afd = require 'afd' - --- node or service -local afd_type = read_config('afd_type') or error('afd_type must be specified!') -local activate_alerting = read_config('activate_alerting') or true -local msg_type -local msg_field_name -local afd_entity - -if afd_type == 'node' then - msg_type = 'afd_node_metric' - msg_field_name = 'node_status' - afd_entity = 'node_role' -elseif afd_type == 'service' then - msg_type = 'afd_service_metric' - msg_field_name = 'service_status' - afd_entity = 'service' -else - error('invalid afd_type value') -end - --- ie: controller for node AFD / rabbitmq for service AFD -local afd_entity_value = read_config('afd_cluster_name') or error('afd_cluster_name must be specified!') - --- ie: cpu for node AFD / queue for service AFD -local msg_field_source = read_config('afd_logical_name') or error('afd_logical_name must be specified!') - -local hostname = read_config('hostname') or error('hostname must be specified') - -local afd_file = read_config('afd_file') or error('afd_file must be specified') -local all_alarms = require(afd_file) -local A = require 'afd_alarms' -A.load_alarms(all_alarms) - -function process_message() - - local metric_name = read_message('Fields[name]') - local ts = read_message('Timestamp') - - local ok, value = utils.get_values_from_metric() - if not ok then - return -1, value - end - -- retrieve field values - local fields = {} - for _, field in ipairs (A.get_metric_fields(metric_name)) do - local field_value = afd.get_entity_name(field) - if not field_value then - return -1, "Cannot find Fields[" .. field .. "] for the metric " .. metric_name - end - fields[field] = field_value - end - A.add_value(ts, metric_name, value, fields) - return 0 -end - -function timer_event(ns) - if A.is_started() then - local state, alarms = A.evaluate(ns) - if state then -- it was time to evaluate at least one alarm - for _, alarm in ipairs(alarms) do - afd.add_to_alarms( - alarm.state, - alarm.alert['function'], - alarm.alert.metric, - alarm.alert.fields, - {}, -- tags - alarm.alert.operator, - alarm.alert.value, - alarm.alert.threshold, - alarm.alert.window, - alarm.alert.periods, - alarm.alert.message) - end - - afd.inject_afd_metric(msg_type, afd_entity, afd_entity_value, msg_field_name, - state, hostname, interval, msg_field_source, activate_alerting) - end - else - A.set_start_time(ns) - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/gse_afd_tcp_notifier.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/gse_afd_tcp_notifier.lua deleted file mode 100644 index 1f03ad876..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/gse_afd_tcp_notifier.lua +++ /dev/null @@ -1,117 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require 'cjson' -require 'string' -require 'table' - -local utils = require 'lma_utils' -local consts = require 'gse_constants' -local afd = require 'afd' - -local debug_mode = read_config('debug_mode') or false -local not_ok_mode = read_config('not_ok_mode') or false --- not_ok_mode: state change notify + WARN, UNKNOWN, CRITICAL, DOWN states notify --- debug_mode: every state notify - - -local statuses = {} - -function process_message() - local cluster - local node_role - -- object: - -- cluster_name for gse_cluster, gse_node_cluster and gse_service_cluster; - -- node_role for afd_node; - -- service for afd_service. - local object - local previous - local service - local alarm_source - local title - - local hostname = read_message('Hostname') - local type = read_message('Type') - local payload = read_message('Payload') - - if not statuses[type] then - statuses[type] = {} - end - - local status = afd.get_status() - if not status then - return -1 - end - - if type == 'heka.sandbox.gse_cluster_metric' - or type == 'heka.sandbox.gse_node_cluster_metric' - or type == 'heka.sandbox.gse_service_cluster_metric' then - cluster = afd.get_entity_name('cluster_name') - alarm_source = '-' - if not cluster then - return -1 - end - object = cluster - else - alarm_source = afd.get_entity_name('source') - if not alarm_source then - return -1 - end - if type == 'heka.sandbox.afd_node_metric' then - node_role = afd.get_entity_name('node_role') - object = node_role - else - service = afd.get_entity_name('service') - object = service - end - object = object .. '/' .. hostname - end - - if not statuses[type][object] then - statuses[type][object] = {} - end - previous = statuses[type][object] - - if not previous.status or (status ~= consts.OKAY and not_ok_mode) or debug_mode then - title = string.format('General status is %s', - consts.status_label(status)) - elseif previous.status ~= status then - title = string.format('General status %s -> %s', - consts.status_label(previous.status), - consts.status_label(status)) - else - -- nothing has changed since the last message - return 0 - end - - local msg = { - Timestamp = read_message('Timestamp'), - Type = 'gse_afd_notification', - Payload = payload, - Severity = utils.label_to_severity_map.INFO, - Hostname = hostname, - Fields = { - alarm_source = alarm_source, - object = object, - source = 'gse_afd_tcp_notifier', - title = title, - type = type - } - } - utils.inject_tags(msg) - - -- store the last status for future messages - previous.status = status - - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/gse_cluster_filter.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/gse_cluster_filter.lua deleted file mode 100644 index 6c8415fbb..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/gse_cluster_filter.lua +++ /dev/null @@ -1,139 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -local cjson = require 'cjson' - -local afd = require 'afd' -local gse = require 'gse' -local lma = require 'lma_utils' - -local output_message_type = read_config('output_message_type') or error('output_message_type must be specified!') -local cluster_field = read_config('cluster_field') -local member_field = read_config('member_field') or error('member_field must be specified!') -local output_metric_name = read_config('output_metric_name') or error('output_metric_name must be specified!') -local source = read_config('source') or error('source must be specified!') -local topology_file = read_config('topology_file') or error('topology_file must be specified!') -local policies_file = read_config('policies_file') or error('policies_file must be specified!') -local interval = (read_config('interval') or error('interval must be specified!')) + 0 -local interval_in_ns = interval * 1e9 -local max_inject = (read_config('max_inject') or 10) + 0 -local warm_up_period = ((read_config('warm_up_period') or 0) + 0) * 1e9 -local activate_alerting = read_config('activate_alerting') or true - -local is_active = false -local first_tick -local last_tick = 0 -local last_index = nil - -local topology = require(topology_file) -local policies = require(policies_file) - -for cluster_name, attributes in pairs(topology.clusters) do - local policy = policies.find(attributes.policy) - if not policy then - error('Cannot find ' .. attributes.policy .. ' policy!') - end - gse.add_cluster(cluster_name, attributes.members, attributes.hints, attributes.group_by, policy) -end - -function process_message() - local name = read_message('Fields[name]') - local hostname = read_message('Fields[hostname]') - if name and name == 'pacemaker_local_resource_active' and read_message("Fields[resource]") == 'vip__management' then - -- Skip pacemaker_local_resource_active metrics that don't - -- concern the local node - if read_message('Hostname') == hostname then - if read_message('Fields[value]') == 1 then - is_active = true - else - is_active = false - end - end - return 0 - end - - local member_id = afd.get_entity_name(member_field) - if not member_id then - return -1, "Cannot find entity's name in the AFD/GSE message" - end - - local status = afd.get_status() - if not status then - return -1, "Cannot find status in the AFD/GSE message" - end - - local alarms = afd.extract_alarms() - if not alarms then - return -1, "Cannot find alarms in the AFD/GSE message" - end - - local cluster_ids - if cluster_field then - local cluster_id = afd.get_entity_name(cluster_field) - if not cluster_id then - return -1, "Cannot find the cluster's name in the AFD/GSE message" - elseif not gse.cluster_exists(cluster_id) then - -- Just ignore AFD/GSE messages which aren't part of a cluster's definition - return 0 - end - cluster_ids = { cluster_id } - else - cluster_ids = gse.find_cluster_memberships(member_id) - end - - -- update all clusters that depend on this entity - for _, cluster_id in ipairs(cluster_ids) do - gse.set_member_status(cluster_id, member_id, status, alarms, hostname) - end - return 0 -end - -function timer_event(ns) - if not is_active then - -- not running as the aggregator - return - elseif not first_tick then - first_tick = ns - return - elseif ns - first_tick <= warm_up_period then - -- not started for a long enough period - return - elseif last_index == nil and (ns - last_tick) < interval_in_ns then - -- nothing to send it - return - end - last_tick = ns - - local injected = 0 - for i, cluster_name in ipairs(gse.get_ordered_clusters()) do - if last_index == nil or i > last_index then - gse.inject_cluster_metric( - output_message_type, - cluster_name, - output_metric_name, - interval, - source, - activate_alerting - ) - last_index = i - injected = injected + 1 - - if injected >= max_inject then - return - end - end - end - - last_index = nil -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/hdd_errors_counter.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/hdd_errors_counter.lua deleted file mode 100644 index e46ce9307..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/hdd_errors_counter.lua +++ /dev/null @@ -1,89 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. - -require 'math' -require 'os' -require 'string' -local utils = require 'lma_utils' - -local hostname = read_config('hostname') or error('hostname must be specified') -local patterns_config = read_config('patterns') or error('patterns must be specified') -local patterns = {} -for pattern in string.gmatch(patterns_config, "/(%S+)/") do - local ok, msg = pcall(string.match, "", pattern) - if not ok then - error("Invalid pattern detected: '" .. pattern "' (" .. msg .. ")") - end - patterns[#patterns + 1] = pattern -end --- Heka cannot guarantee that logs are processed in real-time so the --- grace_interval parameter allows to take into account log messages that are --- received in the current interval but emitted before it. -local grace_interval = (read_config('grace_interval') or 0) + 0 -local metric_source = read_config('source') - -local error_counters = {} -local enter_at -local start_time = os.time() - -function process_message () - -- timestamp values should be converted to seconds because log timestamps - -- have a precision of one second (or millisecond sometimes) - if utils.convert_to_sec(read_message('Timestamp')) + grace_interval < math.max(utils.convert_to_sec(enter_at or 0), start_time) then - -- skip the log message if it doesn't fall into the current interval - return 0 - end - - local payload = read_message('Payload') - if not payload then - return 0 - end - - -- example of kern.log lines: - -- <3>Jul 24 14:42:21 node-164 kernel: [505801.068621] Buffer I/O error on device sdd2, logical block 51184 - -- <4>Aug 22 09:37:09 node-164 kernel: [767975.369264] XFS (sda): xfs_log_force: error 5 returned. - -- <1>May 17 23:07:11 sd-os1-stor05 kernel: [ 2119.105909] XFS (sdf3): metadata I/O error: block 0x68c2b7d8 ("xfs_trans_read_buf_map") error 121 numblks 8 - for _, pattern in ipairs(patterns) do - local ok, device = pcall(string.match, payload, pattern) - if not ok then - return -1, device - end - if device then - error_counters[device] = (error_counters[device] or 0) + 1 - break - end - end - return 0 -end - -function timer_event(ns) - -- Is error_counters empty? - if next(error_counters) == nil then - return 0 - end - - local delta_sec = (ns - (enter_at or 0)) / 1e9 - for dev, value in pairs(error_counters) do - -- Don`t send values from first ticker interval - if enter_at ~= nil then - utils.add_to_bulk_metric("hdd_errors_rate", value / delta_sec, {device=dev}) - end - error_counters[dev] = 0 - end - - enter_at = ns - utils.inject_bulk_metric(ns, hostname, metric_source) - - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/heka_monitoring.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/heka_monitoring.lua deleted file mode 100644 index 51ead4981..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/heka_monitoring.lua +++ /dev/null @@ -1,85 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require 'cjson' -require 'string' -require 'math' -local utils = require 'lma_utils' - -function process_table(typ, array) - -- NOTE: It has been written for "filters" and "decoders". If we need to - -- use it to collect metrics from other components of the Heka pipeline, - -- we need to ensure that JSON provides names and table with - -- ProcessMessageCount and ProcessMessageAvgDuration: - -- - -- "decoder": { - -- ... - -- }, - -- "Name": "a name", - -- "ProcessMessageCount" : { - -- "representation": "count", - -- "value": 12 - -- }, - -- "ProcessMessageAvgDuration" : { - -- "representation": "ns", - -- "value": 192913 - -- }, - -- { ... }} - -- - for _, v in pairs(array) do - if type(v) == "table" then - -- strip off the '_decoder'/'_filter' suffix - local name = v['Name']:gsub("_" .. typ, "") - - local tags = { - ['type'] = typ, - ['name'] = name, - } - - utils.add_to_bulk_metric('hekad_msg_count', v.ProcessMessageCount.value, tags) - utils.add_to_bulk_metric('hekad_msg_avg_duration', v.ProcessMessageAvgDuration.value, tags) - if v.Memory then - utils.add_to_bulk_metric('hekad_memory', v.Memory.value, tags) - end - if v.TimerEventAvgDuration then - utils.add_to_bulk_metric('hekad_timer_event_avg_duration', v.TimerEventAvgDuration.value, tags) - end - if v.TimerEventSamples then - utils.add_to_bulk_metric('hekad_timer_event_count', v.TimerEventSamples.value, tags) - end - end - end -end - -function singularize(str) - return str:gsub('s$', '') -end - -function process_message () - local ok, data = pcall(cjson.decode, read_message("Payload")) - if not ok then - return -1 - end - - local hostname = read_message("Hostname") - local ts = read_message("Timestamp") - - for k, v in pairs(data) do - if k == "filters" or k == "decoders" then - process_table(singularize(k), v) - end - end - - utils.inject_bulk_metric(ts, hostname, 'internal') - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/http_metrics_aggregator.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/http_metrics_aggregator.lua deleted file mode 100644 index 6abe3b782..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/http_metrics_aggregator.lua +++ /dev/null @@ -1,185 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. - -require 'string' -require 'math' -require 'os' -local utils = require 'lma_utils' -local tab = require 'table_utils' -local table = require 'table' - -local hostname = read_config('hostname') or error('hostname must be specified') -local interval = (read_config('interval') or error('interval must be specified')) + 0 --- max_timer_inject is the maximum number of injected messages by timer_event() -local max_timer_inject = (read_config('max_timer_inject') or 10) + 0 --- bulk_size is the maximum number of metrics embedded by a bulk_metric within the Payload. --- The bulk_size depends on the hekad max_message_size (64 KB by default). --- At most, there are 45 metrics/service * 300B (per bucket) =~ 13KB * 4 services = 52KB for 225 metrics. --- With a max_message_size set to 256KB, it's possible to embed more than 800 metrics. -local bulk_size = (read_config('bulk_size') or 225) + 0 -local percentile_thresh = (read_config('percentile') or 90) + 0 --- grace_time is used to palliate the time precision difference --- (in second or millisecond for logs versus nanosecond for the ticker) --- and also to compensate the delay introduced by log parsing/decoding --- which leads to arrive too late in its interval. -local grace_time = (read_config('grace_time') or 0) + 0 -local metric_source = read_config('source') - -local inject_reached_error = 'too many metrics to aggregate, adjust bulk_size and/or max_timer_inject parameters' - -local percentile_field_name = string.format('upper_%s', percentile_thresh) -local last_tick = os.time() * 1e9 -local interval_in_ns = interval * 1e9 - -local http_verbs = { - GET = true, - POST = true, - OPTIONS = true, - DELETE = true, - PUT = true, - HEAD = true, - TRACE = true, - CONNECT = true, - PATCH = true, -} - -local metric_bucket = { - min = 0, - max = 0, - sum = 0, - count = 0, - times = {}, - [percentile_field_name] = 0, - rate = 0, -} -local all_times = {} -local num_metrics = 0 - -function process_message () - local severity = read_message("Fields[severity_label]") - local logger = read_message("Logger") - local timestamp = read_message("Timestamp") - local http_method = read_message("Fields[http_method]") - local http_status = read_message("Fields[http_status]") - local response_time = read_message("Fields[http_response_time]") - - if timestamp < last_tick - grace_time then - -- drop silently old logs - return 0 - end - if http_method == nil or http_status == nil or response_time == nil then - return -1 - end - - -- keep only the first 2 tokens because some services like Neutron report - -- themselves as 'openstack..server' - local service = string.gsub(logger, '(%w+)%.(%w+).*', '%1_%2') - if service == nil then - return -1, "Cannot match any service from " .. logger - end - - -- coerce http_status to integer - http_status = http_status + 0 - local http_status_family - if http_status >= 100 and http_status < 200 then - http_status_family = '1xx' - elseif http_status >= 200 and http_status < 300 then - http_status_family = '2xx' - elseif http_status >= 300 and http_status < 400 then - http_status_family = '3xx' - elseif http_status >= 400 and http_status < 500 then - http_status_family = '4xx' - elseif http_status >= 500 and http_status < 600 then - http_status_family = '5xx' - else - return -1, "Unsupported http_status " .. http_status - end - - if not http_verbs[http_method] then - return -1, "Unsupported http_method " .. http_method - end - - if not all_times[service] then - all_times[service] = {} - end - if not all_times[service][http_method] then - all_times[service][http_method] = {} - end - if not all_times[service][http_method][http_status_family] then - -- verify that the sandbox has enough capacity to emit all metrics - if num_metrics > (bulk_size * max_timer_inject) then - return -1, inject_reached_error - end - all_times[service][http_method][http_status_family] = tab.deepcopy(metric_bucket) - num_metrics = num_metrics + 1 - end - - local bucket = all_times[service][http_method][http_status_family] - bucket.times[#bucket.times + 1] = response_time - bucket.count = bucket.count + 1 - bucket.sum = bucket.sum + response_time - if bucket.max < response_time then - bucket.max = response_time - end - if bucket.min == 0 or bucket.min > response_time then - bucket.min = response_time - end - - return 0 -end - -function timer_event(ns) - - last_tick = ns - - local num = 0 - local msg_injected = 0 - for service, methods in pairs(all_times) do - for method, statuses in pairs(methods) do - for status, bucket in pairs(statuses) do - local metric_name = service .. '_http_response_times' - bucket.rate = bucket.count / interval - bucket[percentile_field_name] = bucket.max - if bucket.count > 1 then - table.sort(bucket.times) - local tmp = ((100 - percentile_thresh) / 100) * bucket.count - local idx = bucket.count - math.floor(tmp + .5) - if idx > 0 and bucket.times[idx] then - bucket[percentile_field_name] = bucket.times[idx] - end - end - bucket.times = nil - utils.add_to_bulk_metric(metric_name, bucket, {hostname=hostname, http_method=method, http_status=status}) - all_times[service][method][status] = nil - num = num + 1 - num_metrics = num_metrics - 1 - if num >= bulk_size then - if msg_injected < max_timer_inject then - utils.inject_bulk_metric(ns, hostname, metric_source) - msg_injected = msg_injected + 1 - num = 0 - num_metrics = 0 - end - end - end - all_times[service][method] = nil - end - all_times[service] = nil - end - if num > 0 then - utils.inject_bulk_metric(ns, hostname, metric_source) - num = 0 - num_metrics = 0 - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/influxdb_accumulator.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/influxdb_accumulator.lua deleted file mode 100644 index 470bdefd2..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/influxdb_accumulator.lua +++ /dev/null @@ -1,142 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require 'cjson' -require 'os' -require 'string' -require 'table' -local utils = require 'lma_utils' -local Accumulator = require 'accumulator' -local Influxdb = require 'influxdb' -local l = require 'lpeg' -l.locale(l) - -local flush_count = (read_config('flush_count') or 100) + 0 -local flush_interval = (read_config('flush_interval') or 5) + 0 -local time_precision = read_config("time_precision") -local payload_name = read_config("payload_name") or "influxdb" -local bulk_metric_type_matcher = read_config("bulk_metric_type_matcher") or "bulk_metric$" - --- the tag_fields parameter is a list of tags separated by spaces -local tag_grammar = l.Ct((l.C((l.P(1) - l.P" ")^1) * l.P" "^0)^0) -local tag_fields = tag_grammar:match(read_config("tag_fields") or "") - -function flush_cb(datapoints) - if #datapoints > 0 then - datapoints[#datapoints+1] = '' - utils.safe_inject_payload("txt", payload_name, table.concat(datapoints, "\n")) - end -end -local accumulator = Accumulator.new(flush_count, flush_interval, flush_cb) -local encoder = Influxdb.new(time_precision) - --- return a table containing the common tags from the message -function get_common_tags() - local tags = {} - for _, t in ipairs(tag_fields) do - tags[t] = read_message(string.format('Fields[%s]', t)) - end - return tags -end - --- process a single metric -function process_single_metric() - local name = read_message("Fields[name]") - - if not name then - return 'Fields[name] is missing' - end - local ok, value = utils.get_values_from_metric() - if not ok then - return value - end - - -- collect tags from Fields[tag_fields] - local tags = get_common_tags() - local i = 0 - while true do - local t = read_message("Fields[tag_fields]", 0, i) - if not t then - break - end - tags[t] = read_message(string.format('Fields[%s]', t)) - i = i + 1 - end - - accumulator:append( - encoder:encode_datapoint( - read_message('Timestamp'), - name, - value, - tags)) - return -end - -function process_bulk_metric() - -- The payload of the message contains a list of datapoints. - -- - -- Each point is formatted either like this: - -- - -- {name='foo', - -- value=1, - -- tags={k1=v1,...}} - -- - -- or like this for multi-value points: - -- - -- {name='bar', - -- values={k1=v1, ..}, - -- tags={k1=v1,...} - -- - local ok, points = pcall(cjson.decode, read_message("Payload")) - if not ok then - return 'Invalid payload value for bulk metric' - end - - local common_tags = get_common_tags() - local msg_timestamp = read_message('Timestamp') - for _, point in ipairs(points) do - point.tags = point.tags or {} - for k,v in pairs(common_tags) do - if point.tags[k] == nil then - point.tags[k] = v - end - end - accumulator:append( - encoder:encode_datapoint( - msg_timestamp, - point.name, - point.value or point.values, - point.tags)) - end - return -end - -function process_message() - local err_msg - local msg_type = read_message("Type") - if msg_type:match(bulk_metric_type_matcher) then - err_msg = process_bulk_metric() - else - err_msg = process_single_metric() - end - - if err_msg then - return -1, err_msg - else - return 0 - end -end - -function timer_event(ns) - accumulator:flush(ns) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/influxdb_annotation.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/influxdb_annotation.lua deleted file mode 100644 index a1f33eee0..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/influxdb_annotation.lua +++ /dev/null @@ -1,92 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require 'cjson' -require 'string' -require 'table' - -local utils = require 'lma_utils' -local consts = require 'gse_constants' -local afd = require 'afd' - -local measurement_name = read_config('measurement_name') or 'annotations' -local html_break_line = '
' - -local statuses = {} - --- Transform a GSE cluster metric into an annotation stored into InfluxDB -function process_message () - local previous - local text - local cluster = afd.get_entity_name('cluster_name') - local status = afd.get_status() - local alarms = afd.extract_alarms() - - if not cluster or not status or not alarms then - return -1 - end - - if not statuses[cluster] then - statuses[cluster] = {} - end - previous = statuses[cluster] - - text = table.concat(afd.alarms_for_human(alarms), html_break_line) - - -- build the title - if not previous.status and status == consts.OKAY then - -- don't send an annotation when we detect a new cluster which is OKAY - return 0 - elseif not previous.status then - title = string.format('General status is %s', - consts.status_label(status)) - elseif previous.status ~= status then - title = string.format('General status %s -> %s', - consts.status_label(previous.status), - consts.status_label(status)) --- TODO(pasquier-s): generate an annotation when the set of alarms has changed. --- the following code generated an annotation whenever at least one value --- associated to an alarm was changing. This led to way too many annotations --- with alarms monitoring the CPU usage for instance. --- elseif previous.text ~= text then --- title = string.format('General status remains %s', --- consts.status_label(status)) - else - -- nothing has changed since the last message - return 0 - end - - local msg = { - Timestamp = read_message('Timestamp'), - Type = 'metric', - Severity = utils.label_to_severity_map.INFO, - Hostname = read_message('Hostname'), - Fields = { - name = measurement_name, - tag_fields = { 'cluster' }, - value_fields = { 'title', 'tags', 'text' }, - title = title, - tags = cluster, - text = text, - cluster = cluster, - source = 'influxdb_annotation' - } - } - utils.inject_tags(msg) - - -- store the last status and alarm text for future messages - previous.status = status - previous.text = text - - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/logs_counter.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/logs_counter.lua deleted file mode 100644 index e6ef2296f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/logs_counter.lua +++ /dev/null @@ -1,87 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. - -require 'math' -require 'os' -require 'string' -local utils = require 'lma_utils' - -local hostname = read_config('hostname') or error('hostname must be specified') --- The filter can receive messages that should be discarded because they are --- way too old (Heka cannot guarantee that logs are processed in real-time). --- The 'grace_interval' parameter allows to define which log messages should be --- kept and which should be discarded. For instance, a value of '10' means that --- the filter will take into account log messages that are at most 10 seconds --- older than the current time. -local grace_interval = (read_config('grace_interval') or 0) + 0 -local logger_matcher = read_config('logger_matcher') or '.*' -local metric_source = read_config('source') - -local discovered_services = {} -local logs_counters = {} -local last_timer_event = os.time() * 1e9 - -function process_message () - local severity = read_message("Fields[severity_label]") - local logger = read_message("Logger") - - local service = string.match(logger, logger_matcher) - if service == nil then - return -1, "Cannot match any service from " .. logger - end - - -- timestamp values should be converted to seconds because log timestamps - -- have a precision of one second (or millisecond sometimes) - if utils.convert_to_sec(read_message('Timestamp')) + grace_interval < utils.convert_to_sec(last_timer_event) then - -- skip the the log message if it doesn't fall into the current interval - return 0 - end - - if not logs_counters[service] then - -- a new service has been discovered - discovered_services[#discovered_services + 1] = service - logs_counters[service] = {} - for _, label in pairs(utils.severity_to_label_map) do - logs_counters[service][label] = 0 - end - end - - logs_counters[service][severity] = logs_counters[service][severity] + 1 - return 0 -end - -function timer_event(ns) - for service, counters in pairs(logs_counters) do - local delta_sec = (ns - last_timer_event) / 1e9 - - for level, val in pairs(counters) do - utils.add_to_bulk_metric( - 'log_messages', - val / delta_sec, - {hostname=hostname, service=service, level=string.lower(level)}) - - -- reset the counter - counters[level] = 0 - end - end - - last_timer_event = ns - - ok, err = utils.inject_bulk_metric(ns, hostname, metric_source, utils.metric_type['DERIVE']) - if ok ~= 0 then - return -1, err - end - - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/resource_creation_time.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/resource_creation_time.lua deleted file mode 100644 index 0047ed3ee..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/resource_creation_time.lua +++ /dev/null @@ -1,82 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require 'math' -local patt = require 'patterns' -local utils = require 'lma_utils' - -local msg = { - Type = "metric", -- will be prefixed by "heka.sandbox." - Timestamp = nil, - Severity = 6, -} - -local event_type_to_name = { - ["compute.instance.create.end"] = "openstack_nova_instance_creation_time", - ["volume.create.end"] = "openstack_cinder_volume_creation_time", - ["volume.attach.end"] = "openstack_cinder_volume_attachment_time", -} - -function process_message () - local metric_name = event_type_to_name[read_message("Fields[event_type]")] - if not metric_name then - return -1 - end - - local started_at, completed_at - - if metric_name == "openstack_cinder_volume_attachment_time" then - --[[ To compute the metric we need fields that are not available - directly in the Heka message. So we need to decode the message, - check if it is a full notification or not and extract the needed - values. ]]-- - local data = read_message("Payload") - local ok, notif = pcall(cjson.decode, data) - if not ok then - return -1 - end - - notif = notif.payload or notif - local t = unpack(notif['volume_attachment']) - started_at = t.created_at or '' - completed_at = t.attach_time or '' - else - started_at = read_message("Fields[created_at]") or '' - completed_at = read_message("Fields[launched_at]") or '' - end - - started_at = patt.Timestamp:match(started_at) - completed_at = patt.Timestamp:match(completed_at) - if started_at == nil or completed_at == nil or started_at == 0 or completed_at == 0 or started_at > completed_at then - return -1 - end - - msg.Timestamp = read_message("Timestamp") - msg.Fields = { - source = read_message('Logger'), - name = metric_name, - -- preserve the original hostname in the Fields attribute because - -- sandboxed filters cannot override the Hostname attribute - hostname = read_message("Fields[hostname]"), - type = utils.metric_type['GAUGE'], - -- Having a millisecond precision for creation time is good enough given - -- that the started_at field has only a 1-second precision. - value = {value = math.floor((completed_at - started_at)/1e6 + 0.5) / 1e3, representation = 's'}, - tenant_id = read_message("Fields[tenant_id]"), - user_id = read_message("Fields[user_id]"), - tag_fields = {'hostname'}, - } - utils.inject_tags(msg) - - return utils.safe_inject_message(msg) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/watchdog.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/watchdog.lua deleted file mode 100644 index 0399d5c93..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/filters/watchdog.lua +++ /dev/null @@ -1,24 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require 'math' - -local payload_name = read_config('payload_name') or error('payload_name is required') -local payload = read_config('payload') - --- Very simple filter that emits a fixed message or the current timestamp (in --- second) every ticker interval. It can be used to check the liveness of the --- Heka service. -function timer_event(ns) - inject_payload("txt", payload_name, payload or math.floor(ns / 1e9)) -end diff --git a/deployment_scripts/puppet/modules/lma_collector/files/plugins/outputs/lastfile.lua b/deployment_scripts/puppet/modules/lma_collector/files/plugins/outputs/lastfile.lua deleted file mode 100644 index 28335a5ae..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/files/plugins/outputs/lastfile.lua +++ /dev/null @@ -1,27 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -require "io" - -local path = read_config('path') or error('path required') -local field = read_config('field') or 'Payload' - --- Very simple output sandbox that writes the value of one of the message's --- fields ('Payload' by default) to a file. -function process_message() - local fh = io.open(path, "w") - io.output(fh) - io.write(read_message(field)) - io.close() - return 0 -end diff --git a/deployment_scripts/puppet/modules/lma_collector/lib/facter/canonical_timezone.rb b/deployment_scripts/puppet/modules/lma_collector/lib/facter/canonical_timezone.rb deleted file mode 100644 index b9b8fd6da..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/lib/facter/canonical_timezone.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. - -Facter.add("canonical_timezone") do - setcode do - tz = nil - File.open('/etc/timezone').each_line do |line| - unless line.match(/^\s*#/) - tz = line.chomp() - end - end - tz - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/lib/facter/collectd_version.rb b/deployment_scripts/puppet/modules/lma_collector/lib/facter/collectd_version.rb deleted file mode 100644 index ae1deab6e..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/lib/facter/collectd_version.rb +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. - -# Workaround because the puppet-collectd module cannot detect the collectd's -# version until the package is installed. -# -# See https://github.com/pdxcat/puppet-module-collectd/issues/162 for details. -Facter.add("collectd_version") do - setcode do - case Facter.value('osfamily') - when /(?i)(debian)/ - "5.4.0-3ubuntu2" - when /(?i)(redhat)/ - "5.4.1-5.mira1.mira1" - end - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/lib/facter/libvirt_daemon.rb b/deployment_scripts/puppet/modules/lma_collector/lib/facter/libvirt_daemon.rb deleted file mode 100644 index 1081a3b55..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/lib/facter/libvirt_daemon.rb +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -Facter.add('libvirt_daemon') do - setcode do - if File.exists? '/etc/init.d/libvirt-bin' - # It is the case for Ubuntu on MOS 6.1 - 'libvirt-bin' - else - 'libvirtd' - end - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/lib/facter/ovs_directory_exists.rb b/deployment_scripts/puppet/modules/lma_collector/lib/facter/ovs_directory_exists.rb deleted file mode 100644 index 8884a946c..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/lib/facter/ovs_directory_exists.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -Facter.add('ovs_log_directory') do - setcode do - File.directory? '/var/log/openvswitch' - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/lib/facter/pacemaker_resources.rb b/deployment_scripts/puppet/modules/lma_collector/lib/facter/pacemaker_resources.rb deleted file mode 100644 index 2a462eec7..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/lib/facter/pacemaker_resources.rb +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -# Return the list of resources managed by Pacemaker -Facter.add('pacemaker_resources') do - if Facter::Util::Resolution.which('crm_resource') - setcode do - # crm_resource -Q -l returns something like this: - # vip__public - # p_ntp:0 - # p_ntp:1 - # p_ntp:2 - # p_dns:0 - # ... - out = Facter::Util::Resolution.exec('crm_resource -Q -l') - # Facter 1.x support only scalar types so we return the list as a - # comma-separated string - out.split(/\n/).collect{ |x| x.gsub(/:.+$/, '')}.uniq().join(',') - end - end -end - diff --git a/deployment_scripts/puppet/modules/lma_collector/lib/puppet/parser/functions/adapt_collectd_python_plugin_config.rb b/deployment_scripts/puppet/modules/lma_collector/lib/puppet/parser/functions/adapt_collectd_python_plugin_config.rb deleted file mode 100644 index 5d5a25a8a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/lib/puppet/parser/functions/adapt_collectd_python_plugin_config.rb +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -# This function is used by the lma_collector::collectd::python defined -# type to work-around a bug in collectd::plugin::python::module where -# the config hash cannot include values that are arrays or hashes. -# See https://github.com/voxpupuli/puppet-collectd/issues/390. -# -# Ex: -# -# ARG0: -# {"key1" => ["e1", "e2"], -# "key2" => {"k1" => "v1", "k2" => "v2"} -# "key3" => "val3"} -# -# Result: -# {"key1 e1" => "", "key1 e2" => "", -# "key2 k1" => "v1", "key2 k2" => "v1", -# "key3" => "val3"} -# - -module Puppet::Parser::Functions - newfunction(:adapt_collectd_python_plugin_config, :type => :rvalue) do |args| - - config = args[0] - raise Puppet::ParseError, "arg[0] isn't a hash" unless config.is_a?(Hash) - - adapted_config = Hash.new - - config.each do |key,val| - if val.is_a?(Array) - val.each do |elt| - adapted_config["#{key} #{elt}"] = "" - end - elsif val.is_a?(Hash) - val.each do |k,v| - adapted_config["#{key} #{k}"] = "#{v}" - end - else - adapted_config["#{key}"] = "#{val}" - end - end - - return adapted_config - - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/lib/puppet/parser/functions/sanitize_name_for_lua.rb b/deployment_scripts/puppet/modules/lma_collector/lib/puppet/parser/functions/sanitize_name_for_lua.rb deleted file mode 100644 index 44c624265..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/lib/puppet/parser/functions/sanitize_name_for_lua.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -# This replace hypens by underscores -# -# ARG0: one-two-three -# Results: one_two_three - -module Puppet::Parser::Functions - newfunction(:sanitize_name_for_lua, :type => :rvalue) do |args| - raise(Puppet::ParseError, "sanitize_name_for_lua: Wrong number of arguments. " + - "Only one string is needed") if args.size != 1 - return args[0].gsub('-','_') - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/afd/api.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/afd/api.pp deleted file mode 100644 index b5619a861..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/afd/api.pp +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::afd::api () { - include lma_collector::params - include lma_collector::service::metric - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::filter::sandbox { 'afd_api_backends': - config_dir => $lma_collector::params::metric_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/afd_api_backends.lua", - message_matcher => '(Type == \'metric\' || Type == \'heka.sandbox.metric\') && Fields[name] == \'haproxy_backend_servers\'', - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::metric'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/afd_filter.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/afd_filter.pp deleted file mode 100644 index 56920e55c..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/afd_filter.pp +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -define lma_collector::afd_filter ( - $type, - $cluster_name, - $logical_name, - $alarms, - $alarms_definitions, - $message_matcher, - $activate_alerting = true, - $enable_notification = false, -) { - include lma_collector::params - include lma_collector::service::metric - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - # name cannot contain '-' - $afd_file = join(['lma_alarms_', sanitize_name_for_lua($name)], '') - $afd_filename = "${lua_modules_dir}/${afd_file}.lua" - - # Create the Lua structures that describe alarms - file { $afd_filename: - ensure => present, - content => template('lma_collector/lma_alarms.lua.erb'), - notify => Class['lma_collector::service::metric'], - } - - # Create the confguration file for Heka - heka::filter::sandbox { "afd_${type}_${cluster_name}_${logical_name}": - config_dir => $lma_collector::params::metric_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/afd.lua", - message_matcher => join(["(Type == \'metric\' || Type == \'heka.sandbox.metric\' ", - "|| Type == \'heka.sandbox.multivalue_metric\') && (${message_matcher})"], ''), - ticker_interval => 10, - config => { - hostname => $::hostname, - afd_type => $type, - afd_file => $afd_file, - afd_cluster_name => $cluster_name, - afd_logical_name => $logical_name, - activate_alerting => $activate_alerting, - enable_notification => $enable_notification, - }, - module_directory => $lua_modules_dir, - require => File[$afd_filename], - notify => Class['lma_collector::service::metric'], - } -} - - diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/afd_nagios.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/afd_nagios.pp deleted file mode 100644 index 7153222f6..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/afd_nagios.pp +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define lma_collector::afd_nagios( - $server, - $http_port, - $http_path, - $user, - $password, - $http_scheme = 'http', - $ensure = present, - $hostname = $::hostname, - $service_template = '%{node_role}.%{source}', - $message_type = 'afd_node_metric', -){ - include lma_collector::params - include lma_collector::service::metric - - validate_integer($http_port) - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - $url = "${http_scheme}://${server}:${http_port}/${http_path}" - - $config = {'nagios_host' => $hostname, 'service_template' => $service_template} - heka::encoder::sandbox { "nagios_afd_${title}": - ensure => $ensure, - config_dir => $lma_collector::params::metric_config_dir, - filename => "${lma_collector::params::plugins_dir}/encoders/status_nagios.lua", - config => $config, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::metric'], - } - - $matcher = join(["Fields[${lma_collector::params::aggregator_flag}] == NIL", - "Type == 'heka.sandbox.${message_type}'", - 'Fields[no_alerting] == NIL', - 'Fields[hostname] != NIL'], ' && ') - - heka::output::http { "nagios_afd_${title}": - ensure => $ensure, - config_dir => $lma_collector::params::metric_config_dir, - url => $url, - message_matcher => $matcher, - username => $user, - password => $password, - encoder => "nagios_afd_${title}", - timeout => $lma_collector::params::nagios_timeout, - headers => { - 'Content-Type' => 'application/x-www-form-urlencoded' - }, - use_buffering => $lma_collector::params::buffering_enabled, - max_buffer_size => $lma_collector::params::buffering_max_buffer_size_for_nagios, - max_file_size => $lma_collector::params::buffering_max_file_size_for_nagios, - queue_full_action => $lma_collector::params::queue_full_action_for_nagios, - require => Heka::Encoder::Sandbox["nagios_afd_${title}"], - notify => Class['lma_collector::service::metric'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/aggregator/client.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/aggregator/client.pp deleted file mode 100644 index 1fd7a80d1..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/aggregator/client.pp +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -class lma_collector::aggregator::client ( - $address = undef, - $port = $lma_collector::params::aggregator_port, -) inherits lma_collector::params { - - include lma_collector::service::metric - - if $address == undef { - fail('address parameter should be defined!') - } - - validate_string($address) - - heka::output::tcp { 'aggregator': - config_dir => $lma_collector::params::metric_config_dir, - address => $address, - port => $port, - use_buffering => $lma_collector::params::buffering_enabled, - max_buffer_size => $lma_collector::params::buffering_max_buffer_size_for_aggregator, - max_file_size => $lma_collector::params::buffering_max_file_size_for_aggregator, - message_matcher => $lma_collector::params::aggregator_client_message_matcher, - queue_full_action => $lma_collector::params::queue_full_action_for_aggregator, - notify => Class['lma_collector::service::metric'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/aggregator/server.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/aggregator/server.pp deleted file mode 100644 index 9479e0016..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/aggregator/server.pp +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::aggregator::server ( - $listen_address = $lma_collector::params::aggregator_address, - $listen_port = $lma_collector::params::aggregator_port, - $http_check_port = undef, -) inherits lma_collector::params { - include lma_collector::service::metric - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - validate_string($listen_address) - validate_integer($listen_port) - - $config_dir = $lma_collector::params::metric_config_dir - - $scribbler_config = { - "${lma_collector::params::aggregator_flag}" => 'present' - } - heka::decoder::scribbler { 'aggregator_flag': - config_dir => $config_dir, - config => $scribbler_config, - notify => Class['lma_collector::service::metric'], - } - - heka::decoder::multidecoder { 'aggregator': - config_dir => $config_dir, - subs => ['ProtobufDecoder', 'aggregator_flag_decoder'], - log_sub_errors => true, - cascade_strategy => 'all', - notify => Class['lma_collector::service::metric'], - } - - heka::input::tcp { 'aggregator': - config_dir => $config_dir, - address => $listen_address, - port => $listen_port, - decoder => 'aggregator', - notify => Class['lma_collector::service::metric'], - } - - if $http_check_port { - heka::decoder::sandbox { 'http-check': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/noop.lua" , - config => { - msg_type => 'lma.http-check', - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::metric'], - } - - heka::input::httplisten { 'http-check': - config_dir => $config_dir, - address => $listen_address, - port => $http_check_port, - decoder => 'http-check', - require => Heka::Decoder::Sandbox['http-check'], - notify => Class['lma_collector::service::metric'], - } - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/apache.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/apache.pp deleted file mode 100644 index f84055097..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/apache.pp +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::apache ( - $host = $lma_collector::params::apache_status_host, - $port = $lma_collector::params::apache_status_port, -) inherits lma_collector::params { - - $apache_url = "http://${host}:${port}/server-status?auto" - - class { 'collectd::plugin::apache': - instances => { - 'localhost' => { - 'url' => $apache_url, - }, - } - } - - lma_collector::collectd::python {'collectd_apache_check': - config => { - 'Url' => "\"${apache_url}\"", - }, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/base.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/base.pp deleted file mode 100644 index 415efd7fe..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/base.pp +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::collectd::base ( - $processes = undef, - $process_matches = undef, - $queue_limit = $lma_collector::params::collectd_queue_limit, - $read_threads = $lma_collector::params::collectd_read_threads, - $hostname = undef, - $purge = false, - $package_provider = 'apt_fuel', -) inherits lma_collector::params { - - include lma_collector::service::metric - - $type_directory = "${lma_collector::params::plugins_dir}/collectd_types/" - $type_files = suffix(prefix($lma_collector::params::collectd_types, $type_directory), '.db') - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - file { $type_directory: - ensure => directory, - source => 'puppet:///modules/lma_collector/collectd/types', - recurse => remote, - before => Class['::collectd'], - } - - # Netlink library is required by the netlink collectd plugin - if $::osfamily == 'RedHat' { - $netlink_pkg_name = 'libmnl' - } else { - $netlink_pkg_name = 'libmnl0' - } - package { $netlink_pkg_name: - ensure => present, - before => Class['::collectd'], - } - - $port = $lma_collector::params::collectd_port - class { '::collectd': - purge => $purge, - recurse => true, - package_provider => $package_provider, - purge_config => true, - fqdnlookup => false, - interval => $lma_collector::params::collectd_interval, - threads => $read_threads, - write_queue_limit_low => $lma_collector::params::collectd_queue_limit, - write_queue_limit_high => $lma_collector::params::collectd_queue_limit, - typesdb => concat(['/usr/share/collectd/types.db'], $type_files) - } - - class { 'collectd::plugin::logfile': - log_level => 'warning', - log_file => $lma_collector::params::collectd_logfile, - } - - $urls = { - "http://127.0.0.1:${port}" => { - 'format' => 'JSON', - storerates => true - } - } - if $::osfamily == 'RedHat' { - # collectd Puppet manifest is broken for RedHat derivatives as it tries to - # install the collectd-write_http package which doesn't exist (for CentOS - # at least) - collectd::plugin {'write_http': - ensure => present, - content => template('collectd/plugin/write_http.conf.erb'), - } - } - else { - class { 'collectd::plugin::write_http': - urls => $urls, - } - } - - class { 'collectd::plugin::cpu': - } - - class { 'collectd::plugin::df': - fstypes => $lma_collector::params::fstypes, - valuespercentage => true, - } - - $block_devices = join(split($::blockdevices, ','), '|') - class { 'collectd::plugin::disk': - disks => [ "/^${ block_devices }$/" ], - } - - class { 'collectd::plugin::netlink': - verboseinterfaces => reject(grep(split($::interfaces, ','), '^[a-z0-9]+$'), '^lo$'), - } - - class { 'collectd::plugin::load': - } - - class { 'collectd::plugin::memory': - } - - class { 'collectd::plugin::processes': - processes => $processes, - process_matches => $process_matches, - } - - class { 'collectd::plugin::swap': - } - - class { 'collectd::plugin::users': - } - - file { '/etc/logrotate.d/collectd': - ensure => present, - content => "${lma_collector::params::collectd_logfile} {\n daily\n missingok\n}" - } - - if $hostname { - $real_hostname = $hostname - } - else { - $real_hostname = $::hostname - } - heka::decoder::sandbox { 'collectd': - config_dir => $lma_collector::params::metric_config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/collectd.lua" , - config => { - hostname => $real_hostname, - swap_size => $::swapsize_mb * 1024 * 1024, - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::metric'], - } - - heka::input::httplisten { 'collectd': - config_dir => $lma_collector::params::metric_config_dir, - address => '127.0.0.1', - port => $port, - decoder => 'collectd', - require => Heka::Decoder::Sandbox['collectd'], - notify => Class['lma_collector::service::metric'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/ceph_mon.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/ceph_mon.pp deleted file mode 100644 index 2e3b7b720..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/ceph_mon.pp +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::ceph_mon { - - lma_collector::collectd::python { ['ceph_pg_mon_status', 'ceph_pool_osd', 'ceph_osd_stats']: - config => {}, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/ceph_osd.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/ceph_osd.pp deleted file mode 100644 index 1a5fec7a0..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/ceph_osd.pp +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2015-2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::ceph_osd { - - lma_collector::collectd::python { 'ceph_osd_perf': - config => { - 'AdminSocket' => '"/var/run/ceph/ceph-*.asok"', - }, - } - -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/check_local_endpoint.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/check_local_endpoint.pp deleted file mode 100644 index 795bef81c..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/check_local_endpoint.pp +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# -class lma_collector::collectd::check_local_endpoint ( - $urls, - $expected_codes = {}, - $timeout = 1, - $max_retries = 3, -) { - - validate_hash($urls) - validate_hash($expected_codes) - validate_integer($timeout) - validate_integer($max_retries) - - # Add quotes around the hash keys and values - $urls_keys = suffix(prefix(keys($urls), '"'), '"') - $urls_values = suffix(prefix(values($urls), '"'), '"') - $real_urls= hash(flatten(zip($urls_keys, $urls_values))) - if ! empty($expected_codes) { - $expected_codes_keys = suffix(prefix(keys($expected_codes), '"'), '"') - $expected_codes_values = suffix(prefix(values($expected_codes), '"'), '"') - $real_expected_codes= hash(flatten(zip($expected_codes_keys, $expected_codes_values))) - } else { - $real_expected_codes= {} - } - - lma_collector::collectd::python { 'check_local_endpoint': - config => { - 'Url' => $real_urls, - 'ExpectedCode' => $real_expected_codes, - 'Timeout' => "\"${timeout}\"", - 'MaxRetries' => "\"${max_retries}\"", - }, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi.pp deleted file mode 100644 index 71b05c10f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi.pp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::collectd::dbi { - include lma_collector::params - - if $::osfamily == 'RedHat' { - package { 'collectd-dbi': - ensure => present, - } - } - - package { $lma_collector::params::collectd_dbi_package: - ensure => present, - } - - collectd::plugin { 'dbi': - require => Package[$lma_collector::params::collectd_dbi_package], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi_mysql_status.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi_mysql_status.pp deleted file mode 100644 index 4306c1369..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi_mysql_status.pp +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define lma_collector::collectd::dbi_mysql_status ( - $database = undef, - $hostname = 'localhost', - $username = undef, - $password = undef, - $dbname = undef, -) { - - include collectd::params - include lma_collector::collectd::dbi - - $plugin_conf_dir = $collectd::params::plugin_conf_dir - - # FIXME(elemoine) we really should use the collectd::plugin::dbi class - # instead of adding collectd configuration files ourselves. Adding collectd - # configuration files ourselves forces us to reference to "collectd" service - # resource, which is private to the "collectd" module. - - file { "${plugin_conf_dir}/dbi_mysql_status.conf": - owner => 'root', - group => $collectd::params::root_group, - mode => '0640', - content => template('lma_collector/collectd_dbi_mysql_status.conf.erb'), - require => Class['lma_collector::collectd::dbi'], - notify => Service['collectd'], - } -} - diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi_services.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi_services.pp deleted file mode 100644 index 04262620e..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/dbi_services.pp +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define lma_collector::collectd::dbi_services ( - $hostname = 'localhost', - $username = undef, - $password = undef, - $dbname = undef, - $report_interval = undef, - $downtime_factor = undef, -) { - - include collectd::params - include lma_collector::collectd::dbi - - $service = $title - - if $report_interval == undef { - fail('report_interval needs to be defined!') - } - if $downtime_factor == undef { - fail('downtime_factor needs to be defined!') - } - - # A service is declared 'down' if no heartbeat has been received since - # "downtime_factor * report_interval" seconds, - # The "report_interval" must match the corresponding configuration of the - # service. - - $downtime = $report_interval * $downtime_factor - - if $service == 'nova' or $service == 'cinder' { - $type = 'services' - }elsif $service == 'neutron' { - $type = 'agents' - }else{ - fail("${service} not supported") - } - - $plugin_conf_dir = $collectd::params::plugin_conf_dir - - # FIXME(elemoine) we really should use the collectd::plugin::dbi class - # instead of adding collectd configuration files ourselves. Adding collectd - # configuration files ourselves forces us to reference to "collectd" service - # resource, which is private to the "collectd" module. - - file { "${plugin_conf_dir}/dbi_${service}_${type}.conf": - owner => 'root', - group => $collectd::params::root_group, - mode => '0640', - content => template('lma_collector/collectd_dbi_services.conf.erb'), - require => Class['lma_collector::collectd::dbi'], - notify => Service['collectd'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/elasticsearch.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/elasticsearch.pp deleted file mode 100644 index 3d7dea803..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/elasticsearch.pp +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# -class lma_collector::collectd::elasticsearch ( - $address, - $port = 9200, -) { - - validate_integer($port) - validate_string($address) - - lma_collector::collectd::python { 'elasticsearch_cluster': - config => { - 'Address' => "\"${address}\"", - 'Port' => "\"${port}\"", - }, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/haproxy.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/haproxy.pp deleted file mode 100644 index 5ba4dd902..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/haproxy.pp +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::haproxy ( - $socket, - $proxy_ignore = [], - $proxy_names = {}, -) { - - include lma_collector::params - - validate_array($proxy_ignore) - validate_hash($proxy_names) - - # Add quotes around the array values - $real_proxy_ignore = suffix(prefix($proxy_ignore, '"'), '"') - - # Add quotes around the hash keys and values - $proxy_names_keys = suffix(prefix(keys($proxy_names), '"'), '"') - $proxy_names_values = suffix(prefix(values($proxy_names), '"'), '"') - $real_proxy_names = hash(flatten(zip($proxy_names_keys, $proxy_names_values))) - - lma_collector::collectd::python { 'haproxy': - config => { - 'Socket' => "\"${socket}\"", - 'Mapping' => $real_proxy_names, - 'ProxyIgnore' => $real_proxy_ignore, - }, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/http_check.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/http_check.pp deleted file mode 100644 index 3bc5129e1..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/http_check.pp +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# -class lma_collector::collectd::http_check ( - $urls, - $expected_codes = {}, - $timeout = 1, - $max_retries = 3, - $pacemaker_master_resource = undef, -) { - - validate_hash($urls) - validate_hash($expected_codes) - validate_integer($timeout) - validate_integer($max_retries) - - # Add quotes around the hash keys and values - $urls_keys = suffix(prefix(keys($urls), '"'), '"') - $urls_values = suffix(prefix(values($urls), '"'), '"') - $real_urls= hash(flatten(zip($urls_keys, $urls_values))) - if ! empty($expected_codes) { - $expected_codes_keys = suffix(prefix(keys($expected_codes), '"'), '"') - $expected_codes_values = suffix(prefix(values($expected_codes), '"'), '"') - $real_expected_codes= hash(flatten(zip($expected_codes_keys, $expected_codes_values))) - } else { - $real_expected_codes= {} - } - - $config = { - 'Url' => $real_urls, - 'ExpectedCode' => $real_expected_codes, - 'Timeout' => "\"${timeout}\"", - 'MaxRetries' => "\"${max_retries}\"", - } - - if $pacemaker_master_resource { - $real_config = merge($config, {'DependsOnResource' => "\"${pacemaker_master_resource}\""}) - } else { - $real_config = $config - } - - lma_collector::collectd::python { 'http_check': - config => $real_config, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/hypervisor.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/hypervisor.pp deleted file mode 100644 index a457a7aa5..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/hypervisor.pp +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::hypervisor ( - $user, - $password, - $tenant, - $keystone_url, - $timeout = $lma_collector::params::openstack_client_timeout, - $pacemaker_master_resource = undef, - $cpu_allocation_ratio = $lma_collector::params::nova_cpu_allocation_ratio, -) inherits lma_collector::params { - - include lma_collector::collectd::python_openstack_base - - $config = { - 'Username' => "\"${user}\"", - 'Password' => "\"${password}\"", - 'Tenant' => "\"${tenant}\"", - 'KeystoneUrl' => "\"${keystone_url}\"", - 'Timeout' => "\"${timeout}\"", - 'CpuAllocationRatio' => "\"${cpu_allocation_ratio}\"", - } - - if $pacemaker_master_resource { - $real_config = merge($config, {'DependsOnResource' => "\"${pacemaker_master_resource}\""}) - } else { - $real_config = $config - } - - lma_collector::collectd::python { 'hypervisor_stats': - config => $real_config, - } - -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/influxdb.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/influxdb.pp deleted file mode 100644 index 830ec43c7..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/influxdb.pp +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. - -class lma_collector::collectd::influxdb ( - $username, - $password, - $address, - $port = 8086, -) { - - lma_collector::collectd::python { 'influxdb': - config => { - 'Username' => "\"${username}\"", - 'Password' => "\"${password}\"", - 'Address' => "\"${address}\"", - 'Port' => "\"${port}\"", - } - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/libvirt.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/libvirt.pp deleted file mode 100644 index 239426b32..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/libvirt.pp +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# -# == Class lma_collector::collectd::libvirt -# -# Class that configures collectd for collecting libvirt metrics. -# -# Note that the collectd plugin is configured to send the instance's UUID as -# the hostname of the collectd data. -# -# === Parameters: -# -# [*connection*] -# (optional) The hypervisor connection URI. Default is 'qemu:///system'. -# -class lma_collector::collectd::libvirt ( - $connection = $lma_collector::params::libvirt_connection, - $refresh_interval = 60, -) inherits lma_collector::params { - - validate_string($connection) - - class { 'collectd::plugin::libvirt': - connection => $connection, - hostname_format => 'uuid', - refresh_interval => $refresh_interval, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/libvirt_check.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/libvirt_check.pp deleted file mode 100644 index 7895aefd9..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/libvirt_check.pp +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# -# == Class lma_collector::collectd::libvirt_check -# -# Class that configures collectd to check availability of libvirt. -# -# === Parameters: -# -# [*connection*] -# (optional) The hypervisor connection URI. Default is 'qemu:///system'. -# -class lma_collector::collectd::libvirt_check ( - $connection = $lma_collector::params::libvirt_connection, -) inherits lma_collector::params { - - validate_string($connection) - - lma_collector::collectd::python { 'collectd_libvirt_check': - config => { - 'Uri' => "\"${connection}\"", - }, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/memcached.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/memcached.pp deleted file mode 100644 index 32ff078f8..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/memcached.pp +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::memcached ( - $host, - $port = 11211, -) { - - validate_integer($port) - - class { 'collectd::plugin::memcached': - host => $host, - port => $port, - } - - lma_collector::collectd::python { 'collectd_memcached_check': - config => { - 'Host' => "\"${host}\"", - 'Port' => "\"${port}\"", - }, - } - -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/mysql.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/mysql.pp deleted file mode 100644 index 590d4f5e9..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/mysql.pp +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::collectd::mysql ( - $username, - $password, - $host = 'localhost', - $socket = undef, -) inherits lma_collector::params { - - # With "config" as the resource title the collectd configuration - # file will be named "mysql-config.conf". - collectd::plugin::mysql::database { 'config': - host => $host, - username => $username, - password => $password, - socket => $socket, - } - - $default_config = { - 'Host' => "\"${host}\"", - 'Username' => "\"${username}\"", - 'Password' => "\"${password}\"", - } - - if $socket { - $config = merge($default_config, {'Socket' => "\"${socket}\""}) - } else { - $config = $default_config - } - - if $::osfamily == 'RedHat' { - $pymysql_pkg_name = 'python-PyMySQL' - } else { - $pymysql_pkg_name = 'python-pymysql' - } - package { $pymysql_pkg_name: - ensure => present, - } - - lma_collector::collectd::python { 'collectd_mysql_check': - config => $config, - require => Package[$pymysql_pkg_name], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/openstack.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/openstack.pp deleted file mode 100644 index 3a5cf4a8b..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/openstack.pp +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -define lma_collector::collectd::openstack ( - $user, - $password, - $tenant, - $keystone_url, - $timeout = 20, - $max_retries = 2, - $pacemaker_master_resource = undef, - $polling_interval = undef, - $pagination_limit = undef, -) { - - include lma_collector::params - include lma_collector::collectd::python_openstack_base - - $service = $title - - $supported_services = ['nova', 'nova_services', - 'cinder', 'cinder_services', 'glance', 'keystone', - 'neutron', 'neutron_agents'] - if ! member($supported_services, $service) { - fail("service '${service}' is not supported") - } - - validate_integer($timeout) - validate_integer($max_retries) - - $config = { - 'Username' => "\"${user}\"", - 'Password' => "\"${password}\"", - 'Tenant' => "\"${tenant}\"", - 'KeystoneUrl' => "\"${keystone_url}\"", - 'Timeout' => "\"${timeout}\"", - 'MaxRetries' => "\"${max_retries}\"", - } - if $polling_interval { - validate_integer($polling_interval) - $polling_config = { - 'PollingInterval' => "\"${polling_interval}\"" - } - } else { - $polling_config = {} - } - if $pagination_limit { - validate_integer($pagination_limit) - $limit_config = { - 'PaginationLimit' => "\"${pagination_limit}\"" - } - } else { - $limit_config = {} - } - - if $pacemaker_master_resource { - $pacemaker_config = {'DependsOnResource' => "\"${pacemaker_master_resource}\""} - } else { - $pacemaker_config = {} - } - $real_config = merge($config, $pacemaker_config, $polling_config, $limit_config) - - lma_collector::collectd::python { "openstack_${title}": - config => $real_config, - } - -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/openstack_checks.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/openstack_checks.pp deleted file mode 100644 index 8182a20dc..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/openstack_checks.pp +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::openstack_checks ( - $user, - $password, - $tenant, - $keystone_url, - $timeout = $lma_collector::params::openstack_client_timeout, - $pacemaker_master_resource = undef, -) inherits lma_collector::params { - - include lma_collector::collectd::python_openstack_base - - $config = { - 'Username' => "\"${user}\"", - 'Password' => "\"${password}\"", - 'Tenant' => "\"${tenant}\"", - 'KeystoneUrl' => "\"${keystone_url}\"", - 'Timeout' => "\"${timeout}\"", - } - - if $pacemaker_master_resource { - $real_config = merge($config, {'DependsOnResource' => "\"${pacemaker_master_resource}\""}) - } else { - $real_config = $config - } - - lma_collector::collectd::python { 'check_openstack_api': - config => $real_config, - } - -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/pacemaker.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/pacemaker.pp deleted file mode 100644 index bd0ba6914..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/pacemaker.pp +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::pacemaker ( - $resources, - $notify_resource = undef, - $hostname = undef, -) { - - validate_hash($resources) - - # Add quotes around the hash keys and values - $resources_keys = suffix(prefix(keys($resources), '"'), '"') - $resources_values = suffix(prefix(values($resources), '"'), '"') - $real_resources = hash(flatten(zip($resources_keys, $resources_values))) - - if $hostname { - $_hostname = {'Hostname' => "\"${hostname}\""} - } else { - $_hostname = {} - } - if $notify_resource { - $_notify_resource = {'NotifyResource' => "\"${notify_resource}\""} - } else { - $_notify_resource = {} - } - - lma_collector::collectd::python { 'collectd_pacemaker': - config => merge({'Resource' => $real_resources}, $_hostname, $_notify_resource) - } - - # Remove configuration bits from versions < 1.0 - collectd::plugin { 'target_notification': - ensure => absent - } - collectd::plugin { 'match_regex': - ensure => absent - } - class { 'collectd::plugin::chain': - ensure => absent - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python.pp deleted file mode 100644 index 7e8382a93..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python.pp +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define lma_collector::collectd::python ( - $config = {}, -) { - include lma_collector::params - include lma_collector::collectd::python_base - - validate_hash($config) - - # We use the adapt_collectd_python_plugin_config function to work around - # a limitation in collectd::plugin::python::module where the config hash - # cannot include values that are arrays or hashes. See - # https://github.com/voxpupuli/puppet-collectd/issues/390. - $real_config = adapt_collectd_python_plugin_config($config) - - collectd::plugin::python::module { "module_${title}": - module => $title, - modulepath => $lma_collector::collectd::python_base::modulepath, - script_source => "puppet:///modules/lma_collector/collectd/${title}.py", - config => $real_config, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python_base.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python_base.pp deleted file mode 100644 index 306356882..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python_base.pp +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::python_base { - include collectd::params - include lma_collector::params - - # variable is exposed for classes/defines including that class - $modulepath = $lma_collector::params::python_module_path - - class { 'collectd::plugin::python': - modulepaths => [$modulepath], - modules => {}, - } - - # The collectd module does not provide a way to add a Python file to Python - # directory without declaring a corresponding module in the collectd Python - # configuration file. For that reason we need to use a "file" resource and - # notify the "collectd" service resource ourselves. The "collectd" service - # resource is private to the "collectd" module, but we have no choice. - - file { 'base.script': - ensure => 'present', - path => "${modulepath}/collectd_base.py", - owner => 'root', - group => $collectd::params::root_group, - mode => '0640', - source => 'puppet:///modules/lma_collector/collectd/collectd_base.py', - require => Class['collectd::plugin::python'], - notify => Service['collectd'], - } - -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python_openstack_base.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python_openstack_base.pp deleted file mode 100644 index 5ed61b2dd..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/python_openstack_base.pp +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::python_openstack_base { - include collectd::params - include lma_collector::collectd::python_base - - $modulepath = $lma_collector::collectd::python_base::modulepath - - # The collectd module does not provide a way to add a Python file to Python - # directory without declaring a corresponding module in the collectd Python - # configuration file. For that reason we need to use a "file" resource and - # notify the "collectd" service resource ourselves. The "collectd" service - # resource is private to the "collectd" module, but we have no choice. - - file { 'openstack.script': - ensure => 'present', - path => "${modulepath}/collectd_openstack.py", - owner => 'root', - group => $collectd::params::root_group, - mode => '0640', - source => 'puppet:///modules/lma_collector/collectd/collectd_openstack.py', - require => Class['lma_collector::collectd::python_base'], - notify => Service['collectd'], - } - -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/rabbitmq.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/rabbitmq.pp deleted file mode 100644 index 457113587..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/collectd/rabbitmq.pp +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# - -class lma_collector::collectd::rabbitmq ( - $username, - $password, - $host = undef, - $port = undef, -) { - - if $host { - $host_config = { - 'Host' => "\"${host}\"", - } - } else { - $host_config = {} - } - - if $port { - validate_integer($port) - $port_config = { - 'Port' => "\"${port}\"", - } - } else { - $port_config = {} - } - - $config = { - 'Username' => "\"${username}\"", - 'Password' => "\"${password}\"", - } - - lma_collector::collectd::python { 'rabbitmq_info': - config => merge($config, $host_config, $port_config) - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/elasticsearch.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/elasticsearch.pp deleted file mode 100644 index 668cd40df..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/elasticsearch.pp +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::elasticsearch ( - $server, - $port, - $flush_interval = 5, - $flush_count = 10, -) { - include lma_collector::params - include lma_collector::service::log - - validate_string($server) - validate_integer($port) - - heka::encoder::es_json { 'elasticsearch': - config_dir => $lma_collector::params::log_config_dir, - index => '%{Type}-%{%Y.%m.%d}', - es_index_from_timestamp => true, - timestamp => '%Y-%m-%dT%H:%M:%S%z', - fields => $lma_collector::params::elasticsearch_fields, - notify => Class['lma_collector::service::log'], - } - - heka::output::elasticsearch { 'elasticsearch': - config_dir => $lma_collector::params::log_config_dir, - server => $server, - port => $port, - message_matcher => 'Type == \'log\' || Type == \'notification\' || Type == \'audit\'', - use_buffering => $lma_collector::params::buffering_enabled, - max_buffer_size => $lma_collector::params::buffering_max_buffer_size_for_log, - max_file_size => $lma_collector::params::buffering_max_file_size_for_log, - queue_full_action => $lma_collector::params::queue_full_action_for_log, - flush_interval => $flush_interval, - flush_count => $flush_count, - require => Heka::Encoder::Es_json['elasticsearch'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/gse_cluster_filter.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/gse_cluster_filter.pp deleted file mode 100644 index 7954757fa..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/gse_cluster_filter.pp +++ /dev/null @@ -1,101 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -define lma_collector::gse_cluster_filter ( - $input_message_types, - $aggregator_flag, - $member_field, - $output_message_type, - $output_metric_name, - $interval = 10, - $cluster_field = undef, - $clusters = {}, - $warm_up_period = undef, - $alerting = 'enabled_with_notification', - $ensure = present, -) { - include lma_collector::params - include lma_collector::service::metric - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - validate_array($input_message_types) - validate_string($cluster_field) - validate_string($member_field) - validate_string($output_metric_name) - if size($input_message_types) == 0 { - fail('input_message_types cannot be empty') - } - - $topology_file = sanitize_name_for_lua("gse_${title}_topology") - if $aggregator_flag { - $aggregator_flag_operator = '!=' - } else { - $aggregator_flag_operator = '==' - } - - $message_matcher = join([ - '(Fields[name] == \'pacemaker_local_resource_active\' && Fields[resource] == \'vip__management\') || ', - "(Fields[${lma_collector::params::aggregator_flag}] ${aggregator_flag_operator} NIL && (", - inline_template('<%= @input_message_types.collect{|x| "Type =~ /#{x}$/"}.join(" || ") %>'), - '))', - ], '') - - if $alerting and $alerting != 'disabled' and $alerting != 'enabled' and - $alerting != 'enabled_with_notification' { - - fail("alerting parameter must be either 'disabled', 'enabled' or 'enabled_with_notification' instead of ${alerting}") - } - - if $alerting != 'disabled' { - $activate_alerting = true - } else { - $activate_alerting = false - } - if $alerting != 'enabled_with_notification' { - $enable_notification = true - } else { - $enable_notification = false - } - - heka::filter::sandbox { "gse_${title}": - config_dir => $lma_collector::params::metric_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/gse_cluster_filter.lua", - message_matcher => $message_matcher, - ticker_interval => 1, - config => { - output_message_type => $output_message_type, - output_metric_name => $output_metric_name, - source => "gse_${title}_filter", - interval => $interval, - topology_file => $topology_file, - policies_file => $lma_collector::params::gse_policies_module, - cluster_field => $cluster_field, - member_field => $member_field, - max_inject => $lma_collector::params::hekad_max_timer_inject, - warm_up_period => $warm_up_period, - enable_notification => $enable_notification, - activate_alerting => $activate_alerting, - }, - module_directory => $lua_modules_dir, - require => File[$topology_file], - notify => Class['lma_collector::service::metric'] - } - - file { $topology_file: - ensure => present, - path => "${lua_modules_dir}/${topology_file}.lua", - content => template('lma_collector/gse_topology.lua.erb'), - notify => Class['lma_collector::service::metric'] - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/gse_nagios.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/gse_nagios.pp deleted file mode 100644 index ab5782fd4..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/gse_nagios.pp +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -define lma_collector::gse_nagios ( - $server, - $http_port, - $http_path, - $user, - $password, - $message_type, - $virtual_hostname, - $ensure = present, - $http_scheme = 'http', - $openstack_deployment_name = '', - $service_template = '%{cluster_name}', -) { - include lma_collector::params - include lma_collector::service::metric - - validate_integer($http_port) - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - $url = "${http_scheme}://${server}:${http_port}/${http_path}" - - # This must be identical logic than in lma-infra-alerting-plugin - $_nagios_host = "${virtual_hostname}-env${openstack_deployment_name}" - - $config = { - 'nagios_host' => $_nagios_host, - 'service_template' => "${title}-${service_template}", - } - heka::encoder::sandbox { "nagios_gse_${title}": - ensure => $ensure, - config_dir => $lma_collector::params::metric_config_dir, - filename => "${lma_collector::params::plugins_dir}/encoders/status_nagios.lua", - config => $config, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::metric'], - } - - heka::output::http { "nagios_gse_${title}": - ensure => $ensure, - config_dir => $lma_collector::params::metric_config_dir, - url => $url, - message_matcher => "Type == 'heka.sandbox.${message_type}' && Fields[no_alerting] == NIL", - username => $user, - password => $password, - encoder => "nagios_gse_${title}", - timeout => $lma_collector::params::nagios_timeout, - headers => { - 'Content-Type' => 'application/x-www-form-urlencoded' - }, - use_buffering => $lma_collector::params::buffering_enabled, - max_buffer_size => $lma_collector::params::buffering_max_buffer_size_for_nagios, - max_file_size => $lma_collector::params::buffering_max_file_size_for_nagios, - queue_full_action => $lma_collector::params::queue_full_action_for_nagios, - require => Heka::Encoder::Sandbox["nagios_gse_${title}"], - notify => Class['lma_collector::service::metric'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/gse_policies.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/gse_policies.pp deleted file mode 100644 index 38670cf0a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/gse_policies.pp +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -class lma_collector::gse_policies ( - $policies -) { - include lma_collector::params - include lma_collector::service::metric - - validate_hash($policies) - - $gse_policies_path = "${lma_collector::params::lua_modules_dir}/${lma_collector::params::gse_policies_module}.lua" - - file { 'gse_policies': - ensure => present, - path => $gse_policies_path, - content => template('lma_collector/gse_policies.lua.erb'), - notify => Class['lma_collector::service::metric'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/heka.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/heka.pp deleted file mode 100644 index 97ec4be98..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/heka.pp +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# -# == Define: lma_collector::heka -# -# The lma_collector::heka resource installs and configures heka service -# -# === Parameters -# -# === Examples -# -# === Authors -# -# Simon Pasquier -# Swann Croiset -# -# === Copyright -# -# Copyright 2016 Mirantis Inc., unless otherwise noted. -# -define lma_collector::heka ( - $user = 'heka', - $groups = [], - $heka_monitoring = true, - $poolsize = 100, - $install_init_script = true, - $version = 'latest', -) { - - include lma_collector::params - - validate_array($groups) - validate_bool($heka_monitoring) - validate_integer($poolsize) - - if ! member(['log_collector', 'metric_collector'], $title){ - fail('lma_collector::heka title must be either "log_collector" or "metric_collector"') - } - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - $additional_groups = $user ? { - 'root' => [], - default => union($lma_collector::params::groups, $groups), - } - - if $title == 'metric_collector' { - - $config_dir = $lma_collector::params::metric_config_dir - $service_class = 'lma_collector::service::metric' - $dashboard_port = $lma_collector::params::metric_dashboard_port - - heka::decoder::sandbox { 'metric': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/metric.lua", - module_directory => $lua_modules_dir, - config => { - 'deserialize_bulk_metric_for_loggers' => 'aggregated_http_metrics_filter hdd_errors_counter_filter logs_counter_filter'}, - notify => Class[$service_class], - } - - heka::input::tcp { 'metric': - config_dir => $config_dir, - address => $lma_collector::params::metric_input_address, - port => $lma_collector::params::metric_input_port, - decoder => 'metric', - require => [::Heka[$title], Heka::Decoder::Sandbox['metric']], - notify => Class[$service_class], - } - - } elsif $title == 'log_collector' { - - $config_dir = $lma_collector::params::log_config_dir - $service_class = 'lma_collector::service::log' - $dashboard_port = $lma_collector::params::log_dashboard_port - - heka::output::tcp { 'metric': - config_dir => $config_dir, - address => $lma_collector::params::metric_input_address, - port => $lma_collector::params::metric_input_port, - message_matcher => '(Type == \'metric\' || Type == \'heka.sandbox.metric\' || Type == \'heka.sandbox.bulk_metric\')', - max_buffer_size => $lma_collector::params::buffering_max_buffer_log_metric_size, - max_file_size => $lma_collector::params::buffering_max_file_log_metric_size, - queue_full_action => $lma_collector::params::queue_full_action_log_metric, - require => ::Heka[$title], - notify => Class[$service_class], - } - } - - ::heka { $title: - config_dir => $config_dir, - user => $user, - additional_groups => $additional_groups, - hostname => $::hostname, - max_message_size => $lma_collector::params::hekad_max_message_size, - max_process_inject => $lma_collector::params::hekad_max_process_inject, - max_timer_inject => $lma_collector::params::hekad_max_timer_inject, - poolsize => $poolsize, - install_init_script => $install_init_script, - version => $version, - } - - # Heka self-monitoring - if $heka_monitoring { - $heka_monitoring_ensure = present - } else { - $heka_monitoring_ensure = absent - } - - heka::filter::sandbox { "heka_monitoring_${title}": - ensure => $heka_monitoring_ensure, - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/heka_monitoring.lua", - message_matcher => "Type == 'heka.all-report'", - require => ::Heka[$title], - module_directory => $lua_modules_dir, - notify => Class[$service_class], - } - - # Dashboard is required to enable monitoring messages - heka::output::dashboard { "dashboard_${title}": - ensure => $heka_monitoring_ensure, - config_dir => $config_dir, - dashboard_address => $lma_collector::params::dashboard_address, - dashboard_port => $dashboard_port, - require => ::Heka[$title], - notify => Class[$service_class], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/influxdb.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/influxdb.pp deleted file mode 100644 index 679787ccc..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/influxdb.pp +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::influxdb ( - $database, - $user, - $password, - $server, - $port, - $tag_fields = $lma_collector::params::influxdb_tag_fields, - $time_precision = $lma_collector::params::influxdb_time_precision, - $flush_count = $lma_collector::params::influxdb_flush_count, - $flush_interval = $lma_collector::params::influxdb_flush_interval, -) inherits lma_collector::params { - include lma_collector::service::metric - - validate_integer($port) - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - validate_string($database, $user, $password, $server, $time_precision) - validate_array($tag_fields) - validate_integer([$flush_count, $flush_interval]) - - heka::filter::sandbox { 'influxdb_accumulator': - config_dir => $lma_collector::params::metric_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/influxdb_accumulator.lua", - message_matcher => $lma_collector::params::influxdb_message_matcher, - ticker_interval => 1, - config => { - flush_interval => $flush_interval, - flush_count => $flush_count, - tag_fields => join(sort($tag_fields), ' '), - time_precision => $time_precision, - # FIXME(pasquier-s): provide the default_tenant_id & default_user_id - # parameters but this requires to request Keystone since we only have - # access to the tenant name and user name for services - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::metric'], - } - - heka::filter::sandbox { 'influxdb_annotation': - config_dir => $lma_collector::params::metric_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/influxdb_annotation.lua", - message_matcher => 'Type == \'heka.sandbox.gse_cluster_metric\'', - config => { - serie_name => $lma_collector::params::annotations_serie_name - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::metric'], - } - - heka::encoder::payload { 'influxdb': - config_dir => $lma_collector::params::metric_config_dir, - notify => Class['lma_collector::service::metric'], - } - - heka::output::http { 'influxdb': - config_dir => $lma_collector::params::metric_config_dir, - url => "http://${server}:${port}/write?db=${database}&precision=${time_precision}", - message_matcher => 'Fields[payload_type] == \'txt\' && Fields[payload_name] == \'influxdb\'', - username => $user, - password => $password, - timeout => $lma_collector::params::influxdb_timeout, - headers => { - 'Content-Type' => 'application/x-www-form-urlencoded' - }, - use_buffering => $lma_collector::params::buffering_enabled, - max_file_size => $lma_collector::params::buffering_max_file_size_for_metric, - max_buffer_size => $lma_collector::params::buffering_max_buffer_size_for_metric, - queue_full_action => $lma_collector::params::queue_full_action_for_metric, - require => Heka::Encoder::Payload['influxdb'], - notify => Class['lma_collector::service::metric'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/init.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/init.pp deleted file mode 100644 index fbaa11385..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/init.pp +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# == Class: lma_collector -# -# The lma_collector class installs the common Lua modules used by -# the Logging, Monitoring and Alerting collector services. -# -# === Parameters -# -# === Examples -# -# === Authors -# -# Simon Pasquier -# Swann Croiset -# -# === Copyright -# -# Copyright 2016 Mirantis Inc., unless otherwise noted. -# -class lma_collector ( - $tags = {}, -) { - include lma_collector::params - include lma_collector::service::log - include lma_collector::service::metric - - validate_hash($tags) - - $plugins_dir = $lma_collector::params::plugins_dir - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - file { $lua_modules_dir: - ensure => directory, - source => 'puppet:///modules/lma_collector/plugins/common', - recurse => remote, - notify => [Class['lma_collector::service::metric'], - Class['lma_collector::service::log']], - } - - file { "${lua_modules_dir}/extra_fields.lua": - ensure => present, - content => template('lma_collector/extra_fields.lua.erb'), - require => File[$lua_modules_dir], - notify => [Class['lma_collector::service::metric'], - Class['lma_collector::service::log']], - } - - file { $plugins_dir: - ensure => directory, - } - - file { "${plugins_dir}/decoders": - ensure => directory, - source => 'puppet:///modules/lma_collector/plugins/decoders', - recurse => remote, - notify => [Class['lma_collector::service::metric'], - Class['lma_collector::service::log']], - require => File[$plugins_dir] - } - - file { "${plugins_dir}/filters": - ensure => directory, - source => 'puppet:///modules/lma_collector/plugins/filters', - recurse => remote, - notify => [Class['lma_collector::service::metric'], - Class['lma_collector::service::log']], - require => File[$plugins_dir] - } - - file { "${plugins_dir}/encoders": - ensure => directory, - source => 'puppet:///modules/lma_collector/plugins/encoders', - recurse => remote, - notify => [Class['lma_collector::service::metric'], - Class['lma_collector::service::log']], - require => File[$plugins_dir] - } - - file { "${plugins_dir}/outputs": - ensure => directory, - source => 'puppet:///modules/lma_collector/plugins/outputs', - recurse => remote, - notify => [Class['lma_collector::service::metric'], - Class['lma_collector::service::log']], - require => File[$plugins_dir] - } - - if size($lma_collector::params::additional_packages) > 0 { - package { $lma_collector::params::additional_packages: - ensure => present, - } - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/aggregated_http_metrics.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/aggregated_http_metrics.pp deleted file mode 100644 index 5473ee5d3..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/aggregated_http_metrics.pp +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::aggregated_http_metrics ( - $interval = 10, - $hostname = $::hostname, - $bulk_size = $lma_collector::params::http_aggregated_metrics_bulk_size, - $max_timer_inject = $lma_collector::params::hekad_max_timer_inject, - $percentile = 90, - $grace_time = 5, -) inherits lma_collector::params { - - include lma_collector::service::log - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::filter::sandbox { 'aggregated_http_metrics': - config_dir => $lma_collector::params::log_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/http_metrics_aggregator.lua", - message_matcher => 'Type == \'log\' && Fields[http_response_time] != NIL', - ticker_interval => $interval, - config => { - hostname => $hostname, - interval => $interval, - max_timer_inject => $max_timer_inject, - bulk_size => $bulk_size, - percentile => $percentile, - grace_time => $grace_time, - source => 'log_collector', - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/counter.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/counter.pp deleted file mode 100644 index 4db64cec3..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/counter.pp +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::counter ( - $hostname, - $interval = 60, - $grace_interval = 30, -) { - include lma_collector::params - include lma_collector::service::log - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::filter::sandbox { 'logs_counter': - config_dir => $lma_collector::params::log_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/logs_counter.lua", - message_matcher => 'Type == \'log\' && Logger =~ /^openstack\\./', - ticker_interval => 60, - preserve_data => true, - config => { - interval => $interval, - hostname => $hostname, - grace_interval => $grace_interval, - logger_matcher => '^openstack%.(%a+)$', - source => 'log_collector', - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/hdd_errors_counter.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/hdd_errors_counter.pp deleted file mode 100644 index 4b4bde5ce..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/hdd_errors_counter.pp +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::hdd_errors_counter ( - $interval = 10, - $hostname = $::hostname, - $grace_interval = 10, -) inherits lma_collector::params { - - include lma_collector::service::log - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::filter::sandbox { 'hdd_errors_counter': - config_dir => $lma_collector::params::log_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/hdd_errors_counter.lua", - message_matcher => 'Type == \'log\' && Logger == \'system.kern\'', - ticker_interval => $interval, - config => { - hostname => $hostname, - grace_interval => $grace_interval, - patterns => '/error%s.+([sv]d[a-z][a-z]?)%d?/ /([sv]d[a-z][a-z]?)%d?.+%serror/', - source => 'log_collector', - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/http_metrics.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/http_metrics.pp deleted file mode 100644 index 9df2dccbc..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/http_metrics.pp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::http_metrics { - - include lma_collector::params - include lma_collector::service::log - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - # This sandbox has been replaced by the aggregated_http_metrics one. - heka::filter::sandbox { 'http_metrics': - ensure => absent, - config_dir => $lma_collector::params::log_config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/http_metrics.lua", - message_matcher => 'Type == \'log\' && Fields[http_response_time] != NIL', - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/keystone_wsgi.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/keystone_wsgi.pp deleted file mode 100644 index 4d21513d4..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/keystone_wsgi.pp +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -# -# == Class lma_collector::logs::keystone_wsgi -# -class lma_collector::logs::keystone_wsgi ( - $log_directory = $lma_collector::params::apache_log_directory, -) inherits lma_collector::params { - include lma_collector::service::log - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::decoder::sandbox { 'keystone_wsgi': - config_dir => $lma_collector::params::log_config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/keystone_wsgi_log.lua", - config => { - apache_log_pattern => $lma_collector::params::apache_log_pattern, - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } - - heka::input::logstreamer { 'keystone_wsgi': - config_dir => $lma_collector::params::log_config_dir, - decoder => 'keystone_wsgi', - log_directory => $log_directory, - file_match => 'keystone_wsgi_(?P.+)_access\.log\.?(?P\d*)$', - differentiator => "['keystone-wsgi-', 'Service']", - priority => '["^Seq"]', - require => Heka::Decoder::Sandbox['keystone_wsgi'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/libvirt.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/libvirt.pp deleted file mode 100644 index f177c3b15..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/libvirt.pp +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Class lma_collector::logs::libvirt - -class lma_collector::logs::libvirt { - - include lma_collector::params - include lma_collector::service::log - - $config_dir = $lma_collector::params::log_config_dir - - $libvirt_dir = '/var/log/libvirt' - $libvirt_log = 'libvirtd.log' - $libvirt_hooks_dir = '/etc/libvirt/hooks' - $libvirt_hook = "${libvirt_hooks_dir}/daemon" - $libvirt_service = $::libvirt_daemon - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - service {$libvirt_service: } - - file { $libvirt_hooks_dir: - ensure => 'directory', - } - - # libvirt is running as root and by default permission are restricted to - # root user. So we need to enable other users to read this file. - file { $libvirt_hook: - owner => 'root', - group => 'root', - mode => '0700', - content => template('lma_collector/hooks_daemon.erb'), - require => File[$libvirt_hooks_dir], - notify => Service[$libvirt_service], - } - - heka::decoder::sandbox { 'libvirt': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/libvirt_log.lua", - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } - - heka::input::logstreamer { 'libvirt': - config_dir => $config_dir, - log_directory => $libvirt_dir, - file_match => $libvirt_log, - decoder => 'libvirt', - differentiator => '["libvirt"]', - require => Heka::Decoder::Sandbox['libvirt'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/mysql.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/mysql.pp deleted file mode 100644 index 33c4c7702..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/mysql.pp +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::mysql { - include lma_collector::params - include lma_collector::service::log - - $config_dir = $lma_collector::params::log_config_dir - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::decoder::sandbox { 'mysql': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/mysql_log.lua" , - config => { - syslog_pattern => $lma_collector::params::syslog_pattern, - tz => $::canonical_timezone, - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } - - heka::input::logstreamer { 'mysql': - config_dir => $config_dir, - decoder => 'mysql', - file_match => 'mysqld\.log$', - differentiator => '[\'mysql\']', - require => Heka::Decoder::Sandbox['mysql'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/openstack.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/openstack.pp deleted file mode 100644 index cc7791dd7..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/openstack.pp +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -# -# == Define: lma_collector::logs::openstack -# -# Declaring this defined type creates an Heka logstreamer that reads logs of -# an OpenStack service. The logstreamer is automatically configured with an -# Heka decoder and an Heka splitter appropriate for OpenStack logs. -# -# It works for "standard" OpenStack services that write their logs into log files -# located in /var/log/{service}, where {service} is the service name. -# -define lma_collector::logs::openstack ( - $service_match = '.+', -) { - - # Note: $log_directory could be made configurable in the future. - - include lma_collector::params - include lma_collector::service::log - include lma_collector::logs::openstack_decoder_splitter - - heka::input::logstreamer { $title: - config_dir => $lma_collector::params::log_config_dir, - log_directory => "/var/log/${title}", - decoder => 'openstack', - splitter => 'openstack', - file_match => "(?P${service_match})\\.log\\.?(?P\\d*)$", - differentiator => "['${title}', '_', 'Service']", - priority => '["^Seq"]', - require => Class['lma_collector::logs::openstack_decoder_splitter'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/openstack_decoder_splitter.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/openstack_decoder_splitter.pp deleted file mode 100644 index d0abee080..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/openstack_decoder_splitter.pp +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -# -# == Class lma_collector::logs::openstack_decoder_splitter -# -# Class that sets a decoder sandbox and a token splitter for processing -# standard OpenStack service logs. -# -class lma_collector::logs::openstack_decoder_splitter { - include lma_collector::params - include lma_collector::service::log - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::decoder::sandbox { 'openstack': - config_dir => $lma_collector::params::log_config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/openstack_log.lua", - module_directory => $lua_modules_dir, - config => { - tz => $::canonical_timezone, - }, - notify => Class['lma_collector::service::log'], - } - - heka::splitter::token { 'openstack': - config_dir => $lma_collector::params::log_config_dir, - delimiter => '\n', - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/ovs.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/ovs.pp deleted file mode 100644 index 0d6919e68..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/ovs.pp +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::ovs { - - include lma_collector::params - include lma_collector::service::log - - $config_dir = $lma_collector::params::log_config_dir - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::decoder::sandbox { 'ovs': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/ovs_log.lua", - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } - - heka::input::logstreamer { 'ovs': - config_dir => $config_dir, - decoder => 'ovs', - log_directory => '/var/log/openvswitch', - file_match => '(?Povs\-vswitchd|ovsdb\-server)\.log$', - differentiator => '[ \'Service\' ]', - require => Heka::Decoder::Sandbox['ovs'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/pacemaker.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/pacemaker.pp deleted file mode 100644 index 26abf9e23..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/pacemaker.pp +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::pacemaker { - include lma_collector::params - include lma_collector::service::log - - $config_dir = $lma_collector::params::log_config_dir - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::decoder::sandbox { 'pacemaker': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/pacemaker_log.lua", - config => { - syslog_pattern => $lma_collector::params::syslog_pattern, - tz => $::canonical_timezone, - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } - - # Use the default splitter 'TokenSplitter' with 'newline' delimiter, - # because Pacemaker may log messages with and without the preamble. - heka::input::logstreamer { 'pacemaker': - config_dir => $config_dir, - decoder => 'pacemaker', - file_match => 'pacemaker\.log$', - differentiator => '[ \'pacemaker\' ]', - require => Heka::Decoder::Sandbox['pacemaker'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/rabbitmq.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/rabbitmq.pp deleted file mode 100644 index 8f6f949b6..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/rabbitmq.pp +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::rabbitmq { - include lma_collector::params - include lma_collector::service::log - - $config_dir = $lma_collector::params::log_config_dir - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::decoder::sandbox { 'rabbitmq': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/rabbitmq.lua" , - module_directory => $lua_modules_dir, - config => { - tz => $::canonical_timezone, - }, - notify => Class['lma_collector::service::log'], - } - - heka::splitter::regex { 'rabbitmq': - config_dir => $config_dir, - delimiter => '\n\n(=[^=]+====)', - delimiter_eol => false, - notify => Class['lma_collector::service::log'], - } - - heka::input::logstreamer { 'rabbitmq': - config_dir => $config_dir, - decoder => 'rabbitmq', - splitter => 'rabbitmq', - log_directory => '/var/log/rabbitmq', - file_match => 'rabbit@(?P.+)\.log$', - differentiator => '["rabbitmq.", "Node"]', - require => [Heka::Decoder::Sandbox['rabbitmq'], Heka::Splitter::Regex['rabbitmq']], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/swift.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/swift.pp deleted file mode 100644 index 62c4d78cf..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/swift.pp +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -# -# == Class lma_collector::logs::swift -# -# Class that configures Heka for reading Swift logs. -# -# The following rsyslog pattern is assumed: -# -# <%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%\n -# -# Swift only uses syslog and doesn't add its logs to log files located in a -# /var/log/swift/ directory as other OpenStack services do. So we make Swift a -# special case and assume rsyslog is used. -# -# === Parameters: -# -# [*file_match*] -# (mandatory) The log file name pattern. Example: 'swift\.log$'. Example -# for a sequential rotating logfile: 'swift\.log\.?(?P\d*)$'. See -# http://hekad.readthedocs.org/en/latest/pluginconfig/logstreamer.html -# for more information. -# -# [*priority*] -# (optional) When using sequential logstreams, the priority defines how -# to sort the logfiles in order from the slowest to newest. Example: -# '["^Seq"]'. See -# http://hekad.readthedocs.org/en/latest/pluginconfig/logstreamer.html -# for more information. -# -# [*log_directory*] -# (optional) The log directory. Default is /var/log. -# -class lma_collector::logs::swift ( - $file_match, - $priority = undef, - $log_directory = $lma_collector::params::log_directory, -) inherits lma_collector::params { - include lma_collector::service::log - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - $config_dir = $lma_collector::params::log_config_dir - # Note: syslog_pattern could be made configurable in the future. - heka::decoder::sandbox { 'swift': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/generic_syslog.lua", - config => { - syslog_pattern => $lma_collector::params::syslog_pattern, - fallback_syslog_pattern => $lma_collector::params::fallback_syslog_pattern, - tz => $::canonical_timezone, - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } - - heka::input::logstreamer { 'swift': - config_dir => $config_dir, - decoder => 'swift', - log_directory => $log_directory, - file_match => $file_match, - differentiator => '[\'openstack.swift\']', - priority => $priority, - require => Heka::Decoder::Sandbox['swift'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/system.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/logs/system.pp deleted file mode 100644 index bf3bb50f1..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/logs/system.pp +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::logs::system { - include lma_collector::params - include lma_collector::service::log - - $config_dir = $lma_collector::params::log_config_dir - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - heka::decoder::sandbox { 'system': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/generic_syslog.lua" , - config => { - syslog_pattern => $lma_collector::params::syslog_pattern, - fallback_syslog_pattern => $lma_collector::params::fallback_syslog_pattern, - tz => $::canonical_timezone, - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } - - heka::input::logstreamer { 'system': - config_dir => $config_dir, - decoder => 'system', - file_match => '(?Pdaemon\.log|cron\.log|haproxy\.log|kern\.log|auth\.log|syslog|messages|debug)', - differentiator => '[ \'system.\', \'Service\' ]', - require => Heka::Decoder::Sandbox['system'], - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/notifications/input.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/notifications/input.pp deleted file mode 100644 index e3cb72cc3..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/notifications/input.pp +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::notifications::input ( - $topic, - $user, - $password, - $host, - $port = $lma_collector::params::rabbitmq_port, -) inherits lma_collector::params { - - include lma_collector::service::log - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - validate_string($topic) - validate_string($user) - validate_string($password) - validate_string($host) - validate_integer($port) - - # We need to pick one exchange and we settled on 'nova'. The default - # exchange ("") doesn't work because Heka would fail to create the queue in - # case it doesn't exist yet. - $exchange = 'nova' - - $config_dir = $lma_collector::params::log_config_dir - heka::decoder::sandbox { 'notification': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/decoders/notification.lua" , - config => { - include_full_notification => false - }, - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } - - create_resources( - heka::input::amqp, - { - 'openstack_info' => { - queue => "${topic}.info", - routing_key => "${topic}.info", - }, - 'openstack_warn' => { - queue => "${topic}.warn", - routing_key => "${topic}.warn", - }, - 'openstack_error' => { - queue => "${topic}.error", - routing_key => "${topic}.error", - }, - }, - { - config_dir => $config_dir, - decoder => 'notification', - user => $user, - password => $password, - host => $host, - port => $port, - exchange => $exchange, - exchange_durability => false, - exchange_auto_delete => false, - queue_auto_delete => false, - exchange_type => 'topic', - notify => Class['lma_collector::service::log'], - } - ) -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/notifications/metrics.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/notifications/metrics.pp deleted file mode 100644 index 12c5adf45..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/notifications/metrics.pp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::notifications::metrics { - include lma_collector::params - include lma_collector::service::log - - $config_dir = $lma_collector::params::log_config_dir - - $lua_modules_dir = $lma_collector::params::lua_modules_dir - - # Filter to compute resource's creation time metric - heka::filter::sandbox { 'resource_creation_time': - config_dir => $config_dir, - filename => "${lma_collector::params::plugins_dir}/filters/resource_creation_time.lua", - message_matcher => 'Type == \'notification\' && Fields[event_type] =~ /^(compute.instance|volume).(create|attach).end$/', - module_directory => $lua_modules_dir, - notify => Class['lma_collector::service::log'], - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/params.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/params.pp deleted file mode 100644 index 1cfa91a70..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/params.pp +++ /dev/null @@ -1,184 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -class lma_collector::params { - $metric_service_name = 'metric_collector' - $log_service_name = 'log_collector' - $metric_config_dir = "/etc/${metric_service_name}" - $log_config_dir = "/etc/${log_service_name}" - $lua_modules_dir = '/usr/share/lma_collector_modules' - # Lua plugins are shared across log and metric collectors - $plugins_dir = '/usr/share/lma_collector' - - $pacemaker_managed = false - - # Address and port of the Heka dashboard for health reports. - $dashboard_address = '127.0.0.1' - $log_dashboard_port = '4352' - $metric_dashboard_port = '4353' - - # Address and port of the metric input - $metric_input_address = '127.0.0.1' - $metric_input_port = 5567 - - $aggregator_address = '127.0.0.1' - $aggregator_port = 5565 - $aggregator_flag = 'aggregator' - # matcher for the messages sent to the aggregator - $aggregator_client_message_matcher = join([ - "(Fields[${aggregator_flag}] == NIL && ", - '(Type =~ /^heka\\.sandbox\\.afd.*metric$/ || ', - '(Fields[hostname] == NIL && Type =~ /^.*metric$/)))'], '') - - $log_watchdog_file = "/tmp/${log_service_name}.watchdog" - $log_watchdog_payload_name = "${log_service_name}.watchdog" - $metric_watchdog_file = "/tmp/${metric_service_name}.watchdog" - $metric_watchdog_payload_name = "${metric_service_name}.watchdog" - $watchdog_interval = 1 - $watchdog_timeout = 10 * $watchdog_interval - - $tags = {} - - $log_directory = '/var/log' - $syslog_pattern = '<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%\n' - # same pattern except the tag - $fallback_syslog_pattern = '%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%\n' - - $apache_log_directory = '/var/log/apache2' - $apache_log_pattern = '%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"' - - # required to read the log files - case $::osfamily { - 'Debian': { - $groups = ['syslog', 'adm'] - } - 'RedHat': { - $groups = [] - } - default: { - fail("${::osfamily} not supported") - } - } - - $buffering_enabled = true - - # Maximum size of 227Kb has been oberved by a client. - # Lets configure 256Kb by default. - # https://bugs.launchpad.net/lma-toolchain/+bug/1548093 - $hekad_max_message_size = 256 * 1024 - - $buffering_max_file_size_for_metric = 128 * 1024 * 1024 - $buffering_max_buffer_size_for_metric = 1536 * 1024 * 1024 - $queue_full_action_for_metric = 'drop' - - $buffering_max_file_size_for_aggregator = 64 * 1024 * 1024 - $buffering_max_buffer_size_for_aggregator = 256 * 1024 * 1024 - $queue_full_action_for_aggregator = 'drop' - - # The log collector should have enough room to deal with transient spikes of - # data otherwise it may fill up the local buffer which in turn blocks the - # Heka pipeline. Once the pipeline is stuck, it will have a hard time to - # recover from that situation. In most cases, 1Gb should be enough. - $buffering_max_file_size_for_log = 128 * 1024 * 1024 - $buffering_max_buffer_size_for_log = 1024 * 1024 * 1024 - $queue_full_action_for_log = 'block' - - $buffering_max_file_log_metric_size = 64 * 1024 * 1024 - $buffering_max_buffer_log_metric_size = 256 * 1024 * 1024 - $queue_full_action_for_log_metric = 'drop' - - $buffering_max_file_size_for_nagios = 512 * 1024 - $buffering_max_buffer_size_for_nagios = 1 * 1024 * 1024 - $queue_full_action_for_nagios = 'drop' - - # HTTP aggregated metrics bulk_size parameter depends on hekad_max_message_size. - # The bulk_size is calculated considering that one metric bucket is a string - # of 300B size and we pick 60% of the theorical value. - # With the hekad_max_message_size set to 256KB, the bulk_size is 524 metrics. - $http_aggregated_metrics_bulk_size = floor($hekad_max_message_size / 300 * 0.6) - - # Heka's default value is 1 - $hekad_max_process_inject = 1 - - # Heka's default value is 10 - $hekad_max_timer_inject = 10 - - # Parameters for OpenStack notifications - $rabbitmq_port = '5672' - - # collectd parameters - $collectd_port = '8325' - $collectd_interval = 10 - $collectd_queue_limit = 10000 - $collectd_read_threads = 5 - $collectd_logfile = '/var/log/collectd.log' - case $::osfamily { - 'Debian': { - $python_module_path = '/usr/lib/collectd' - $collectd_dbi_package = 'libdbd-mysql' - } - 'RedHat': { - $python_module_path = '/usr/lib64/collectd' - $collectd_dbi_package = 'libdbi-dbd-mysql' - } - default: { - fail("${::osfamily} not supported") - } - } - $additional_packages = [ 'python-dateutil' ] - $openstack_user = '' - $openstack_password = '' - $openstack_tenant = '' - $openstack_url = 'http://127.0.0.1:5000/v2.0/' - $openstack_client_timeout = 5 - $nova_cpu_allocation_ratio = 16.0 - $fstypes = ['ext2', 'ext3', 'ext4', 'xfs', 'tmpfs'] - $collectd_types = [ 'ceph', 'ceph_perf' ] - $libvirt_connection = 'qemu:///system' - - $heartbeat_timeout = 30 - - $annotations_serie_name = 'annotations' - - $worker_report_interval = 60 - $worker_downtime_factor = 2 - - $elasticsearch_fields = ['Timestamp', 'Type', 'Logger', 'Severity', 'Payload', 'Pid', 'Hostname', 'DynamicFields'] - - $influxdb_timeout = 5 - $influxdb_flush_interval = 5 - # InfluxDB recommends a batch size of 5,000 points but we are limited to 400 - # due to the hekad_max_message_size. The limit is reached when the influxdb - # accumulator inject data points. - $influxdb_flush_count = 400 - $influxdb_tag_fields = [] - $influxdb_time_precision = 'ms' - $influxdb_message_matcher = join([ - "Fields[${aggregator_flag}] == NIL", ' && ', - 'Type =~ /metric$/' - ], '') - - $apache_status_host = '127.0.0.1' - $apache_status_port = '80' - - $gse_policies_module = 'gse_policies' - - # Nagios parameters - # - $nagios_timeout = 2 - - # Parameters for SMTP alert of service status - $smtp_from = 'lma-alert@localhost.localdomain' - $smtp_send_interval = 0 -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/service/log.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/service/log.pp deleted file mode 100644 index f84bd704a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/service/log.pp +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Class: lma_collector::service::log -# -# Manages the Log and Notification collector daemon -# -# Sample Usage: -# -# sometype { 'foo': -# notify => Class['lma_collector::service::log'], -# } -# -# -class lma_collector::service::log { - include lma_collector::params - - service { $::lma_collector::params::log_service_name: - ensure => 'running', - enable => true, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/manifests/service/metric.pp b/deployment_scripts/puppet/modules/lma_collector/manifests/service/metric.pp deleted file mode 100644 index c559ca22e..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/manifests/service/metric.pp +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# Class: lma_collector::service:metric -# -# Manages the Metric collector daemon -# -# Sample Usage: -# -# sometype { 'foo': -# notify => Class['lma_collector::service::metric'], -# } -# -# -class lma_collector::service::metric { - include lma_collector::params - - service { $::lma_collector::params::metric_service_name: - ensure => 'running', - enable => true, - } -} diff --git a/deployment_scripts/puppet/modules/lma_collector/metadata.json b/deployment_scripts/puppet/modules/lma_collector/metadata.json deleted file mode 100644 index ec45a50dd..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/metadata.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "mirantis-lma_collector", - "version": "1.0.0", - "author": "Simon Pasquier ", - "summary": "Puppet LMA Collector Module", - "license": "Apache-2.0", - "source": "https://git.openstack.org/cgit/openstack/fuel-plugin-lma-collector.git", - "project_page": "none", - "issues_url": "none", - "operatingsystem_support": [ - { - "operatingsystem": "Ubuntu", - "operatingsystemrelease": ["14.04"] - } - ], - "requirements": [ - {"name": "puppet", "version_requirement": "3.x"} - ], - "description": "Puppet module for configuring the LMA collector service", - "dependencies": [ - {"name": "mirantis/heka", "version_requirement": "1.x"}, - {"name": "puppet/collectd", "version_requirement": ">= 4.3.0"}, - {"name": "puppetlabs/apache", "version_requirement": ">= 1.4.0"}, - {"name": "puppetlabs/inifile", "version_requirement": ">= 1.4.2"}, - {"name": "puppetlabs/stdlib", "version_requirement": "4.x"} - ] -} diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_afd_api_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_afd_api_spec.rb deleted file mode 100644 index b455a907f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_afd_api_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::afd::api' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - it { is_expected.to contain_heka__filter__sandbox('afd_api_backends') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_aggregator_client_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_aggregator_client_spec.rb deleted file mode 100644 index fe34ab105..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_aggregator_client_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::aggregator::client' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - it { is_expected.to raise_error(Puppet::Error) } - end - - describe 'with address = 127.0.0.2' do - let(:params) do - {:address => '127.0.0.2'} - end - it { is_expected.to contain_heka__output__tcp('aggregator').with_address('127.0.0.2') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_aggregator_server_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_aggregator_server_spec.rb deleted file mode 100644 index 7fd84ce5d..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_aggregator_server_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::aggregator::server' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - it { is_expected.to contain_heka__input__tcp('aggregator') } - it { is_expected.to contain_heka__decoder__multidecoder('aggregator') } - it { is_expected.to contain_heka__decoder__scribbler('aggregator_flag') } - it { is_expected.not_to contain_heka__input__http_listen('check-http') } - end - - describe 'with http_check_port = 3000' do - let(:params) do - {:http_check_port => 3000} - end - it { is_expected.to contain_heka__input__tcp('aggregator') } - it { is_expected.to contain_heka__decoder__multidecoder('aggregator') } - it { is_expected.to contain_heka__decoder__scribbler('aggregator_flag') } - it { is_expected.to contain_heka__input__httplisten('http-check').with_port(3000) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_apache_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_apache_spec.rb deleted file mode 100644 index ccd2ea331..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_apache_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::apache' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with default params' do - it { is_expected.to contain_class('collectd::plugin::apache') } - end - - describe 'with "host" and "port" param' do - let(:params) {{:host => 'example.com', :port => '8081'}} - it { - is_expected.to contain_class('collectd::plugin::apache') \ - .with_instances({'localhost' => {'url' => 'http://example.com:8081/server-status?auto'}}) - is_expected.to contain_lma_collector__collectd__python('collectd_apache_check') \ - .with_config({'Url' => "\"http://example.com:8081/server-status?auto\""}) - } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_base_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_base_spec.rb deleted file mode 100644 index 5fda69719..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_base_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::base' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo', - :swapsize_mb => 1024} - end - - describe 'with defaults' do - it { is_expected.to contain_class('collectd') } - end - - describe 'with interfaces' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo', - :interfaces => 'br-mgmt,en0,bond0,lo', :swapsize_mb => 1024} - end - - it { is_expected.to contain_class('collectd').with_purge(false) } - it { is_expected.to contain_class('collectd::plugin::netlink').with_verboseinterfaces(['en0', 'bond0']) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_ceph_mon_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_ceph_mon_spec.rb deleted file mode 100644 index 5cf5b7aad..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_ceph_mon_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::ceph_mon' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with default params' do - it { is_expected.to contain_lma_collector__collectd__python('ceph_pg_mon_status') \ - .with_config({}) } - it { is_expected.to contain_lma_collector__collectd__python('ceph_pool_osd') \ - .with_config({}) } - it { is_expected.to contain_lma_collector__collectd__python('ceph_osd_stats') \ - .with_config({}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_ceph_osd_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_ceph_osd_spec.rb deleted file mode 100644 index 676f066ee..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_ceph_osd_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2015-2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::ceph_osd' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with default params' do - it { is_expected.to contain_lma_collector__collectd__python('ceph_osd_perf') \ - .with_config({'AdminSocket' => '"/var/run/ceph/ceph-*.asok"'}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_dbi_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_dbi_spec.rb deleted file mode 100644 index a96dccf53..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_dbi_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::dbi' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - it { is_expected.to contain_collectd__plugin('dbi') } - end - - describe 'with defaults for CentOS' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'CentOS', - :osfamily => 'RedHat'} - end - - it { is_expected.to contain_collectd__plugin('dbi') } - end -end - diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_haproxy_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_haproxy_spec.rb deleted file mode 100644 index fcc3271e3..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_haproxy_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::haproxy' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with socket param' do - let(:params) do - {:socket => '/path/to/socket'} - end - it { is_expected.to contain_lma_collector__collectd__python('haproxy') \ - .with_config({'Socket' => '"/path/to/socket"', 'Mapping' => {}, - 'ProxyIgnore' => []}) } - end - - describe 'with optional params' do - let(:params) do - {:socket => '/path/to/socket', :proxy_ignore => ['lma'], - :proxy_names => {'keystone-1' => 'keystone-public-api'}} - end - it { is_expected.to contain_lma_collector__collectd__python('haproxy') \ - .with_config({'Socket' => '"/path/to/socket"', - 'Mapping' => {'"keystone-1"' => '"keystone-public-api"'}, - 'ProxyIgnore' => ['"lma"']}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_http_check_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_http_check_spec.rb deleted file mode 100644 index 434dd830a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_http_check_spec.rb +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::http_check' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'urls with expected codes' do - let(:params) do - {:urls => { - 'vip_test' => 'http://foo.com:99', - 'vip_foo' => 'http://bar.com:9200', - 'vip_bar' => 'https://ok.com', - }, - :expected_codes => { - 'vip_test' => 401, - 'vip_foo' => 204, - }, - :timeout => 5, - :max_retries => 1, - } - end - it { is_expected.to contain_lma_collector__collectd__python('http_check') \ - .with_config({ - 'Url' => { - '"vip_test"' => '"http://foo.com:99"', - '"vip_foo"' => '"http://bar.com:9200"', - '"vip_bar"' => '"https://ok.com"', - }, - 'ExpectedCode' => { - '"vip_test"' => '"401"', - '"vip_foo"' => '"204"', - }, - 'Timeout' => '"5"', - 'MaxRetries' => '"1"', - }) - } - end - - describe 'urls without expected codes' do - let(:params) do - {:urls => { - 'vip_bar' => 'https://ok.com', - }, - } - end - it { is_expected.to contain_lma_collector__collectd__python('http_check') \ - .with_config({ - 'Url' => { - '"vip_bar"' => '"https://ok.com"', - }, - 'ExpectedCode' => {}, - 'Timeout' => '"1"', - 'MaxRetries' => '"3"', - }) - } - end - - describe 'urls with dependency' do - let(:params) do - {:urls => { - 'vip_bar' => 'https://ok.com', - }, - :pacemaker_master_resource => 'vip__foobar', - } - end - it { is_expected.to contain_lma_collector__collectd__python('http_check') \ - .with_config({ - 'Url' => { - '"vip_bar"' => '"https://ok.com"', - }, - 'ExpectedCode' => {}, - 'Timeout' => '"1"', - 'MaxRetries' => '"3"', - 'DependsOnResource' => '"vip__foobar"', - }) - } - end -end - diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_hypervisor_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_hypervisor_spec.rb deleted file mode 100644 index c1bf73aa4..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_hypervisor_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::hypervisor' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with required params' do - let(:params) do - {:user => 'user', :password => 'password', :tenant => 'tenant', - :keystone_url => 'http://example.com/keystone'} - end - it { is_expected.to contain_lma_collector__collectd__python('hypervisor_stats') \ - .with_config({"Username" => '"user"', "Password" => '"password"', - "Tenant" => '"tenant"', - "KeystoneUrl" => '"http://example.com/keystone"', - "Timeout" => '"5"', "CpuAllocationRatio" => '"16.0"'}) } - end - - describe 'with required and optional params' do - let(:title) { :nova } - let(:params) {{:user => "user", :password => "password", :tenant => "tenant", - :keystone_url => "http://example.com/keystone", - :timeout => 10, :cpu_allocation_ratio => 10.0, - :pacemaker_master_resource => "vip__management"}} - it { is_expected.to contain_lma_collector__collectd__python('hypervisor_stats') \ - .with_config({"Username" => '"user"', "Password" => '"password"', - "Tenant" => '"tenant"', - "KeystoneUrl" => '"http://example.com/keystone"', - "Timeout" => '"10"', - "CpuAllocationRatio" => '"10.0"', - "DependsOnResource" => '"vip__management"'}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_libvirt.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_libvirt.rb deleted file mode 100644 index 54d1e6935..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_libvirt.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::libvirt' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - it { is_expected.to contain_class('collectd::plugin::libvirt') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_libvirt_check_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_libvirt_check_spec.rb deleted file mode 100644 index d06ab5d4c..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_libvirt_check_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::libvirt_check' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with defaults' do - it { is_expected.to contain_lma_collector__collectd__python('collectd_libvirt_check') \ - .with_config({'Uri' => '"qemu:///system"'}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_memcached_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_memcached_spec.rb deleted file mode 100644 index 671e79921..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_memcached_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::memcached' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with host param' do - let(:params) {{:host => 'example.com' }} - it { - is_expected.to contain_class('collectd::plugin::memcached') \ - .with_host('example.com') - is_expected.to contain_lma_collector__collectd__python('collectd_memcached_check') \ - .with_config({ - "Host" => '"example.com"', - "Port" => '"11211"', - }) - } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_mysql_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_mysql_spec.rb deleted file mode 100644 index 87d58e4da..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_mysql_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::mysql' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with params' do - let(:params) do - {:username => 'user', :password => 'password'} - end - it { is_expected.to contain_collectd__plugin__mysql__database('config') \ - .with_host('localhost') \ - .with_username('user') \ - .with_password('password') } - it { is_expected.to contain_lma_collector__collectd__python('collectd_mysql_check') \ - .with_config({'Username' => '"user"', - 'Password' => '"password"', - 'Host' => '"localhost"',} - ) - } - end - - describe 'with socket param' do - let(:params) do - {:username => 'user', :password => 'password', :socket => '/var/run/mysqld.sock'} - end - it { is_expected.to contain_collectd__plugin__mysql__database('config') \ - .with_host('localhost') \ - .with_username('user') \ - .with_password('password') \ - .with_socket('/var/run/mysqld.sock') - } - it { is_expected.to contain_lma_collector__collectd__python('collectd_mysql_check') \ - .with_config({'Username' => '"user"', - 'Password' => '"password"', - 'Host' => '"localhost"', - 'Socket' => '"/var/run/mysqld.sock"'} - ) - } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_openstack_checks_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_openstack_checks_spec.rb deleted file mode 100644 index 8bb793dde..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_openstack_checks_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::openstack_checks' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with required params' do - let(:params) do - {:user => 'user', :password => 'password', :tenant => 'tenant', - :keystone_url => 'http://example.com/keystone'} - end - it { is_expected.to contain_lma_collector__collectd__python('check_openstack_api') \ - .with_config({"Username" => '"user"', "Password" => '"password"', - "Tenant" => '"tenant"', - "KeystoneUrl" => '"http://example.com/keystone"', - "Timeout" => '"5"'}) } - end - - describe 'with required and optional params' do - let(:title) { :nova } - let(:params) {{:user => "user", :password => "password", :tenant => "tenant", - :keystone_url => "http://example.com/keystone", - :timeout => 10, :pacemaker_master_resource => "vip__management"}} - it { is_expected.to contain_lma_collector__collectd__python('check_openstack_api') \ - .with_config({"Username" => '"user"', "Password" => '"password"', - "Tenant" => '"tenant"', - "KeystoneUrl" => '"http://example.com/keystone"', - "Timeout" => '"10"', "DependsOnResource" => '"vip__management"'}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_pacemaker_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_pacemaker_spec.rb deleted file mode 100644 index 29e89aaa0..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_pacemaker_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::pacemaker' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with "resources" param' do - let(:params) {{:resources => {'vip__public' => 'public', 'vip__management' => 'mgmt'}}} - it { is_expected.to contain_lma_collector__collectd__python('collectd_pacemaker') \ - .with_config({'Resource' => {'"vip__public"' => '"public"', '"vip__management"' => '"mgmt"'}}) } - end - - describe 'with "hostname" param' do - let(:params) {{:resources => {'vip__public' => 'public', 'vip__management' => 'mgmt'}, - :hostname => 'foo.example.com'}} - it { is_expected.to contain_lma_collector__collectd__python('collectd_pacemaker') \ - .with_config({'Resource' => {'"vip__public"' => '"public"', '"vip__management"' => '"mgmt"'}, - 'Hostname' => '"foo.example.com"'}) } - end - - describe 'with "notify_resource" param' do - let(:params) do - {:resources => {'vip__public' => 'public', 'vip__management' => 'mgmt'}, - :notify_resource => 'vip__management'} - end - it { is_expected.to contain_lma_collector__collectd__python('collectd_pacemaker') \ - .with_config({'Resource' => {'"vip__public"' => '"public"', '"vip__management"' => '"mgmt"'}, - "NotifyResource"=>"\"vip__management\""}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_python_base_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_python_base_spec.rb deleted file mode 100644 index 789c2e998..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_python_base_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::python_base' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with defaults' do - it { is_expected.to contain_class('collectd::plugin::python') \ - .with_modulepaths(['/usr/lib/collectd']) \ - .with_modules({}) } - it { is_expected.to contain_file('base.script') \ - .with( - 'ensure' => 'present', - 'path' => '/usr/lib/collectd/collectd_base.py', - 'owner' => 'root', - 'group' => 'root', - 'mode' => '0640', - ) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_python_openstack_base_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_python_openstack_base_spec.rb deleted file mode 100644 index 5cf8c25fc..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_python_openstack_base_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::python_openstack_base' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with defaults' do - it { is_expected.to contain_file('openstack.script').with({ - :ensure => 'present', - :path => '/usr/lib/collectd/collectd_openstack.py', - :owner => 'root', - :group => 'root', - :mode => '0640', - }) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_rabbitmq_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_rabbitmq_spec.rb deleted file mode 100644 index 36c66a1cf..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_collectd_rabbitmq_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::rabbitmq' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with minimal parameters' do - let(:params) do - {:username => 'foouser', :password => 'foopass' } - end - it { is_expected.to contain_lma_collector__collectd__python('rabbitmq_info') \ - .with_config({'Username' => '"foouser"', 'Password' => '"foopass"'}) - } - end - describe 'with host and port parameters' do - let(:params) do - {:username => 'foouser', :password => 'foopass', :host => 'foohost', - :port => 123, - } - end - it { is_expected.to contain_lma_collector__collectd__python('rabbitmq_info') \ - .with_config({'Username' => '"foouser"', 'Password' => '"foopass"', - 'Port' => '"123"', 'Host' => '"foohost"'}) - } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_elasticsearch_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_elasticsearch_spec.rb deleted file mode 100644 index dda8c6691..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_elasticsearch_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::elasticsearch' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with localhost server' do - let(:params) {{ :server => 'localhost', :port => 9200 }} - it { is_expected.to contain_heka__output__elasticsearch('elasticsearch') } - it { is_expected.to contain_heka__encoder__es_json('elasticsearch') } - end - - describe 'with localhost server and flush_* parameters' do - let(:params) {{ :server => 'localhost', :port => 9200, - :flush_interval => 10, :flush_count => 100, - }} - it { - is_expected.to contain_heka__output__elasticsearch('elasticsearch').with( - :flush_interval => 10, - :flush_count => 100, - :server => 'localhost', - :port => 9200, - ) - } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_gse_policies_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_gse_policies_spec.rb deleted file mode 100644 index 399b8af90..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_gse_policies_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::gse_policies' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with some policies' do - yaml_policies =<' - threshold: 0 - - status: critical - trigger: - logical_operator: or - rules: - - function: count - arguments: [ critical ] - relational_operator: '>' - threshold: 0 - - status: warning - trigger: - logical_operator: or - rules: - - function: count - arguments: [ warning ] - relational_operator: '>' - threshold: 0 - - status: okay - trigger: - logical_operator: or - rules: - - function: count - arguments: [ okay ] - relational_operator: '>' - threshold: 0 - - status: unknown -EOS - let(:params) do { - :policies => YAML.load(yaml_policies) - } - end - - it { is_expected.to contain_file('gse_policies') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_influxdb_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_influxdb_spec.rb deleted file mode 100644 index f3451c515..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_influxdb_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::influxdb' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with mandatory parameters' do - let(:params) {{ :server => 'localhost', :port => 8086, :user => 'lma', - :password => 'lma', :database => 'lma' }} - it { is_expected.to contain_heka__output__http('influxdb') } - it { is_expected.to contain_heka__encoder__payload('influxdb') } - it { is_expected.to contain_heka__filter__sandbox('influxdb_accumulator') } - it { is_expected.to contain_heka__filter__sandbox('influxdb_annotation') } - end - - describe 'with tag_fields parameter' do - let(:params) {{ :server => 'localhost', :port => 8086, :user => 'lma', - :password => 'lma', :database => 'lma', - :tag_fields => ['foo', 'zzz'] }} - it { is_expected.to contain_heka__output__http('influxdb') } - it { is_expected.to contain_heka__encoder__payload('influxdb') } - it { is_expected.to contain_heka__filter__sandbox('influxdb_accumulator').with_config({ - "tag_fields" => "foo zzz", "flush_interval"=> 5, - "flush_count"=> 400, "time_precision" => "ms"}) } - it { is_expected.to contain_heka__filter__sandbox('influxdb_annotation') } - end - - describe 'with flush and precision parameters' do - let(:params) {{ :server => 'localhost',:port => 8086, :user => 'lma', :password => 'lma', - :database => 'lma', :flush_count => 1, :flush_interval => 2, - :time_precision => 's' - }} - it { is_expected.to contain_heka__output__http('influxdb') } - it { is_expected.to contain_heka__encoder__payload('influxdb') } - it { is_expected.to contain_heka__filter__sandbox('influxdb_accumulator').with_config({ - "flush_interval"=> "2", "flush_count"=> "1", "time_precision" => "s", - "tag_fields" => "" - }) } - it { is_expected.to contain_heka__filter__sandbox('influxdb_annotation') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_counter_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_counter_spec.rb deleted file mode 100644 index 01845decd..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_counter_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. - -require 'spec_helper' - -describe 'lma_collector::logs::counter' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with localhost' do - let(:params) {{ :hostname => 'localhost' }} - it { is_expected.to contain_heka__filter__sandbox('logs_counter') } - end -end - diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_openstack_decoder_splitter_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_openstack_decoder_splitter_spec.rb deleted file mode 100644 index 1021425dc..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_openstack_decoder_splitter_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -require 'spec_helper' - -describe 'lma_collector::logs::openstack_decoder_splitter' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'without file_match' do - it { is_expected.to contain_heka__decoder__sandbox('openstack') } - it { is_expected.to contain_heka__splitter__token('openstack') \ - .with_delimiter('\n') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_swift_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_swift_spec.rb deleted file mode 100644 index a4ccd6dd1..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_swift_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::logs::swift' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'without file_match' do - it { is_expected.to raise_error(Puppet::Error, /must pass file_match/i) } - end - - describe 'with file_match => swift\.log$' do - let(:params) do - {:file_match => 'swift\.log$'} - end - it {is_expected.to contain_heka__input__logstreamer('swift') \ - .with_file_match('swift\.log$') } - end - - describe 'with file_match => swift\.log\.?(?P\d*)$ and priority => ["^Seq"]' do - let(:params) do - {:file_match => 'swift\.log\.?(?P\d*)$', - :priority => '["^Seq"]'} - end - it {is_expected.to contain_heka__input__logstreamer('swift') \ - .with_file_match('swift\.log\.?(?P\d*)$') \ - .with_priority('["^Seq"]') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_system_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_system_spec.rb deleted file mode 100644 index e83144a21..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_logs_system_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::logs::system' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - it { is_expected.to contain_heka__decoder__sandbox('system') } - it { is_expected.to contain_heka__input__logstreamer('system') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_notifications_input_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_notifications_input_spec.rb deleted file mode 100644 index 822cc9639..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_notifications_input_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::notifications::input' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with localhost server' do - let(:params) do - { :host => 'localhost', :topic => 'foo', :user => 'bob', - :password => 'secret' } - end - it { is_expected.to contain_heka__decoder__sandbox('notification') } - it { is_expected.to contain_heka__input__amqp('openstack_info') } - it { is_expected.to contain_heka__input__amqp('openstack_warn') } - it { is_expected.to contain_heka__input__amqp('openstack_error') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_service_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_service_spec.rb deleted file mode 100644 index 8c015704f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_service_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::service::log' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'default params' do - it { is_expected.to contain_service('log_collector') \ - .with({'ensure' => 'running', 'enable' => true}) } - end -end - -describe 'lma_collector::service::metric' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'default params' do - it { is_expected.to contain_service('metric_collector') \ - .with({'ensure' => 'running', 'enable' => true}) } - end -end - diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_spec.rb deleted file mode 100644 index c3f951d49..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/classes/lma_collector_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - it { is_expected.to contain_file('/usr/share/lma_collector_modules/extra_fields.lua') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_afd_nagios_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_afd_nagios_spec.rb deleted file mode 100644 index 574a6b163..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_afd_nagios_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::afd_nagios' do - let(:title) { :global} - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - let(:params) do - {:server => 'nagios.org', - :http_port => 9999, - :http_path => 'status', - :user => 'foo', - :password => 'secret', - :message_type => 'foo_type' - } - end - - it { should contain_heka__encoder__sandbox('nagios_afd_global') } - it { should contain_heka__output__http('nagios_afd_global') } -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_dbi_mysql_status_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_dbi_mysql_status_spec.rb deleted file mode 100644 index ca8d60dd9..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_dbi_mysql_status_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::dbi_mysql_status' do - let(:title) { :nova } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - it { is_expected.to contain_file('/etc/collectd/conf.d/dbi_mysql_status.conf') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_dbi_services_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_dbi_services_spec.rb deleted file mode 100644 index 510054517..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_dbi_services_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::dbi_services' do - let(:title) { :nova } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with title = nova' do - let(:params) {{:report_interval => 30, :downtime_factor => 2}} - it { is_expected.to contain_file('/etc/collectd/conf.d/dbi_nova_services.conf') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_openstack_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_openstack_spec.rb deleted file mode 100644 index ac4b693cd..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_openstack_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::openstack' do - let(:title) { :nova } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with required params' do - let(:title) { :nova } - let(:params) {{:user => "user", :password => "password", :tenant => "tenant", - :keystone_url => "http://example.com/keystone"}} - it { is_expected.to contain_lma_collector__collectd__python('openstack_nova') \ - .with_config({"Username" => '"user"', "Password" => '"password"', - "Tenant" => '"tenant"', - "KeystoneUrl" => '"http://example.com/keystone"', - "Timeout" => '"20"', - "MaxRetries" => '"2"'}) } - end - - describe 'with required and optional params' do - let(:title) { :nova } - let(:params) {{:user => "user", :password => "password", :tenant => "tenant", - :keystone_url => "http://example.com/keystone", - :timeout => 10, :max_retries => 1, - :pacemaker_master_resource => "vip__management"}} - it { is_expected.to contain_lma_collector__collectd__python('openstack_nova') \ - .with_config({"Username" => '"user"', "Password" => '"password"', - "Tenant" => '"tenant"', - "KeystoneUrl" => '"http://example.com/keystone"', - "Timeout" => '"10"', "MaxRetries" => '"1"', - "DependsOnResource" => '"vip__management"'}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_python_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_python_spec.rb deleted file mode 100644 index b4aa6999d..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_collectd_python_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::collectd::python' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian', :concat_basedir => '/foo'} - end - - describe 'with title = haproxy' do - let(:title) { :haproxy } - let(:params) {{:config => {"Foo" => "Bar"}}} - it { is_expected.to contain_collectd__plugin__python__module('module_haproxy') \ - .with_module('haproxy') \ - .with_modulepath('/usr/lib/collectd') \ - .with_config({"Foo" => "Bar"}) } - end - - describe 'with complex config' do - let(:title) { :haproxy } - let(:params) do - {:config => {"key1" => ["elt0", "elt1"], - "key2" => {"k1" => "v1", "k2" => "v2"}}} - end - it { is_expected.to contain_collectd__plugin__python__module('module_haproxy') \ - .with_module('haproxy') \ - .with_modulepath('/usr/lib/collectd') \ - .with_config({"key1 elt0" => "", "key1 elt1" => "", - "key2 k1" => "v1", "key2 k2" => "v2"}) } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_gse_cluster_filter_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_gse_cluster_filter_spec.rb deleted file mode 100644 index 6ecbba318..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_gse_cluster_filter_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::gse_cluster_filter' do - let(:title) { :service } - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'with defaults' do - let(:params) do - {:input_message_types => ['afd_service_metric'], - :aggregator_flag => true, - :cluster_field => 'service', - :member_field => 'source', - :output_message_type => 'gse_service_cluster_metric', - :output_metric_name => 'cluster_service_status'} - end - it { is_expected.to contain_heka__filter__sandbox('gse_service').with_message_matcher("(Fields[name] == 'pacemaker_local_resource_active' && Fields[resource] == 'vip__management') || (Fields[aggregator] != NIL && (Type =~ /afd_service_metric$/))") } - it { is_expected.to contain_file('gse_service_topology') } - end - - describe 'with dependencies' do - let(:params) do - {:input_message_types => ['gse_service_cluster_metric', 'gse_node_cluster_metric'], - :aggregator_flag => false, - :member_field => 'cluster_name', - :output_message_type => 'gse_cluster_metric', - :output_metric_name => 'cluster_status', - :warm_up_period => 30, - :clusters => { - 'nova' => { - 'members' => ['nova-api', 'nova-scheduler', 'controller_nodes'], - 'group_by' => 'member', - 'hints' => ['keystone'], - 'policy' => 'some_policy' - }, - 'keystone' => { - 'members' => ['keystone-public-api', 'keystone-admin-api', 'controller_nodes'], - 'group_by' => 'member', - 'policy' => 'some_policy' - } - } - } - end - it { is_expected.to contain_heka__filter__sandbox('gse_service').with_message_matcher("(Fields[name] == 'pacemaker_local_resource_active' && Fields[resource] == 'vip__management') || (Fields[aggregator] == NIL && (Type =~ /gse_service_cluster_metric$/ || Type =~ /gse_node_cluster_metric$/))") } - it { is_expected.to contain_file('gse_service_topology') } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_gse_nagios_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_gse_nagios_spec.rb deleted file mode 100644 index 2e49d1ac7..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_gse_nagios_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::gse_nagios' do - let(:title) { :global} - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - let(:params) do - {:server => 'nagios.org', - :http_port => 9999, - :http_path => 'status', - :user => 'foo', - :password => 'secret', - :message_type => 'foo_type', - :virtual_hostname => 'foo_vhost'} - end - - it { should contain_heka__encoder__sandbox('nagios_gse_global') } - it { should contain_heka__output__http('nagios_gse_global') } -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_heka_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_heka_spec.rb deleted file mode 100644 index 2bd5df56a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_heka_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2016 Mirantis, Inc. -# -# 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. -require 'spec_helper' - -describe 'lma_collector::heka' do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe 'log_collector with default' do - let(:title) { :log_collector} - it { - should contain_heka('log_collector').with( - 'user' => 'heka', - 'poolsize' => 100, - ) - should contain_heka__output__tcp('metric') - should contain_heka__filter__sandbox('heka_monitoring_log_collector') - should contain_heka__output__dashboard('dashboard_log_collector' ) - } - end - describe 'metric_collector with default' do - let(:title) { :metric_collector} - it { - should contain_heka('metric_collector').with( - 'user' => 'heka', - 'poolsize' => 100, - ) - should contain_heka__input__tcp('metric') - should contain_heka__decoder__sandbox('metric' ) - should contain_heka__filter__sandbox('heka_monitoring_metric_collector') - should contain_heka__output__dashboard('dashboard_metric_collector' ) - } - end - describe 'with an invalid title' do - let(:title) { :invalidname} - it do - expect { - is_expected.to compile - }.to raise_error(/title must be either/) - end - end - describe 'metric_collector with no self-monitoring and poolsize' do - let(:title) { :metric_collector} - let(:params) do - { :heka_monitoring => false, - :poolsize => 42, - :user => 'foo', - } - end - it { - should contain_heka('metric_collector').with( - 'user' => 'foo', - 'poolsize' => 42, - ) - should contain_heka__input__tcp('metric') - should contain_heka__decoder__sandbox('metric' ) - should contain_heka__filter__sandbox('heka_monitoring_metric_collector').with( - 'ensure' => 'absent' - ) - should contain_heka__output__dashboard('dashboard_metric_collector' ).with( - 'ensure' => 'absent' - ) - } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_logs_openstack_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_logs_openstack_spec.rb deleted file mode 100644 index d763e5d6a..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/defines/lma_collector_logs_openstack_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# - -require 'spec_helper' - -describe "lma_collector::logs::openstack" do - let(:facts) do - {:kernel => 'Linux', :operatingsystem => 'Ubuntu', - :osfamily => 'Debian'} - end - - describe "with title" do - let(:title) { :nova } - it { is_expected.to contain_heka__input__logstreamer('nova') \ - .with_differentiator("['nova', '_', 'Service']") \ - .with_file_match('(?P.+)\.log\.?(?P\d*)$') - } - end - describe "with title and service_match" do - let(:title) { :nova } - let(:params) do - { :service_match => '(dhcp-agent|l3-agent|metadata-agent|neutron-netns-cleanup|openvswitch-agent|server)' } - end - - it { is_expected.to contain_heka__input__logstreamer('nova') \ - .with_file_match('(?P(dhcp-agent|l3-agent|metadata-agent|neutron-netns-cleanup|openvswitch-agent|server))\.log\.?(?P\d*)$') - } - end -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/functions/sanitize_name_for_lua_spec.rb b/deployment_scripts/puppet/modules/lma_collector/spec/functions/sanitize_name_for_lua_spec.rb deleted file mode 100644 index 5781c7ac6..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/functions/sanitize_name_for_lua_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'spec_helper' - -describe 'sanitize_name_for_lua' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('un', 'deux').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('').and_return('')} - it { is_expected.to run.with_params('one-two-three').and_return('one_two_three')} -end diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/spec.opts b/deployment_scripts/puppet/modules/lma_collector/spec/spec.opts deleted file mode 100644 index 91cd6427e..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/spec.opts +++ /dev/null @@ -1,6 +0,0 @@ ---format -s ---colour ---loadby -mtime ---backtrace diff --git a/deployment_scripts/puppet/modules/lma_collector/spec/spec_helper.rb b/deployment_scripts/puppet/modules/lma_collector/spec/spec_helper.rb deleted file mode 100644 index d8df693e5..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/spec/spec_helper.rb +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -require 'rspec-puppet' - -fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) - -RSpec.configure do |c| - c.module_path = File.join(fixture_path, 'modules') - c.manifest_dir = File.join(fixture_path, 'manifests') - c.environmentpath = File.join(Dir.pwd, 'spec') -end diff --git a/deployment_scripts/puppet/modules/lma_collector/templates/collectd_dbi_mysql_status.conf.erb b/deployment_scripts/puppet/modules/lma_collector/templates/collectd_dbi_mysql_status.conf.erb deleted file mode 100644 index 5911e8e2f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/templates/collectd_dbi_mysql_status.conf.erb +++ /dev/null @@ -1,40 +0,0 @@ - - - Statement "select replace(lower(VARIABLE_NAME), 'wsrep_', 'cluster.') as metric, replace(replace(VARIABLE_VALUE, 'ON', 1), 'OFF', 0) as value from information_schema.GLOBAL_STATUS where VARIABLE_NAME IN ('wsrep_ready', 'wsrep_connected');" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - - Statement "select replace(replace(lower(VARIABLE_NAME), 'wsrep_', ''), '_', '.') as metric, replace(replace(replace(VARIABLE_VALUE, 'Primary', 1), 'Non-Primary', 2), 'Disconnected', 3) as value from information_schema.GLOBAL_STATUS where VARIABLE_NAME = 'wsrep_cluster_status';" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - - Statement "select replace(replace(lower(VARIABLE_NAME), 'wsrep_', 'cluster.'), 'cluster_size', 'size') as metric, VARIABLE_VALUE as value from information_schema.GLOBAL_STATUS where VARIABLE_NAME IN ('wsrep_cluster_size', 'wsrep_replicated', 'wsrep_replicated_bytes', 'wsrep_received_bytes', 'wsrep_received', 'wsrep_local_commits', 'wsrep_local_cert_failures', 'wsrep_local_send_queue', 'Slow_queries');" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - "> - Driver "mysql" - DriverOption "host" "<%= @hostname %>" - DriverOption "username" "<%= @username %>" - DriverOption "password" "<%= @password %>" - DriverOption "dbname" "<%= @dbname %>" - SelectDB "<%= @dbname %>" - Query "wsrep_ready" - Query "wsrep_cluster_status" - Query "wsrep_cluster" - - diff --git a/deployment_scripts/puppet/modules/lma_collector/templates/collectd_dbi_services.conf.erb b/deployment_scripts/puppet/modules/lma_collector/templates/collectd_dbi_services.conf.erb deleted file mode 100644 index 0bf2f2af5..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/templates/collectd_dbi_services.conf.erb +++ /dev/null @@ -1,90 +0,0 @@ - -<% if @type == 'services' %> - _<%= @type %>"> - Statement "select concat_ws('.', 'services', replace(replace(s.binary, 'nova-', ''), 'cinder-', ''), 'down', s.host) as metric, 1 as value from (select * from services where deleted=0) s where s.disabled=0 and timestampdiff(SECOND,s.updated_at,utc_timestamp())><%= @downtime %> group by s.binary, s.host UNION select concat_ws('.', 'services', replace(replace(s.binary, 'nova-', ''), 'cinder-', ''), 'up', s.host) as metric, 0 as value from (select * from services where deleted=0) s where s.disabled=0 and timestampdiff(SECOND,s.updated_at,utc_timestamp())<=<%= @downtime %> group by s.binary, s.host UNION select concat_ws('.', 'services', replace(replace(s.binary, 'nova-', ''), 'cinder-', ''), 'disabled', s.host) as metric, 2 as value from (select * from services where deleted=0) s where s.disabled=1 group by s.binary, s.host;" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - _<%= @type %>_down"> - Statement "select concat_ws('.', 'services', replace(replace(s1.binary, 'nova-', ''), 'cinder-', ''), 'down') as metric, count(s2.id) as value from (select * from services where deleted=0) s1 left outer join services s2 on s1.id = s2.id and s1.disabled=0 and timestampdiff(SECOND,s1.updated_at,utc_timestamp())><%= @downtime %> group by s1.binary;" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - _<%= @type %>_up"> - Statement "select concat_ws('.', 'services', replace(replace(s1.binary, 'nova-', ''), 'cinder-', ''), 'up') as metric, count(s2.id) as value from (select * from services where deleted=0) s1 left outer join services s2 on s1.id = s2.id and s1.disabled=0 and timestampdiff(SECOND,s1.updated_at,utc_timestamp())<=<%= @downtime %> group by s1.binary;" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - _<%= @type %>_disabled"> - Statement "select concat_ws('.', 'services', replace(replace(s1.binary, 'nova-', ''), 'cinder-', ''), 'disabled') as metric, count(s2.id) as value from (select * from services where deleted=0) s1 left outer join services s2 on s1.id = s2.id and s2.disabled = 1 group by s1.binary;" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - -<% end %> -<% if @type == 'agents' %> - _<%= @type %>"> - Statement "select concat_ws('.', 'agents', replace(replace(a.binary, '-agent', ''), 'neutron-', ''), 'down', a.host) as metric, 1 as value from agents a where a.admin_state_up=1 and timestampdiff(SECOND,a.heartbeat_timestamp,utc_timestamp())><%= @downtime %> group by a.binary, a.host UNION select concat_ws('.', 'agents', replace(replace(a.binary, '-agent', ''), 'neutron-', ''), 'up', a.host) as metric, 0 as value from agents a where a.admin_state_up=1 and timestampdiff(SECOND,a.heartbeat_timestamp,utc_timestamp())<=<%= @downtime %> group by a.binary, a.host UNION select concat_ws('.', 'agents', replace(replace(a.binary, '-agent', ''), 'neutron-', ''), 'disabled', a.host) as metric, 2 as value from agents a where a.admin_state_up=0 group by a.binary, a.host;" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - _<%= @type %>_down"> - Statement "select concat_ws('.', 'agents', replace(replace(a1.binary, '-agent', ''), 'neutron-', ''), 'down') as metric, count(a2.id) as value from agents a1 left outer join agents a2 on a1.id = a2.id and a1.admin_state_up=1 and timestampdiff(SECOND,a1.heartbeat_timestamp,utc_timestamp())><%= @downtime %> group by a1.binary;" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - _<%= @type %>_up"> - Statement "select concat_ws('.', 'agents', replace(replace(a1.binary, '-agent', ''), 'neutron-', ''), 'up') as metric, count(a2.id) as value from agents a1 left outer join agents a2 on a1.id = a2.id and a1.admin_state_up=1 and timestampdiff(SECOND,a1.heartbeat_timestamp,utc_timestamp())<=<%= @downtime %> group by a1.binary;" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - - _<%= @type %>_disabled"> - Statement "select concat_ws('.', 'agents', replace(replace(a1.binary, '-agent', ''), 'neutron-', ''), 'disabled') as metric, count(a2.id) as value from agents a1 left outer join agents a2 on a1.id = a2.id and a1.admin_state_up=0 group by a1.binary;" - MinVersion 50000 - - Type "gauge" - InstancesFrom "metric" - ValuesFrom "value" - - -<% end %> - _<%= @service%>"> - Driver "mysql" - DriverOption "host" "<%= @hostname %>" - DriverOption "username" "<%= @username %>" - DriverOption "password" "<%= @password %>" - DriverOption "dbname" "<%= @dbname %>" - SelectDB "<%= @dbname %>" - Query "<%= @dbname %>_<%= @type %>_disabled" - Query "<%= @dbname %>_<%= @type %>_up" - Query "<%= @dbname %>_<%= @type %>_down" - Query "<%= @dbname %>_<%= @type %>" - - diff --git a/deployment_scripts/puppet/modules/lma_collector/templates/collectd_python.conf.erb b/deployment_scripts/puppet/modules/lma_collector/templates/collectd_python.conf.erb deleted file mode 100644 index 263597907..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/templates/collectd_python.conf.erb +++ /dev/null @@ -1,30 +0,0 @@ - - Globals true - - - - ModulePath "<%= @python_module_path %>" - -<% @modules.sort.each do |module_name,config| -%> - Import "<%= module_name %>" -<% end -%> - -<% @modules.sort.each do |module_name,config| -%> - "> -<% config.sort.each do |key,value| -%> - <%- if value.is_a?(Hash) -%> - <%- value.sort.each do |original,new| -%> - <%= key -%> "<%= original -%>" "<%= new -%>" - <%- end -%> - <%- elsif value.is_a?(Array) -%> - <% value.sort.each do |x| -%> - <%= key -%> "<%= x -%>" - <% end -%> - <%- else -%> - <%= key -%> "<%= value -%>" - <%- end -%> -<% end -%> - -<% end -%> - - diff --git a/deployment_scripts/puppet/modules/lma_collector/templates/extra_fields.lua.erb b/deployment_scripts/puppet/modules/lma_collector/templates/extra_fields.lua.erb deleted file mode 100644 index 131cc69c2..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/templates/extra_fields.lua.erb +++ /dev/null @@ -1,24 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - --- list of fields that are added to Heka messages by the collector -tags = { -<% @tags.keys().sort().each do |k| -%> - ['<%= k.to_s().gsub("'"){"\\'"} %>'] = '<%= @tags[k].to_s().gsub("'"){"\\'"} %>', -<% end -%> -} - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/templates/gse_policies.lua.erb b/deployment_scripts/puppet/modules/lma_collector/templates/gse_policies.lua.erb deleted file mode 100644 index 68dc946f9..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/templates/gse_policies.lua.erb +++ /dev/null @@ -1,51 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local gse_policy = require 'gse_policy' - -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - -local policies = { -<% @policies.keys().sort().each do |policy_name| -%> - ['<%= policy_name.to_s().gsub("'"){"\\'"} %>']={ -<% @policies[policy_name].each do |policy_rule| -%> - gse_policy.new({ - status='<%= policy_rule['status'] %>', -<% if policy_rule.has_key?('trigger') -%> - trigger={ - logical_operator='<%= policy_rule['trigger']['logical_operator'] %>', - rules={ -<% policy_rule['trigger']['rules'].each do |rule| -%> - { - ['function']='<%= rule['function'] %>', - ['arguments']={<%= rule['arguments'].sort.collect{|x| "'#{x}'"}.join(',') %>}, - ['relational_operator']='<%= rule['relational_operator'] %>', - ['threshold']=<%= rule['threshold'] %>, - }, -<% end -%> - } - }, -<% end -%> - }), -<% end -%> - }, -<% end -%> -} - -function find(policy) - return policies[policy] -end - -return M - diff --git a/deployment_scripts/puppet/modules/lma_collector/templates/gse_topology.lua.erb b/deployment_scripts/puppet/modules/lma_collector/templates/gse_topology.lua.erb deleted file mode 100644 index 9ba3c13df..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/templates/gse_topology.lua.erb +++ /dev/null @@ -1,28 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - -clusters = { -<% @clusters.keys().sort().each do |cluster_id| -%> - ['<%= cluster_id.to_s().gsub("'"){"\\'"} %>']={ - ['members']={<%= @clusters[cluster_id]['members'].sort().collect{ |x| "'" + x.to_s().gsub("'"){"\\'"} + "'"}.join(',') %>}, - ['hints']={<%= (@clusters[cluster_id]['hints'] || []).sort().collect{ |x| "'" + x.to_s().gsub("'"){"\\'"} + "'"}.join(',') %>}, - ['group_by']='<%= @clusters[cluster_id]['group_by'] %>', - ['policy']='<%= @clusters[cluster_id]['policy'].gsub("'"){"\\'"} %>' - }, -<% end -%> -} - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/templates/hooks_daemon.erb b/deployment_scripts/puppet/modules/lma_collector/templates/hooks_daemon.erb deleted file mode 100644 index 31683233b..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/templates/hooks_daemon.erb +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -chmod 0644 <%= @libvirt_dir %>/<%= @libvirt_log %> diff --git a/deployment_scripts/puppet/modules/lma_collector/templates/lma_alarms.lua.erb b/deployment_scripts/puppet/modules/lma_collector/templates/lma_alarms.lua.erb deleted file mode 100644 index 6ee5b3fd3..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/templates/lma_alarms.lua.erb +++ /dev/null @@ -1,48 +0,0 @@ -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - -local alarms = { -<% @alarms.each do |alarm_name| -%> -<% @alarms_definitions.each do |alarm| -%> -<% if alarm["enabled"].to_s != 'false' -%> -<% if alarm_name == alarm["name"] -%> - { - ['name'] = '<%= alarm_name %>', - ['description'] = '<%= alarm["description"].to_s().gsub("'"){"\\'"} %>', - ['severity'] = '<%= alarm["severity"] %>', -<%- if alarm.key?("no_data_policy") -%> - ['no_data_policy'] = '<%= alarm["no_data_policy"] %>', -<%- end -%> - ['trigger'] = { - ['logical_operator'] = '<%= alarm["trigger"]["logical_operator"] || 'or' %>', - ['rules'] = { -<% alarm["trigger"]["rules"].each do |rule| -%> - { - ['metric'] = '<%= rule["metric"] %>', - ['fields'] = { -<% (rule["fields"] || []).each do |k, v| -%> - ['<%= k %>'] = '<%= v %>', -<% end -%> - }, - ['relational_operator'] = '<%= rule["relational_operator"] %>', - ['threshold'] = '<%= rule["threshold"] %>', - ['window'] = '<%= rule["window"] %>', - ['periods'] = '<%= rule["periods"] || 0 %>', - ['function'] = '<%= rule["function"] %>', - ['group_by'] = { -<% (rule["group_by"] || []).each do |g| -%> - <%= g %>, -<% end -%> - }, - }, -<% end -%> - }, - }, - }, -<% end -%> -<% end -%> -<% end -%> -<% end -%> -} - -return alarms diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/init.pp b/deployment_scripts/puppet/modules/lma_collector/tests/init.pp deleted file mode 100644 index c8cd65c0f..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/init.pp +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2015 Mirantis, Inc. -# -# 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. -# -# The baseline for module testing used by Puppet Labs is that each manifest -# should have a corresponding test manifest that declares that class or defined -# type. -# -# Tests are then run by using puppet apply --noop (to check for compilation -# errors and view a log of events) or by fully applying the test in a virtual -# environment (to compare the resulting system state to the desired state). -# -# Learn more about module testing here: -# http://docs.puppetlabs.com/guides/tests_smoke.html -# -include lma_collector diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/mocks/extra_fields.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/mocks/extra_fields.lua deleted file mode 100644 index 1bba81476..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/mocks/extra_fields.lua +++ /dev/null @@ -1,23 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. -local M = {} -setfenv(1, M) -- Remove external access to contain everything in the module - -environment_id = 42 - -tags = { - environment_id=environment_id -} - -return M diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_accumulator.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_accumulator.lua deleted file mode 100644 index 2890dc393..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_accumulator.lua +++ /dev/null @@ -1,68 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -require('os') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - -local accumulator = require('accumulator') - -TestAccumulator = {} - - function TestAccumulator:test_flush_on_append() - local sentinel = false - local function test_cb(items) - assertEquals(#items, 3) - sentinel = true - end - local accum = accumulator.new(2, 5, test_cb) - accum:append(1) - assertEquals(sentinel, false) - accum:append(2) - assertEquals(sentinel, false) - accum:append(3) - assertEquals(sentinel, true) - end - - function TestAccumulator:test_flush_interval_with_buffer() - local now = os.time() - local sentinel = false - local function test_cb(items) - assertEquals(#items, 1) - sentinel = true - end - local accum = accumulator.new(20, 1, test_cb) - accum:append(1) - assertEquals(sentinel, false) - accum:flush((now + 2) * 1e9) - assertEquals(sentinel, true) - end - - function TestAccumulator:test_flush_interval_with_empty_buffer() - local now = os.time() - local sentinel = false - local function test_cb(items) - assertEquals(#items, 0) - sentinel = true - end - local accum = accumulator.new(20, 1, test_cb) - accum:flush((now + 2) * 1e9) - assertEquals(sentinel, true) - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) - diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_afd.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_afd.lua deleted file mode 100644 index aa696268c..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_afd.lua +++ /dev/null @@ -1,155 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - --- mock the inject_message() function from the Heka sandbox library -local last_injected_msg -function inject_message(msg) - last_injected_msg = msg -end - -local afd = require('afd') -local consts = require('gse_constants') -local extra = require('extra_fields') - -TestAfd = {} - - function TestAfd:setUp() - afd.reset_alarms() - end - - function TestAfd:test_add_to_alarms() - afd.add_to_alarms(consts.CRIT, 'last', 'metric_1', {}, {}, '==', 0, 0, nil, nil, "crit message") - local alarms = afd.get_alarms() - assertEquals(alarms[1].severity, 'CRITICAL') - assertEquals(alarms[1].metric, 'metric_1') - assertEquals(alarms[1].message, 'crit message') - - afd.add_to_alarms(consts.WARN, 'last', 'metric_2', {}, {}, '>=', 10, 2, 5, 600, "warn message") - alarms = afd.get_alarms() - assertEquals(alarms[2].severity, 'WARN') - assertEquals(alarms[2].metric, 'metric_2') - assertEquals(alarms[2].message, 'warn message') - end - - function TestAfd:test_inject_afd_service_metric_without_alarms() - afd.inject_afd_service_metric('nova-scheduler', consts.OKAY, 'node-1', 10, 'some_source') - - local alarms = afd.get_alarms() - assertEquals(#alarms, 0) - assertEquals(last_injected_msg.Type, 'afd_service_metric') - assertEquals(last_injected_msg.Fields.value, consts.OKAY) - assertEquals(last_injected_msg.Fields.hostname, 'node-1') - assertEquals(last_injected_msg.Payload, '{"alarms":[]}') - end - - function TestAfd:test_inject_afd_service_metric_with_alarms() - afd.add_to_alarms(consts.CRIT, 'last', 'metric_1', {}, {}, '==', 0, 0, nil, nil, "important message") - afd.inject_afd_service_metric('nova-scheduler', consts.CRIT, 'node-1', 10, 'some_source') - - local alarms = afd.get_alarms() - assertEquals(#alarms, 0) - assertEquals(last_injected_msg.Type, 'afd_service_metric') - assertEquals(last_injected_msg.Fields.value, consts.CRIT) - assertEquals(last_injected_msg.Fields.hostname, 'node-1') - assertEquals(last_injected_msg.Fields.environment_id, extra.environment_id) - assert(last_injected_msg.Payload:match('"message":"important message"')) - assert(last_injected_msg.Payload:match('"severity":"CRITICAL"')) - end - - function TestAfd:test_alarms_for_human_without_fields() - local alarms = afd.alarms_for_human({{ - severity='WARNING', - ['function']='avg', - metric='load_longterm', - fields={}, - tags={}, - operator='>', - value=7, - threshold=5, - window=600, - periods=0, - message='load too high', - }}) - - assertEquals(#alarms, 1) - assertEquals(alarms[1], 'load too high (WARNING, rule=\'avg(load_longterm)>5\', current=7.00)') - end - - function TestAfd:test_alarms_for_human_with_fields() - local alarms = afd.alarms_for_human({{ - severity='CRITICAL', - ['function']='avg', - metric='fs_space_percent_free', - fields={fs='/'}, - tags={}, - operator='<=', - value=2, - threshold=5, - window=600, - periods=0, - message='free disk space too low' - }}) - - assertEquals(#alarms, 1) - assertEquals(alarms[1], 'free disk space too low (CRITICAL, rule=\'avg(fs_space_percent_free[fs="/"])<=5\', current=2.00)') - end - - function TestAfd:test_alarms_for_human_with_hostname() - local alarms = afd.alarms_for_human({{ - severity='WARNING', - ['function']='avg', - metric='load_longterm', - fields={}, - tags={}, - operator='>', - value=7, - threshold=5, - window=600, - periods=0, - message='load too high', - hostname='node-1' - }}) - - assertEquals(#alarms, 1) - assertEquals(alarms[1], 'load too high (WARNING, rule=\'avg(load_longterm)>5\', current=7.00, host=node-1)') - end - - function TestAfd:test_alarms_for_human_with_hints() - local alarms = afd.alarms_for_human({{ - severity='WARNING', - ['function']='avg', - metric='load_longterm', - fields={}, - tags={dependency_level='hint',dependency_name='controller'}, - operator='>', - value=7, - threshold=5, - window=600, - periods=0, - message='load too high', - hostname='node-1' - }}) - - assertEquals(#alarms, 2) - assertEquals(alarms[1], 'Other related alarms:') - assertEquals(alarms[2], 'load too high (WARNING, rule=\'avg(load_longterm)>5\', current=7.00, host=node-1)') - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_afd_alarm.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_afd_alarm.lua deleted file mode 100644 index 55588f615..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_afd_alarm.lua +++ /dev/null @@ -1,1080 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" -local lma_alarm = require('afd_alarms') -local consts = require('gse_constants') - -local alarms = { - { -- 1 - name = 'FS_all_no_field', - description = 'FS all no field', - enabled = true, - trigger = { - rules = { - { - metric = 'fs_space_percent_free', - window = 120, - ['function'] = 'avg', - relational_operator = '<=', - threshold = 11, - }, - }, - logical_operator = 'and', - }, - severity = 'warning', - }, - { -- 2 - name = 'RabbitMQ_Critical', - description = 'Number of messages in queue is critical', - enabled = true, - trigger = { - rules = { - { - relational_operator = '>=', - metric = 'rabbitmq_messages', - fields = {}, - window = "300", - periods = "0", - ['function'] = 'min', - threshold = "50", - }, - }, - logical_operator = 'or', - }, - severity = 'critical', - }, - { -- 3 - name = 'CPU_Critical_Controller', - description = 'CPU is critical for the controller', - enabled = true, - trigger = { - rules = { - { - metric = 'cpu_idle', - window = 120, - periods = 2, - ['function'] = 'avg', - relational_operator = '<=', - threshold = 5, - }, - { - metric = 'cpu_wait', - window = 120, - periods = 1, - ['function'] = 'avg', - relational_operator = '>=', - threshold = 20, - }, - }, - logical_operator = 'or', - }, - severity = 'critical', - }, - { -- 4 - name = 'CPU_Warning_Controller', - description = 'CPU is warning for controller', - enabled = true, - trigger = { - rules = { - { - metric = 'cpu_idle', - window = 100, - periods = 2, - ['function'] = 'avg', - relational_operator = '<=', - threshold = 15, - }, - { - metric = 'cpu_wait', - window = 60, - periods = 0, - ['function'] = 'avg', - relational_operator = '>=', - threshold = 25, - }, - }, - logical_operator = 'or', - }, - severity = 'warning', - }, - { -- 5 - name = 'CPU_Critical_Controller_AND', - description = 'CPU is critical for controller', - enabled = true, - trigger = { - rules = { - { - metric = 'cpu_idle', - window = 120, - periods = 2, - ['function'] = 'avg', - relational_operator = '<=', - threshold = 3, - }, - { - metric = 'cpu_wait', - window = 60, - periods = 1, - ['function'] = 'avg', - relational_operator = '>=', - threshold = 30, - }, - }, - logical_operator = 'and', - }, - severity = 'critical', - }, - { -- 6 - name = 'FS_root', - description = 'FS root', - enabled = true, - trigger = { - rules = { - { - metric = 'fs_space_percent_free', - window = 120, - ['function'] = 'avg', - fields = { fs='/'}, - relational_operator = '<=', - threshold = 10, - }, - }, - logical_operator = 'and', - }, - severity = 'critical', - }, - { -- 7 - name = 'Backend_errors_5xx', - description = 'Errors 5xx on backends', - enabled = true, - trigger = { - rules = { - { - metric = 'haproxy_backend_response_5xx', - window = 30, - periods = 1, - ['function'] = 'diff', - relational_operator = '>', - threshold = 0, - }, - }, - logical_operator = 'or', - }, - severity = 'warning', - }, - { -- 8 - name = 'nova_logs_errors_rate', - description = 'Rate of change for nova logs in error is too high', - enabled = true, - trigger = { - rules = { - { - metric = 'log_messages', - window = 60, - periods = 4, - ['function'] = 'roc', - threshold = 1.5, - }, - }, - }, - severity = 'warning', - }, - { -- 9 - name = 'heartbeat', - description = 'No metric!', - enabled = true, - trigger = { - rules = { - { - metric = 'foo_heartbeat', - window = 60, - periods = 1, - ['function'] = 'last', - relational_operator = '==', - threshold = 0, - }, - }, - }, - severity = 'down', - }, -} - -afd_on_multivalue = { - name = 'keystone-high-http-response-times', - description = 'The 90 percentile response time for Keystone is too high', - enabled = true, - trigger = { - rules = { - { - metric = 'http_response_times', - window = 60, - periods = 1, - ['function'] = 'max', - threshold = 5, - fields = { http_method = 'POST' }, - relational_operator = '>=', - value = 'upper_90', - }, - }, - }, - severity = 'warning', -} - -missing_value_afd_on_multivalue = { - name = 'keystone-high-http-response-times', - description = 'The 90 percentile response time for Keystone is too high', - enabled = true, - trigger = { - rules = { - { - metric = 'http_response_times', - window = 30, - periods = 2, - ['function'] = 'max', - threshold = 5, - fields = { http_method = 'POST' }, - relational_operator = '>=', - -- value = 'upper_90', - }, - }, - }, - severity = 'warning', -} - -TestLMAAlarm = {} - -local current_time = 0 - -function TestLMAAlarm:tearDown() - lma_alarm.reset_alarms() - current_time = 0 -end - -local function next_time(inc) - if not inc then inc = 10 end - current_time = current_time + (inc*1e9) - return current_time -end - -function TestLMAAlarm:test_start_evaluation() - lma_alarm.load_alarm(alarms[3]) -- window=120 period=2 - lma_alarm.set_start_time(current_time) - local alarm = lma_alarm.get_alarm('CPU_Critical_Controller') - assertEquals(alarm:is_evaluation_time(next_time(10)), false) -- 10 seconds - assertEquals(alarm:is_evaluation_time(next_time(50)), false) -- 60 seconds - assertEquals(alarm:is_evaluation_time(next_time(60)), false) -- 120 seconds - assertEquals(alarm:is_evaluation_time(next_time(120)), true) -- 240 seconds - assertEquals(alarm:is_evaluation_time(next_time(240)), true) -- later -end - -function TestLMAAlarm:test_not_the_time() - lma_alarm.load_alarms(alarms) - lma_alarm.set_start_time(current_time) - local state, _ = lma_alarm.evaluate(next_time()) -- no alarm w/ window <= 10s - assertEquals(state, nil) -end - -function TestLMAAlarm:test_lookup_fields_for_metric() - lma_alarm.load_alarms(alarms) - local fields_required = lma_alarm.get_metric_fields('fs_space_percent_free') - assertItemsEquals(fields_required, {"fs"}) -end - -function TestLMAAlarm:test_lookup_empty_fields_for_metric() - lma_alarm.load_alarms(alarms) - local fields_required = lma_alarm.get_metric_fields('cpu_idle') - assertItemsEquals(fields_required, {}) - local fields_required = lma_alarm.get_metric_fields('fs_space_percent_free') - assertItemsEquals(fields_required, {'fs'}) -end - -function TestLMAAlarm:test_lookup_interested_alarms() - lma_alarm.load_alarms(alarms) - local alarms = lma_alarm.get_interested_alarms('foometric') - assertEquals(#alarms, 0) - local alarms = lma_alarm.get_interested_alarms('cpu_wait') - assertEquals(#alarms, 3) - -end - -function TestLMAAlarm:test_get_alarms() - lma_alarm.load_alarms(alarms) - local all_alarms = lma_alarm.get_alarms() - local num = 0 - for _, _ in pairs(all_alarms) do - num = num + 1 - end - assertEquals(num, #alarms) -end - -function TestLMAAlarm:test_no_datapoint() - lma_alarm.load_alarms(alarms) - lma_alarm.set_start_time(current_time) - local t = next_time(300) -- at this time all alarms can be evaluated - local state, results = lma_alarm.evaluate(t) - assertEquals(state, consts.UNKW) - assert(#results > 0) - for _, result in ipairs(results) do - assertEquals(result.alert.message, 'No datapoint have been received ever') - assertNotEquals(result.alert.fields, nil) - end -end - -function TestLMAAlarm:test_rules_logical_op_and_no_alert() - lma_alarm.load_alarms(alarms) - local alarm = lma_alarm.get_alarm('CPU_Critical_Controller_AND') - lma_alarm.set_start_time(current_time) - local t1 = next_time(60) -- 60s - local t2 = next_time(60) -- 120s - local t3 = next_time(60) -- 180s - local t4 = next_time(60) -- 240s - lma_alarm.add_value(t1, 'cpu_wait', 3) - lma_alarm.add_value(t2, 'cpu_wait', 10) - lma_alarm.add_value(t3, 'cpu_wait', 1) - lma_alarm.add_value(t4, 'cpu_wait', 10) - - lma_alarm.add_value(t1, 'cpu_idle', 30) - lma_alarm.add_value(t2, 'cpu_idle', 10) - lma_alarm.add_value(t3, 'cpu_idle', 10) - lma_alarm.add_value(t4, 'cpu_idle', 20) - local state, result = alarm:evaluate(t4) - assertEquals(#result, 0) - assertEquals(state, consts.OKAY) -end - -function TestLMAAlarm:test_rules_logical_missing_datapoint__op_and() - lma_alarm.load_alarm(alarms[5]) - lma_alarm.set_start_time(current_time) - local t1 = next_time(60) - local t2 = next_time(60) - local t3 = next_time(60) - local t4 = next_time(60) - lma_alarm.add_value(t1, 'cpu_wait', 0) -- 60s - lma_alarm.add_value(t2, 'cpu_wait', 2) -- 120s - lma_alarm.add_value(t3, 'cpu_wait', 5) -- 180s - lma_alarm.add_value(t4, 'cpu_wait', 6) -- 240s - lma_alarm.add_value(t1, 'cpu_idle', 20) -- 60s - lma_alarm.add_value(t2, 'cpu_idle', 20) -- 120s - lma_alarm.add_value(t3, 'cpu_idle', 20) -- 180s - lma_alarm.add_value(t4, 'cpu_idle', 20) -- 240s - local state, result = lma_alarm.evaluate(t4) -- 240s we can evaluate - assertEquals(state, consts.OKAY) - assertEquals(#result, 0) - local state, result = lma_alarm.evaluate(next_time(60)) -- 60s w/o datapoint - assertEquals(state, consts.OKAY) - -- cpu_wait have no data within its observation period - local state, result = lma_alarm.evaluate(next_time(1)) -- 61s w/o datapoint - assertEquals(state, consts.UNKW) - assertEquals(#result, 1) - assertEquals(result[1].alert.metric, 'cpu_wait') - assert(result[1].alert.message:match('No datapoint have been received over the last')) - - -- both cpu_idle and cpu_wait have no data within their observation periods - local state, result = lma_alarm.evaluate(next_time(180)) -- 241s w/o datapoint - assertEquals(state, consts.UNKW) - assertEquals(#result, 2) - assertEquals(result[1].alert.metric, 'cpu_idle') - assert(result[1].alert.message:match('No datapoint have been received over the last')) - assertEquals(result[2].alert.metric, 'cpu_wait') - assert(result[2].alert.message:match('No datapoint have been received over the last')) - - -- datapoints come back for both metrics - lma_alarm.add_value(next_time(), 'cpu_idle', 20) - lma_alarm.add_value(next_time(), 'cpu_idle', 20) - lma_alarm.add_value(next_time(), 'cpu_wait', 20) - lma_alarm.add_value(next_time(), 'cpu_wait', 20) - local state, result = lma_alarm.evaluate(next_time()) -- 240s we can evaluate - assertEquals(state, consts.OKAY) - assertEquals(#result, 0) -end - -function TestLMAAlarm:test_rules_logical_missing_datapoint__op_and_2() - lma_alarm.load_alarm(alarms[5]) - lma_alarm.set_start_time(current_time) - local t1 = next_time(60) - local t2 = next_time(60) - local t3 = next_time(60) - local t4 = next_time(60) - lma_alarm.add_value(t1, 'cpu_wait', 0) -- 60s - lma_alarm.add_value(t2, 'cpu_wait', 2) -- 120s - lma_alarm.add_value(t3, 'cpu_wait', 5) -- 180s - lma_alarm.add_value(t4, 'cpu_wait', 6) -- 240s - lma_alarm.add_value(t1, 'cpu_idle', 20) -- 60s - lma_alarm.add_value(t2, 'cpu_idle', 20) -- 120s - lma_alarm.add_value(t3, 'cpu_idle', 20) -- 180s - lma_alarm.add_value(t4, 'cpu_idle', 20) -- 240s - local state, result = lma_alarm.evaluate(t4) -- 240s we can evaluate - assertEquals(state, consts.OKAY) - assertEquals(#result, 0) - local state, result = lma_alarm.evaluate(next_time(60)) -- 60s w/o datapoint - assertEquals(state, consts.OKAY) - -- cpu_wait have no data within its observation period - local state, result = lma_alarm.evaluate(next_time(1)) -- 61s w/o datapoint - assertEquals(state, consts.UNKW) - assertEquals(#result, 1) - assertEquals(result[1].alert.metric, 'cpu_wait') - assert(result[1].alert.message:match('No datapoint have been received over the last')) - - lma_alarm.add_value(next_time(170), 'cpu_wait', 20) - -- cpu_idle have no data within its observation period - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(state, consts.UNKW) - assertEquals(#result, 1) - assertEquals(result[1].alert.metric, 'cpu_idle') - assert(result[1].alert.message:match('No datapoint have been received over the last')) - - -- datapoints come back for both metrics - lma_alarm.add_value(next_time(), 'cpu_idle', 20) - lma_alarm.add_value(next_time(), 'cpu_idle', 20) - lma_alarm.add_value(next_time(), 'cpu_wait', 20) - lma_alarm.add_value(next_time(), 'cpu_wait', 20) - local state, result = lma_alarm.evaluate(next_time()) -- 240s we can evaluate - assertEquals(state, consts.OKAY) - assertEquals(#result, 0) -end - -function TestLMAAlarm:test_rules_logical_op_and() - lma_alarm.load_alarm(alarms[5]) - local cpu_critical_and = lma_alarm.get_alarm('CPU_Critical_Controller_AND') - lma_alarm.add_value(next_time(1), 'cpu_wait', 30) - lma_alarm.add_value(next_time(1), 'cpu_wait', 30) - lma_alarm.add_value(next_time(1), 'cpu_wait', 35) - - lma_alarm.add_value(next_time(2), 'cpu_idle', 0) - lma_alarm.add_value(next_time(2), 'cpu_idle', 1) - lma_alarm.add_value(next_time(2), 'cpu_idle', 7) - lma_alarm.add_value(next_time(2), 'cpu_idle', 2) - local state, result = cpu_critical_and:evaluate(current_time) - assertEquals(state, consts.CRIT) - assertEquals(#result, 2) -- both rules match: avg(cpu_wait)>=30 and avg(cpu_idle)<=15 - - lma_alarm.add_value(next_time(120), 'cpu_idle', 70) - lma_alarm.add_value(next_time(), 'cpu_idle', 70) - lma_alarm.add_value(next_time(), 'cpu_idle', 70) - lma_alarm.add_value(next_time(), 'cpu_wait', 40) - lma_alarm.add_value(next_time(), 'cpu_wait', 38) - local state, result = cpu_critical_and:evaluate(current_time) - assertEquals(state, consts.OKAY) - assertEquals(#result, 0) -- avg(cpu_wait)>=30 matches but not avg(cpu_idle)<=15 - - lma_alarm.add_value(next_time(200), 'cpu_idle', 70) - lma_alarm.add_value(next_time(), 'cpu_idle', 70) - local state, result = cpu_critical_and:evaluate(current_time) - assertEquals(state, consts.UNKW) - assertEquals(#result, 1) -- no data for avg(cpu_wait)>=30 and avg(cpu_idle)<=3 doesn't match - - next_time(240) -- spend enough time to invalidate datapoints of cpu_wait - lma_alarm.add_value(current_time, 'cpu_idle', 2) - lma_alarm.add_value(next_time(), 'cpu_idle', 2) - local state, result = cpu_critical_and:evaluate(current_time) - assertEquals(state, consts.UNKW) - assertEquals(#result, 2) -- no data for avg(cpu_wait)>=30 and avg(cpu_idle)<=3 matches -end - -function TestLMAAlarm:test_rules_logical_op_or_one_alert() - lma_alarm.load_alarms(alarms) - local cpu_warn_and = lma_alarm.get_alarm('CPU_Warning_Controller') - lma_alarm.add_value(next_time(), 'cpu_wait', 15) - lma_alarm.add_value(next_time(), 'cpu_wait', 10) - lma_alarm.add_value(next_time(), 'cpu_wait', 20) - - lma_alarm.add_value(next_time(), 'cpu_idle', 11) - lma_alarm.add_value(next_time(), 'cpu_idle', 8) - lma_alarm.add_value(next_time(), 'cpu_idle', 7) - local state, result = cpu_warn_and:evaluate(current_time) - assertEquals(state, consts.WARN) - assertEquals(#result, 1) -- avg(cpu_wait) IS NOT >=25 and avg(cpu_idle)<=2 -end - -function TestLMAAlarm:test_rules_logical_op_or_all_alert() - lma_alarm.load_alarm(alarms[4]) - local cpu_warn_and = lma_alarm.get_alarm('CPU_Warning_Controller') - lma_alarm.add_value(next_time(), 'cpu_wait', 35) - lma_alarm.add_value(next_time(), 'cpu_wait', 20) - lma_alarm.add_value(next_time(), 'cpu_wait', 32) - - lma_alarm.add_value(next_time(), 'cpu_idle', 3) - lma_alarm.add_value(next_time(), 'cpu_idle', 2.5) - lma_alarm.add_value(next_time(), 'cpu_idle', 1.5) - local state, result = cpu_warn_and:evaluate(current_time) - assertEquals(state, consts.WARN) - assertEquals(#result, 2) -- avg(cpu_wait) >=25 and avg(cpu_idle)<=3 -end - -function TestLMAAlarm:test_min() - lma_alarm.load_alarms(alarms) - lma_alarm.add_value(next_time(), 'rabbitmq_messages', 50) - lma_alarm.add_value(next_time(), 'rabbitmq_messages', 100) - lma_alarm.add_value(next_time(), 'rabbitmq_messages', 75) - lma_alarm.add_value(next_time(), 'rabbitmq_messages', 81) - local rabbitmq_critical = lma_alarm.get_alarm('RabbitMQ_Critical') - assertEquals(rabbitmq_critical.severity, consts.CRIT) - local state_crit, result = rabbitmq_critical:evaluate(current_time) - assertEquals(state_crit, consts.CRIT) -- min()>=50 - assertEquals(#result, 1) - assertEquals(result[1].value, 50) -end - - function TestLMAAlarm:test_max() - local a = { - name = 'foo alert', - description = 'foo description', - trigger = { - rules = { - { - metric = 'rabbitmq_queue_messages', - window = 30, - periods = 2, - ['function'] = 'max', - threshold = 200, - relational_operator = '>=', - }, - }, - }, - severity = 'warning', - } - lma_alarm.load_alarm(a) - lma_alarm.add_value(next_time(), 'rabbitmq_queue_messages', 0, {queue = 'queue-XX', hostname = 'node-x'}) - lma_alarm.add_value(next_time(), 'rabbitmq_queue_messages', 260, {queue = 'queue-XX', hostname = 'node-x'}) - lma_alarm.add_value(next_time(), 'rabbitmq_queue_messages', 200, {queue = 'queue-XX', hostname = 'node-x'}) - lma_alarm.add_value(next_time(), 'rabbitmq_queue_messages', 152, {queue = 'queue-XX', hostname = 'node-x'}) - lma_alarm.add_value(next_time(), 'rabbitmq_queue_messages', 152, {queue = 'nova', hostname = 'node-x'}) - lma_alarm.add_value(next_time(), 'rabbitmq_queue_messages', 532, {queue = 'nova', hostname = 'node-x'}) - local state_warn, result = lma_alarm.evaluate(current_time) - assertEquals(state_warn, consts.WARN) - assertEquals(#result, 1) - assertEquals(result[1].alert['function'], 'max') - assertEquals(result[1].alert.value, 532) - end - -function TestLMAAlarm:test_diff() - lma_alarm.load_alarms(alarms) - local errors_5xx = lma_alarm.get_alarm('Backend_errors_5xx') - assertEquals(errors_5xx.severity, consts.WARN) - - -- with 5xx errors - lma_alarm.add_value(next_time(), 'haproxy_backend_response_5xx', 1) - lma_alarm.add_value(next_time(), 'haproxy_backend_response_5xx', 11) -- +10s - lma_alarm.add_value(next_time(), 'haproxy_backend_response_5xx', 21) -- +10s - local state, result = errors_5xx:evaluate(current_time) - assertEquals(state, consts.WARN) - assertEquals(#result, 1) - assertEquals(result[1].value, 20) - - -- without 5xx errors - lma_alarm.add_value(next_time(), 'haproxy_backend_response_5xx', 21) - lma_alarm.add_value(next_time(), 'haproxy_backend_response_5xx', 21) -- +10s - lma_alarm.add_value(next_time(), 'haproxy_backend_response_5xx', 21) -- +10s - local state, result = errors_5xx:evaluate(current_time) - assertEquals(state, consts.OKAY) - assertEquals(#result, 0) - - -- missing data - local state, result = errors_5xx:evaluate(next_time(60)) - assertEquals(state, consts.UNKW) -end - -function TestLMAAlarm:test_roc() - lma_alarm.load_alarms(alarms) - local errors_logs = lma_alarm.get_alarm('nova_logs_errors_rate') - assertEquals(errors_logs.severity, consts.WARN) - local m_values = {} - - -- Test one error in the current window - m_values = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- historical window 0 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- historical window 0 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- historical window 3 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- historical window 4 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- previous window - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } -- current window - for _,v in pairs(m_values) do - lma_alarm.add_value(next_time(5), 'log_messages', v, {service = 'nova', level = 'error'}) - end - local state, _ = errors_logs:evaluate(current_time) - assertEquals(state, consts.WARN) - - -- Test one error in the historical window - m_values = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- historical window 0 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- historical window 0 - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -- historical window 3 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- historical window 4 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- previous window - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -- current window - for _,v in pairs(m_values) do - lma_alarm.add_value(next_time(5), 'log_messages', v, {service = 'nova', level = 'error'}) - end - local state, _ = errors_logs:evaluate(current_time) - assertEquals(state, consts.OKAY) - - -- with rate errors - m_values = { 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- historical window 1 - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- historical window 2 - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- historical window 3 - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- historical window 4 - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- previous window - 1, 2, 1, 1, 1, 2, 1, 5, 5, 7, 1, 7 } -- current window - for _,v in pairs(m_values) do - lma_alarm.add_value(next_time(5), 'log_messages', v, {service = 'nova', level = 'error'}) - end - local state, _ = errors_logs:evaluate(current_time) - assertEquals(state, consts.WARN) - - -- without rate errors - m_values = { 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- historical window 1 - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- historical window 2 - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- historical window 3 - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- historical window 4 - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, -- previous window - 1, 2, 1, 1, 1, 2, 1, 3, 4, 3, 3, 4 } -- current window - for _,v in pairs(m_values) do - lma_alarm.add_value(next_time(5), 'log_messages', v, {service = 'nova', level = 'error'}) - end - local state, _ = errors_logs:evaluate(current_time) - assertEquals(state, consts.OKAY) -end - -function TestLMAAlarm:test_alarm_first_match() - lma_alarm.load_alarm(alarms[3]) -- cpu critical (window 240s) - lma_alarm.load_alarm(alarms[4]) -- cpu warning (window 120s) - lma_alarm.set_start_time(current_time) - - next_time(240) -- both alarms can now be evaluated - lma_alarm.add_value(next_time(), 'cpu_idle', 15) - lma_alarm.add_value(next_time(), 'cpu_wait', 9) - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(state, consts.WARN) -- 2nd alarm raised - assertEquals(#result, 1) -- cpu_idle match (<= 15) and cpu_wait don't match (>= 25) - - next_time(240) -- both alarms can now be evaluated with new datapoints - lma_alarm.add_value(next_time(), 'cpu_wait', 15) - lma_alarm.add_value(next_time(), 'cpu_idle', 4) - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(state, consts.CRIT) -- first alarm raised - assertEquals(#result, 1) -- cpu_idle match (<= 5) and cpu_wait don't match (>= 20) -end - -function TestLMAAlarm:test_rules_fields() - lma_alarm.load_alarm(alarms[1]) -- FS_all_no_field - lma_alarm.load_alarm(alarms[6]) -- FS_root - lma_alarm.set_start_time(current_time) - - local t = next_time() - lma_alarm.add_value(t, 'fs_space_percent_free', 6, {fs = '/'}) - lma_alarm.add_value(t, 'fs_space_percent_free', 6 ) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 12, {fs = '/'}) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 17 ) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 6, {fs = '/'}) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 6, {fs = 'foo'}) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 3, {fs = 'foo'}) - local t = next_time() - - local root_fs = lma_alarm.get_alarm('FS_root') - local state, result = root_fs:evaluate(t) - assertEquals(#result, 1) - assertItemsEquals(result[1].fields, {fs='/'}) - assertEquals(result[1].value, 8) - - - local root_fs = lma_alarm.get_alarm('FS_all_no_field') - local state, result = root_fs:evaluate(t) - assertEquals(#result, 1) - - assertItemsEquals(result[1].fields, {}) - assertEquals(result[1].value, 8) -end - -function TestLMAAlarm:test_last_fct() - lma_alarm.load_alarm(alarms[9]) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(), 'foo_heartbeat', 1) - lma_alarm.add_value(next_time(), 'foo_heartbeat', 1) - lma_alarm.add_value(next_time(), 'foo_heartbeat', 0) - lma_alarm.add_value(next_time(), 'foo_heartbeat', 1) - lma_alarm.add_value(next_time(), 'foo_heartbeat', 0) - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(state, consts.DOWN) - next_time(61) - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(state, consts.UNKW) - lma_alarm.add_value(next_time(), 'foo_heartbeat', 0) - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(state, consts.DOWN) - lma_alarm.add_value(next_time(), 'foo_heartbeat', 1) - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(state, consts.OKAY) -end - -function TestLMAAlarm:test_rule_with_multivalue() - lma_alarm.load_alarm(afd_on_multivalue) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 0.4, foo = 1}, {http_method = 'POST'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 0.2, foo = 1}, {http_method = 'POST'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 6, foo = 1}, {http_method = 'POST'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 3, foo = 1}, {http_method = 'POST'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 4, foo = 1}, {http_method = 'POST'}) - local state, result = lma_alarm.evaluate(next_time()) -- window 60 second - assertEquals(state, consts.WARN) - assertItemsEquals(result[1].alert.fields, {http_method='POST'}) - assertEquals(result[1].alert.value, 6) -end - -function TestLMAAlarm:test_nocrash_missing_value_with_multivalue_metric() - lma_alarm.load_alarm(missing_value_afd_on_multivalue) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 0.4, foo = 1}, {http_method = 'POST'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 0.2, foo = 1}, {http_method = 'POST'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 6, foo = 1}, {http_method = 'POST'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 3, foo = 1}, {http_method = 'POST'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 4, foo = 1}, {http_method = 'POST'}) - local state, result = lma_alarm.evaluate(next_time()) -- window 60 second - assertEquals(state, consts.UNKW) -end - -function TestLMAAlarm:test_complex_field_matching_alarm_trigger() - local alert = { - name = 'keystone-high-http-response-times', - description = 'The 90 percentile response time for Keystone is too high', - enabled = true, - trigger = { - rules = { - { - metric = 'http_response_times', - window = 30, - periods = 2, - ['function'] = 'max', - threshold = 5, - fields = { http_method = 'POST || GET', - http_status = '2xx || ==3xx'}, - relational_operator = '>=', - value = 'upper_90', - }, - }, - }, - severity = 'warning', - } - lma_alarm.load_alarm(alert) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 0.4, foo = 1}, {http_method = 'POST', http_status = '2xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 0.2, foo = 1}, {http_method = 'POST', http_status = '2xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 6, foo = 1}, {http_method = 'POST', http_status = '3xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 999, foo = 1}, {http_method = 'POST', http_status = '5xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 3, foo = 1}, {http_method = 'GET', http_status = '2xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 4, foo = 1}, {http_method = 'POST', http_status = '2xx'}) - local state, result = lma_alarm.evaluate(next_time()) -- window 60 second - assertEquals(state, consts.WARN) - assertEquals(result[1].alert.value, 6) -- the max - assertItemsEquals(result[1].alert.fields, {http_method='POST || GET', http_status='2xx || ==3xx'}) -end - -function TestLMAAlarm:test_complex_field_matching_alarm_ok() - local alert = { - name = 'keystone-high-http-response-times', - description = 'The 90 percentile response time for Keystone is too high', - enabled = true, - trigger = { - rules = { - { - metric = 'http_response_times', - window = 30, - periods = 2, - ['function'] = 'avg', - threshold = 5, - fields = { http_method = 'POST || GET', - http_status = '2xx || 3xx'}, - relational_operator = '>=', - value = 'upper_90', - }, - }, - }, - severity = 'warning', - } - - lma_alarm.load_alarm(alert) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 0.4, foo = 1}, {http_method = 'POST', http_status = '2xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 0.2, foo = 1}, {http_method = 'POST', http_status = '2xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 6, foo = 1}, {http_method = 'POST', http_status = '2xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 3, foo = 1}, {http_method = 'GET', http_status = '2xx'}) - lma_alarm.add_value(next_time(), 'http_response_times', {upper_90 = 4, foo = 1}, {http_method = 'POST', http_status = '2xx'}) - local state, result = lma_alarm.evaluate(next_time()) -- window 60 second - assertEquals(state, consts.OKAY) -end - -function TestLMAAlarm:test_group_by_required_field() - local alert = { - name = 'foo-alarm', - description = 'foo description', - enabled = true, - trigger = { - rules = { - { - metric = 'foo_metric_name', - window = 30, - periods = 1, - ['function'] = 'avg', - fields = { foo = 'bar', bar = 'foo' }, - group_by = {'fs'}, - relational_operator = '<=', - threshold = 5, - }, - }, - }, - severity = 'warning', - } - lma_alarm.load_alarm(alert) - local fields = lma_alarm.get_metric_fields('foo_metric_name') - assertItemsEquals(fields, { "fs", "foo", "bar" }) - - local fields = lma_alarm.get_metric_fields('non_existant_metric') - assertItemsEquals(fields, {}) -end - -function TestLMAAlarm:test_group_by_one_field() - local alert = { - name = 'osd-filesystem-warning', - description = 'free space is too low', - enabled = true, - trigger = { - rules = { - { - metric = 'fs_space_percent_free', - window = 30, - periods = 1, - ['function'] = 'avg', - fields = { fs = '=~ osd%-%d && !~ /var/log' }, - group_by = {'fs'}, - relational_operator = '<=', - threshold = 5, - }, - }, - }, - severity = 'warning', - } - lma_alarm.load_alarm(alert) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 5, {fs = 'osd-1'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 4, {fs = 'osd-2'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 80, {fs = 'osd-3'}) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 4, {fs = 'osd-1'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 3, {fs = 'osd-2'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 80, {fs = 'osd-3'}) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 4, {fs = 'osd-1'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 2, {fs = 'osd-2'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 80, {fs = 'osd-3'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 1, {fs = '/var/log/osd-3'}) - - local state, result = lma_alarm.evaluate(next_time()) -- window 60 second - assertEquals(#result, 2) - assertEquals(state, consts.WARN) - - next_time(100) -- spend enough time to invalidate datapoints - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 50, {fs = 'osd-1'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 50, {fs = 'osd-2'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 50, {fs = 'osd-3'}) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 50, {fs = 'osd-1'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 50, {fs = 'osd-2'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 50, {fs = 'osd-3'}) - local state, result = lma_alarm.evaluate(next_time()) -- window 60 second - assertEquals(#result, 0) - assertEquals(state, consts.OKAY) -end - -function TestLMAAlarm:test_group_by_several_fields() - local alert = { - name = 'osd-filesystem-warning', - description = 'free space is too low', - enabled = true, - trigger = { - rules = { - { - metric = 'fs_space_percent_free', - window = 30, - periods = 1, - ['function'] = 'last', - fields = {}, - group_by = {'fs', 'osd'}, - relational_operator = '<=', - threshold = 5, - }, - }, - }, - severity = 'warning', - } - lma_alarm.load_alarm(alert) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 5, {fs = '/foo', osd = '1'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 4, {fs = '/foo', osd = '2'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 80, {fs = '/foo', osd = '3'}) - - local state, result = lma_alarm.evaluate(next_time(20)) - assertEquals(state, consts.WARN) - -- one item for {fs = '/foo', osd = '1'} and another one for {fs = '/foo', osd = '2'} - assertEquals(#result, 2) - - next_time(100) -- spend enough time to invalidate datapoints - - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 5, {fs = '/foo', osd = '1'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 4, {fs = '/foo', osd = '2'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 80, {fs = '/foo', osd = '3'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 15, {fs = '/bar', osd = '1'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 14, {fs = '/bar', osd = '2'}) - lma_alarm.add_value(current_time, 'fs_space_percent_free', 2, {fs = '/bar', osd = '3'}) - local state, result = lma_alarm.evaluate(next_time(20)) - assertEquals(state, consts.WARN) - -- one item for {fs = '/foo', osd = '1'}, another one for {fs = '/foo', osd = '2'} - -- and another one for {fs = '/bar', osd = '3'} - assertEquals(#result, 3) -end - -function TestLMAAlarm:test_group_by_missing_field_is_unknown() - local alert = { - name = 'osd-filesystem-warning', - description = 'free space is too low', - enabled = true, - trigger = { - rules = { - { - metric = 'fs_space_percent_free', - window = 30, - periods = 1, - ['function'] = 'avg', - fields = { fs = '=~ osd%-%d && !~ /var/log' }, - group_by = {'fs'}, - relational_operator = '<=', - threshold = 5, - }, - }, - }, - severity = 'warning', - } - lma_alarm.load_alarm(alert) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 5) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 4) - lma_alarm.add_value(next_time(), 'fs_space_percent_free', 4) - - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(#result, 1) - assertEquals(state, consts.UNKW) -end - -function TestLMAAlarm:test_no_data_policy_okay() - local alarm = { - name = 'foo-alarm', - description = 'foo description', - enabled = true, - trigger = { - rules = { - { - metric = 'foo_metric_name', - window = 30, - periods = 1, - ['function'] = 'avg', - fields = { foo = 'bar', bar = 'foo' }, - group_by = {'fs'}, - relational_operator = '<=', - threshold = 5, - }, - }, - }, - severity = 'warning', - no_data_policy = 'okay', - } - lma_alarm.load_alarm(alarm) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(100), 'another_metric', 5) - - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(#result, 0) - assertEquals(state, consts.OKAY) -end - -function TestLMAAlarm:test_no_data_policy_critical() - local alarm = { - name = 'foo-alarm', - description = 'foo description', - enabled = true, - trigger = { - rules = { - { - metric = 'foo_metric_name', - window = 30, - periods = 1, - ['function'] = 'avg', - fields = { foo = 'bar', bar = 'foo' }, - group_by = {'fs'}, - relational_operator = '<=', - threshold = 5, - }, - }, - }, - severity = 'critical', - no_data_policy = 'critical', - } - lma_alarm.load_alarm(alarm) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(100), 'another_metric', 5) - - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(#result, 1) - assertEquals(state, consts.CRIT) -end - -function TestLMAAlarm:test_no_data_policy_skip() - local alarm = { - name = 'foo-alarm', - description = 'foo description', - enabled = true, - trigger = { - rules = { - { - metric = 'foo_metric_name', - window = 30, - periods = 1, - ['function'] = 'avg', - fields = { foo = 'bar', bar = 'foo' }, - group_by = {'fs'}, - relational_operator = '<=', - threshold = 5, - }, - }, - }, - severity = 'critical', - no_data_policy = 'skip', - } - lma_alarm.load_alarm(alarm) - lma_alarm.set_start_time(current_time) - - lma_alarm.add_value(next_time(100), 'another_metric', 5) - - local state, result = lma_alarm.evaluate(next_time()) - assertEquals(state, nil) -end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse.lua deleted file mode 100644 index d218dd664..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse.lua +++ /dev/null @@ -1,248 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - --- mock the inject_message() function from the Heka sandbox library -local last_injected_msg -function inject_message(msg) - last_injected_msg = msg -end - -local cjson = require('cjson') -local consts = require('gse_constants') - -local gse = require('gse') -local gse_policy = require('gse_policy') - -highest_policy = { - gse_policy.new({ - status='down', - trigger={ - logical_operator='or', - rules={{ - ['function']='count', - arguments={'down'}, - relational_operator='>', - threshold=0 - }} - } - }), - gse_policy.new({ - status='critical', - trigger={ - logical_operator='or', - rules={{ - ['function']='count', - arguments={'critical'}, - relational_operator='>', - threshold=0 - }} - } - }), - gse_policy.new({ - status='warning', - trigger={ - logical_operator='or', - rules={{ - ['function']='count', - arguments={'warning'}, - relational_operator='>', - threshold=0 - }} - } - }), - gse_policy.new({status='okay'}) -} - --- define clusters -gse.add_cluster("heat", {'heat-api', 'controller'}, {'nova', 'glance', 'neutron', 'keystone', 'rabbitmq'}, 'member', highest_policy) -gse.add_cluster("nova", {'nova-api', 'nova-ec2-api', 'nova-scheduler'}, {'glance', 'neutron', 'keystone', 'rabbitmq'}, 'member', highest_policy) -gse.add_cluster("neutron", {'neutron-api'}, {'keystone', 'rabbitmq'}, 'member', highest_policy) -gse.add_cluster("keystone", {'keystone-admin-api', 'keystone-public-api'}, {}, 'member', highest_policy) -gse.add_cluster("glance", {'glance-api', 'glance-registry-api'}, {'keystone'}, 'member', highest_policy) -gse.add_cluster("rabbitmq", {'rabbitmq-cluster', 'controller'}, {}, 'hostname', highest_policy) - --- provision facts -gse.set_member_status("neutron", "neutron-api", consts.DOWN, {{message="All neutron endpoints are down"}}, 'node-1') -gse.set_member_status('keystone', 'keystone-admin-api', consts.OKAY, {}, 'node-1') -gse.set_member_status('glance', "glance-api", consts.WARN, {{message="glance-api endpoint is down on node-1"}}, 'node-1') -gse.set_member_status('glance', "glance-registry-api", consts.DOWN, {{message='glance-registry endpoints are down'}}, 'node-1') -gse.set_member_status("rabbitmq", 'rabbitmq-cluster', consts.WARN, {{message="1 RabbitMQ node out of 3 is down"}}, 'node-2') -gse.set_member_status("rabbitmq", 'rabbitmq-cluster', consts.OKAY, {}, 'node-1') -gse.set_member_status("rabbitmq", 'rabbitmq-cluster', consts.OKAY, {}, 'node-3') -gse.set_member_status('heat', "heat-api", consts.WARN, {{message='5xx errors detected'}}, 'node-1') -gse.set_member_status('nova', "nova-api", consts.OKAY, {}, 'node-1') -gse.set_member_status('nova', "nova-ec2_api", consts.OKAY, {}, 'node-1') -gse.set_member_status('nova', "nova-scheduler", consts.OKAY, {}, 'node-1') -gse.set_member_status('rabbitmq', "controller", consts.WARN, {{message='no space left'}}, 'node-1') -gse.set_member_status('heat', "controller", consts.WARN, {{message='no space left'}}, 'node-1') - -for _, v in ipairs({'rabbitmq', 'keystone', 'glance', 'neutron', 'nova', 'heat'}) do - gse.resolve_status(v) -end - -TestGse = {} - - function TestGse:test_ordered_clusters() - local ordered_clusters = gse.get_ordered_clusters() - assertEquals(#ordered_clusters, 6) - assertEquals(ordered_clusters[1], 'rabbitmq') - assertEquals(ordered_clusters[2], 'keystone') - assertEquals(ordered_clusters[3], 'glance') - assertEquals(ordered_clusters[4], 'neutron') - assertEquals(ordered_clusters[5], 'nova') - assertEquals(ordered_clusters[6], 'heat') - end - - function TestGse:test_01_rabbitmq_is_warning() - local status, alarms = gse.resolve_status('rabbitmq') - assertEquals(status, consts.WARN) - assertEquals(#alarms, 2) - assertEquals(alarms[1].hostname, 'node-1') - assertEquals(alarms[1].tags.dependency_name, 'controller') - assertEquals(alarms[1].tags.dependency_level, 'direct') - assertEquals(alarms[2].hostname, 'node-2') - assertEquals(alarms[2].tags.dependency_name, 'rabbitmq-cluster') - assertEquals(alarms[2].tags.dependency_level, 'direct') - end - - function TestGse:test_02_keystone_is_okay() - local status, alarms = gse.resolve_status('keystone') - assertEquals(status, consts.OKAY) - assertEquals(#alarms, 0) - end - - function TestGse:test_03_glance_is_down() - local status, alarms = gse.resolve_status('glance') - assertEquals(status, consts.DOWN) - assertEquals(#alarms, 2) - assert(alarms[1].hostname == nil) - assertEquals(alarms[1].tags.dependency_name, 'glance-api') - assertEquals(alarms[1].tags.dependency_level, 'direct') - assert(alarms[2].hostname == nil) - assertEquals(alarms[2].tags.dependency_name, 'glance-registry-api') - assertEquals(alarms[2].tags.dependency_level, 'direct') - end - - function TestGse:test_04_neutron_is_down() - local status, alarms = gse.resolve_status('neutron') - assertEquals(status, consts.DOWN) - assertEquals(#alarms, 3) - assertEquals(alarms[1].tags.dependency_name, 'neutron-api') - assertEquals(alarms[1].tags.dependency_level, 'direct') - assert(alarms[1].hostname == nil) - assertEquals(alarms[2].tags.dependency_name, 'rabbitmq') - assertEquals(alarms[2].tags.dependency_level, 'hint') - assertEquals(alarms[2].hostname, 'node-1') - assertEquals(alarms[3].tags.dependency_name, 'rabbitmq') - assertEquals(alarms[3].tags.dependency_level, 'hint') - assertEquals(alarms[3].hostname, 'node-2') - end - - function TestGse:test_05_nova_is_okay() - local status, alarms = gse.resolve_status('nova') - assertEquals(status, consts.OKAY) - assertEquals(#alarms, 0) - end - - function TestGse:test_06_heat_is_warning_with_hints() - local status, alarms = gse.resolve_status('heat') - assertEquals(status, consts.WARN) - assertEquals(#alarms, 6) - assertEquals(alarms[1].tags.dependency_name, 'controller') - assertEquals(alarms[1].tags.dependency_level, 'direct') - assert(alarms[1].hostname == nil) - assertEquals(alarms[2].tags.dependency_name, 'heat-api') - assertEquals(alarms[2].tags.dependency_level, 'direct') - assert(alarms[2].hostname == nil) - assertEquals(alarms[3].tags.dependency_name, 'glance') - assertEquals(alarms[3].tags.dependency_level, 'hint') - assert(alarms[3].hostname == nil) - assertEquals(alarms[4].tags.dependency_name, 'glance') - assertEquals(alarms[4].tags.dependency_level, 'hint') - assert(alarms[4].hostname == nil) - assertEquals(alarms[5].tags.dependency_name, 'neutron') - assertEquals(alarms[5].tags.dependency_level, 'hint') - assert(alarms[5].hostname == nil) - assertEquals(alarms[6].tags.dependency_name, 'rabbitmq') - assertEquals(alarms[6].tags.dependency_level, 'hint') - assertEquals(alarms[6].hostname, 'node-2') - end - - function TestGse:test_inject_cluster_metric_for_nova() - gse.inject_cluster_metric( - 'gse_service_cluster_metric', - 'nova', - 'service_cluster_status', - 10, - 'gse_service_cluster_plugin' - ) - local metric = last_injected_msg - assertEquals(metric.Type, 'gse_service_cluster_metric') - assertEquals(metric.Fields.cluster_name, 'nova') - assertEquals(metric.Fields.name, 'service_cluster_status') - assertEquals(metric.Fields.value, consts.OKAY) - assertEquals(metric.Fields.interval, 10) - assertEquals(metric.Payload, '{"alarms":[]}') - end - - function TestGse:test_inject_cluster_metric_for_glance() - gse.inject_cluster_metric( - 'gse_service_cluster_metric', - 'glance', - 'service_cluster_status', - 10, - 'gse_service_cluster_plugin' - ) - local metric = last_injected_msg - assertEquals(metric.Type, 'gse_service_cluster_metric') - assertEquals(metric.Fields.cluster_name, 'glance') - assertEquals(metric.Fields.name, 'service_cluster_status') - assertEquals(metric.Fields.value, consts.DOWN) - assertEquals(metric.Fields.interval, 10) - assert(metric.Payload:match("glance%-registry endpoints are down")) - assert(metric.Payload:match("glance%-api endpoint is down on node%-1")) - end - - function TestGse:test_inject_cluster_metric_for_heat() - gse.inject_cluster_metric( - 'gse_service_cluster_metric', - 'heat', - 'service_cluster_status', - 10, - 'gse_service_cluster_plugin' - ) - local metric = last_injected_msg - assertEquals(metric.Type, 'gse_service_cluster_metric') - assertEquals(metric.Fields.cluster_name, 'heat') - assertEquals(metric.Fields.name, 'service_cluster_status') - assertEquals(metric.Fields.value, consts.WARN) - assertEquals(metric.Fields.interval, 10) - assert(metric.Payload:match("5xx errors detected")) - assert(metric.Payload:match("1 RabbitMQ node out of 3 is down")) - end - - function TestGse:test_reverse_index() - local clusters = gse.find_cluster_memberships('controller') - assertEquals(#clusters, 2) - assertEquals(clusters[1], 'heat') - assertEquals(clusters[2], 'rabbitmq') - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse_cluster_policy.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse_cluster_policy.lua deleted file mode 100644 index 961e6b372..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse_cluster_policy.lua +++ /dev/null @@ -1,201 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - -local gse_policy = require('gse_policy') -local consts = require('gse_constants') - -local test_policy_down = gse_policy.new({ - status='down', - trigger={ - logical_operator='or', - rules={{ - ['function']='count', - arguments={'down'}, - relational_operator='>', - threshold=0 - }} - } -}) - -local test_policy_critical = gse_policy.new({ - status='critical', - trigger={ - logical_operator='and', - rules={{ - ['function']='count', - arguments={'critical'}, - relational_operator='>', - threshold=0 - }, { - ['function']='percent', - arguments={'okay', 'warning'}, - relational_operator='<', - threshold=50 - }} - } -}) - -local test_policy_warning = gse_policy.new({ - status='warning', - trigger={ - logical_operator='or', - rules={{ - ['function']='percent', - arguments={'okay'}, - relational_operator='<', - threshold=50 - }, { - ['function']='percent', - arguments={'warning'}, - relational_operator='>', - threshold=30 - }} - } -}) - -local test_policy_okay = gse_policy.new({ - status='okay' -}) - -TestGsePolicy = {} - - function TestGsePolicy:test_policy_down() - assertEquals(test_policy_down.status, consts.DOWN) - assertEquals(test_policy_down.logical_op, 'or') - assertEquals(#test_policy_down.rules, 1) - assertEquals(test_policy_down.rules[1]['function'], 'count') - assertEquals(#test_policy_down.rules[1].arguments, 1) - assertEquals(test_policy_down.rules[1].arguments[1], consts.DOWN) - assertEquals(test_policy_down.rules[1].relational_op, '>') - assertEquals(test_policy_down.rules[1].threshold, 0) - assertEquals(test_policy_down.require_percent, false) - end - - function TestGsePolicy:test_policy_okay_evaluate_true() - local facts = { - [consts.OKAY]=5, - [consts.WARN]=0, - [consts.CRIT]=0, - [consts.DOWN]=0, - [consts.UNKW]=0, - } - assertEquals(test_policy_okay:evaluate(facts), true) - end - - function TestGsePolicy:test_policy_okay_evaluate_true_again() - local facts = { - [consts.OKAY]=0, - [consts.WARN]=0, - [consts.CRIT]=0, - [consts.DOWN]=0, - [consts.UNKW]=0, - } - assertEquals(test_policy_okay:evaluate(facts), true) - end - - function TestGsePolicy:test_policy_warn_evaluate_true() - local facts = { - [consts.OKAY]=2, - [consts.WARN]=2, - [consts.CRIT]=0, - [consts.DOWN]=0, - [consts.UNKW]=1, - } - assertEquals(test_policy_warning:evaluate(facts), true) - end - - function TestGsePolicy:test_policy_warn_evaluate_false() - local facts = { - [consts.OKAY]=6, - [consts.WARN]=2, - [consts.CRIT]=0, - [consts.DOWN]=0, - [consts.UNKW]=1, - } - assertEquals(test_policy_warning:evaluate(facts), false) - end - - function TestGsePolicy:test_policy_warn_evaluate_true_again() - local facts = { - [consts.OKAY]=3, - [consts.WARN]=2, - [consts.CRIT]=0, - [consts.DOWN]=0, - [consts.UNKW]=0, - } - assertEquals(test_policy_warning:evaluate(facts), true) - end - - function TestGsePolicy:test_policy_crit_evaluate_true() - local facts = { - [consts.OKAY]=1, - [consts.WARN]=1, - [consts.CRIT]=3, - [consts.DOWN]=0, - [consts.UNKW]=0, - } - assertEquals(test_policy_critical:evaluate(facts), true) - end - - function TestGsePolicy:test_policy_crit_evaluate_false() - local facts = { - [consts.OKAY]=4, - [consts.WARN]=1, - [consts.CRIT]=3, - [consts.DOWN]=0, - [consts.UNKW]=0, - } - assertEquals(test_policy_critical:evaluate(facts), false) - end - - function TestGsePolicy:test_policy_crit_evaluate_false_again() - local facts = { - [consts.OKAY]=3, - [consts.WARN]=1, - [consts.CRIT]=0, - [consts.DOWN]=0, - [consts.UNKW]=0, - } - assertEquals(test_policy_critical:evaluate(facts), false) - end - - function TestGsePolicy:test_policy_down_evaluate_true() - local facts = { - [consts.OKAY]=2, - [consts.WARN]=2, - [consts.CRIT]=0, - [consts.DOWN]=1, - [consts.UNKW]=0, - } - assertEquals(test_policy_down:evaluate(facts), true) - end - - function TestGsePolicy:test_policy_down_evaluate_false() - local facts = { - [consts.OKAY]=2, - [consts.WARN]=3, - [consts.CRIT]=0, - [consts.DOWN]=0, - [consts.UNKW]=0, - } - assertEquals(test_policy_down:evaluate(facts), false) - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse_utils.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse_utils.lua deleted file mode 100644 index 090b13844..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_gse_utils.lua +++ /dev/null @@ -1,36 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -require('luaunit') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - -local gse_utils = require('gse_utils') -local consts = require('gse_constants') - -TestGseUtils = {} - - function TestGseUtils:test_max_status() - local status = gse_utils.max_status(consts.DOWN, consts.WARN) - assertEquals(consts.DOWN, status) - local status = gse_utils.max_status(consts.OKAY, consts.WARN) - assertEquals(consts.WARN, status) - local status = gse_utils.max_status(consts.OKAY, consts.DOWN) - assertEquals(consts.DOWN, status) - local status = gse_utils.max_status(consts.UNKW, consts.DOWN) - assertEquals(consts.DOWN, status) - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_influxdb.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_influxdb.lua deleted file mode 100644 index cbcf4ebf8..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_influxdb.lua +++ /dev/null @@ -1,52 +0,0 @@ --- Copyright 2016 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -require('os') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - -local influxdb = require('influxdb') - -TestInfluxDB = {} - - function TestInfluxDB:test_ms_precision_encoder() - local encoder = influxdb.new("ms") - assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 1), 'foo value=1.000000 1000000') - assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 'bar'), 'foo value="bar" 1000000') - assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 'b"ar'), 'foo value="b\\"ar" 1000000') - assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 1, {tag2="t2",tag1="t1"}), 'foo,tag1=t1,tag2=t2 value=1.000000 1000000') - assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', {a=1, b=2}), 'foo a=1.000000,b=2.000000 1000000') - end - - function TestInfluxDB:test_second_precision_encoder() - local encoder = influxdb.new("s") - assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 1), 'foo value=1.000000 1000') - end - - function TestInfluxDB:test_us_precision_encoder() - local encoder = influxdb.new("us") - assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 1), 'foo value=1.000000 1000000000') - end - - function TestInfluxDB:test_encoder_with_bad_input() - local encoder = influxdb.new() - assertEquals(encoder:encode_datapoint(1e9 * 1000, nil, 1), '') - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) - - diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_lma_utils.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_lma_utils.lua deleted file mode 100644 index fae61f285..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_lma_utils.lua +++ /dev/null @@ -1,102 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - -function inject_message(msg) - if msg == 'fail' then - error('fail') - end -end - -function inject_payload(payload_type, payload_name, data) - if data == 'fail' then - error('fail') - end -end - -local lma_utils = require('lma_utils') - -TestLmaUtils = {} - - function TestLmaUtils:test_safe_json_encode_with_valid_data() - local ret = lma_utils.safe_json_encode({}) - assertEquals(ret, '{}') - end - - function TestLmaUtils:test_safe_inject_message_without_error() - local ret, msg = lma_utils.safe_inject_message({}) - assertEquals(ret, 0) - assertEquals(msg, nil) - end - - function TestLmaUtils:test_safe_inject_message_with_error() - local ret, msg = lma_utils.safe_inject_message('fail') - assertEquals(ret, -1) - assert(msg:match(': fail')) - end - - function TestLmaUtils:test_safe_inject_payload_without_error() - local ret, msg = lma_utils.safe_inject_payload('txt', 'foo', {}) - assertEquals(ret, 0) - assertEquals(msg, nil) - end - - function TestLmaUtils:test_safe_inject_payload_with_error() - local ret, msg = lma_utils.safe_inject_payload('txt', 'foo', 'fail') - assertEquals(ret, -1) - assert(msg:match(': fail')) - end - - function TestLmaUtils:test_truncate_with_small_string() - local ret = lma_utils.truncate('foo', 10, '
') - assertEquals(ret, 'foo') - end - - function TestLmaUtils:test_truncate_with_large_string() - local ret = lma_utils.truncate('foo and long string', 10, '
') - assertEquals(ret, 'foo and lo') - end - - function TestLmaUtils:test_truncate_with_one_delimiter() - local ret = lma_utils.truncate('foo
longstring', 10, '
') - assertEquals(ret, 'foo') - end - - function TestLmaUtils:test_truncate_with_several_delimiters_1() - local ret = lma_utils.truncate('foo
bar
longstring', 10, '
') - assertEquals(ret, 'foo') - end - - function TestLmaUtils:test_truncate_with_several_delimiters_2() - local ret = lma_utils.truncate('foo
ba
longstring', 10, '
') - assertEquals(ret, 'foo
ba') - end - - function TestLmaUtils:test_truncate_with_several_delimiters_3() - local ret = lma_utils.truncate('foo
ba
long
string', 12, '
') - assertEquals(ret, 'foo
ba') - end - - function TestLmaUtils:test_convert_to_sec() - assertEquals(lma_utils.convert_to_sec(1000000001), 1) - assertEquals(lma_utils.convert_to_sec(1999999999), 1) - assertEquals(lma_utils.convert_to_sec(2000000001), 2) - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_patterns.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_patterns.lua deleted file mode 100644 index 8f79d1044..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_patterns.lua +++ /dev/null @@ -1,122 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -require('os') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - -local patt = require('patterns') -local l = require('lpeg') - -TestPatterns = {} - - function TestPatterns:test_Uuid() - assertEquals(patt.Uuid:match('be6876f2-c1e6-42ea-ad95-792a5500f0fa'), - 'be6876f2-c1e6-42ea-ad95-792a5500f0fa') - assertEquals(patt.Uuid:match('be6876f2c1e642eaad95792a5500f0fa'), - 'be6876f2-c1e6-42ea-ad95-792a5500f0fa') - assertEquals(patt.Uuid:match('ze6876f2c1e642eaad95792a5500f0fa'), - nil) - assertEquals(patt.Uuid:match('be6876f2-c1e642eaad95792a5500f0fa'), - nil) - end - - function TestPatterns:test_Timestamp() - -- note that Timestamp:match() returns the number of nanosecs since the - -- Epoch in the local timezone - local_epoch = os.time(os.date("!*t",0)) * 1e9 - assertEquals(patt.Timestamp:match('1970-01-01 00:00:01+00:00'), - local_epoch + 1e9) - assertEquals(patt.Timestamp:match('1970-01-01 00:00:02'), - local_epoch + 2e9) - assertEquals(patt.Timestamp:match('1970-01-01 00:00:03'), - local_epoch + 3e9) - assertEquals(patt.Timestamp:match('1970-01-01T00:00:04-00:00'), - local_epoch + 4e9) - assertEquals(patt.Timestamp:match('1970-01-01 01:00:05+01:00'), - local_epoch + 5e9) - assertEquals(patt.Timestamp:match('1970-01-01 00:00:00.123456+00:00'), - local_epoch + 0.123456 * 1e9) - assertEquals(patt.Timestamp:match('1970-01-01 00:01'), - nil) - end - - function TestPatterns:test_programname() - assertEquals(l.C(patt.programname):match('nova-api'), 'nova-api') - assertEquals(l.C(patt.programname):match('nova-api foo'), 'nova-api') - end - - function TestPatterns:test_anywhere() - assertEquals(patt.anywhere(l.C(patt.dash)):match(' - '), '-') - assertEquals(patt.anywhere(patt.dash):match(' . '), nil) - end - - function TestPatterns:test_openstack() - local_epoch = os.time(os.date("!*t",0)) * 1e9 - assertEquals(patt.openstack:match( - '1970-01-01 00:00:02 3434 INFO oslo_service.periodic_task [-] Blabla...'), - {Timestamp = local_epoch + 2e9, Pid = '3434', SeverityLabel = 'INFO', - PythonModule = 'oslo_service.periodic_task', Message = '[-] Blabla...'}) - end - - function TestPatterns:test_openstack_request_context() - assertEquals(patt.openstack_request_context:match('[-]'), nil) - assertEquals(patt.openstack_request_context:match( - "[req-4db318af-54c9-466d-b365-fe17fe4adeed - - - - -]"), - {RequestId = '4db318af-54c9-466d-b365-fe17fe4adeed'}) - assertEquals(patt.openstack_request_context:match( - "[req-4db318af-54c9-466d-b365-fe17fe4adeed 8206d40abcc3452d8a9c1ea629b4a8d0 112245730b1f4858ab62e3673e1ee9e2 - - -]"), - {RequestId = '4db318af-54c9-466d-b365-fe17fe4adeed', - UserId = '8206d40a-bcc3-452d-8a9c-1ea629b4a8d0', - TenantId = '11224573-0b1f-4858-ab62-e3673e1ee9e2'}) - end - - function TestPatterns:test_openstack_http() - assertEquals(patt.openstack_http:match( - '"OPTIONS / HTTP/1.0" status: 200 len: 497 time: 0.0006731'), - {http_method = 'OPTIONS', http_url = '/', http_version = '1.0', - http_status = 200, http_response_size = 497, - http_response_time = 0.0006731}) - assertEquals(patt.openstack_http:match( - 'foo "OPTIONS / HTTP/1.0" status: 200 len: 497 time: 0.0006731 bar'), - {http_method = 'OPTIONS', http_url = '/', http_version = '1.0', - http_status = 200, http_response_size = 497, - http_response_time = 0.0006731}) - end - - function TestPatterns:test_openstack_http_with_extra_space() - assertEquals(patt.openstack_http:match( - '"OPTIONS / HTTP/1.0" status: 200 len: 497 time: 0.0006731'), - {http_method = 'OPTIONS', http_url = '/', http_version = '1.0', - http_status = 200, http_response_size = 497, - http_response_time = 0.0006731}) - assertEquals(patt.openstack_http:match( - 'foo "OPTIONS / HTTP/1.0" status: 200 len: 497 time: 0.0006731 bar'), - {http_method = 'OPTIONS', http_url = '/', http_version = '1.0', - http_status = 200, http_response_size = 497, - http_response_time = 0.0006731}) - end - - function TestPatterns:test_ip_address() - assertEquals(patt.ip_address:match('192.168.1.2'), - {ip_address = '192.168.1.2'}) - assertEquals(patt.ip_address:match('foo 192.168.1.2 bar'), - {ip_address = '192.168.1.2'}) - assertEquals(patt.ip_address:match('192.1688.1.2'), nil) - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_table_utils.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_table_utils.lua deleted file mode 100644 index b450f4ee4..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_table_utils.lua +++ /dev/null @@ -1,86 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" - -local table_utils = require('table_utils') - -TestTableUtils = {} - - function TestTableUtils:setUp() - self.array = { 'a', 'b', 'c' } - self.dict = { c='C', a='A', b='B' } - end - - function TestTableUtils:test_item_pos_with_match() - assertEquals(table_utils.item_pos('b', self.array), 2) - end - - function TestTableUtils:test_item_pos_without_match() - assertEquals(table_utils.item_pos('z', self.array), nil) - end - - function TestTableUtils:test_item_find_with_match() - assertEquals(table_utils.item_find('b', self.array), true) - end - - function TestTableUtils:test_item_find_without_match() - assertEquals(table_utils.item_find('z', self.array), false) - end - - function TestTableUtils:test_deep_copy() - local copy = table_utils.deepcopy(self.array) - assertEquals(#copy, #self.array) - assertEquals(copy[1], self.array[1]) - assertEquals(copy[2], self.array[2]) - assertEquals(copy[3], self.array[3]) - assert(copy ~= self.array) - end - - function TestTableUtils:test_orderedPairs() - local t = {} - for k,v in table_utils.orderedPairs(self.dict) do - t[#t+1] = { k=k, v=v } - end - assertEquals(#t, 3) - assertEquals(t[1].k, 'a') - assertEquals(t[1].v, 'A') - assertEquals(t[2].k, 'b') - assertEquals(t[2].v, 'B') - assertEquals(t[3].k, 'c') - assertEquals(t[3].v, 'C') - end - - function TestTableUtils:test_table_equal_with_equal_keys_and_values() - assertTrue(table_utils.table_equal({a = 'a', b = 'b'}, {a = 'a', b = 'b'})) - end - - function TestTableUtils:test_table_equal_with_nonequal_values() - assertFalse(table_utils.table_equal({a = 'a', b = 'b'}, {a = 'a', b = 'c'})) - end - - function TestTableUtils:test_table_equal_with_nonequal_keys_1() - assertFalse(table_utils.table_equal({a = 'a', b = 'b'}, {a = 'a', c = 'b'})) - end - - function TestTableUtils:test_table_equal_with_nonequal_keys_2() - assertFalse(table_utils.table_equal({a = 'a', b = 'b'}, - {a = 'a', b = 'b', c = 'c'})) - end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_value_matching.lua b/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_value_matching.lua deleted file mode 100644 index fc7d75415..000000000 --- a/deployment_scripts/puppet/modules/lma_collector/tests/lua/test_value_matching.lua +++ /dev/null @@ -1,229 +0,0 @@ --- Copyright 2015 Mirantis, Inc. --- --- 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. - -EXPORT_ASSERT_TO_GLOBALS=true -require('luaunit') -package.path = package.path .. ";files/plugins/common/?.lua;tests/lua/mocks/?.lua" -local M = require('value_matching') - -TestValueMatching = {} - -function TestValueMatching:test_simple_matching() - local tests = { - {'/var/log', '/var/log'}, - {'== /var/log', '/var/log'}, - {'==/var/log', '/var/log'}, - {'==/var/log ', '/var/log'}, - {'==\t/var/log', '/var/log'}, - {'=="/var/log"', '/var/log'}, - {'== "/var/log"', '/var/log'}, - {'== " /var/log"', ' /var/log'}, - {'== "/var/log "', '/var/log '}, - {'== " /var/log "', ' /var/log '}, - {8, 8}, - {8, '8'}, - {"9", "9"}, - {"==10", " 10"}, - {"10", 10}, - {"== 10", " 10"}, - {"== 10.0", " 10.0"}, - {"== -10.01", " -10.01"}, - {"== 10 ", " 10 "}, - {' <=11', '-11'}, - {"!= -12", 42}, - {"!= 12", 42}, - {" > 13", 42}, - {">= 13", 13}, - {">= -13", 42}, - {"< 14", -0}, - {"<= 14 ", 0}, - {"<= 14", "14"}, - } - local r - for _, v in ipairs(tests) do - local exp, value = v[1], v[2] - local m = M.new(exp) - r = m:matches(value) - assertTrue(r) - end -end - -function TestValueMatching:test_simple_not_matching() - local tests = { - {'/var/log', '/var/log/mysql'}, - {'== "/var/log"' , '/var/log '}, - {'"/var/log"', '/var/log '}, - {'"/var/log "', '/var/log'}, - {'nova-api', 'nova-compute'}, - {'== /var/log', '/var/log/mysql'}, - {'==/var/log', '/var/log/mysql'}, - {'!=/var/log', '/var/log'}, - {'!= /var/log', '/var/log'}, - {'>10', '5'}, - {'> 10', '5 '}, - {' <11', '11'}, - {' >=11', '-11'}, - {' >=11 && <= 42', '-11'}, - {' >=11 || == 42', '-11'}, - } - - for _, v in ipairs(tests) do - local exp, value = v[1], v[2] - local m = M.new(exp) - r = m:matches(value) - assertFalse(r) - end -end - -function TestValueMatching:test_string_matching() - local tests = { - {'== "foo.bar"', "foo.bar", true}, - {'== foo.bar', "foo.bar", true}, - {'== foo.bar ', "foo.bar", true}, - {'== foo || bar', "bar", true}, - {'== foo || bar', "foo", true}, - {'== foo || bar', "??", false}, - {'!= foo || != bar', "42", true}, - } - - for _, v in ipairs(tests) do - local exp, value, expected = v[1], v[2], v[3] - local m = M.new(exp) - r = m:matches(value) - assertEquals(r, expected) - end - -end - -function TestValueMatching:test_invalid_expression() - local tests = { - '&& 1 && 1', - ' && 1', - '|| == 1', - '&& != 12', - ' ', - ' ', - '\t', - '', - nil, - } - for _, exp in ipairs(tests) do - assertError(M.new, exp) - end -end - -function TestValueMatching:test_range_matching() - local tests = { - {'>= 200 && < 300', 200, true}, - {'>=200&&<300' , 200, true}, - {' >=200&&<300' , 200, true}, - {'>= 200 && < 300', 204, true}, - {'>= 200 && < 300', 300, false}, - {'>= 200 && < 300', 42, false}, - {'>= 200 && < 300', 0, false}, - } - - for _, v in ipairs(tests) do - local exp, value, expected = v[1], v[2], v[3] - local m = M.new(exp) - r = m:matches(value) - assertEquals(r, expected) - end -end - -function TestValueMatching:test_wrong_data() - local tests = { - {'>= 200 && < 300', "foo", false}, - {'>= 200 && < 300', "" , false}, - {'== 200' , "bar", false}, - {'== foo' , "10" , false}, - {'!= foo' , " 10", true}, - } - for _, v in ipairs(tests) do - local exp, value, expected = v[1], v[2], v[3] - local m = M.new(exp) - r = m:matches(value) - assertEquals(r, expected) - end -end - -function TestValueMatching:test_precedence() - local tests = { - {'>= 200 && < 300 || >500', "200", true}, - {'>= 200 && < 300 || >500', "501", true}, - {'>= 200 && < 300 || >=500', "500", true}, - {'>400 || >= 200 && < 300', "500", true}, - {'>=300 && <500 || >= 200 && < 300', "300", true}, - {'>=300 && <500 || >= 200 && < 300', "500", false}, - } - - for _, v in ipairs(tests) do - local exp, value, expected = v[1], v[2], v[3] - local m = M.new(exp) - r = m:matches(value) - assertEquals(r, expected) - end -end - -function TestValueMatching:test_pattern_matching() - local tests = { - {'=~ /var/lib/ceph/osd/ceph%-%d+', "/var/lib/ceph/osd/ceph-1", true}, - {'=~ /var/lib/ceph/osd/ceph%-%d+', "/var/lib/ceph/osd/ceph-42", true}, - {'=~ ^/var/lib/ceph/osd/ceph%-%d+$', "/var/lib/ceph/osd/ceph-42", true}, - {'=~ "/var/lib/ceph/osd/ceph%-%d+"', "/var/lib/ceph/osd/ceph-42", true}, - {'=~ "ceph%-%d+"', "/var/lib/ceph/osd/ceph-42", true}, - {'=~ "/var/lib/ceph/osd/ceph%-%d+$"', "/var/lib/ceph/osd/ceph-42 ", false}, -- trailing space - {'=~ /var/lib/ceph/osd/ceph%-%d+', "/var/log", false}, - {'=~ /var/lib/ceph/osd/ceph%-%d+ || foo', "/var/lib/ceph/osd/ceph-1", true}, - {'=~ "foo||bar" || foo', "foo||bar", true}, - {'=~ "foo||bar" || foo', "foo", true}, - {'=~ "foo&&bar" || foo', "foo&&bar", true}, - {'=~ "foo&&bar" || foo', "foo", true}, - {'=~ bar && /var/lib/ceph/osd/ceph%-%d+', "/var/lib/ceph/osd/ceph-1", false}, - {'=~ -', "-", true}, - {'=~ %-', "-", true}, - {'!~ /var/lib/ceph/osd/ceph', "/var/log", true}, - {'!~ /var/lib/ceph/osd/ceph%-%d+', "/var/log", true}, - {'!~ .+osd%-%d+', "/var/log", true}, - {'!~ osd%-%d+', "/var/log", true}, - --{'=~ [', "[", true}, - } - - for _, v in ipairs(tests) do - local exp, value, expected = v[1], v[2], v[3] - local m = M.new(exp) - r = m:matches(value) - assertEquals(r, expected) - end -end - -function TestValueMatching:test_wrong_patterns_never_match() - -- These patterns raise errors like: - -- malformed pattern (missing ']') - local tests = { - {'=~ [', "[", false}, - {'!~ [', "[", false}, - } - - for _, v in ipairs(tests) do - local exp, value, expected = v[1], v[2], v[3] - local m = M.new(exp) - r = m:matches(value) - assertEquals(r, expected) - end -end - -lu = LuaUnit -lu:setVerbosity( 1 ) -os.exit( lu:run() ) diff --git a/deployment_tasks.yaml b/deployment_tasks.yaml deleted file mode 100644 index b693c42c1..000000000 --- a/deployment_tasks.yaml +++ /dev/null @@ -1,167 +0,0 @@ -# Tasks definitions for the deployment -# #################################### -# The OCF script should exist before any nodes try to configure the -# collector services with Pacemaker. -- id: install-ocf-script - type: puppet - version: 2.0.0 - groups: ["/(primary-)?(controller|standalone-database|standalone-rabbitmq)/"] - requires: [fuel_pkgs] - # Required for the cluster tasks when the environment is scaled up - required_for: [primary-cluster, cluster] - parameters: - puppet_manifest: puppet/manifests/install_ocf_script.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 120 - -# Tasks definitions for the post-deployment -# ######################################### - -# The Hiera data needs to be populated first so that other plugins (eg LMA -# Infrastructure Alerting) can use it. -- id: lma-hiera-override - type: puppet - version: 2.0.0 - requires: [post_deployment_start] - required_for: [post_deployment_end] - role: '*' - parameters: - puppet_manifest: puppet/manifests/hiera_override.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - -- id: lma-configure-apt - type: puppet - version: 2.0.0 - # We use upload_nodes_info as an anchor to order the post-deployment tasks executed - # by this plugin and the InfluxDB & Elasticsearch plugins. The dependency chain is: - # Other plugins tasks -> upload_nodes_info -> (LMA collector tasks) - requires: [post_deployment_start, upload_nodes_info, lma-hiera-override] - required_for: [post_deployment_end] - role: '*' - parameters: - puppet_manifest: puppet/manifests/configure_apt.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - -- id: lma-base - type: puppet - version: 2.0.0 - requires: [lma-configure-apt] - required_for: [post_deployment_end] - role: '*' - parameters: - puppet_manifest: puppet/manifests/base.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - -- id: lma-collectd - type: puppet - version: 2.0.0 - requires: [lma-base] - required_for: [post_deployment_end] - role: '*' - parameters: - puppet_manifest: puppet/manifests/collectd.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - -# All tasks lma-main-* must be executed before lma-aggregator. So we don't -# need to add a requirement to post_deployment_end because it is implied -# by the one to lma-aggregator. -- id: lma-main-controller - type: puppet - version: 2.0.0 - requires: [lma-base, lma-collectd] - required_for: [lma-aggregator] - role: [controller, primary-controller] - parameters: - puppet_manifest: puppet/manifests/controller.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - -- id: lma-main-compute - type: puppet - version: 2.0.0 - requires: [lma-base, lma-collectd] - required_for: [lma-aggregator] - role: [compute] - parameters: - puppet_manifest: puppet/manifests/compute.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - -- id: lma-main-cinder - type: puppet - version: 2.0.0 - requires: [lma-base, lma-collectd] - required_for: [lma-aggregator] - role: [cinder] - parameters: - puppet_manifest: puppet/manifests/cinder.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - -- id: lma-aggregator - type: puppet - version: 2.0.0 - requires: [lma-base, lma-collectd] - required_for: [post_deployment_end] - role: '*' - parameters: - puppet_manifest: puppet/manifests/aggregator.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - -- id: lma-configure-afd-filters - type: puppet - version: 2.0.0 - requires: [lma-aggregator] - # Required for post_deployment_end is induced by lma-cleanup-apt-config - required_for: [lma-cleanup-apt-config] - role: '*' - # The AFD filters shouldn't send data before the aggregator service is - # configured on all the controllers, hence the cross-depends parameter that - # is required when running in a task-based deployment mode. - cross-depends: - - name: lma-aggregator - role: [primary-controller, controller] - parameters: - puppet_manifest: puppet/manifests/configure_afd_filters.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes - - -# This task must be executed at the very end of the deployment. -- id: lma-cleanup-apt-config - type: puppet - version: 2.0.0 - # We use update_hosts as an anchor to order the post-deployment tasks - # executed by the LMA infrastructure plugin. The dependency chain is: - # LMA collector tasks -> update_hosts -> (LMA Infrastructure Alerting tasks) - required_for: [post_deployment_end, update_hosts] - role: '*' - parameters: - puppet_manifest: puppet/manifests/cleanup_apt_config.pp - puppet_modules: puppet/modules:/etc/puppet/modules - timeout: 600 - reexecute_on: - - deploy_changes diff --git a/doc/.gitignore b/doc/.gitignore deleted file mode 100644 index 8d60ee62c..000000000 --- a/doc/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build/ -images/*.pdf diff --git a/doc/dev/Makefile b/doc/dev/Makefile deleted file mode 100644 index 5cad1b569..000000000 --- a/doc/dev/Makefile +++ /dev/null @@ -1,191 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# SVG to PDF conversion -SVG2PDF = inkscape -SVG2PDF_FLAGS = -# Build a list of SVG files to convert to PDF -PDF_FILES := $(foreach dir, images, $(patsubst %.svg,%.pdf,$(wildcard $(dir)/*.svg))) - - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - rm -f $(PDF_FILES) - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/LMAcollector.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/LMAcollector.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/LMAcollector" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/LMAcollector" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: $(PDF_FILES) - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: $(PDF_FILES) - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -# Rule for building the PDF files only -images: $(PDF_FILES) - -# Pattern rule for converting SVG to PDF -%.pdf : %.svg - $(SVG2PDF) -f $< -A $@ diff --git a/doc/dev/source/_static/.gitkeep b/doc/dev/source/_static/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/doc/dev/source/common_message_format.rst b/doc/dev/source/common_message_format.rst deleted file mode 100644 index 9f97d873d..000000000 --- a/doc/dev/source/common_message_format.rst +++ /dev/null @@ -1,53 +0,0 @@ -.. _common_message_format: - -===================== -Common Message Format -===================== - -Heka turns the incoming data into Heka messages [#]_ with a well-defined format -which is described below. - -* **Timestamp** (number), the timestamp of the message (in nanoseconds since the - Epoch). - -* **Logger** (string), the datasource from the Heka's standpoint. - -* **Type** (string), the type of message. - -* **Hostname** (string), the name of the host that emitted the message. - -* **Severity** (number), severity level as defined by the Syslog `RFC - 5424 `_. - -* **Payload** (string), the input data in most cases. - -* **Pid** (number), the Process ID that generated the message. - -* **Fields**, array of Field structures (see below). - -Field Format -============ - -Every message (either originating from logs, metrics or notifications) is -populated with a set of predefined fields: - -Attributes in **bold** are always present in the messages while attributes in -*italic* are optional. - -* **deployment_id** (number), the deployment identifier of the Fuel - environment. - -* **openstack_region** (string), the name of the OpenStack region. - -* **openstack_release** (string), the name of the OpenStack release. - -* **openstack_roles** (string), a comma-separated list of the node's roles (eg - 'controller', 'compute,cinder'). - -* **environment_label** (string), the label assigned to the OpenStack - environment. - -.. note:: All date/time fields represented as string are formatted according - to the `RFC3339 `_ document. - -.. [#] `Heka message structure `_ diff --git a/doc/dev/source/conf.py b/doc/dev/source/conf.py deleted file mode 100644 index 9949f73b4..000000000 --- a/doc/dev/source/conf.py +++ /dev/null @@ -1,33 +0,0 @@ -import sys -import os -extensions = [] -templates_path = ['_templates'] -source_suffix = '.rst' -master_doc = 'index' -project = u'The LMA Collector Developer Documentation' -copyright = u'2015, Mirantis Inc.' -version = '0.9' -release = '0.9.0' -exclude_patterns = [ -] -pygments_style = 'sphinx' -html_theme = 'default' -html_static_path = ['_static'] -htmlhelp_basename = 'LMAcollectordevdoc' -latex_elements = { -} -latex_documents = [ - ('index', 'LMAcollectorDev.tex', u'The LMA Collector Developer Documentation', - u'Mirantis Inc.', 'manual'), -] -man_pages = [ - ('index', 'lmacollector', u'The LMA Collector Developer Documentation', - [u'Mirantis Inc.'], 1) -] -texinfo_documents = [ - ('index', 'LMAcollector', u'The LMA Collector Developer Documentation', - u'Mirantis Inc.', 'LMAcollector', 'One line description of project.', - 'Miscellaneous'), -] -latex_elements = {'classoptions': ',openany,oneside', 'babel': - '\\usepackage[english]{babel}'} diff --git a/doc/dev/source/index.rst b/doc/dev/source/index.rst deleted file mode 100644 index 6ac79a158..000000000 --- a/doc/dev/source/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -======================================================================== -Welcome to the Mirantis OpenStack LMA Collector Developer Documentation! -======================================================================== - -.. toctree:: - :maxdepth: 2 - - overview - common_message_format - logs - notifications - metrics - outputs - install_without_fuel - tests - -Indices and Tables -================== - -* :ref:`search` diff --git a/doc/dev/source/install_without_fuel.rst b/doc/dev/source/install_without_fuel.rst deleted file mode 100644 index 6e2dafc08..000000000 --- a/doc/dev/source/install_without_fuel.rst +++ /dev/null @@ -1,109 +0,0 @@ -Installation without Fuel -========================= - -This section provides instructions and hints on how the LMA Collector service -can be deployed without using the Fuel plugin package. For instance, the Fuel -version that you are running isn't compatible with the current release of the -LMA Collector or you want to have more control on the configuration of the LMA -Collector. - -In such situations, it is possible to leverage directly the Puppet modules and -write your own Puppet manifests to configure and run the LMA Collector service -on the OpenStack nodes. - -Pre-requisites -^^^^^^^^^^^^^^ - -* The nodes are already deployed with the OpenStack services. - -* The nodes can download and install packages from a repository server that you - manage. - -* Configuration management is done with Puppet >= 3.x. Both `master and - masterless methods - `_ - are supported. - -* You have already written the main Puppet manifests. You can have a look at the - `reference documentation - `_ - and at the `examples - `_ - of the `lma_collector` Puppet module. - -* The satellite clusters (Elasticsearch/Kibana, InfluxDB/Grafana and Nagios) - are already deployed and the nodes where LMA Collectors run have access - to them. - -Download the packages -^^^^^^^^^^^^^^^^^^^^^ - -Before running the Puppet manifests, you have to make sure that the nodes will -be able to download and install the necessary packages. - -This small script will get you started: - -.. code-block:: bash - - WORK_DIR=/tmp/lma_collector - PACKAGES_DIR=${WORK_DIR}/packages - mkdir -p ${PACKAGES_DIR} - rm -rf ${PACKAGES_DIR:?}/* - pushd $WORK_DIR - git clone https://github.com/openstack/fuel-plugin-lma-collector.git - cd fuel-plugin-lma-collector - ./pre_build_hook - cp ./repositories/ubuntu/*.deb ${PACKAGES_DIR} - (cd ${PACKAGES_DIR} && dpkg-scanpackages . > Packages) - echo "The packages directory is available at ${PACKAGES_DIR}" - popd - -Then you should copy the `packages` directory to your local repository server -and update the APT configuration on the deployed nodes accordingly to enable -the new source repository. - -Building the Puppet modules -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You have to build locally the `lma_collector` and `heka` Puppet modules because -they aren't yet available from PuppetForge. - -.. code-block:: bash - - WORK_DIR=/tmp/lma_collector - mkdir -p ${WORK_DIR} - rm -rf ${WORK_DIR:?}/* - pushd $WORK_DIR - git clone https://github.com/openstack/fuel-plugin-lma-collector.git - cd fuel-plugin-lma-collector/deployment_scripts/puppet/modules/ - for module in heka lma_collector - do - pushd $module - puppet module build - cp pkg/*.tar.gz ${WORK_DIR} - popd - done - echo "The Puppet modules are available at ${WORK_DIR}" - popd - -Installing the Puppet modules -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -After building the `lma_collector` and `heka` Puppet modules, you need to -install them on your Puppet master or on all the nodes (in case of masterless -installation). - -.. code-block:: bash - - puppet module install mirantis-heka-1.0.0.tar.gz - puppet module install mirantis-lma_collector-1.0.0.tar.gz - -Running the main Puppet manifest(s) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Finally you can run your main Puppet manifest(s). For the masterless case, it -would mean executing the `puppet apply` command similar to this snippet: - -.. code-block:: bash - - puppet apply /etc/puppet/manifests/ diff --git a/doc/dev/source/logs.rst b/doc/dev/source/logs.rst deleted file mode 100644 index 7f74ffa03..000000000 --- a/doc/dev/source/logs.rst +++ /dev/null @@ -1,83 +0,0 @@ -.. _logs: - -============ -Log Messages -============ - -The Heka collector service is configured to tail the following log files: - -* System logs. - - * ``/var/log/syslog`` - * ``/var/log/messages`` - * ``/var/log/debug`` - * ``/var/log/auth.log`` - * ``/var/log/cron.log`` - * ``/var/log/daemon.log`` - * ``/var/log/kern.log`` - * ``/var/log/pacemaker.log`` - -* MySQL server logs (for controller nodes). - -* RabbitMQ server logs (for controller nodes). - -* Pacemaker logs (for controller nodes). - -* OpenStack logs. - -* Open vSwitch logs (all nodes). - - * ``/var/log/openvswitch/ovsdb-server.log`` - * ``/var/log/openvswitch/ovs-vswitchd.log`` - -Log Messages Format -=================== - -In addition to the common :ref:`common_message_format`, log-based messages have -additional properties. - -Attributes in **bold** are always present in the messages while attributes in -*italic* are optional. - -* **Logger** (string), ``system.``, ``mysql`` or - ``openstack.``. - -* **Type** (string), always ``log``. - -* **Fields** - - * **severity_label** (string), the textual representation of the severity - level. - - * *programname* (string), the application name for Syslog-based messages, or - the OpenStack service daemon name for OpenStack log messages (eg - "nova-compute"). - - * *syslogfacility* (number), the Syslog facility for Syslog-based messages. - - * *python_module* (string), the Python module that generated the log message - for OpenStack service logs. - - * *http_method* (string), the HTTP method (for instance 'GET'). - - * *http_client_ip_address* (string), the IP address of the client that - originated the HTTP request. - - * *http_response_size* (number), the size of the HTTP response (in bytes). - - * *http_response_time* (number), the HTTP response time (in seconds). - - * *http_status* (string), the HTTP response status. - - * *http_url* (string), the requested HTTP URL. - - * *http_version* (string), the HTTP version (eg '1.1). - - * *request_id* (string), the UUID of the OpenStack request to which the - message applies. - - * *tenant_id* (string), the UUID of the OpenStack tenant to which the message - applies. - - * *user_id* (string), the UUID of the OpenStack user to which the message - applies. diff --git a/doc/dev/source/metrics.rst b/doc/dev/source/metrics.rst deleted file mode 100644 index 9544d0de8..000000000 --- a/doc/dev/source/metrics.rst +++ /dev/null @@ -1,79 +0,0 @@ -.. _metrics: - -=============== -Metric Messages -=============== - -Metrics are extracted from several sources: - -* Data received from collectd. - -* Log messages processed by the collector service. - -* OpenStack notifications processed by the collector service. - -Metric Messages Format -====================== - -In addition to the common :ref:`common_message_format`, metric messages have -additional properties. - -Attributes in **bold** are always present in the messages while attributes in -*italic* are optional. - -* **Logger** (string), the datasource from the Heka's standpoint, it can be - ``collectd``, ``notification_processor`` or ``http_log_parser``. - -* **Type** (string) - - * ``metric`` or ``heka.sandbox.metric`` for the single-value metrics. - - * ``heka.sandbox.multivalue_metric`` for the multi-valued metrics (eg annotations). - - * ``heka.sandbox.bulk_metric`` for the metrics sent by bulk. - - * ``heka.sandbox.afd_service_metric`` for the AFD service metrics. - - * ``heka.sandbox.afd_node_metric`` for the AFD node metrics. - - * ``heka.sandbox.gse_service_cluster_metric`` for the GSE service cluster metrics. - - * ``heka.sandbox.gse_node_cluster_metric`` for the GSE node cluster metrics. - - * ``heka.sandbox.gse_cluster_metric`` for the GSE global cluster metrics. - -* **Severity** (number), it is always equal to 6 (INFO). - -* **Fields** - - * **name** (string), the name of the metric. See the `User Documentation`_ for the - current metric names that are emitted. - - * **value** (number), the value associated to the metric. - - * **type** (string), the metric's type, either ``gauge`` (a value that can go - up or down), ``counter`` (an always increasing value) or ``derive`` (a - per-second rate). - - * **source** (string), the source from where the metric comes from, it can be - the name of the collectd plugin, ``-api`` for HTTP response metrics. - - * **hostname** (string), the name of the host to which the metric applies. It - may be different from the ``Hostname`` value. For instance when the metric is - extracted from an OpenStack notification, ``Hostname`` is the host that - captured the notification and ``Fields[hostname]`` is the host that emitted - the notification. - - * *interval* (number), the interval at which the metric is emitted (for - the ``collectd`` metrics). - - * *tenant_id* (string), the UUID of the OpenStack tenant to which the metric - applies. - - * *user_id* (string), the UUID of the OpenStack user to which the metric - applies. - -Metric messages may include additional fields to specify the scope of the -measurement. Refer to the `User Documentation`_ for more details. - -.. _User Documentation: http://fuel-plugin-lma-collector.readthedocs.io/en/latest/appendix_b.html diff --git a/doc/dev/source/notifications.rst b/doc/dev/source/notifications.rst deleted file mode 100644 index bdbf23616..000000000 --- a/doc/dev/source/notifications.rst +++ /dev/null @@ -1,88 +0,0 @@ -.. _notifications: - -===================== -Notification Messages -===================== - -OpenStack services can be configured to send notifications on the message bus -about the executing task or the state of the cloud resources [#]_. These -notifications are received by the LMA collector service and turned into Heka -messages. - -Notification Messages Format -============================ - -In addition to the :ref:`common_message_format`, notification-based messages -have additional properties. - -Attributes in **bold** are always present in the messages while attributes in -*italic* are optional. - -* **Logger** (string), the OpenStack service that emitted the notification, - (eg, ``nova``). - -* **Payload** (string), the payload of the OpenStack notification. - -* **Hostname** (string), the name of the host that originated the notification. - -* **Type** (string), always ``notification``. - -* **Fields** - - * **hostname** (string), the name of the host that originated the - notification. - - * **publisher** (string), the name of the underlying service that emitted the - notification (eg, ``scheduler``). - - * **severity_label** (string), the textual representation of the severity - level. - - * **event_type** (string), the notification's type (eg - ``compute.instance.create.end``). - - * *tenant_id* (string), the UUID of the OpenStack tenant to which the message - applies. - - * *user_id* (string), the UUID of the OpenStack user to which the message - applies. - - * *instance_id* (string), the UUID of the virtual instance to which the - message applies. - - * *image_name* (string), the image used by the image. - - * *display_name* (string), the visible name of the resource. - - * *instance_type* (string), the type of instance (eg ``m1.small``). - - * *availability_zone* (string), the availability zone of the instance. - - * *vcpus* (number), the number of VCPU provisioned for the instance. - - * *memory_mb* (number), the amount of RAM provisioned for the instance. - - * *disk_gb* (number), the disk space provisioned for the instance. - - * *old_state* (string), the previous state of the instance (eg ``building``). - - * *state* (string), the state of the instance (eg ``active``). - - * *old_task_state* (string), the previous task state for the instance (eg - ``block_device_mapping``). - - * *new_task_state* (string), the new task state for the instance (eg - ``spawning``). - - * *created_at* (string): the date of creation of the instance. - - * *launched_at* (string): the date when the instance was effectively - launched. - - * *deleted_at* (string): the date of deletion of the instance. - - * *terminated_at* (string): the date when the instance was effectively - terminated. - -.. [#] - `OpenStack notifications `_ diff --git a/doc/dev/source/outputs.rst b/doc/dev/source/outputs.rst deleted file mode 100644 index f6eab435d..000000000 --- a/doc/dev/source/outputs.rst +++ /dev/null @@ -1,82 +0,0 @@ -.. _outputs: - -================== -Supported Outputs -================== - -The LMA collector can forward part or all of the processed Heka messages to any -kind of external system, provided that the system supports a protocol-based -interface such as HTTP, SMTP or AMQP. - -The supported backends are described hereunder. - -.. _elasticsearch_output: - -Elasticsearch -============= - -The LMA collector is able to send :ref:`logs` and :ref:`notifications` to -`Elasticsearch `_. - -There is one index per day and per type of message: - -* Index for log messages is ``log-``. - -* Index for notification messages is ``notification-``. - -.. _influxdb_output: - -InfluxDB -======== - -The LMA collector is able to send :ref:`metrics` to `InfluxDB -`_. - -A metric message is stored into a measurement whose name is taken from -`Fields[name]`. The datapoint's timestamp is taken from the `Timestamp` field -and `Fields[value]` is stored as the `value` field. Note that numerical values -are always encoded as float numbers. - -Some tags are associated to all measurements: - -* `deployment_id` - -* `hostname` - -If the metric message contains a non-empty `Fields[tag_fields]` list, the -items listed in this field are encoded as additional key-value tags. - -For instance, lets take the following Heka message:: - - 2015/09/15 16:16:05 - :Timestamp: 2015-09-15 16:15:37.645999872 +0000 UTC - :Type: metric - :Hostname: node-1 - :Pid: 15595 - :Uuid: e67f91c5-259b-489f-adfa-8eea0b389eb2 - :Logger: collectd - :Payload: {"type":"cpu","values":[0],"type_instance":"idle","dsnames":["value"], - "plugin":"cpu","time":1442333737.646,"interval":10,"host":"node-1", - "dstypes":["derive"],"plugin_instance":"0"} - :EnvVersion: - :Severity: 6 - :Fields: - | name:"type" type:string value:"derive" - | name:"source" type:string value:"cpu" - | name:"deployment_id" type:string value:"1" - | name:"openstack_roles" type:string value:"primary-controller" - | name:"openstack_release" type:string value:"2015.1.0-7.0" - | name:"tag_fields" type:string value:"cpu_number" - | name:"openstack_region" type:string value:"RegionOne" - | name:"name" type:string value:"cpu_idle" - | name:"hostname" type:string value:"node-1" - | name:"value" type:double value:0 - | name:"environment_label" type:string value:"deploy_lma_infra_alerting_ha" - | name:"interval" type:double value:10 - | name:"cpu_number" type:string value:"95" - -Using the InfluxDB line protocol, it would be encoded like this:: - - cpu_idle,cpu_number=0,deployment_id=1,hostname=node-1 value=95.000000 1442333737645 - - diff --git a/doc/dev/source/overview.rst b/doc/dev/source/overview.rst deleted file mode 100644 index 2c404c651..000000000 --- a/doc/dev/source/overview.rst +++ /dev/null @@ -1,68 +0,0 @@ -Overview -======== - -The Mirantis OpenStack LMA (Logging, Monitoring and Alerting) Toolchain is comprised -of a collection of open-source tools to help you monitor and diagnose problems in your -OpenStack environment. These tools are packaged and delivered as `Fuel plugins -`_ you can install from within the -graphic user interface of Fuel starting with Mirantis OpenStack version 6.1. - -From a high level view, the LMA Toolchain includes: - -* The LMA Collector (or just the Collector) to gather all operational data that we - think are relevant to increase the **operational visibility** over your OpenStack - environment. Those data are collected from a variety of sources including the log messages, - `collectd `_, and the `OpenStack notifications bus `_ -* Pluggable external systems we call **satellite clusters** which can take action on the - data received from the Collectors running on the OpenStack nodes. - -The Collector is best described as a **pluggable message processing and routing pipeline**. -Its core components are : - -* Collectd that is bundled with a collection of monitoring plugins. Many of them are purpose-built - for OpenStack. -* `Heka `_ which is the cornerstone component - of the Collector. -* A collection of Heka plugins written in Lua to decode, process and encode the data to be sent - to external systems. - -The primary function of the Collector is to transform the acquired raw -operational data into an internal message representation that is based on the -`Heka message structure `_. -that can be further exploited to, for example, detect anomalies or create -new metric messages. - -The satellite clusters delivered as part of the LMA Toolchain starting with Mirantis OpenStack 6.1 include: - -* `Elasticsearch `_, a powerful open source search server based - on Lucene and analytics engine that makes data like log messages and notifications easy to explore and analyse. -* `InfluxDB `_, an open-source and distributed time-series database to store and search metrics. - -By combining Elasticsearch with `Kibana `_, -the LMA Toolchain provides an effective way to search and correlate all service-affecting events -that occurred in the system for root cause analysis. - -Likewise, by combining InfluxDB with `Grafana `_, the LMA Toolchain -brings you insightful metrics analytics to visualise how OpenStack behaves over time. -This includes metrics for the OpenStack services status and a variety of resource usage -and performance indicators. The ability to visualise time-series over a period of time that -can vary from 5 minutes to the last 30 days helps anticipating failure conditions and plan -capacity ahead of time to cope with a changing demand. - -Furthermore, the LMA Toolchain has been designed with the dual objective to be both insightful and adaptive. - -It is, for example, quite possible (without any code change) to integrate the Collector -with an external monitoring application like Nagios. This could simply be done through enabling -the Nagios output plugin of Heka for a subset of messages matching the -`message matcher `_ -syntax of the output plugin. You should probably not modify the configuration of the LMA -Collector manually but apply any configuration change to the Puppet manifests that are shipped -with the LMA Collector plugin for Fuel. Many other integration combinations are possible thanks -to the extreme flexibility of Heka. - -We recommend you to read the Heka `documentation `_ -to become more familiar with that technology. - -The rest of this document is organised in several chapters that will take you through a -description of the internal message structure for the categories of operational data -that are handled by the LMA Toolchain. diff --git a/doc/dev/source/tests.rst b/doc/dev/source/tests.rst deleted file mode 100644 index 3edf57aa9..000000000 --- a/doc/dev/source/tests.rst +++ /dev/null @@ -1,15 +0,0 @@ -Running tests -------------- - -You need to have `tox` and `bundler` installed for running the tests. - -Quickstart for Ubuntu Trusty:: - - apt-get install tox ruby ruby1.9.1-dev - gem install bundler - tox - -For `tox` to run the Lua unit tests included in the ``lma_collector`` Puppet -module additional system packages are required:: - - apt-get install cmake lua5.1 liblua5.1 liblua5.1-dev lua-cjson lua-unit diff --git a/doc/images/AFD_and_GSE_message_flow.svg b/doc/images/AFD_and_GSE_message_flow.svg deleted file mode 100755 index d164467a8..000000000 --- a/doc/images/AFD_and_GSE_message_flow.svg +++ /dev/null @@ -1,1056 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GSE ServiceCluster Plugin - GSE NodeCluster Plugin - GSE GlobalCluster Plugin - - diff --git a/doc/images/collector_settings.png b/doc/images/collector_settings.png deleted file mode 100644 index c5a1ad6bfef90ec65db199360963cc9d487c9018..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113862 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 diff --git a/doc/images/toolchain_map.png b/doc/images/toolchain_map.png deleted file mode 100644 index 5da5fd27b4d3d8d1032fd33fbdf40c3dc6aa0ea4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1105154 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%0A9fr`Ih+dZrC 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 Pz&~XLjq3&1Zu<WZ#gsTI diff --git a/doc/qa/Makefile b/doc/qa/Makefile deleted file mode 100644 index 77c31e966..000000000 --- a/doc/qa/Makefile +++ /dev/null @@ -1,177 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/LMAcollector.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/LMAcollector.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/LMAcollector" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/LMAcollector" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/qa/source/_static/.gitkeep b/doc/qa/source/_static/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/doc/qa/source/appendix.rst b/doc/qa/source/appendix.rst deleted file mode 100644 index 9198c0010..000000000 --- a/doc/qa/source/appendix.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. _appendix: - -Appendix -======== - -* The `LMA Collector documentation <http://fuel-plugin-lma-collector.readthedocs.io/>`_. -* The `LMA Infrastructure Alerting documentation <http://fuel-plugin-lma-infrastructure-alerting.readthedocs.io/>`_. -* The `Elasticsearch-Kibana documentation <http://fuel-plugin-elasticsearch-kibana.readthedocs.io/>`_. -* The `InfluxDB-Grafana documentation <http://fuel-plugin-influxdb-grafana.readthedocs.io/>`_. -* The official `Kibana documentation <https://www.elastic.co/guide/en/kibana/3.0/index.html>`_. -* The official `Grafana documentation <http://docs.grafana.org/>`_. -* The official `Nagios documentation <https://www.nagios.org/documentation/>`_. - diff --git a/doc/qa/source/conf.py b/doc/qa/source/conf.py deleted file mode 100644 index 070ece05b..000000000 --- a/doc/qa/source/conf.py +++ /dev/null @@ -1,39 +0,0 @@ -import sys -import os - -extensions = [] -templates_path = ['_templates'] -source_suffix = '.rst' -master_doc = 'index' -project = u'The LMA Collector Plugin for Fuel' -copyright = u'2015, Mirantis Inc.' -version = '0.9' -release = '0.9.0' - -exclude_patterns = [ - 'tests/*.rst' -] - -pygments_style = 'sphinx' - -html_theme = 'default' -html_static_path = ['_static'] -htmlhelp_basename = 'LMAcollectortestplandoc' - -latex_elements = { -} -latex_documents = [ - ('index', 'LMAcollector.tex', u'The LMA Collector Plugin for Fuel Documentation for QA', - u'Mirantis Inc.', 'manual'), -] - -man_pages = [ - ('index', 'lmacollector', u'The LMA Collector Plugin for Fuel Documentation for QA', - [u'Mirantis Inc.'], 1) -] - -texinfo_documents = [ - ('index', 'LMAcollector', u'The LMA Collector Plugin for Fuel Documentation for QA', - u'Mirantis Inc.', 'LMAcollector', 'One line description of project.', - 'Miscellaneous'), -] diff --git a/doc/qa/source/index.rst b/doc/qa/source/index.rst deleted file mode 100644 index b0242c07c..000000000 --- a/doc/qa/source/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -============================================================== -Welcome to the Mirantis OpenStack LMA Collector Documentation! -============================================================== - -QA documentation -================ - -.. toctree:: - :maxdepth: 2 - - strategy - testing - appendix - -Indices and Tables -================== - -* :ref:`search` diff --git a/doc/qa/source/strategy.rst b/doc/qa/source/strategy.rst deleted file mode 100644 index f60e05e83..000000000 --- a/doc/qa/source/strategy.rst +++ /dev/null @@ -1,56 +0,0 @@ -Test Strategy -============= - -The test plan implements system, functional and non-functional tests. These -tests will be automated but tests of the user interfaces will have to be done -manually. - -Acceptance Criteria -------------------- - -#. The plugins can be installed and enabled on the Fuel master node. - -#. The LMA Collector service is deployed on all the nodes of the environment - including nodes with the 'base-os' role and custom roles (influxdb_grafana, - elasticsearch_kibana, infrastructure_alerting). - -#. The Elasticsearch server and the Kibana UI are deployed on one node with the elasticsearch_kibana role. - -#. The InfluxDB server and the Grafana UI are deployed on one node with the influxdb_grafana role. - -#. The Nagios server and dashboard are deployed on one node with the infrastructure_alerting role. - -#. Kibana UI can be used to index and search both log messages and notifications. - -#. The Grafana dashboards display detailed metrics for the main OpenStack services. - -#. The Nagios UI displays status of all nodes and OpenStack services. - -#. The plugins can be uninstalled when no environment uses them. - - -Test environment, infrastructure and tools ------------------------------------------- - -The 4 LMA plugins are installed on the Fuel master node. - -For the controller nodes, it is recommended to deploy on hosts with at least 2 -CPUs and 4G of RAM. - - -Product compatibility matrix ----------------------------- - -+------------------------------------+-----------------+ -| Product | Version/Comment | -+====================================+=================+ -| Mirantis OpenStack | 8.0, 9.0 | -+------------------------------------+-----------------+ -| LMA collector plugin | 0.10.0 | -+------------------------------------+-----------------+ -| Elasticsearch-Kibana plugin | 0.10.0 | -+------------------------------------+-----------------+ -| InfluxDB-Grafana plugin | 0.10.0 | -+------------------------------------+-----------------+ -| LMA Infrastructure Alerting plugin | 0.10.0 | -+------------------------------------+-----------------+ diff --git a/doc/qa/source/testing.rst b/doc/qa/source/testing.rst deleted file mode 100644 index 5c367883f..000000000 --- a/doc/qa/source/testing.rst +++ /dev/null @@ -1,203 +0,0 @@ -.. _system_testing: - -System testing -============== - -.. _install_lma_plugins: - -Install the plugins -------------------- - -.. include:: tests/install.rst - -.. _deploy_lma_plugins: - -Deploy an environment with the plugins --------------------------------------- - -.. include:: tests/deploy.rst - -.. _add_remove_controller: - -Add/remove controller nodes in existing environment ---------------------------------------------------- - -.. include:: tests/scale_controller.rst - -.. _add_remove_compute: - -Add/remove compute nodes in existing environment ------------------------------------------------- - -.. include:: tests/scale_compute.rst - -.. _uninstall_plugins_with_env: - -Uninstall the plugins with deployed environment ------------------------------------------------ - -.. include:: tests/uninstall_plugins_with_env.rst - -.. _uninstall_plugins: - -Uninstall the plugins ---------------------- - -.. include:: tests/uninstall_plugins.rst - -.. _functional_testing: - -Functional testing -================== - -.. _deploy_ha_mode: - -Deploy plugins in HA mode -------------------------- - -.. include:: tests/deploy_ha_mode.rst - -.. _scale_influx: - -Add/remove InfluxDB nodes in existing environment -------------------------------------------------- - -.. include:: tests/scale_influx.rst - -.. _scale_elasticsearch: - -Add/remove Elasticsearch nodes in existing environment ------------------------------------------------------- - -.. include:: tests/scale_elasticsearch.rst - -.. _scale_infrastructure_alerting: - -Add/remove infrastructure alerting nodes in existing environment ----------------------------------------------------------------- - -.. include:: tests/scale_infrastructure_alerting.rst - -.. _shutdown_influx_node: - -Shutdown InfluxDB node ----------------------- - -.. include:: tests/shutdown_influx_node.rst - -.. _shutdown_elasticsearch_node: - -Shutdown Elasticsearch node ---------------------------- - -.. include:: tests/shutdown_elasticsearch_node.rst - -.. _shutdown_infrastructure_alerting_node: - -Shutdown infrastructure alerting node -------------------------------------- - -.. include:: tests/shutdown_infrastructure_alerting_node.rst - -.. _query_logs_in_kibana_ui: - -Display and query logs in the Kibana UI ---------------------------------------- - -.. include:: tests/query_logs_in_kibana_ui.rst - -.. _query_nova_notifications_in_kibana_ui: - -Display and query Nova notifications in the Kibana UI ------------------------------------------------------ - -.. include:: tests/query_nova_notifications_in_kibana_ui.rst - -.. _query_glance_notifications_in_kibana_ui: - -Display and query Glance notifications in the Kibana UI -------------------------------------------------------- - -.. include:: tests/query_glance_notifications_in_kibana_ui.rst - -.. _query_cinder_notifications_in_kibana_ui: - -Display and query Cinder notifications in the Kibana UI -------------------------------------------------------- - -.. include:: tests/query_cinder_notifications_in_kibana_ui.rst - -.. _query_heat_notifications_in_kibana_ui: - -Display and query Heat notifications in the Kibana UI ------------------------------------------------------ - -.. include:: tests/query_heat_notifications_in_kibana_ui.rst - -.. _query_neutron_notifications_in_kibana_ui: - -Display and query Neutron notifications in the Kibana UI --------------------------------------------------------- - -.. include:: tests/query_neutron_notifications_in_kibana_ui.rst - -.. _query_keystone_notifications_in_kibana_ui: - -Display and query Keystone notifications in the Kibana UI ---------------------------------------------------------- - -.. include:: tests/query_keystone_notifications_in_kibana_ui.rst - -.. _display_dashboards_in_grafana_ui: - -Display the dashboards in the Grafana UI ----------------------------------------- - -.. include:: tests/display_dashboards_in_grafana_ui.rst - -.. _display_nova_metrics_in_grafana_ui: - -Display the Nova metrics in the Grafana UI ------------------------------------------- - -.. include:: tests/display_nova_metrics_in_grafana_ui.rst - -.. _report_service_alerts_with_warning_severity: - -Report service alerts with warning severity -------------------------------------------- - -.. include:: tests/report_service_alerts_with_warning_severity.rst - -.. _report_service_alerts_with_critical_severity: - -Report service alerts with critical severity --------------------------------------------- - -.. include:: tests/report_service_alerts_with_critical_severity.rst - -.. _report_node_alerts_with_warning_severity: - -Report node alerts with warning severity ----------------------------------------- - -.. include:: tests/report_node_alerts_with_warning_severity.rst - -.. _report_node_alerts_with_critical_severity: - -Report node alerts with critical severity ------------------------------------------ - -.. include:: tests/report_node_alerts_with_critical_severity.rst - -.. _non_functional_testing: - -Non-functional testing -====================== - -.. _network_failure_on_analytics_node: - -Simulate network failure on the analytics node ----------------------------------------------- - -.. include:: tests/network_failure_on_analytics_node.rst diff --git a/doc/qa/source/tests/deploy.rst b/doc/qa/source/tests/deploy.rst deleted file mode 100644 index f17d089f8..000000000 --- a/doc/qa/source/tests/deploy.rst +++ /dev/null @@ -1,87 +0,0 @@ - -+---------------+---------------------------------------------------------------------------------+ -| Test Case ID | deploy_lma_plugins | -+---------------+---------------------------------------------------------------------------------+ -| Description | Verify that the plugins can be deployed. | -+---------------+---------------------------------------------------------------------------------+ -| Prerequisites | Plugins are installed on the Fuel master node (see :ref:`install_lma_plugins`). | -+---------------+---------------------------------------------------------------------------------+ - -Steps -::::: - -#. Connect to the Fuel web UI. - -#. Create a new environment with the Fuel UI wizard with the default settings. - -#. Click on the Settings tab of the Fuel web UI. - -#. Select the LMA collector plugin tab and fill-in the following fields: - - a. Enable the plugin. - - #. Select 'Local node' for "Event analytics". - - #. Select 'Local node' for "Metric analytics". - - #. Select 'Alerts sent to a local node running the LMA Infrastructure Alerting plugin' for "Alerting". - -#. Select the Elasticsearch-Kibana plugin tab and enable it. - -#. Select the InfluxDB-Grafana plugin and fill-in the required fields: - - a. Enable the plugin. - - #. Enter 'lmapass' as the root, user and grafana user passwords. - -#. Select the LMA Infrastructure-Alerting plugin and fill-in the required fields: - - a. Enable the plugin. - - #. Enter 'root\@localhost' as the recipient - - #. Enter 'nagios\@localhost' as the sender - - #. Enter '127.0.0.1' as the SMTP server address - - #. Choose "None" for SMTP authentication (default) - -#. Click on the Nodes tab of the Fuel web UI. - -#. Assign roles to nodes: - - a. 1 node with these 3 roles (this node is referenced later as the 'lma' node): - - i. influxdb_grafana - - #. elasticsearch_kibana - - #. infrastructure_alerting - - #. 3 nodes with the 'controller' role - - #. 1 node with the 'compute' + 'cinder' node - -#. Click 'Deploy changes'. - -#. Once the deployment has finished, connect to each node of the environment using ssh and run the following checks: - - a. Check that hekad and collectd processes are up and running on all the nodes as described in the `LMA Collector documentation <http://fuel-plugin-lma-collector.readthedocs.io/en/stable/configuration.html#plugin-verification>`_. - - #. Look for errors in /var/log/lma_collector.log - - #. Check that the node can connect to the Elasticsearch server (:samp:`http://<{IP address of the 'lma' node}>:9200/`) - - #. Check that the node can connect to the InfluxDB server (:samp:`http://<{IP address of the 'lma' node}>:8086/`) - -#. Check that the dashboards are running - - a. Check that you can connect to the Kibana UI (:samp:`http://<{IP address of the 'lma' node}>:80/`) - #. Check that you can connect to the Grafana UI (:samp:`http://<{IP address of the 'lma' node}>:8000/`) with user='lma', password='lmapass' - #. Check that you can connect to the Nagios UI (:samp:`http://<{IP address of the 'lma' node}>:8001/`) with user='nagiosadmin', password='r00tme' - - -Expected Result -::::::::::::::: - -The environment is deployed successfully. diff --git a/doc/qa/source/tests/deploy_ha_mode.rst b/doc/qa/source/tests/deploy_ha_mode.rst deleted file mode 100644 index 84c655988..000000000 --- a/doc/qa/source/tests/deploy_ha_mode.rst +++ /dev/null @@ -1,89 +0,0 @@ - -+---------------+---------------------------------------------------------------------------------+ -| Test Case ID | deploy_lma_plugins_ha_mode | -+---------------+---------------------------------------------------------------------------------+ -| Description | Verify that the plugins can be deployed in HA mode. | -+---------------+---------------------------------------------------------------------------------+ -| Prerequisites | Plugins are installed on the Fuel master node (see :ref:`install_lma_plugins`). | -+---------------+---------------------------------------------------------------------------------+ - -Steps -::::: - -#. Connect to the Fuel web UI. - -#. Create a new environment with the Fuel UI wizard with the default settings. - -#. Click on the Settings tab of the Fuel web UI and select the 'Other' link. - -#. Select the LMA collector plugin tab and fill-in the following fields: - - a. Enable the plugin. - - #. Select 'Local node' for "Event analytics". - - #. Select 'Local node' for "Metric analytics". - - #. Select 'Alerts sent to a local node running the LMA Infrastructure Alerting plugin' for "Alerting". - -#. Select the Elasticsearch-Kibana plugin tab and enable it. - -#. Select the InfluxDB-Grafana plugin and fill-in the required fields: - - a. Enable the plugin. - - #. Enter 'lmapass' as the root, user and grafana user passwords. - -#. Select the LMA Infrastructure-Alerting plugin and fill-in the required fields: - - a. Enable the plugin. - - #. Enter 'root\@localhost' as the recipient - - #. Enter 'nagios\@localhost' as the sender - - #. Enter '127.0.0.1' as the SMTP server address - - #. Choose "None" for SMTP authentication (default) - -#. Click on the Nodes tab of the Fuel web UI. - -#. Assign roles to nodes: - - a. 3 nodes with these 3 roles: - - i. influxdb_grafana - - #. elasticsearch_kibana - - #. infrastructure_alerting - - #. 3 nodes with the 'controller' role - - #. 1 node with the 'compute' + 'cinder' node - -#. Click 'Deploy changes'. - -#. Once the deployment has finished, connect to each node of the environment using ssh and run the following checks: - - a. Check that hekad and collectd processes are up and running on all the nodes as described in the `LMA Collector documentation <http://fuel-plugin-lma-collector.readthedocs.io/en/stable/configuration.html#plugin-verification>`_. - - #. Run 'pcs resource' on one of nodes with plugin roles and check that all services are started. - - #. Look for errors in /var/log/lma_collector.log on controller nodes and in /var/log/upstart/lma_collector.log on other nodes. - - #. Check that the node can connect to the Elasticsearch server (:samp:`http://<{vip_es_vip_mgmt}>:9200/`) - - #. Check that the node can connect to the InfluxDB server (:samp:`http://<{vip_influxdb}>:8086/`) - -#. Check that the dashboards are running - - a. Check that you can connect to the Kibana UI (open the 'Dashboard' tab and click the 'Kibana' link) - #. Check that you can connect to the Grafana UI (open the 'Dashboard' tab and click the 'Grafana' link) with user='lma', password='lmapass' - #. Check that you can connect to the Nagios UI (open the 'Dashboard' tab and click the 'Nagios' link) with user='nagiosadmin', password='r00tme' - - -Expected Result -::::::::::::::: - -The environment is deployed successfully. diff --git a/doc/qa/source/tests/display_dashboards_in_grafana_ui.rst b/doc/qa/source/tests/display_dashboards_in_grafana_ui.rst deleted file mode 100644 index 572522d71..000000000 --- a/doc/qa/source/tests/display_dashboards_in_grafana_ui.rst +++ /dev/null @@ -1,59 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | display_dashboards_in_grafana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the dashboards show up in the Grafana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Open the Grafana URL (open the 'Dashboard' tab and click the 'Grafana' link). - -#. Sign-in using the credentials provided during the configuration of the environment. - -#. Go to the Main dashboard and verify that everything is ok. - -#. Repeat the previous step for the following dashboards: - - a. Cinder - - #. Glance - - #. Heat - - #. Keystone - - #. Nova - - #. Neutron - - #. HAProxy - - #. RabbitMQ - - #. MySQL - - #. Apache - - #. Memcached - - #. System - - #. LMA Self-monitoring - - #. Hypervisor - - #. Elasticsearch - - #. InfluxDB - - - -Expected Result -::::::::::::::: - -The Grafana UI shows the overall status of the OpenStack services and detailed -statistics about the selected controller. diff --git a/doc/qa/source/tests/display_nova_metrics_in_grafana_ui.rst b/doc/qa/source/tests/display_nova_metrics_in_grafana_ui.rst deleted file mode 100644 index 409e35e3f..000000000 --- a/doc/qa/source/tests/display_nova_metrics_in_grafana_ui.rst +++ /dev/null @@ -1,27 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | display_nova_metrics_in_grafana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the Nova metrics show up in the Grafana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Open the Grafana URL at :samp:`http://<{IP address of the 'lma' node}>:8000/` - -#. Sign-in using the credentials provided during the configuration of the environment. - -#. Go to the Nova dashboard. - -#. Connect to the Fuel web UI, launch the full suite of OSTF tests and wait for their completion. - -#. Check that the 'instance creation time' graph in the Nova dashboard reports values. - - -Expected Result -::::::::::::::: - -The Grafana UI shows the instance creation time over time. diff --git a/doc/qa/source/tests/install.rst b/doc/qa/source/tests/install.rst deleted file mode 100644 index c7ad5ecc8..000000000 --- a/doc/qa/source/tests/install.rst +++ /dev/null @@ -1,29 +0,0 @@ - -+---------------+-------------------------------------------+ -| Test Case ID | install_lma_plugins | -+---------------+-------------------------------------------+ -| Description | Verify that the plugins can be installed. | -+---------------+-------------------------------------------+ -| Prerequisites | N/A | -+---------------+-------------------------------------------+ - -Steps -::::: - -#. Copy the 4 plugins to the Fuel master node using scp. - -#. Connect to the Fuel master node using ssh. - -#. Install the plugins using the fuel CLI. - -#. Connect to the Fuel web UI. - -#. Create a new environment using the Fuel UI Wizard. - -#. Click on the Plugins tab. - - -Expected Result -::::::::::::::: - -The 4 plugins are present in the Fuel UI. diff --git a/doc/qa/source/tests/network_failure_on_analytics_node.rst b/doc/qa/source/tests/network_failure_on_analytics_node.rst deleted file mode 100644 index 4c3efbc5f..000000000 --- a/doc/qa/source/tests/network_failure_on_analytics_node.rst +++ /dev/null @@ -1,33 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | network_failure_on_analytics_node | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the backends and dashboards recover after a network failure. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Copy this script to the analytics node:: - - #!/bin/sh - /sbin/iptables -I INPUT -j DROP - sleep 30 - /sbin/iptables -D INPUT -j DROP - -#. Login to the analytics node using SSH - -#. Run the script and wait for it to complete. - -#. Check that the Kibana, Grafana and Nagios dashboards are available. - -#. Check that data continues to be pushed by the various nodes once the network failure has ended. - - - -Expected Result -::::::::::::::: - -The collectors recover from the network outage of the analytics node. diff --git a/doc/qa/source/tests/query_cinder_notifications_in_kibana_ui.rst b/doc/qa/source/tests/query_cinder_notifications_in_kibana_ui.rst deleted file mode 100644 index 8face1d36..000000000 --- a/doc/qa/source/tests/query_cinder_notifications_in_kibana_ui.rst +++ /dev/null @@ -1,27 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | query_cinder_notifications_in_kibana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the cinder notifications show up in the Kibana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Create and update a volume in the OpenStack environment (using the Horizon - dashboard for example) and write down the volume id. - -#. Open the Kibana URL at :samp:`http://<{IP address of the 'lma' node}>/` - -#. Open the Notifications dashboard using the 'Load' icon. - -#. Enter 'volume_id:<uuid>' in the Query box where <uuid> is the id of the created volume. - - -Expected Result -::::::::::::::: - -All `event types for Cinder <https://docs.google.com/a/mirantis.com/spreadsheets/d/1ES_hWWLpn_eAur2N1FPNyqQAs5U36fQOcuCxRZjHESY/edit?usp=sharing>`_ -are listed. diff --git a/doc/qa/source/tests/query_glance_notifications_in_kibana_ui.rst b/doc/qa/source/tests/query_glance_notifications_in_kibana_ui.rst deleted file mode 100644 index 680e7d11f..000000000 --- a/doc/qa/source/tests/query_glance_notifications_in_kibana_ui.rst +++ /dev/null @@ -1,26 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | query_glance_notifications_in_kibana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the Glance notifications show up in the Kibana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Run the OSTF platform test "Check create, update and delete image actions using Glance v2". - -#. Open the Kibana URL at :samp:`http://<{IP address of the 'lma' node}>/` - -#. Open the Notifications dashboard using the 'Load' icon. - -#. Enter 'glance' in the Query box. - - -Expected Result -::::::::::::::: - -All `event types for Glance <https://docs.google.com/a/mirantis.com/spreadsheets/d/1ES_hWWLpn_eAur2N1FPNyqQAs5U36fQOcuCxRZjHESY/edit?usp=sharing>`_ -are listed. diff --git a/doc/qa/source/tests/query_heat_notifications_in_kibana_ui.rst b/doc/qa/source/tests/query_heat_notifications_in_kibana_ui.rst deleted file mode 100644 index 160393f5b..000000000 --- a/doc/qa/source/tests/query_heat_notifications_in_kibana_ui.rst +++ /dev/null @@ -1,26 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | query_heat_notifications_in_kibana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the heat notifications show up in the Kibana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Run all OSTF Heat platform tests. - -#. Open the Kibana URL at :samp:`http://<{IP address of the 'lma' node}>/` - -#. Open the Notifications dashboard using the 'Load' icon. - -#. Enter 'heat' in the Query box. - - -Expected Result -::::::::::::::: - -All `event types for Heat <https://docs.google.com/a/mirantis.com/spreadsheets/d/1ES_hWWLpn_eAur2N1FPNyqQAs5U36fQOcuCxRZjHESY/edit?usp=sharing>`_ -are listed. diff --git a/doc/qa/source/tests/query_keystone_notifications_in_kibana_ui.rst b/doc/qa/source/tests/query_keystone_notifications_in_kibana_ui.rst deleted file mode 100644 index cc7a082bc..000000000 --- a/doc/qa/source/tests/query_keystone_notifications_in_kibana_ui.rst +++ /dev/null @@ -1,26 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | query_keystone_notifications_in_kibana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the Keystone notifications show up in the Kibana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Run OSTF platform test: 'Create user and authenticate with it to Horizon'. - -#. Open the Kibana URL at :samp:`http://<{IP address of the 'lma' node}>/` - -#. Open the Notifications dashboard using the 'Load' icon. - -#. Enter 'keystone' in the Query box. - - -Expected Result -::::::::::::::: - -All `event types for Keystone <https://docs.google.com/a/mirantis.com/spreadsheets/d/1ES_hWWLpn_eAur2N1FPNyqQAs5U36fQOcuCxRZjHESY/edit?usp=sharing>`_ -are listed. diff --git a/doc/qa/source/tests/query_logs_in_kibana_ui.rst b/doc/qa/source/tests/query_logs_in_kibana_ui.rst deleted file mode 100644 index 932bff4eb..000000000 --- a/doc/qa/source/tests/query_logs_in_kibana_ui.rst +++ /dev/null @@ -1,24 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | query_logs_in_kibana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the logs show up in the Kibana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Open the Kibana URL at :samp:`http://<{IP address of the 'lma' node}>/` - -#. Enter 'programname:nova*' in the Query box. - -#. Check that Nova logs are displayed. - - -Expected Result -::::::::::::::: - -The Kibana UI displays entries for all the controller and compute nodes -deployed in the environment. diff --git a/doc/qa/source/tests/query_neutron_notifications_in_kibana_ui.rst b/doc/qa/source/tests/query_neutron_notifications_in_kibana_ui.rst deleted file mode 100644 index 8dcd377f5..000000000 --- a/doc/qa/source/tests/query_neutron_notifications_in_kibana_ui.rst +++ /dev/null @@ -1,27 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | query_neutron_notifications_in_kibana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the Neutron notifications show up in the Kibana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Run OSTF functional tests: 'Create security group' and 'Check network - connectivity from instance via floating IP'. - -#. Open the Kibana URL at :samp:`http://<{IP address of the 'lma' node}>/` - -#. Open the Notifications dashboard using the 'Load' icon. - -#. Enter 'neutron' in the Query box. - - -Expected Result -::::::::::::::: - -All `event types for Neutron <https://docs.google.com/a/mirantis.com/spreadsheets/d/1ES_hWWLpn_eAur2N1FPNyqQAs5U36fQOcuCxRZjHESY/edit?usp=sharing>`_ -are listed. diff --git a/doc/qa/source/tests/query_nova_notifications_in_kibana_ui.rst b/doc/qa/source/tests/query_nova_notifications_in_kibana_ui.rst deleted file mode 100644 index 226e4675e..000000000 --- a/doc/qa/source/tests/query_nova_notifications_in_kibana_ui.rst +++ /dev/null @@ -1,28 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | query_nova_notifications_in_kibana_ui | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the Nova notifications show up in the Kibana UI. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Launch, update, rebuild, resize, power-off, power-on, snapshot, suspend, - shutdown, and delete an instance in the OpenStack environment (using the - Horizon dashboard for example) and write down the instance's id. - -#. Open the Kibana URL at :samp:`http://<{IP address of the 'lma' node}>/` - -#. Open the Notifications dashboard using the 'Load' icon. - -#. Enter 'instance_id:<uuid>' in the Query box where <uuid> is the id of the launched instance. - - -Expected Result -::::::::::::::: - -All `event types for Nova <https://docs.google.com/a/mirantis.com/spreadsheets/d/1ES_hWWLpn_eAur2N1FPNyqQAs5U36fQOcuCxRZjHESY/edit?usp=sharing>`_ -are listed except compute.instance.create.error and compute.instance.resize.revert.{start|end}. diff --git a/doc/qa/source/tests/report_node_alerts_with_critical_severity.rst b/doc/qa/source/tests/report_node_alerts_with_critical_severity.rst deleted file mode 100644 index c1d88e6c2..000000000 --- a/doc/qa/source/tests/report_node_alerts_with_critical_severity.rst +++ /dev/null @@ -1,83 +0,0 @@ - -+---------------+---------------------------------------------------------------------------------+ -| Test Case ID | report_node_alerts_with_critical_severity | -+---------------+---------------------------------------------------------------------------------+ -| Description | Verify that the critical alerts for nodes show up in the Grafana and Nagios UI. | -+---------------+---------------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+---------------------------------------------------------------------------------+ - -Steps -::::: - -#. Open the Grafana URL at :samp:`http://<{IP address of the 'lma' node}>:8000/` - and load the MySQL dashboard. - -#. Open the Nagios URL at :samp:`http://<{IP address of the 'lma' node}>:8001/` - in another tab and click the 'Services' menu item. - -#. Connect to one of the controller nodes using ssh and run:: - - fallocate -l $(df | grep /dev/mapper/mysql-root | awk '{ printf("%.0f\n", 1024 * ((($3 + $4) * 98 / 100) - $3))}') /var/lib/mysql/test - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'OKAY' with an green background, - -#. On Nagios, check the following items: - - a. the 'mysql' service is in 'OK' state, - - #. the 'mysql-nodes.mysql-fs' service is in 'CRITICAL' state for the node. - -#. Connect to a second controller node using ssh and run:: - - fallocate -l $(df | grep /dev/mapper/mysql-root | awk '{ printf("%.0f\n", 1024 * ((($3 + $4) * 98 / 100) - $3))}') /var/lib/mysql/test - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'CRIT' with an red background, - - #. an annotation telling that the service went from 'OKAY' to 'CRIT' is displayed. - -#. On Nagios, check the following items: - - a. the 'mysql' service is in 'CRITICAL' state, - - #. the 'mysql-nodes.mysql-fs' service is in 'CRITICAL' state for the 2 nodes, - - #. the local user root on the lma node has received an email about the service being in critical state. - -#. Run the following command on both controller nodes:: - - rm /var/lib/mysql/test - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'OKAY' with an green background, - - #. an annotation telling that the service went from 'CRIT' to 'OKAY' is displayed. - -#. On Nagios, check the following items: - - a. the 'mysql' service is in 'OK' state, - - #. the 'mysql-nodes.mysql-fs' service is in 'OKAY' state for the 2 nodes, - - #. the local user root on the lma node has received an email about the recovery of the service. - - -Expected Result -::::::::::::::: - -The Grafana UI shows that the global 'mysql' status goes from ok to critical and -back to ok. It also reports detailed information about the problem in the annotations. - -The Nagios UI shows that the service status goes from ok to critical and back to -ok. Alerts are sent by email to the configured recipient. diff --git a/doc/qa/source/tests/report_node_alerts_with_warning_severity.rst b/doc/qa/source/tests/report_node_alerts_with_warning_severity.rst deleted file mode 100644 index 1f3973912..000000000 --- a/doc/qa/source/tests/report_node_alerts_with_warning_severity.rst +++ /dev/null @@ -1,83 +0,0 @@ - -+---------------+--------------------------------------------------------------------------------+ -| Test Case ID | report_node_alerts_with_warning_severity | -+---------------+--------------------------------------------------------------------------------+ -| Description | Verify that the warning alerts for nodes show up in the Grafana and Nagios UI. | -+---------------+--------------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------------+ - -Steps -::::: - -#. Open the Grafana URL at :samp:`http://<{IP address of the 'lma' node}>:8000/` - and load the MySQL dashboard. - -#. Open the Nagios URL at :samp:`http://<{IP address of the 'lma' node}>:8001/` - in another tab and click the 'Services' menu item. - -#. Connect to one of the controller nodes using ssh and run:: - - fallocate -l $(df | grep /dev/mapper/mysql-root | awk '{ printf("%.0f\n", 1024 * ((($3 + $4) * 96 / 100) - $3))}') /var/lib/mysql/test - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'OKAY' with an green background, - -#. On Nagios, check the following items: - - a. the 'mysql' service is in 'OK' state, - - #. the 'mysql-nodes.mysql-fs' service is in 'WARNING' state for the node. - -#. Connect to a second controller node using ssh and run:: - - fallocate -l $(df | grep /dev/mapper/mysql-root | awk '{ printf("%.0f\n", 1024 * ((($3 + $4) * 96 / 100) - $3))}') /var/lib/mysql/test - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'WARN' with an orange background, - - #. an annotation telling that the service went from 'OKAY' to 'WARN' is displayed. - -#. On Nagios, check the following items: - - a. the 'mysql' service is in 'WARNING' state, - - #. the 'mysql-nodes.mysql-fs' service is in 'WARNING' state for the 2 nodes, - - #. the local user root on the lma node has received an email about the service being in warning state. - -#. Run the following command on both controller nodes:: - - rm /var/lib/mysql/test - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'OKAY' with an green background, - - #. an annotation telling that the service went from 'WARN' to 'OKAY' is displayed. - -#. On Nagios, check the following items: - - a. the 'mysql' service is in 'OK' state, - - #. the 'mysql-nodes.mysql-fs' service is in 'OKAY' state for the 2 nodes, - - #. the local user root on the lma node has received an email about the recovery of the service. - - -Expected Result -::::::::::::::: - -The Grafana UI shows that the global 'mysql' status goes from ok to warning and -back to ok. It also reports detailed information about the problem in the annotations. - -The Nagios UI shows that the service status goes from ok to warning and back to -ok. Alerts are sent by email to the configured recipient. diff --git a/doc/qa/source/tests/report_service_alerts_with_critical_severity.rst b/doc/qa/source/tests/report_service_alerts_with_critical_severity.rst deleted file mode 100644 index 4935e7e3a..000000000 --- a/doc/qa/source/tests/report_service_alerts_with_critical_severity.rst +++ /dev/null @@ -1,109 +0,0 @@ - -+---------------+------------------------------------------------------------------------------------+ -| Test Case ID | report_service_alerts_with_critical_severity | -+---------------+------------------------------------------------------------------------------------+ -| Description | Verify that the critical alerts for services show up in the Grafana and Nagios UI. | -+---------------+------------------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+------------------------------------------------------------------------------------+ - -Steps -::::: - -#. Open the Grafana URL at :samp:`http://<{IP address of the 'lma' node}>:8000/` - and load the Nova dashboard. - -#. Open the Nagios URL at :samp:`http://<{IP address of the 'lma' node}>:8001/` - in another tab and click the 'Services' menu item. - -#. Connect to one of the controller nodes using ssh and stop the nova-api service. - -#. Connect to a second controller node using ssh and stop the nova-api service. - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'CRIT' with a red background, - - #. the API panels report 2 entities as down. - -#. On Nagios, check the following items: - - a. the 'nova' service is in 'CRITICAL' state, - - #. the local user root on the lma node has received an email about the service being in critical state. - -#. Restart the nova-api service on both nodes. - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'OKAY' with an green background, - - #. the API panels report 0 entity as down. - -#. On Nagios, check the following items: - - a. the 'nova' service is in 'OK' state, - - #. the local user root on the lma node has received an email about the recovery of the service. - -#. Connect to one of the controller nodes using ssh and stop the nova-scheduler service. - -#. Connect to a second controller node using ssh and stop the nova-scheduler service. - -#. Wait for at least 3 minutes. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'CRIT' with a red background, - - #. the scheduler panel reports 2 entities as down. - -#. On Nagios, check the following items: - - a. the 'nova' service is in 'CRITICAL' state, - - #. the local user root on the lma node has received an email about the service being in critical state. - -#. Restart the nova-scheduler service on both nodes. - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'OKAY' with an green background, - - #. the scheduler panel reports 0 entity as down. - -#. On Nagios, check the following items: - - a. the 'nova' service is in 'OK' state, - - #. the local user root on the lma node has received an email about the recovery of the service. - -#. Repeat steps 2 to 21 for the following services: - - a. Cinder (stopping and starting the cinder-api and cinder-scheduler services respectively). - - #. Neutron (stopping and starting the neutron-server and neutron-openvswitch-agent services respectively). - -#. Repeat steps 2 to 11 for the following services: - - a. Glance (stopping and starting the glance-api service). - - #. Heat (stopping and starting the heat-api service). - - #. Keystone (stopping and starting the Apache service). - - -Expected Result -::::::::::::::: - -The Grafana UI shows that the global service status goes from ok to critical and -back to ok. It also reports detailed information about which entity is missing. - -The Nagios UI shows that the service status goes from ok to critical and back to -ok. Alerts are sent by email to the configured recipient. diff --git a/doc/qa/source/tests/report_service_alerts_with_warning_severity.rst b/doc/qa/source/tests/report_service_alerts_with_warning_severity.rst deleted file mode 100644 index ea3bce8aa..000000000 --- a/doc/qa/source/tests/report_service_alerts_with_warning_severity.rst +++ /dev/null @@ -1,105 +0,0 @@ - -+---------------+-----------------------------------------------------------------------------------+ -| Test Case ID | report_service_alerts_with_warning_severity | -+---------------+-----------------------------------------------------------------------------------+ -| Description | Verify that the warning alerts for services show up in the Grafana and Nagios UI. | -+---------------+-----------------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+-----------------------------------------------------------------------------------+ - -Steps -::::: - -#. Open the Grafana URL at :samp:`http://<{IP address of the 'lma' node}>:8000/` - and load the Nova dashboard. - -#. Open the Nagios URL at :samp:`http://<{IP address of the 'lma' node}>:8001/` - in another tab and click the 'Services' menu item. - -#. Connect to one of the controller nodes using ssh and stop the nova-api service. - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'WARN' with an orange background, - - #. the API panels report 1 entity as down. - -#. On Nagios, check the following items: - - a. the 'nova' service is in 'WARNING' state, - - #. the local user root on the lma node has received an email about the service being in warning state. - -#. Restart the nova-api service. - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'OKAY' with an green background, - - #. the API panels report 0 entity as down. - -#. On Nagios, check the following items: - - a. the 'nova' service is in 'OK' state, - - #. the local user root on the lma node has received an email about the recovery of the service. - -#. Stop the nova-scheduler service. - -#. Wait for at least 3 minutes. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'WARN' with an orange background, - - #. the scheduler panel reports 1 entity as down. - -#. On Nagios, check the following items: - - a. the 'nova' service is in 'WARNING' state, - - #. the local user root on the lma node has received an email about the service being in warning state. - -#. Restart the nova-scheduler service. - -#. Wait for at least 1 minute. - -#. On Grafana, check the following items: - - a. the box in the upper left corner of the dashboard displays 'OKAY' with an green background, - - #. the scheduler panel reports 0 entity as down. - -#. On Nagios, check the following items: - - a. the 'nova' service is in 'OK' state, - - #. the local user root on the lma node has received an email about the recovery of the service. - -#. Repeat steps 2 to 18 for the following services: - - a. Cinder (stopping and starting the cinder-api and cinder-scheduler services respectively). - - #. Neutron (stopping and starting the neutron-server and neutron-openvswitch-agent services respectively). - -#. Repeat steps 2 to 10 for the following services: - - a. Glance (stopping and starting the glance-api service). - - #. Heat (stopping and starting the heat-api service). - - #. Keystone (stopping and starting the Apache service). - - -Expected Result -::::::::::::::: - -The Grafana UI shows that the global service status goes from ok to warning and -back to ok. It also reports detailed information about which entity is missing. - -The Nagios UI shows that the service status goes from ok to warning and back to -ok. Alerts are sent by email to the configured recipient. diff --git a/doc/qa/source/tests/scale_compute.rst b/doc/qa/source/tests/scale_compute.rst deleted file mode 100644 index 748bac4ee..000000000 --- a/doc/qa/source/tests/scale_compute.rst +++ /dev/null @@ -1,43 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | modify_env_with_plugin_remove_add_compute | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the number of computes can scale up and down. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (See :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Remove 1 node with the compute role. - -#. Re-deploy the cluster. - -#. Check the plugin services using the CLI - -#. Check in the Nagios UI that the removed node is no longer monitored. - -#. Run the health checks (OSTF). - -#. Add 1 new node with the compute role. - -#. Re-deploy the cluster. - -#. Check the plugin services using the CLI. - -#. Check in the Nagios UI that the new node is monitored. - -#. Run the health checks (OSTF). - - -Expected Result -::::::::::::::: - -The OSTF tests pass successfully. - -All the plugin services are running and work as expected after each -modification of the environment. - -The Nagios service has been reconfigured to take care of the node removal and -addition. diff --git a/doc/qa/source/tests/scale_controller.rst b/doc/qa/source/tests/scale_controller.rst deleted file mode 100644 index ee85fb3e7..000000000 --- a/doc/qa/source/tests/scale_controller.rst +++ /dev/null @@ -1,43 +0,0 @@ - -+---------------+--------------------------------------------------------------------------+ -| Test Case ID | modify_env_with_plugin_remove_add_controller | -+---------------+--------------------------------------------------------------------------+ -| Description | Verify that the number of controllers can scale up and down. | -+---------------+--------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (See :ref:`deploy_lma_plugins`). | -+---------------+--------------------------------------------------------------------------+ - -Steps -::::: - -#. Remove 1 node with the controller role. - -#. Re-deploy the cluster. - -#. Check the plugin services using the CLI - -#. Check in the Nagios UI that the removed node is no longer monitored. - -#. Run the health checks (OSTF). - -#. Add 1 new node with the controller role. - -#. Re-deploy the cluster. - -#. Check the plugin services using the CLI. - -#. Check in the Nagios UI that the new node is monitored. - -#. Run the health checks (OSTF). - - -Expected Result -::::::::::::::: - -The OSTF tests pass successfully. - -All the plugin services are running and work as expected after each -modification of the environment. - -The Nagios service has been reconfigured to take care of the node removal and -addition. diff --git a/doc/qa/source/tests/scale_elasticsearch.rst b/doc/qa/source/tests/scale_elasticsearch.rst deleted file mode 100644 index 10bafcdb5..000000000 --- a/doc/qa/source/tests/scale_elasticsearch.rst +++ /dev/null @@ -1,48 +0,0 @@ -+---------------+---------------------------------------------------------------------+ -| Test Case ID | modify_elasticsearch_plugin_remove_add_node | -+---------------+---------------------------------------------------------------------+ -| Description | Verify that Elasticsearch cluster can scale up and down. | -+---------------+---------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (See :ref:`deploy_ha_mode`).| -+---------------+---------------------------------------------------------------------+ - -Steps -::::: - -#. Remove 1 node with the elasticsearch_kibana role. - -#. Re-deploy the cluster. - -#. Check the plugin services using CLI. - -#. Check that the Kibana UI works correctly. - -#. Open the 'Elasticsearch' dashboard in the Grafana UI and check that the number of node equals 2. - -#. Run OSTF. - -#. Add 1 new node with the elasticsearch_kibana role. - -#. Re-deploy cluster. - -#. Check the plugin services using CLI. - -#. Check that the Kibana UI works correctly. - -#. Open the 'Elasticsearch' dashboard in the Grafana UI and check that the number of node equals 3. - -#. Run OSTF. - - -Expected Result -::::::::::::::: - -The OSTF tests pass successfully. - -Grafana dashboard and Nagios UI reports a short downtime for Elasticsearch cluster. - -All the plugin services are running and work as expected after each -modification of the environment. - -The Nagios service has been reconfigured to take care of the node removal and -addition. diff --git a/doc/qa/source/tests/scale_influx.rst b/doc/qa/source/tests/scale_influx.rst deleted file mode 100644 index cd40b863c..000000000 --- a/doc/qa/source/tests/scale_influx.rst +++ /dev/null @@ -1,50 +0,0 @@ -+---------------+----------------------------------------------------------------------+ -| Test Case ID | modify_influxdb_plugin_remove_add_node | -+---------------+----------------------------------------------------------------------+ -| Description | Verify that InfluxDB cluster can scale up and down. | -+---------------+----------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (See :ref:`deploy_ha_mode`). | -+---------------+----------------------------------------------------------------------+ - -Steps -::::: - -#. Remove 1 node with the influxdb_grafana role. - -#. Re-deploy the cluster. - -#. Run command 'curl -u root:<rootpassword> -G 'http://{vip_influxdb}:8086/query' --data-urlencode 'q=SHOW SERVERS'' - -#. Check that output contains information about only two InfluxDB nodes. - -#. Check the plugin services using CLI. - -#. Check that Grafana UI works correctly. - -#. Run OSTF. - -#. Add 1 new node with the influxdb_grafana role. - -#. Re-deploy cluster. - -#. Run command 'curl -u root:<rootpassword> -G 'http://{vip_influxdb}:8086/query' --data-urlencode 'q=SHOW SERVERS'' - -#. Check that output contains information about three InfluxDB nodes. - -#. Check the plugin services using CLI. - -#. Check that Grafana UI works correctly. - -#. Run OSTF. - - -Expected Result -::::::::::::::: - -The OSTF tests pass successfully. - -All the plugin services are running and work as expected after each -modification of the environment. - -The Nagios service has been reconfigured to take care of the node removal and -addition. diff --git a/doc/qa/source/tests/scale_infrastructure_alerting.rst b/doc/qa/source/tests/scale_infrastructure_alerting.rst deleted file mode 100644 index 025f09560..000000000 --- a/doc/qa/source/tests/scale_infrastructure_alerting.rst +++ /dev/null @@ -1,42 +0,0 @@ -+---------------+---------------------------------------------------------------------+ -| Test Case ID | modify_lma_infrastructure_alerting_plugin_remove_add_node | -+---------------+---------------------------------------------------------------------+ -| Description | Verify that infrastructure alerting cluster can scale up and down. | -+---------------+---------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (See :ref:`deploy_ha_mode`).| -+---------------+---------------------------------------------------------------------+ - -Steps -::::: - -#. Remove 1 node with the infrastructure_alerting role. - -#. Re-deploy the cluster. - -#. Check the plugin services using CLI. - -#. Check that Nagios UI works correctly. - -#. Run OSTF. - -#. Add 1 new node with the infrastructure_alerting role. - -#. Re-deploy cluster. - -#. Check the plugin services using CLI. - -#. Check that Nagios UI works correctly. - -#. Run OSTF. - - -Expected Result -::::::::::::::: - -The OSTF tests pass successfully. - -All the plugin services are running and work as expected after each -modification of the environment. - -The Nagios service has been reconfigured to take care of the node removal and -addition. diff --git a/doc/qa/source/tests/shutdown_elasticsearch_node.rst b/doc/qa/source/tests/shutdown_elasticsearch_node.rst deleted file mode 100644 index fc5a69fee..000000000 --- a/doc/qa/source/tests/shutdown_elasticsearch_node.rst +++ /dev/null @@ -1,49 +0,0 @@ -+---------------+----------------------------------------------------------------------+ -| Test Case ID | shutdown_elasticsearch_node | -+---------------+----------------------------------------------------------------------+ -| Description | Verify that failover for Elasticsearch cluster works. | -+---------------+----------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (See :ref:`deploy_ha_mode`). | -+---------------+----------------------------------------------------------------------+ - -Steps -::::: - -#. Connect to any elasticsearch_kibana node and run command 'crm status'. - -#. Run command 'curl -XGET 'http://{vip_es_vip_mgmt}:9200/_cat/indices?v'' and save the output. - -#. Shutdown the node were vip_es_vip_mgmt was started. - -#. Check that vip_es_vip_mgmt was started on another elasticsearch_kibana node. - -#. Check that cluster status became 'WARNING'. - -#. Check the plugin services using CLI. - -#. Check that Kibana UI works correctly. - -#. Run command 'curl -XGET 'http://{vip_es_vip_mgmt}:9200/_cat/indices?v'' one more time and compare this output with the first output. - -#. Run OSTF. - -#. Start the node. - -#. After few minutes check that the cluster status is 'OKAY'. - - -Expected Result -::::::::::::::: - -The OSTF tests pass successfully. - -All the plugin services are running and work as expected after each -modification of the environment. - -vip_es_vip_mgmt was started on another node after shutdown. - -The number of documents in the second output must be equal or greather than in the first output. - -There is no gap in the time line in the Kibana dashboards. - - diff --git a/doc/qa/source/tests/shutdown_influx_node.rst b/doc/qa/source/tests/shutdown_influx_node.rst deleted file mode 100644 index d325149fc..000000000 --- a/doc/qa/source/tests/shutdown_influx_node.rst +++ /dev/null @@ -1,35 +0,0 @@ -+---------------+----------------------------------------------------------------------+ -| Test Case ID | shutdown_influxdb_node | -+---------------+----------------------------------------------------------------------+ -| Description | Verify that failover for InfluxDB cluster works. | -+---------------+----------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (See :ref:`deploy_ha_mode`). | -+---------------+----------------------------------------------------------------------+ - -Steps -::::: - -#. Connect to any influxdb_grafana node and run command 'crm status'. - -#. Shutdown node were vip_influxdb was started. - -#. Check that vip_influxdb was started on another influxdb_grafana node. - -#. Check the plugin services using CLI. - -#. Check that Grafana UI works correctly. - -#. Check that no data lost after shutdown. - -#. Run OSTF. - - -Expected Result -::::::::::::::: - -The OSTF tests pass successfully. - -All the plugin services are running and work as expected after each -modification of the environment. - -vip_influxdb was started on another node after shutdown. diff --git a/doc/qa/source/tests/shutdown_infrastructure_alerting_node.rst b/doc/qa/source/tests/shutdown_infrastructure_alerting_node.rst deleted file mode 100644 index ba2850707..000000000 --- a/doc/qa/source/tests/shutdown_infrastructure_alerting_node.rst +++ /dev/null @@ -1,35 +0,0 @@ -+---------------+----------------------------------------------------------------------+ -| Test Case ID | shutdown_infrastructure_alerting_node | -+---------------+----------------------------------------------------------------------+ -| Description | Verify that failover for infrastructure alerting cluster works. | -+---------------+----------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (See :ref:`deploy_ha_mode`). | -+---------------+----------------------------------------------------------------------+ - -Steps -::::: - -#. Connect to any infrastructure_alerting node and run command 'crm status'. - -#. Shutdown node were vip_infrastructure_alerting_mgmt_vip was started. - -#. Check that vip_infrastructure_alerting was started on another infrastructure_alerting node. - -#. Check the plugin services using CLI. - -#. Check that Nagios UI works correctly. - -#. Check that no data lost after shutdown. - -#. Run OSTF. - - -Expected Result -::::::::::::::: - -The OSTF tests pass successfully. - -All the plugin services are running and work as expected after each -modification of the environment. - -vip_infrastructure_alerting_mgmt_vip was started on another node after shutdown. diff --git a/doc/qa/source/tests/uninstall_plugins.rst b/doc/qa/source/tests/uninstall_plugins.rst deleted file mode 100644 index 1f87b5f8d..000000000 --- a/doc/qa/source/tests/uninstall_plugins.rst +++ /dev/null @@ -1,18 +0,0 @@ - -+---------------+--------------------------------------------------------------------------------+ -| Test Case ID | uninstall_plugin | -+---------------+--------------------------------------------------------------------------------+ -| Description | Verify that the plugins can be uninstalled. | -+---------------+--------------------------------------------------------------------------------+ -| Prerequisites | The 4 plugins are installed on the Fuel node (see :ref:`install_lma_plugins`). | -+---------------+--------------------------------------------------------------------------------+ - -Steps -::::: - -#. Remove the plugins. - -Expected Result -::::::::::::::: - -The plugins are removed. diff --git a/doc/qa/source/tests/uninstall_plugins_with_env.rst b/doc/qa/source/tests/uninstall_plugins_with_env.rst deleted file mode 100644 index 9cce80406..000000000 --- a/doc/qa/source/tests/uninstall_plugins_with_env.rst +++ /dev/null @@ -1,25 +0,0 @@ - -+---------------+---------------------------------------------------------------------------------------+ -| Test Case ID | uninstall_plugin_with_deployed_env | -+---------------+---------------------------------------------------------------------------------------+ -| Description | Verify that the plugins can be uninstalled after the deployed environment is removed. | -+---------------+---------------------------------------------------------------------------------------+ -| Prerequisites | Environment deployed with the 4 plugins (see :ref:`deploy_lma_plugins`). | -+---------------+---------------------------------------------------------------------------------------+ - -Steps -::::: - -#. Try to remove the plugins using the Fuel CLI and ensure that the command - fails with "Can't delete plugin which is enabled for some environment". - -#. Remove the environment. - -#. Remove the plugins. - -Expected Result -::::::::::::::: - -An alert is raised when we try to delete plugins which are attached to an active environment. - -After the environment is removed, the plugins are removed successfully too. diff --git a/doc/user/Makefile b/doc/user/Makefile deleted file mode 100644 index da90cc3eb..000000000 --- a/doc/user/Makefile +++ /dev/null @@ -1,191 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# SVG to PDF conversion -SVG2PDF = inkscape -SVG2PDF_FLAGS = -# Build a list of SVG files to convert to PDF -PDF_FILES := $(foreach dir, ../images, $(patsubst %.svg,%.pdf,$(wildcard $(dir)/*.svg))) - - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - rm -f $(PDF_FILES) - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/LMAcollector.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/LMAcollector.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/LMAcollector" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/LMAcollector" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: $(PDF_FILES) - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: $(PDF_FILES) - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -# Rule for building the PDF files only -images: $(PDF_FILES) - -# Pattern rule for converting SVG to PDF -%.pdf : %.svg - $(SVG2PDF) -f $< -A $@ diff --git a/doc/user/source/_static/.gitkeep b/doc/user/source/_static/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/doc/user/source/appendix_alarms.rst b/doc/user/source/appendix_alarms.rst deleted file mode 100644 index aa84aa8cf..000000000 --- a/doc/user/source/appendix_alarms.rst +++ /dev/null @@ -1,2987 +0,0 @@ -.. _alarms: - -.. raw:: latex - - \pagebreak - -List of built-in alarms ------------------------ - -The following is a list of StackLight built-in alarms:: - - alarms: - - name: 'cpu-critical-controller' - description: 'The CPU usage is too high (controller node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - metric: cpu_wait - relational_operator: '>=' - threshold: 35 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-controller' - description: 'The CPU usage is high (controller node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 15 - window: 120 - periods: 0 - function: avg - - metric: cpu_wait - relational_operator: '>=' - threshold: 25 - window: 120 - periods: 0 - function: avg - - name: 'swap-usage-critical' - description: 'There is no more swap free space' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: swap_free - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: max - - name: 'swap-activity-warning' - description: 'The swap activity is high' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: swap_io_in - relational_operator: '>=' - threshold: 1048576 # 1 Mb/s - window: 120 - periods: 0 - function: avg - - metric: swap_io_out - relational_operator: '>=' - threshold: 1048576 # 1 Mb/s - window: 120 - periods: 0 - function: avg - - name: 'swap-usage-warning' - description: 'The swap free space is low' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: swap_percent_used - relational_operator: '>=' - threshold: 0.8 - window: 60 - periods: 0 - function: avg - - name: 'cpu-critical-compute' - description: 'The CPU usage is too high (compute node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 30 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-compute' - description: 'The CPU usage is high (compute node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 20 - window: 120 - periods: 0 - function: avg - - name: 'cpu-critical-rabbitmq' - description: 'The CPU usage is too high (RabbitMQ node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-rabbitmq' - description: 'The CPU usage is high (RabbitMQ node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 15 - window: 120 - periods: 0 - function: avg - - name: 'cpu-critical-mysql' - description: 'The CPU usage is too high (MySQL node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-mysql' - description: 'The CPU usage is high (MySQL node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 15 - window: 120 - periods: 0 - function: avg - - name: 'cpu-critical-storage' - description: 'The CPU usage is too high (storage node)' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 40 - window: 120 - periods: 0 - function: avg - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - name: 'cpu-warning-storage' - description: 'The CPU usage is high (storage node)' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 30 - window: 120 - periods: 0 - function: avg - - metric: cpu_idle - relational_operator: '<=' - threshold: 15 - window: 120 - periods: 0 - function: avg - - name: 'cpu-critical-default' - description: 'The CPU usage is too high' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_wait - relational_operator: '>=' - threshold: 35 - window: 120 - periods: 0 - function: avg - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - name: 'rabbitmq-disk-limit-critical' - description: 'RabbitMQ has reached the free disk threshold. All producers are blocked' - severity: 'critical' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_remaining_disk - relational_operator: '<=' - threshold: 0 - window: 20 - periods: 0 - function: min - - name: 'rabbitmq-disk-limit-warning' - description: 'RabbitMQ is getting close to the free disk threshold' - severity: 'warning' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_remaining_disk - relational_operator: '<=' - threshold: 104857600 # 100MB - window: 20 - periods: 0 - function: min - - name: 'rabbitmq-memory-limit-critical' - description: 'RabbitMQ has reached the memory threshold. All producers are blocked' - severity: 'critical' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_remaining_memory - relational_operator: '<=' - threshold: 0 - window: 20 - periods: 0 - function: min - - name: 'rabbitmq-memory-limit-warning' - description: 'RabbitMQ is getting close to the memory threshold' - severity: 'warning' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_remaining_memory - relational_operator: '<=' - threshold: 104857600 # 100MB - window: 20 - periods: 0 - function: min - - name: 'rabbitmq-queue-warning' - description: 'The number of outstanding messages is too high' - severity: 'warning' - # If the local RabbitMQ instance is down, it will be caught by the - # rabbitmq-check alarm - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: rabbitmq_messages - relational_operator: '>=' - threshold: 200 - window: 120 - periods: 0 - function: avg - - name: 'rabbitmq-pacemaker-down' - description: 'The RabbitMQ cluster is down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - logical_operator: 'and' - rules: - - metric: pacemaker_resource_percent - fields: - resource: rabbitmq - status: up - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'rabbitmq-pacemaker-critical' - description: 'The RabbitMQ cluster is critical because less than half of the nodes are up' - severity: 'critical' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - logical_operator: 'and' - rules: - - metric: pacemaker_resource_percent - fields: - resource: rabbitmq - status: up - relational_operator: '<' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'rabbitmq-pacemaker-warning' - description: 'The RabbitMQ cluster is degraded because some RabbitMQ nodes are missing' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - logical_operator: 'and' - rules: - - metric: pacemaker_resource_percent - fields: - resource: rabbitmq - status: up - relational_operator: '<' - threshold: 100 - window: 60 - periods: 0 - function: last - - name: 'apache-warning' - description: 'There is no Apache idle workers available' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: apache_idle_workers - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: min - - name: 'apache-check' - description: 'Apache cannot be checked' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: apache_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'log-fs-warning' - description: "The log filesystem's free space is low" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/log' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'log-fs-critical' - description: "The log filesystem's free space is too low" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/log' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'root-fs-warning' - description: "The root filesystem's free space is low" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'root-fs-critical' - description: "The root filesystem's free space is too low" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'mysql-fs-warning' - description: "The MySQL filesystem's free space is low" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/mysql' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'mysql-fs-critical' - description: "The MySQL filesystem's free space is too low" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/mysql' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'nova-fs-warning' - description: "The filesystem's free space is low (compute node)" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/nova' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'nova-fs-critical' - description: "The filesystem's free space is too low (compute node)" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/nova' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'other-fs-warning' - description: "The filesystem's free space is low" - severity: 'warning' - enabled: 'true' - no_data_policy: 'okay' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '!= /var/lib/nova && != /var/log && != /var/lib/mysql && != / && !~ ceph%-%d+$' - group_by: [fs] - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'other-fs-critical' - description: "The filesystem's free space is too low" - severity: 'critical' - enabled: 'true' - no_data_policy: 'okay' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '!= /var/lib/nova && != /var/log && != /var/lib/mysql && != / && !~ ceph%-%d+$' - group_by: [fs] - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'osd-disk-critical' - description: "The filesystem's free space is too low (OSD disk)" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - # Real FS is /var/lib/ceph/osd/ceph-0 but Collectd substituted '/' by '-' - fs: '=~ ceph/%d+$' - group_by: [fs] - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'nova-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on nova-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'nova-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'nova-logs-error' - description: 'Too many errors have been detected in Nova logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'nova' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'heat-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on heat-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'heat-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'heat-logs-error' - description: 'Too many errors have been detected in Heat logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'heat' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'swift-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on swift-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'swift-api || object-storage' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'swift-logs-error' - description: 'Too many errors have been detected in Swift logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'swift' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'cinder-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on cinder-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'cinder-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'cinder-logs-error' - description: 'Too many errors have been detected in Cinder logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'cinder' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'glance-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on glance-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'glance-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'glance-logs-error' - description: 'Too many errors have been detected in Glance logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'glance' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'neutron-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on neutron-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'neutron-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'neutron-logs-error' - description: 'Too many errors have been detected in Neutron logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'neutron' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'keystone-response-time-duration' - description: 'Keystone API is too slow' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: openstack_keystone_http_response_times - fields: - http_method: '== GET || == POST' - http_status: '!= 5xx' - relational_operator: '>' - threshold: 0.3 - window: 60 - periods: 0 - value: upper_90 - function: max - - name: 'keystone-public-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on keystone-public-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'keystone-public-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'keystone-admin-api-http-errors' - description: 'Too many 5xx HTTP errors have been detected on keystone-admin-api' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'keystone-admin-api' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'horizon-web-http-errors' - description: 'Too many 5xx HTTP errors have been detected on horizon' - severity: 'warning' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: haproxy_backend_response_5xx - fields: - backend: 'horizon-web || horizon-https' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 1 - function: diff - - name: 'keystone-logs-error' - description: 'Too many errors have been detected in Keystone logs' - severity: 'warning' - no_data_policy: 'okay' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: log_messages - fields: - service: 'keystone' - level: 'error' - relational_operator: '>' - threshold: 0.1 - window: 70 - periods: 0 - function: max - - name: 'mysql-node-connected' - description: 'The MySQL service has lost connectivity with the other nodes' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: mysql_cluster_connected - relational_operator: '==' - threshold: 0 - window: 30 - periods: 1 - function: min - - name: 'mysql-node-ready' - description: "The MySQL service isn't ready to serve queries" - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: mysql_cluster_ready - relational_operator: '==' - threshold: 0 - window: 30 - periods: 1 - function: min - - name: 'ceph-health-critical' - description: 'Ceph health is critical' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: ceph_health - relational_operator: '==' - threshold: 3 # HEALTH_ERR - window: 60 - function: max - - name: 'ceph-health-warning' - description: 'Ceph health is warning' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: ceph_health - relational_operator: '==' - threshold: 2 # HEALTH_WARN - window: 60 - function: max - - name: 'ceph-capacity-critical' - description: 'Ceph free capacity is too low' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: ceph_pool_total_percent_free - relational_operator: '<' - threshold: 2 - window: 60 - function: max - - name: 'ceph-capacity-warning' - description: 'Ceph free capacity is low' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: ceph_pool_total_percent_free - relational_operator: '<' - threshold: 5 - window: 60 - function: max - - name: 'elasticsearch-health-critical' - description: 'Elasticsearch cluster health is critical' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: elasticsearch_cluster_health - relational_operator: '==' - threshold: 3 # red - window: 60 - function: min - - name: 'elasticsearch-health-warning' - description: 'Elasticsearch health is warning' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: elasticsearch_cluster_health - relational_operator: '==' - threshold: 2 # yellow - window: 60 - function: min - - name: 'elasticsearch-fs-warning' - description: "The filesystem's free space is low (Elasticsearch node)" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/opt/es/data' # Real FS is /opt/es-data but Collectd substituted '/' by '-' - relational_operator: '<' - threshold: 20 # The low watermark for disk usage is 85% by default - window: 60 - periods: 0 - function: min - - name: 'elasticsearch-fs-critical' - description: "The filesystem's free space is too low (Elasticsearch node)" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/opt/es/data' # Real FS is /opt/es-data but Collectd substituted '/' by '-' - relational_operator: '<' - threshold: 15 # The high watermark for disk usage is 90% by default - window: 60 - periods: 0 - function: min - - name: 'influxdb-fs-warning' - description: "The filesystem's free space is low (InfluxDB node)" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/influxdb' - relational_operator: '<' - threshold: 10 - window: 60 - periods: 0 - function: min - - name: 'influxdb-fs-critical' - description: "The filesystem's free space is too low (InfluxDB node)" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - fields: - fs: '/var/lib/influxdb' - relational_operator: '<' - threshold: 5 - window: 60 - periods: 0 - function: min - - name: 'haproxy-check' - description: "HAProxy cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'rabbitmq-check' - description: "RabbitMQ cannot be checked" - # This alarm's severity is warning because the effective status of the - # RabbitMQ cluster is computed by rabbitmq-pacemaker-* alarms. - # This alarm is still useful because it will report the node(s) on which - # RabbitMQ isn't running. - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: rabbitmq_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceph-mon-check' - description: "Ceph monitor cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: ceph_mon_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceph-osd-check' - description: "Ceph OSD cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: ceph_osd_check - relational_operator: '==' - threshold: 0 - window: 80 # The metric interval collection is 60s - periods: 0 - function: last - - name: 'pacemaker-check' - description: "Pacemaker cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: pacemaker_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'elasticsearch-check' - description: "Elasticsearch cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: elasticsearch_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'influxdb-check' - description: "InfluxDB cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: influxdb_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'libvirt-check' - description: "Libvirt cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: libvirt_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'memcached-check' - description: "memcached cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: memcached_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'mysql-check' - description: "MySQL cannot be checked" - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: mysql_check - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'network-warning-dropped-rx' - description: "Some received packets have been dropped" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: if_dropped_rx - relational_operator: '>' - threshold: 100 - window: 60 - periods: 0 - function: avg - - name: 'network-critical-dropped-rx' - description: "Too many received packets have been dropped" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: if_dropped_rx - relational_operator: '>' - threshold: 1000 - window: 60 - periods: 0 - function: avg - - name: 'network-warning-dropped-tx' - description: "Some transmitted packets have been dropped" - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: if_dropped_tx - relational_operator: '>' - threshold: 100 - window: 60 - periods: 0 - function: avg - - name: 'network-critical-dropped-tx' - description: "Too many transmitted packets have been dropped" - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: if_dropped_tx - relational_operator: '>' - threshold: 1000 - function: avg - window: 60 - - name: 'instance-creation-time-warning' - description: "Instance creation takes too much time" - severity: 'warning' - no_data_policy: 'okay' # This is a sporadic metric - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_instance_creation_time - relational_operator: '>' - threshold: 20 - window: 600 - periods: 0 - function: avg - - name: 'hdd-errors-critical' - description: 'Errors on hard drive(s) have been detected' - severity: 'critical' - enabled: 'true' - no_data_policy: okay - trigger: - rules: - - metric: hdd_errors_rate - group_by: ['device'] - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: max - - name: 'total-nova-free-vcpu-warning' - description: 'There is none VCPU available for new instances' - severity: 'warning' - enabled: 'true' - no_data_policy: skip # the metric is only collected from the aggregator node - trigger: - rules: - - metric: openstack_nova_total_free_vcpus - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: max - - name: 'total-nova-free-memory-warning' - description: 'There is none memory available for new instances' - severity: 'warning' - enabled: 'true' - no_data_policy: skip # the metric is only collected from the aggregator node - trigger: - rules: - - metric: openstack_nova_total_free_ram - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: max - - name: 'nova-aggregates-free-memory-warning' - description: "The nova aggregates free memory percent is low" - severity: 'warning' - enabled: 'true' - no_data_policy: skip # the metric is only collected from the aggregator node - trigger: - rules: - - metric: openstack_nova_aggregate_free_ram_percent - group_by: [aggregate] - relational_operator: '<' - threshold: 10.0 - window: 60 - periods: 0 - function: min - - name: 'nova-aggregates-free-memory-critical' - description: "The nova aggregates free memory percent is too low" - severity: 'critical' - enabled: 'true' - no_data_policy: skip # the metric is only collected from the aggregator node - trigger: - rules: - - metric: openstack_nova_aggregate_free_ram_percent - group_by: [aggregate] - relational_operator: '<' - threshold: 1.0 - window: 60 - periods: 0 - function: min - - # Adds alarm on local check for OpenStack services endpoint - - name: 'cinder-api-local-endpoint' - description: 'Cinder API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'cinder-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-api-local-endpoint' - description: 'Glance API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'glance-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-api-local-endpoint' - description: 'Heat API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'heat-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-local-endpoint' - description: 'Heat CFN API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'heat-cfn-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-local-endpoint' - description: 'Keystone public API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'keystone-public-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-local-endpoint' - description: 'Neutron API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'neutron-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-api-local-endpoint' - description: 'Nova API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'nova-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-api-local-endpoint' - description: 'Swift API is locally down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: openstack_check_local_api - fields: - service: 'swift-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - # Following are the OpenStack service check API definitions and - # also InfluxDB API - - name: 'influxdb-api-check-failed' - description: 'Endpoint check for InfluxDB is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: http_check - fields: - service: 'influxdb-cluster' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-api-check-failed' - description: 'Endpoint check for nova-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'nova-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-check-failed' - description: 'Endpoint check for neutron-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'neutron-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-api-check-failed' - description: 'Endpoint check for cinder-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'cinder-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-v2-api-check-failed' - description: 'Endpoint check for cinder-v2-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'cinder-v2-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-api-check-failed' - description: 'Endpoint check for glance-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'glance-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-api-check-failed' - description: 'Endpoint check for heat-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'heat-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-check-failed' - description: 'Endpoint check for heat-cfn-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'heat-cfn-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-api-check-failed' - description: 'Endpoint check for swift-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'swift-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-s3-api-check-failed' - description: 'Endpoint check for swift-s3-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'swift-s3-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-check-failed' - description: 'Endpoint check for keystone-public-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'keystone-public-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceilometer-api-check-failed' - description: 'Endpoint check for ceilometer-api is failed' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the controller running the management VIP - enabled: 'true' - trigger: - rules: - - metric: openstack_check_api - fields: - service: 'ceilometer-api' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - # Following are the AFD generated to check API backends - # All backends are down - - name: 'elasticsearch-api-backends-all-down' - description: 'All Elasticsearch backends are down' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'elasticsearch-rest' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'kibana-api-backends-all-down' - description: 'All API backends are down for Kibana' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'kibana' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'influxdb-api-backends-all-down' - description: 'All API backends are down for InfluxDB' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'influxdb' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'grafana-api-backends-all-down' - description: 'All API backends are down for Grafana' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'grafana' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-registry-api-backends-all-down' - description: 'All API backends are down for glance-registry-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'glance-registry-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-api-backends-all-down' - description: 'All API backends are down for nova-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-api-backends-all-down' - description: 'All API backends are down for cinder-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'cinder-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'object-storage-api-backends-all-down' - description: 'All API backends are down for object-storage' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'object-storage' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-backends-all-down' - description: 'All API backends are down for heat-cfn-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-cfn-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'horizon-web-api-backends-all-down' - description: 'All API backends are down for horizon-web' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'horizon-web || horizon-https' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-novncproxy-websocket-api-backends-all-down' - description: 'All API backends are down for nova-novncproxy-websocket' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-novncproxy-websocket' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-api-backends-all-down' - description: 'All API backends are down for heat-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-backends-all-down' - description: 'All API backends are down for keystone-public-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'keystone-public-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cloudwatch-api-backends-all-down' - description: 'All API backends are down for heat-cloudwatch-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-cloudwatch-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-metadata-api-backends-all-down' - description: 'All API backends are down for nova-metadata-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-metadata-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'mysqld-tcp-api-backends-all-down' - description: 'All API backends are down for mysqld-tcp' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'mysqld-tcp' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-admin-api-backends-all-down' - description: 'All API backends are down for keystone-admin-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'keystone-admin-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-api-backends-all-down' - description: 'All API backends are down for glance-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'glance-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-backends-all-down' - description: 'All API backends are down for neutron-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'neutron-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-api-backends-all-down' - description: 'All API backends are down for swift-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'swift-api || object-storage' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceilometer-api-backends-all-down' - description: 'All API backends are down for ceilometer-api' - severity: 'down' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'ceilometer-api' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - # At least one backend is down - - name: 'elasticsearch-api-backends-one-down' - description: 'At least one API backend is down for elasticsearch' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'elasticsearch-rest' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'kibana-api-backends-one-down' - description: 'At least one API backend is down for kibana' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'kibana' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'influxdb-api-backends-one-down' - description: 'At least one API backend is down for influxdb' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'influxdb' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'grafana-api-backends-one-down' - description: 'At least one API backend is down for grafana' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'grafana' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-registry-api-backends-one-down' - description: 'At least one API backend is down for glance-registry-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'glance-registry-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-api-backends-one-down' - description: 'At least one API backend is down for nova-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-api-backends-one-down' - description: 'At least one API backend is down for cinder-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'cinder-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'object-storage-api-backends-one-down' - description: 'At least one API backend is down for object-storage' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'object-storage' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-backends-one-down' - description: 'At least one API backend is down for heat-cfn-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-cfn-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'horizon-web-api-backends-one-down' - description: 'At least one API backend is down for horizon-web' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'horizon-web || horizon-https' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-novncproxy-websocket-api-backends-one-down' - description: 'At least one API backend is down for nova-novncproxy-websocket' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-novncproxy-websocket' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-api-backends-one-down' - description: 'At least one API backend is down for heat-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-backends-one-down' - description: 'At least one API backend is down for keystone-public-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'keystone-public-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'heat-cloudwatch-api-backends-one-down' - description: 'At least one API backend is down for heat-cloudwatch-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'heat-cloudwatch-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-metadata-api-backends-one-down' - description: 'At least one API backend is down for nova-metadata-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'nova-metadata-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'mysqld-tcp-api-backends-one-down' - description: 'At least one API backend is down for mysqld-tcp' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'mysqld-tcp' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'keystone-admin-api-backends-one-down' - description: 'At least one API backend is down for keystone-admin-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'keystone-admin-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'glance-api-backends-one-down' - description: 'At least one API backend is down for glance-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'glance-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-backends-one-down' - description: 'At least one API backend is down for neutron-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'neutron-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'swift-api-backends-one-down' - description: 'At least one API backend is down for swift-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'swift-api || object-storage' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'ceilometer-api-backends-one-down' - description: 'At least one API backend is down for ceilometer-api' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers - fields: - backend: 'ceilometer-api' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - # Less than 50% of backends are up - - name: 'elasticsearch-api-backends-majority-down' - description: 'Less than 50% of backends are up for elasticsearch' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'elasticsearch-rest' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'kibana-api-backends-majority-down' - description: 'Less than 50% of backends are up for kibana' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'kibana' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'influxdb-api-backends-majority-down' - description: 'Less than 50% of backends are up for influxdb' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'influxdb' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'grafana-api-backends-majority-down' - description: 'Less than 50% of backends are up for grafana' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'grafana' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'glance-registry-api-backends-majority-down' - description: 'Less than 50% of backends are up for glance-registry-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'glance-registry-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-api-backends-majority-down' - description: 'Less than 50% of backends are up for nova-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'nova-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'cinder-api-backends-majority-down' - description: 'Less than 50% of backends are up for cinder-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'cinder-api' - state: 'up' - - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'object-storage-api-backends-majority-down' - description: 'Less than 50% of backends are up for object-storage' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'object-storage' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'heat-cfn-api-backends-majority-down' - description: 'Less than 50% of backends are up for heat-cfn-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'heat-cfn-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'horizon-web-api-backends-majority-down' - description: 'Less than 50% of backends are up for horizon-web' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'horizon-web || horizon-https' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-novncproxy-websocket-api-backends-majority-down' - description: 'Less than 50% of backends are up for nova-novncproxy-websocket' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'nova-novncproxy-websocket' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'heat-api-backends-majority-down' - description: 'Less than 50% of backends are up for heat-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'heat-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'keystone-public-api-backends-majority-down' - description: 'Less than 50% of backends are up for keystone-public-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'keystone-public-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'heat-cloudwatch-api-backends-majority-down' - description: 'Less than 50% of backends are up for heat-cloudwatch-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'heat-cloudwatch-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-metadata-api-backends-majority-down' - description: 'Less than 50% of backends are up for nova-metadata-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'nova-metadata-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'mysqld-tcp-api-backends-majority-down' - description: 'Less than 50% of backends are up for mysqld-tcp' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'mysqld-tcp' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'keystone-admin-api-backends-majority-down' - description: 'Less than 50% of backends are up for keystone-admin-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'keystone-admin-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'glance-api-backends-majority-down' - description: 'Less than 50% of backends are up for glance-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'glance-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-api-backends-majority-down' - description: 'Less than 50% of backends are up for neutron-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'neutron-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'swift-api-backends-majority-down' - description: 'Less than 50% of backends are up for swift-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'swift-api || object-storage' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'ceilometer-api-backends-majority-down' - description: 'Less than 50% of backends are up for ceilometer-api' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: haproxy_backend_servers_percent - fields: - backend: 'ceilometer-api' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - # Following are the AFD generated to check workers - # All workers are down - - name: 'nova-scheduler-all-down' - description: 'All Nova schedulers are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'scheduler' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-cert-all-down' - description: 'All Nova certs are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'cert' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-consoleauth-all-down' - description: 'All Nova consoleauths are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'consoleauth' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-compute-all-down' - description: 'All Nova computes are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'compute' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-conductor-all-down' - description: 'All Nova conductors are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'conductor' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-scheduler-all-down' - description: 'All Cinder schedulers are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services - fields: - service: 'scheduler' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-volume-all-down' - description: 'All Cinder volumes are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services - fields: - service: 'volume' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-l3-all-down' - description: 'All Neutron L3 agents are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'l3' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-dhcp-all-down' - description: 'All Neutron DHCP agents are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'dhcp' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-metadata-all-down' - description: 'All Neutron metadata agents are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'metadata' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-openvswitch-all-down' - description: 'All Neutron openvswitch agents are down' - severity: 'down' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'openvswitch' - state: 'up' - relational_operator: '==' - threshold: 0 - window: 60 - periods: 0 - function: last - # At least one backend is down - - name: 'nova-scheduler-one-down' - description: 'At least one Nova scheduler is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'scheduler' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-cert-one-down' - description: 'At least one Nova cert is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'cert' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-consoleauth-one-down' - description: 'At least one Nova consoleauth is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'consoleauth' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-compute-one-down' - description: 'At least one Nova compute is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'compute' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'nova-conductor-one-down' - description: 'At least one Nova conductor is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services - fields: - service: 'conductor' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-scheduler-one-down' - description: 'At least one Cinder scheduler is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services - fields: - service: 'scheduler' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'cinder-volume-one-down' - description: 'At least one Cinder volume is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services - fields: - service: 'volume' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-l3-one-down' - description: 'At least one L3 agent is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'l3' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-dhcp-one-down' - description: 'At least one DHCP agent is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'dhcp' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-metadata-one-down' - description: 'At least one metadata agents is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'metadata' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - - name: 'neutron-openvswitch-one-down' - description: 'At least one openvswitch agents is down' - severity: 'warning' - no_data_policy: 'skip' # the metric is only collected from the DC node - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents - fields: - service: 'openvswitch' - state: 'down' - relational_operator: '>' - threshold: 0 - window: 60 - periods: 0 - function: last - # Less than 50% of service are up (compared to up and down). - - name: 'nova-scheduler-majority-down' - description: 'Less than 50% of Nova schedulers are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'scheduler' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-cert-majority-down' - description: 'Less than 50% of Nova certs are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'cert' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-consoleauth-majority-down' - description: 'Less than 50% of Nova consoleauths are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'consoleauth' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-compute-majority-down' - description: 'Less than 50% of Nova computes are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'compute' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'nova-conductor-majority-down' - description: 'Less than 50% of Nova conductors are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_nova_services_percent - fields: - service: 'conductor' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'cinder-scheduler-majority-down' - description: 'Less than 50% of Cinder schedulers are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services_percent - fields: - service: 'scheduler' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'cinder-volume-majority-down' - description: 'Less than 50% of Cinder volumes are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_cinder_services_percent - fields: - service: 'volume' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-l3-majority-down' - description: 'Less than 50% of Neutron L3 agents are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents_percent - fields: - service: 'l3' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-dhcp-majority-down' - description: 'Less than 50% of Neutron DHCP agents are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents_percent - fields: - service: 'dhcp' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-metadata-majority-down' - description: 'Less than 50% of Neutron metadata agents are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents_percent - fields: - service: 'metadata' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last - - name: 'neutron-openvswitch-majority-down' - description: 'Less than 50% of Neutron openvswitch agents are up' - severity: 'critical' - enabled: 'true' - trigger: - rules: - - metric: openstack_neutron_agents_percent - fields: - service: 'openvswitch' - state: 'up' - relational_operator: '<=' - threshold: 50 - window: 60 - periods: 0 - function: last diff --git a/doc/user/source/appendix_metrics.rst b/doc/user/source/appendix_metrics.rst deleted file mode 100644 index 07a2c85c3..000000000 --- a/doc/user/source/appendix_metrics.rst +++ /dev/null @@ -1,86 +0,0 @@ -.. _metrics: - -List of metrics ---------------- - -The following is a list of metrics that are emitted by the StackLight Collector. -The metrics are listed by category, then by metric name. - -System -++++++ - -.. include:: metrics/system.rst - -Apache -++++++ - -.. include:: metrics/apache.rst - -MySQL -+++++ - -.. include:: metrics/mysql.rst - -RabbitMQ -++++++++ - -.. include:: metrics/rabbitmq.rst - -HAProxy -+++++++ - -.. include:: metrics/haproxy.rst - -Memcached -+++++++++ - -.. include:: metrics/memcached.rst - -Libvirt -+++++++ - -.. include:: metrics/libvirt.rst - - -OpenStack -+++++++++ - -.. include:: metrics/openstack.rst - - -Ceph -++++ - -.. include:: metrics/ceph.rst - -Pacemaker -+++++++++ - -.. include:: metrics/pacemaker.rst - -Clusters -++++++++ - -.. include:: metrics/clusters.rst - -Self-monitoring -+++++++++++++++ - -.. include:: metrics/lma.rst - - -Elasticsearch -+++++++++++++ - -.. include:: metrics/elasticsearch.rst - - -InfluxDB -++++++++ - -.. include:: metrics/influxdb.rst - -Checks -++++++ - -.. include:: metrics/checks.rst diff --git a/doc/user/source/conf.py b/doc/user/source/conf.py deleted file mode 100644 index 0606d35fd..000000000 --- a/doc/user/source/conf.py +++ /dev/null @@ -1,265 +0,0 @@ -# -*- coding: utf-8 -*- -# -# LMA collector documentation build configuration file, created by -# sphinx-quickstart on Tue Jan 27 10:27:29 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'The StackLight Collector Plugin for Fuel' -copyright = u'2016, Mirantis Inc.' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.1' -# The full version, including alpha/beta/rc tags. -release = '1.1.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [ - 'metrics/*.rst', -] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# "<project> v<release> documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a <link> tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'LMAcollectordoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'LMAcollector.tex', u'The StackLight Collector Plugin for Fuel Documentation', - u'Mirantis Inc.', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'lmacollector', u'The StackLight Collector Plugin for Fuel Documentation', - [u'Mirantis Inc.'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'LMAcollector', u'The StackLight Collector Plugin for Fuel Documentation', - u'Mirantis Inc.', 'LMAcollector', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - -# make latex stop printing blank pages between sections -# http://stackoverflow.com/questions/5422997/sphinx-docs-remove-blank-pages-from-generated-pdfs -latex_elements = {'classoptions': ',openany,oneside', 'babel': - '\\usepackage[english]{babel}'} diff --git a/doc/user/source/configure_alarms.rst b/doc/user/source/configure_alarms.rst deleted file mode 100644 index 5da1d0e9a..000000000 --- a/doc/user/source/configure_alarms.rst +++ /dev/null @@ -1,1113 +0,0 @@ -.. _configure_alarms: - -Overview --------- - -The process of running alarms in StackLight is not centralized, as it is often -the case in more conventional monitoring systems, but distributed across all -the StackLight Collectors. - -Each Collector is individually responsible for monitoring the resources and -services that are deployed on the node and for reporting any anomaly or fault -it has detected to the Aggregator. - -The anomaly and fault detection logic in StackLight is designed more like an -*expert system* in that the Collector and the Aggregator use artifacts we -can refer to as *facts* and *rules*. - -The *facts* are the operational data ingested in the StackLight's -stream-processing pipeline. The *rules* are either alarm rules or aggregation -rules. They are declaratively defined in YAML files that can be modified. -Those rules are turned into a collection of Lua plugins that are executed by -the Collector and the Aggregator. They are generated dynamically using the -Puppet modules of the StackLight Collector Plugin. - -The following are the two types of Lua plugins related to the processing of -alarms: - -* The **AFD plugin** -- Anomaly and Fault Detection plugin -* The **GSE plugin** -- Global Status Evaluation plugin - -These plugins create special types of metrics, as follows: - -* The **AFD metric**, which contains information about the health status of a - node or service in the OpenStack environment. The AFD metrics are sent on a - regular basis to the Aggregator where they are further processed by the GSE - plugins. - -* The **GSE metric**, which contains information about the health status of a - cluster in the OpenStack environment. A cluster is a logical grouping of - nodes or services. We call them node clusters and service clusters hereafter. - A service cluster can be anything like a cluster of API endpoints or a - cluster of workers. A cluster of nodes is a grouping of nodes that have the - same role. For example, *compute* or *storage*. - -.. note:: The AFD and GSE metrics are new types of metrics introduced in - StackLight version 0.8. They contain detailed information about the fault - and anomalies detected by StackLight. For more information about the - message structure of these metrics, refer to - `Metrics section of the Developer Guide - <http://lma-developer-guide.readthedocs.io/en/latest/metrics.html>`_. - -The following figure shows the StackLight stream-processing pipeline workflow: - -.. figure:: ../../images/AFD_and_GSE_message_flow.* - :width: 800 - :alt: Message flow for the AFD and GSE metrics - -.. raw:: latex - - \pagebreak - -The AFD and GSE plugins ------------------------ - -The current version of StackLight contains the following three types of GSE -plugins: - -* The **Service Cluster GSE Plugin**, which receives AFD metrics for services - from the AFD plugins. -* The **Node Cluster GSE Plugin**, which receives AFD metrics for nodes - from the AFD plugins. -* The **Global Cluster GSE Plugin**, which receives GSE metrics from the - GSE plugins above. It aggregates and correlates the GSE metrics to issue a - global health status for the top-level clusters like Nova, MySQL, and others. - -The health status exposed in the GSE metrics is as follows: - -* ``Down``: One or several primary functions of a cluster has failed or is - failing. For example, the API service for Nova or Cinder is not accessible. -* ``Critical``: One or several primary functions of a cluster are severely - degraded. The quality of service delivered to the end user is severely - impacted. -* ``Warning``: One or several primary functions of the cluster are slightly - degraded. The quality of service delivered to the end user is slightly - impacted. -* ``Unknown``: There is not enough data to infer the actual health status of - the cluster. -* ``Okay``: None of the above was found to be true. - -The AFD and GSE persisters --------------------------- - -The AFD and GSE metrics are also consumed by other types of Lua plugins called -**persisters**: - -* The **InfluxDB persister** transforms the GSE metrics into InfluxDB data - points and Grafana annotations. They are used in Grafana to graph the health - status of the OpenStack clusters. -* The **Elasticsearch persister** transforms the AFD metrics into events that - are indexed in Elasticsearch. Using Kibana, these events can be searched to - display a fault or an anomaly that occurred in the environment (not yet - implemented). -* The **Nagios persister** transforms the GSE and AFD metrics into passive - checks that are sent to Nagios for alerting and escalation. - -New persisters can be easily created to feed other systems with the -operational insight contained in the AFD and GSE metrics. - -.. _alarm_configuration: - -Alarms configuration --------------------- - -StackLight comes with a predefined set of alarm rules. We have tried to make -these rules as comprehensive and relevant as possible, but your mileage may -vary depending on the specifics of your OpenStack environment and monitoring -requirements. Therefore, it is possible to modify those predefined rules and -create new ones. To do so, modify the ``/etc/hiera/override/alarming.yaml`` -file and apply the :ref:`Puppet manifest <puppet_apply>` that will dynamically -generate Lua plugins, known as the AFD Plugins, which are the actuators of the -alarm rules. But before you proceed, verify that understand the structure of -that file. - -.. _alarm_structure: - -Alarm structure -+++++++++++++++ - -An alarm rule is defined declaratively using the YAML syntax. For example:: - - name: 'fs-warning' - description: 'Filesystem free space is low' - severity: 'warning' - enabled: 'true' - trigger: - rules: - - metric: fs_space_percent_free - group_by: ['fs'] - relational_operator: '<' - fields: - fs: "=~ ceph/%d+$" - threshold: 5 - window: 60 - periods: 0 - function: min - -**Where** - -| name: -| Type: unicode -| The name of the alarm definition - -| description: -| Type: unicode -| A description of the alarm definition for humans - -| severity: -| Type: Enum(0 (down), 1 (critical) , 2 (warning)) -| The severity of the alarm - -| enabled: -| Type: Enum('true' | 'false') -| The alarm is enabled or disabled - -| relational_operator: -| Type: Enum('lt' | '<' | 'gt' | '>' | 'lte' | '<=' | 'gte' | '>=') -| The comparison against the alarm threshold - -| rules -| Type: list -| List of rules to execute - -| logical_operator -| Type: Enum('and' | '&&' | 'or' | '||') -| The conjunction relation for the alarm rules - -| metric -| Type: unicode -| The name of the metric - -| value -| Type: unicode -| The value of the metric - -| group_by -| Type: list -| The list of fields to group by. - For example, the alarm definition sample given above would apply the rule - for each of the file system mount points associated with the - ``fs_space_percent_free`` metric. - -| fields -| Type: list -| List of field name/value pairs, also known as dimensions, used to select - a particular device for the metric, such as a network interface name or - file system mount point. If the value is not provided, then the rule - applies to all the aggregated values for the specified field name. - In the example above, the rule applies to the metrics having an **fs** - dimension that matches the pattern **"=~ ceph/%d+$"**. - See :ref:`Dimension pattern matching <dim_pattern_matching>`. - -| window -| Type: integer -| The in-memory time-series analysis window in seconds - -| periods -| Type: integer -| The number of prior time-series analysis window to compare the window with -| (this is not implemented yet). - -| function -| Type: enum('last' | 'min' | 'max' | 'sum' | 'count' | 'avg' | 'median' | 'mode' | 'roc' | 'mww' | 'mww_nonparametric') -| Where: -| last: -| returns the last value of all the values -| min: -| returns the minimum of all the values -| max: -| returns the maximum of all the values -| sum: -| returns the sum of all the values -| count: -| returns the number of metric observations -| avg: -| returns the arithmetic mean of all the values -| median: -| returns the middle value of all the values (not implemented yet) -| mode: -| returns the value that occurs most often in all the values -| (not implemented yet) -| roc: -| The 'roc' function detects a significant rate of change when comparing - current metrics values with historical data. To achieve this, it - computes the average of the values in the current window and the - average of the values in the window before the current window and - compares the difference against the standard deviation of the - historical window. The function returns ``true`` if the difference - exceeds the standard deviation multiplied by the 'threshold' value. - This function uses the rate of change algorithm already available in the - anomaly detection module of Heka. It can only be applied to normal - distributions. With an alarm rule using the 'roc' function, the - 'window' parameter specifies the duration in seconds of the current - window, and the 'periods' parameter specifies the number of windows - used for the historical data. You need at least one period and the - 'periods' parameter must not be zero. If you choose a period of 'p', - the function will compute the rate of change using a historical data - window of ('p' * window) seconds. For example, if you specify the - following in the alarm rule: -| -| window = 60 -| periods = 3 -| threshold = 1.5 -| -| the function will store in a circular buffer the value of the metrics - received during the last 300 seconds (5 minutes) where: -| -| Current window (CW) = 60 sec -| Previous window (PW) = 60 sec -| Historical window (HW) = 180 sec -| -| and apply the following formula: -| -| abs(avg(CW) - avg(PW)) > std(HW) * 1.5 ? true : false -| mww: -| returns the result (true, false) of the Mann-Whitney-Wilcoxon test - function of Heka that can be used only with normal distributions (not - implemented yet) -| mww-nonparametric: -| returns the result (true, false) of the Mann-Whitney-Wilcoxon test - function of Heka that can be used with non-normal distributions (not - implemented yet) -| diff: -| returns the difference between the last value and the first value of - all the values - -| threshold -| Type: float -| The threshold of the alarm rule - -.. _dim_pattern_matching: - -Dimension pattern matching -++++++++++++++++++++++++++ - -The alarming framework allows specifying alarms against metrics with a -filtering mechanism called **dimension pattern matching**. For details, see -the `specification <https://blueprints.launchpad.net/lma-toolchain/+spec/afd-alarm-fields-matching>`_. - -The pattern matching is evaluated against the field/dimension specified by the -alarm rule:: - - rules: - - metric: foo_metric - fields: - my_dimension: <PATTERN MATCHING EXPRESSION> - -where the pattern matching expression has the following format:: - - EXP ::= “<relation operator> string” - -Expressions can be combined with logical operator(s):: - - EXP (<logical_operator> EXP, ..) - -Where: - -* Logical operators: - - * OR: **||** - * AND: **&&** - -* Relational operators: - - * Strings and numbers: - - * Equality: **==** - * Not equal: **!=** - - * Strings only (for syntax, see `Lua pattern matching <http://www.lua.org/manual/5.1/manual.html#5.4.1>`_): - - * Match: **=~** - * Negated match: **!~** - - * Numbers only: - - * Greater than: **>** - * Greater than equals: **>=** - * Less than: **<** - * Less than equals: **<=** - -Example: - -+---------------+------------+----------+ -| Value | Pattern | Matching | -+===============+============+==========+ -| 10 | 10 | True | -+---------------+------------+----------+ -| 10 | == 10 | True | -+---------------+------------+----------+ -| 10 | != 42 | True | -+---------------+------------+----------+ -| 10 | > 42 | False | -+---------------+------------+----------+ -| 10 | >= 10 | True | -+---------------+------------+----------+ -| foo | == foo | True | -+---------------+------------+----------+ -| foo | == bar | False | -+---------------+------------+----------+ -| /var/log | =~ /log$ | True | -+---------------+------------+----------+ -| /data | !~ ^/data$ | False | -+---------------+------------+----------+ -| /var/log/data | !~ /data$ | False | -+---------------+------------+----------+ -| /var/log/data | !~ ^/data$ | True | -+---------------+------------+----------+ - - -Modify or create an alarm -+++++++++++++++++++++++++ - -To modify or create an alarm, edit the ``/etc/hiera/override/alarming.yaml`` -file. This file has the following sections: - -#. The ``alarms`` section contains a global list of alarms that are executed - by the Collectors. These alarms are global to the LMA toolchain and should - be kept identical on all nodes of the OpenStack environment. The following - is another example of the definition of an alarm:: - - alarms: - - name: 'cpu-critical-controller' - description: 'CPU critical on controller' - severity: 'critical' - enabled: 'true' - trigger: - logical_operator: 'or' - rules: - - metric: cpu_idle - relational_operator: '<=' - threshold: 5 - window: 120 - periods: 0 - function: avg - - metric: cpu_wait - relational_operator: '>=' - threshold: 35 - window: 120 - periods: 0 - function: avg - - This alarm is called 'cpu-critical-controller'. It says that CPU activity - is critical (severity: 'critical') if any of the rules in the alarm - definition evaluate to true. - - The rule says that the alarm will evaluate to 'true' if the value of the - metric ``cpu_idle`` has been in average (function: avg), below or equal - (relational_operator: <=) to 5 for the last 2 minutes (window: 120). - - OR (logical_operator: 'or') - - If the value of the metric **cpu_wait** has been in average (function: avg), - superior or equal (relational_operator: >=) to 35 for the last 2 minutes - (window: 120) - - Note that these metrics are expressed in percentage. - - What alarms are executed on which node depends on the mapping between the - alarm definition and the definition of a cluster as described in the - following sections. - -#. The ``node_cluster_roles`` section defines the mapping between the internal - definition of a cluster of nodes and one or several Fuel roles. - For example:: - - node_cluster_roles: - controller: ['primary-controller', 'controller'] - compute: ['compute'] - storage: ['cinder', 'ceph-osd'] - [ ... ] - - Creates a mapping between the 'primary-controller' and 'controller' Fuel - roles, and the internal definition of a cluster of nodes called 'controller'. - Likewise, the internal definition of a cluster of nodes called 'storage' is - mapped to the 'cinder' and 'ceph-osd' Fuel roles. The internal definition - of a cluster of nodes is used to assign the alarms to the relevant category - of nodes. This mapping is also used to configure the **passive checks** - in Nagios. Therefore, it is critically important to keep exactly the same - copy of ``/etc/hiera/override/alarming.yaml`` across all nodes of the - OpenStack environment including the node(s) where Nagios is installed. - -#. The ``service_cluster_roles`` section defines the mapping between the - internal definition of a cluster of services and one or several Fuel roles. - For example:: - - service_cluster_roles: - rabbitmq: ['primary-controller', 'controller'] - nova-api: ['primary-controller', 'controller'] - elasticsearch: ['primary-elasticsearch_kibana', 'elasticsearch_kibana'] - [ ... ] - - Creates a mapping between the 'primary-controller' and 'controller' Fuel - roles, and the internal definition of a cluster of services called 'rabbitmq'. - Likewise, the internal definition of a cluster of services called - 'elasticsearch' is mapped to the 'primary-elasticsearch_kibana' and - 'elasticsearch_kibana' Fuel roles. As for the clusters of nodes, the - internal definition of a cluster of services is used to assign the alarms - to the relevant category of services. - -#. The ``node_cluster_alarms`` section defines the mapping between the - internal definition of a cluster of nodes and the alarms that are assigned - to that category of nodes. For example:: - - node_cluster_alarms: - controller-nodes: - apply_to_node: controller - alerting: enabled - members: - cpu: - alarms: ['cpu-critical-controller', 'cpu-warning-controller'] - root-fs: - alarms: ['root-fs-critical', 'root-fs-warning'] - log-fs: - alarms: ['log-fs-critical', 'log-fs-warning'] - hdd-errors: - alerting: enabled_with_notification - alarms: ['hdd-errors-critical'] - - Creates four alarm groups for the cluster of controller nodes: - - * The *cpu* alarm group is mapped to two alarms defined in the ``alarms`` - section known as the 'cpu-critical-controller' and - 'cpu-warning-controller' alarms. These alarms monitor the CPU on the - controller nodes. The order matters here since the first alarm that - evaluates to 'true' stops the evaluation. Therefore, it is important - to start the list with the most critical alarms. - * The *root-fs* alarm group is mapped to two alarms defined in the - ``alarms`` section known as the 'root-fs-critical' and 'root-fs-warning' - alarms. These alarms monitor the root file system on the controller nodes. - * The *log-fs* alarm group is mapped to two alarms defined in the ``alarms`` - section known as the 'log-fs-critical' and 'log-fs-warning' alarms. These - alarms monitor the file system where the logs are created on the - controller nodes. - * The *hdd-errors* alarm group is mapped to the 'hdd-errors-critical' alarm - defined in the ``alarms`` section. This alarm monitors the ``kern.log`` - log entries containing critical IO errors detected by the kernel. - The *hdd-error* alarm obtains the *enabled_with_notification* alerting - attribute, meaning that the operator will be notified if any of the - controller nodes encounters a disk failure. Other alarms do not trigger - notification per node but at an aggregated cluster level. - - .. note:: An *alarm group* is a mere implementation artifact (although it - has functional value) that is primarily used to distribute the alarms - evaluation workload across several Lua plugins. Since the Lua plugins - runtime is sandboxed within Heka, it is preferable to run smaller sets - of alarms in different plugins rather than a large set of alarms in a - single plugin. This is to avoid having alarms evaluation plugins - shut down by Heka. Furthermore, the alarm groups are used to identify - what is called a *source*. A *source* is a tuple in which we associate - a cluster with an alarm group. For example, the tuple - ['controller', 'cpu'] is a *source*. It associates a 'controller' - cluster with the 'cpu' alarm group. The tuple ['controller', 'root-fs'] - is another *source* example. The *source* is used by the GSE Plugins to - remember the AFD metrics it has received. If a GSE Plugin stops receiving - AFD metrics it used to get, then the GSE Plugin infers that the health - status of the cluster associated with the source is *Unknown*. - - This is evaluated every *ticker-interval*. By default, the - *ticker interval* for the GSE Plugins is set to 10 seconds. - -.. _aggreg_correl_config: - -Aggregation and correlation configuration ------------------------------------------ - -StackLight comes with a predefined set of aggregation rules and correlation -policies. However, you can create new aggregation rules and correlation -policies or modify the existing ones. To do so, modify the ``/etc/hiera/override/gse_filters.yaml`` file and apply the -:ref:`Puppet manifest <puppet_apply>` that will generate Lua plugins known as -the GSE Plugins, which are the actuators of these aggregation rules and -correlation policies. But before you proceed, verify that you understand the -structure of that file. - -.. note:: As for ``/etc/hiera/override/alarming.yaml``, it is critically - important to keep exactly the same copy of - ``/etc/hiera/override/gse_filters.yaml`` across all the nodes of the - OpenStack environment including the node(s) where Nagios is installed. - -The aggregation rules and correlation policies are defined in the ``/etc/hiera/override/gse_filters.yaml`` configuration file. - -This file has the following sections: - -#. The ``gse_policies`` section contains the :ref:`health status correlation - policies <gse_policies>` that apply to the node clusters and service - clusters. -#. The ``gse_cluster_service`` section contains the :ref:`aggregation rules - <gse_cluster_service>` for the service clusters. These aggregation rules - are actuated by the Service Cluster GSE Plugin that runs on the Aggregator. -#. The ``gse_cluster_node`` section contains the :ref:`aggregation rules - <gse_cluster_node>` for the node clusters. These aggregation rules are - actuated by the Node Cluster GSE Plugin that runs on the Aggregator. -#. The ``gse_cluster_global`` section contains the :ref:`aggregation - rules <gse_cluster_global>` for the so-called top-level clusters. A global - cluster is a kind of logical construct of node clusters and service - clusters. These aggregation rules are actuated by the Global Cluster GSE - Plugin that runs on the Aggregator. - -.. _gse_policies: - -Health status policies -++++++++++++++++++++++ - -The correlation logic implemented by the GSE plugins is policy-based. The -policies define how the GSE plugins infer the health status of a cluster. - -By default, there are two policies: - -* The **highest_severity** policy defines that the cluster's status depends on - the member with the highest severity, typically used for a cluster of - services. -* The **majority_of_members** policy defines that the cluster is healthy as - long as (N+1)/2 members of the cluster are healthy. This is typically used - for clusters managed by Pacemaker. - -A policy consists of a list of rules that are evaluated against the current -status of the cluster's members. When one of the rules matches, the cluster's -status gets the value associated with the rule and the evaluation stops. The -last rule of the list is usually a catch-all rule that defines the default -status if none of the previous rules matches. - -The following example shows the policy rule definition:: - - # The following rule definition reads as: "the cluster's status is critical - # if more than 50% of its members are either down or critical" - - status: critical - trigger: - logical_operator: or - rules: - - function: percent - arguments: [ down, critical ] - relational_operator: '>' - threshold: 50 - -Where - -| status: -| Type: Enum(down, critical, warning, okay, unknown) -| The cluster's status if the condition is met - -| logical_operator -| Type: Enum('and' | '&&' | 'or' | '||') -| The conjunction relation for the condition rules - -| rules -| Type: list -| List of condition rules to execute - -| function -| Type: enum('count' | 'percent') -| Where: -| count: -| returns the *number of members* that match the passed value(s). -| percent: -| returns the *percentage of members* that match the passed value(s). - -| arguments: -| Type: list of status values -| List of status values passed to the function - -| relational_operator: -| Type: Enum('lt' | '<' | 'gt' | '>' | 'lte' | '<=' | 'gte' | '>=') -| The comparison against the threshold - -| threshold -| Type: float -| The threshold value - -Consider the policy called *highest_severity*:: - - gse_policies: - - highest_severity: - - status: down - trigger: - logical_operator: or - rules: - - function: count - arguments: [ down ] - relational_operator: '>' - threshold: 0 - - status: critical - trigger: - logical_operator: or - rules: - - function: count - arguments: [ critical ] - relational_operator: '>' - threshold: 0 - - status: warning - trigger: - logical_operator: or - rules: - - function: count - arguments: [ warning ] - relational_operator: '>' - threshold: 0 - - status: okay - trigger: - logical_operator: or - rules: - - function: count - arguments: [ okay ] - relational_operator: '>' - threshold: 0 - - status: unknown - -The policy definition reads as follows: - -* The status of the cluster is ``Down`` if the status of at least one - cluster's member is ``Down``. - -* Otherwise, the status of the cluster is ``Critical`` if the status of at - least one cluster's member is ``Critical``. - -* Otherwise, the status of the cluster is ``Warning`` if the status of at - least one cluster's member is ``Warning``. - -* Otherwise, the status of the cluster is ``Okay`` if the status of at least - one cluster's entity is *Okay*. - -* Otherwise, the status of the cluster is ``Unknown``. - -.. _gse_cluster_service: - -Service cluster aggregation rules -+++++++++++++++++++++++++++++++++ - -The service cluster aggregation rules are used to designate the members of a -service cluster along with the AFD metrics that must be taken into account to -derive a health status for the service cluster. The following is an example of -the service cluster aggregation rules:: - - gse_cluster_service: - input_message_types: - - afd_service_metric - aggregator_flag: true - cluster_field: service - member_field: source - output_message_type: gse_service_cluster_metric - output_metric_name: cluster_service_status - interval: 10 - warm_up_period: 20 - alerting: enabled_with_notification - clusters: - nova-api: - policy: highest_severity - group_by: member - members: - - backends - - endpoint - - http_errors - -Where - -| input_message_types -| Type: list -| The type(s) of AFD metric messages consumed by the GSE plugin. - -| aggregator_flag -| Type: boolean -| Whether or not the input messages are received from the upstream collectors. - This is true for the Service and Node Cluster plugins and false for the - Global Cluster plugin. - -| cluster_field -| Type: unicode -| The field in the input message used by the GSE plugin to associate the - AFD metrics to the clusters. - -| member_field -| Type: unicode -| The field in the input message used by the GSE plugin to identify the - cluster members. - -| output_message_type -| Type: unicode -| The type of metric messages emitted by the GSE plugin. - -| output_metric_name -| Type: unicode -| The Fields[name] value of the metric messages that the GSE plugin emits. - -| interval -| Type: integer -| The interval (in seconds) at which the GSE plugin emits its metric messages. - -| warm_up_period -| Type: integer -| The number of seconds after a (re)start that the GSE plugin will wait - before emitting its metric messages. - -| alerting -| Type: string (one of 'disabled', 'enabled' or 'enabled_with_notification'). -| The alerting configuration of the service clusters. - -| clusters -| Type: list -| The list of service clusters that the plugin handles. See - :ref:`service_cluster` for details. - -.. _service_cluster: - -Service cluster definition -++++++++++++++++++++++++++ - -The following example shows the service clusters definition:: - - gse_cluster_service: - [...] - clusters: - nova-api: - members: - - backends - - endpoint - - http_errors - group_by: member - policy: highest_severity - -Where - -| members -| Type: list -| The list of cluster members. - The AFD messages that are associated with the cluster when the - ``cluster_field`` value is equal to the cluster name and the - ``member_field`` value is in this list. - -| group_by -| Type: Enum(member, hostname) -| This parameter defines how the incoming AFD metrics are aggregated. -| -| member: -| aggregation by member, irrespective of the host that emitted the AFD -| metric. This setting is typically used for AFD metrics that are not -| host-centric. -| -| hostname: -| aggregation by hostname then by member. -| This setting is typically used for AFD metrics that are host-centric, -| such as those working on the file system or CPU usage metrics. - -| policy: -| Type: unicode -| The policy to use for computing the service cluster status. - See :ref:`gse_policies` for details. - -A closer look into the example above defines that the Service Cluster GSE -plugin resulting from those rules will emit a *gse_service_cluster_metric* -message every 10 seconds to report the current status of the *nova-api* -cluster. This status is computed using the *afd_service_metric* metric for -which Fields[service] is 'nova-api' and Fields[source] is one of 'backends', -'endpoint', or 'http_errors'. The 'nova-api' cluster's status is computed using -the 'highest_severity' policy, which means that it will be equal to the 'worst' -status across all members. - -.. _gse_cluster_node: - -Node cluster aggregation rules -++++++++++++++++++++++++++++++ - -The node cluster aggregation rules are used to designate the members of a node -cluster along with the AFD metrics that must be taken into account to derive -a health status for the node cluster. The following is an example of the node -cluster aggregation rules:: - - gse_cluster_node: - input_message_types: - - afd_node_metric - aggregator_flag: true - # the field in the input messages to identify the cluster - cluster_field: node_role - # the field in the input messages to identify the cluster's member - member_field: source - output_message_type: gse_node_cluster_metric - output_metric_name: cluster_node_status - interval: 10 - warm_up_period: 80 - alerting: enabled_with_notification - clusters: - controller: - policy: majority_of_members - group_by: hostname - members: - - cpu - - root-fs - - log-fs - -Where - -| input_message_types -| Type: list -| The type(s) of AFD metric messages consumed by the GSE plugin. - -| aggregator_flag -| Type: boolean -| Whether or not the input messages are received from the upstream collectors. - This is true for the Service and Node Cluster plugins and false for the - Global Cluster plugin. - -| cluster_field -| Type: unicode -| The field in the input message used by the GSE plugin to associate the - AFD metrics to the clusters. - -| member_field -| Type: unicode -| The field in the input message used by the GSE plugin to identify the - cluster members. - -| output_message_type -| Type: unicode -| The type of metric messages emitted by the GSE plugin. - -| output_metric_name -| Type: unicode -| The Fields[name] value of the metric messages that the GSE plugin emits. - -| interval -| Type: integer -| The interval (in seconds) at which the GSE plugin emits its metric messages. - -| warm_up_period -| Type: integer -| The number of seconds after a (re)start that the GSE plugin will wait - before emitting its metric messages. - -| alerting -| Type: string (one of 'disabled', 'enabled' or 'enabled_with_notification'). -| The alerting configuration of the node clusters. - -| clusters -| Type: list -| The list of node clusters that the plugin handles. See - :ref:`node_cluster` for details. - -.. _node_cluster: - -Node cluster definition -+++++++++++++++++++++++ - -The following example shows the node clusters definition:: - - gse_cluster_node: - [...] - clusters: - controller: - policy: majority_of_members - group_by: hostname - members: - - cpu - - root-fs - - log-fs - -Where - -| members -| Type: list -| The list of cluster members. - The AFD messages are associated to the cluster when the ``cluster_field`` - value is equal to the cluster name and the ``member_field`` value is in - this list. - -| group_by -| Type: Enum(member, hostname) -| This parameter defines how the incoming AFD metrics are aggregated. -| -| member: -| aggregation by member, irrespective of the host that emitted the AFD -| metric. This setting is typically used for AFD metrics that are not -| host-centric. -| -| hostname: -| aggregation by hostname then by member. -| This setting is typically used for AFD metrics that are host-centric, -| such as those working on the file system or CPU usage metrics. - -| policy: -| Type: unicode -| The policy to use for computing the node cluster status. - See :ref:`gse_policies` for details. - -A closer look into the example above defines that the Node Cluster GSE plugin -resulting from those rules will emit a *gse_node_cluster_metric* message every -10 seconds to report the current status of the *controller* cluster. This -status is computed using the *afd_node_metric* metric for which -Fields[node_role] is 'controller' and Fields[source] is one of 'cpu', -'root-fs' or 'log-fs'. The 'controller' cluster's status is computed using the 'majority_of_members' policy which means that it will be equal to the 'majority' -status across all members. - -.. _gse_cluster_global: - -Top-level cluster aggregation rules -+++++++++++++++++++++++++++++++++++ - -The top-level aggregation rules aggregate GSE metrics from the Service -Cluster GSE Plugin and the Node Cluster GSE Plugin. This is the last -aggregation stage that issues health status for the top-level clusters. -A top-level cluster is a logical construct of service and node clustering. -By default, we define that the health status of Nova, as a top-level cluster, -depends on the health status of several service clusters related to Nova and -the health status of the 'controller' and 'compute' node clusters. But it can -be anything. For example, you can define a 'control-plane' top-level cluster -that would exclude the health status of the 'compute' node cluster if required. -The top-level cluster aggregation rules are used to designate the node -clusters and service clusters members of a top-level cluster along with the -GSE metrics that must be taken into account to derive a health status for the -top-level cluster. The following is an example of a top-level cluster -aggregation rules:: - - gse_cluster_global: - input_message_types: - - gse_service_cluster_metric - - gse_node_cluster_metric - aggregator_flag: false - # the field in the input messages to identify the cluster's member - member_field: cluster_name - output_message_type: gse_cluster_metric - output_metric_name: cluster_status - interval: 10 - warm_up_period: 30 - clusters: - nova: - policy: highest_severity - group_by: member - members: - - nova-logs - - nova-api - - nova-metadata-api - - nova-scheduler - - nova-compute - - nova-conductor - - nova-cert - - nova-consoleauth - - nova-novncproxy-websocket - - controller - - compute - hints: - - cinder - - glance - - keystone - - neutron - - mysql - - rabbitmq - -Where - -| input_message_types -| Type: list -| The type(s) of GSE metric messages consumed by the GSE plugin. - -| aggregator_flag -| Type: boolean - This is always false for the Global Cluster plugin. - -| member_field -| Type: unicode -| The field in the input message used by the GSE plugin to identify the - cluster members. - -| output_message_type -| Type: unicode -| The type of metric messages emitted by the GSE plugin. - -| output_metric_name -| Type: unicode -| The Fields[name] value of the metric messages that the GSE plugin emits. - -| interval -| Type: integer -| The interval (in seconds) at which the GSE plugin emits its metric messages. - -| warm_up_period -| Type: integer -| The number of seconds after a (re)start that the GSE plugin will wait - before emitting its metric messages. - -| clusters -| Type: list -| The list of node clusters and service clusters that the plugin handles. See - :ref:`global_cluster` for details. - -.. _global_cluster: - -Top-level cluster definition -++++++++++++++++++++++++++++ - -The following example shows the top-level clusters definition:: - - gse_cluster_global: - [...] - clusters: - nova: - policy: highest_severity - group_by: member - members: - - nova-logs - - nova-api - - nova-metadata-api - - nova-scheduler - - nova-compute - - nova-conductor - - nova-cert - - nova-consoleauth - - nova-novncproxy-websocket - - controller - - compute - hints: - - cinder - - glance - - keystone - - neutron - - mysql - - rabbitmq - -Where - -| members -| Type: list -| The list of cluster members. -| The GSE messages are associated to the cluster when the ``member_field`` -| value (``cluster_name``), is on this list. - -| hints -| Type: list -| The list of clusters that are indirectly associated with the top-level -| cluster. The GSE messages are indirectly associated to the cluster when -| the ``member_field`` value (``cluster_name``) is on this list. This means -| that they are not used to derive the health status of the top-level -| cluster but as 'hints' for root cause analysis. - -| group_by -| Type: Enum(member, hostname) -| This parameter defines how the incoming GSE metrics are aggregated. -| In the case of the top-level cluster definition, it is always by member. - -| policy: -| Type: unicode -| The policy to use for computing the top-level cluster status. - See :ref:`gse_policies` for details. - -.. _puppet_apply: - -Apply your configuration changes --------------------------------- - -Once you have edited and saved your changes in -``/etc/hiera/override/alarming.yaml`` and / or -``/etc/hiera/override/gse_filters.yaml``, -apply the following Puppet manifest on all the nodes of your OpenStack -environment **including the node(s) where Nagios is installed** -for the changes to take effect:: - - # puppet apply --modulepath=/etc/fuel/plugins/lma_collector-<version>/puppet/modules:\ - /etc/puppet/modules \ - /etc/fuel/plugins/lma_collector-<version>/puppet/manifests/configure_afd_filters.pp - -If you have also deployed *lma_infrastructure_alerting" plugin, Nagios must be reconfigured as well -by running the following commands on all the nodes with the *lma_infrastructure_alerting* role:: - - # rm -f /etc/nagios3/conf.d/lma_* && puppet apply \ - --modulepath=/etc/fuel/plugins/lma_infrastructure_alerting-<version>/puppet/modules:\ - /etc/puppet/modules \ - /etc/fuel/plugins/lma_infrastructure_alerting-<version>/puppet/manifests/nagios.pp diff --git a/doc/user/source/configure_plugin.rst b/doc/user/source/configure_plugin.rst deleted file mode 100644 index 7996158b8..000000000 --- a/doc/user/source/configure_plugin.rst +++ /dev/null @@ -1,301 +0,0 @@ -.. _plugin_configuration: - -Plugin configuration --------------------- - -**To configure the StackLight Collector plugin:** - -#. Create a new environment as described in `Create a new OpenStack environment - <http://docs.openstack.org/developer/fuel-docs/userdocs/fuel-user-guide/create-environment/start-create-env.html>`__. - -#. In the Fuel web UI, click the :guilabel:`Settings` tab and select the - :guilabel:`Other` category. - -#. Scroll down through the settings until you find the StackLight Collector - Plugin section. You should see a page like this: - - .. image:: ../../images/collector_settings.png - :width: 400pt - :alt: The StackLight Collector Plugin settings - -#. Select :guilabel:`The Logging, Monitoring and Alerting (LMA) Collector - Plugin` and fill in the required fields as indicated below. - - a. Optional. Provide an :guilabel:`Environment Label` of your choice to tag - your data. - #. In the :guilabel:`Events Analytics` section, select - :guilabel:`Local node` if you plan to use the Elasticsearch-Kibana - Plugin in the environment. Otherwise, select :guilabel:`Remote server` - and specify the fully qualified name or the IP address of an external - Elasticsearch server. - #. In the :guilabel:`Metrics Analytics` section, select - :guilabel:`Local node` if you plan to use the InfluxDB-Grafana Plugin in - the environment. Otherwise, select :guilabel:`Remote server` and specify - the fully qualified name or the IP address of an external InfluxDB - server. Then, specify the InfluxDB database name you want to use, a - username and password that have read and write access permissions. - #. In the :guilabel:`Alerting` section, select - :guilabel:`Alerts sent by email` if you want to receive alerts sent by - email from the Collector. Otherwise, select - :guilabel:`Alerts sent to a local cluster` if you plan to use the - Infrastructure Alerting Plugin (Nagios) in the environment. - Alternatively, select :guilabel:`Alerts sent to a remote Nagios server`. - #. For :guilabel:`Alerts sent by email`, specify the SMTP authentication - method you want to use. Then, specify the SMTP server fully qualified - name or IP address, the SMTP username and password to have the - permissions to send emails. - -#. Configure your environment as described in `Configure your environment - <http://docs.openstack.org/developer/fuel-docs/userdocs/fuel-user-guide/configure-environment.html>`__. - - .. note:: By default, StackLight is configured to use the *management - network* of the so-called *default node network group* created by Fuel. - While this default setup may be appropriate for small deployments or - evaluation purposes, it is recommended that you not use the default - *management network* for StackLight. Instead, create a dedicated network - when configuring your environment. This will improve the overall - performance of both OpenStack and StackLight and facilitate the access - to the Kibana and Grafana analytics. - -#. Deploy your environment as described in `Deploy an OpenStack environment - <http://docs.openstack.org/developer/fuel-docs/userdocs/fuel-user-guide/deploy-environment.html>`__. - - .. note:: The StackLight Collector Plugin is a *hot-pluggable* plugin. - Therefore, it is possible to install and deploy the *collector* in an - environment that is already deployed. After the installation of the - StackLight Collector Plugin, define the settings of the plugin and - run the commands shown below from the *Fuel master node* for every - node of your deployment starting with *the controller node(s)*: - - .. code-block:: console - - [root@nailgun ~]# fuel nodes --env <env_id> --node <node_id> --tasks hiera install-ocf-script - - Once the task has completed for the node, run the following command: - - .. code-block:: console - - [root@nailgun ~]# fuel nodes --env <env_id> --node <node_id> --start post_deployment_start - -.. _plugin_verification: - -.. raw:: latex - - \pagebreak - -Plugin verification -------------------- - -Once the OpenStack environment is ready, verify that both the *collectd* and -*hekad* processes are running on the OpenStack nodes: - -.. code-block:: console - - [root@node-1 ~]# pidof hekad - 5568 - 5569 - [root@node-1 ~]# pidof collectd - 5684 - -.. note:: Starting with StackLight version 0.10, there are two *hekad* - processes running instead of one. One is used to collect and process the - logs and the notifications, the other one is used to process the metrics. - -.. _troubleshooting: - -Troubleshooting ---------------- - -If you see no data in the Kibana and/or Grafana dashboards, follow the -instructions below to troubleshoot the issue: - -#. Verify that the *collector* services are up and running: - - * On the controller nodes: - - .. code-block:: console - - [root@node-1 ~]# crm resource status metric_collector - [root@node-1 ~]# crm resource status log_collector - - * On non-controller nodes: - - .. code-block:: console - - [root@node-2 ~]# status log_collector - [root@node-2 ~]# status metric_collector - -#. If a *collector* is down, restart it: - - * On the controller nodes: - - .. code-block:: console - - [root@node-1 ~]# crm resource start log_collector - [root@node-1 ~]# crm resource start metric_collector - - * On non-controller nodes: - - .. code-block:: console - - [root@node-2 ~]# start log_collector - [root@node-2 ~]# start metric_collector - -#. Look for errors in the log file of the *collectors* located at - ``/var/log/log_collector.log`` and ``/var/log/metric_collector.log``. - -#. Look for errors in the log file of *collectd* located at - ``/var/log/collectd.log``. - -#. Verify that the nodes are able to connect to the Elasticsearch server on port - 9200. - -#. Verify that the nodes are able to connect to the InfluxDB server on port 8086. - -.. _diagnostic: - -Diagnostic tool ---------------- - -The StackLight Collector Plugin installs a **global diagnostic tool** on the -Fuel Master node. The global diagnostic tool checks that StackLight is -configured and running properly across the entire LMA toolchain for all the -nodes that are ready in your OpenStack environment: - -.. code-block:: console - - [root@nailgun ~]# /var/www/nailgun/plugins/lma_collector-<version>/contrib/tools/diagnostic.sh - Running lma_diagnostic tool on all available nodes (this can take several minutes) - The diagnostic archive is here: /var/lma_diagnostics.2016-06-10_11-23-1465557820.tgz - -.. note:: A global diagnostic can take several minutes. - -All the results are consolidated in the -``/var/lma_diagnostics.[date +%Y-%m-%d_%H-%M-%s].tgz`` archive. - -Instead of running a global diagnostic, you may want to run the diagnostic -on individual nodes. Based on the role of the node, the tool determines what -checks should be executed. For example: - -.. code-block:: console - - root@node-3:~# hiera roles - ["controller"] - - root@node-3:~# lma_diagnostics - - 2016-06-10-11-08-04 INFO node-3.test.domain.local role ["controller"] - 2016-06-10-11-08-04 INFO ** LMA Collector - 2016-06-10-11-08-04 INFO 2 process(es) 'hekad -config' found - 2016-06-10-11-08-04 INFO 1 process(es) hekad is/are listening on port 4352 - 2016-06-10-11-08-04 INFO 1 process(es) hekad is/are listening on port 8325 - 2016-06-10-11-08-05 INFO 1 process(es) hekad is/are listening on port 5567 - 2016-06-10-11-08-05 INFO 1 process(es) hekad is/are listening on port 4353 - [...] - -In the example above, the diagnostic tool reports that two *hekad* processes -are running on *node-3*, which is the expected outcome. In the case when one -*hekad* process is not running, the diagnostic tool reports an error. For -example: - -.. code-block:: console - - root@node-3:~# lma_diagnostics - 2016-06-10-11-11-48 INFO node-3.test.domain.local role ["controller"] - 2016-06-10-11-11-48 INFO ** LMA Collector - 2016-06-10-11-11-48 ERROR 1 'hekad -config' processes found, 2 expected! - 2016-06-10-11-11-48 ERROR 'hekad' process does not LISTEN on port: 4352 - [...] - -In the example above, the diagnostic tool reported two errors: - - #. There is only one *hekad* process running instead of two. - #. No *hekad* process is listening on port 4352. - -These examples describe only one type of checks performed by the diagnostic -tool, but there are many others. - -On the OpenStack nodes, the diagnostic results are stored in ``/var/lma_diagnostics/diagnostics.log``. - -.. note:: A successful LMA toolchain diagnostic should be free of errors. - -.. _advanced_configuration: - -Advanced configuration ----------------------- - -Due to a current limitation in Fuel, when a node is removed from an OpenStack -environment through the Fuel web UI or CLI, the services that were running on -that node are not automatically removed from the database. Therefore, -StackLight reports these services as failed. To resolve this issue, remove -these services manually. - -**To reconfigure the StackLight Collector after removing a node:** - -#. From a controller node, list the services that are reported failed. In the - example below, it is ``node-7``. - - .. code-block:: console - - root@node-6:~# source ./openrc - root@node-6:~# neutron agent-list - +--------------+-------------------+-------------------+-------------------+-------+ - | id | agent_type | host | availability_zone | alive | - +--------------+-------------------+-------------------+-------------------+-------+ - | 08a69bad-... | Metadata agent | node-8.domain.tld | | :-) | - | 11b6dca6-... | Metadata agent | node-7.domain.tld | | xxx | - | 22ea82e3-... | DHCP agent | node-6.domain.tld | nova | :-) | - | 2d82849e-... | L3 agent | node-6.domain.tld | nova | :-) | - | 3221ec18-... | Open vSwitch agent| node-6.domain.tld | | :-) | - | 84bfd240-... | Open vSwitch agent| node-7.domain.tld | | xxx | - | 9452e8f0-... | Open vSwitch agent| node-9.domain.tld | | :-) | - | 97136b09-... | Open vSwitch agent| node-8.domain.tld | | :-) | - | c198bc94-... | DHCP agent | node-7.domain.tld | nova | xxx | - | c76c4ed4-... | L3 agent | node-7.domain.tld | nova | xxx | - | d0fd8bb5-... | L3 agent | node-8.domain.tld | nova | :-) | - | d21f9cea-... | DHCP agent | node-8.domain.tld | nova | :-) | - | f6f871b7-... | Metadata agent | node-6.domain.tld | | :-) | - +--------------+-------------------+-------------------+-------------------+-------+ - root@node-6:~# nova service-list - +--+----------------+-----------------+---------+--------+-------+-----------------+ - |Id|Binary |Host | Zone | Status | State | Updated_at | - +--+----------------+-----------------+---------+--------+-------+-----------------+ - |1 |nova-consoleauth|node-6.domain.tld| internal| enabled| up | 2016-07-19T11:43| - |4 |nova-scheduler |node-6.domain.tld| internal| enabled| up | 2016-07-19T11:43| - |7 |nova-cert |node-6.domain.tld| internal| enabled| up | 2016-07-19T11:43| - |10|nova-conductor |node-6.domain.tld| internal| enabled| up | 2016-07-19T11:42| - |22|nova-cert |node-7.domain.tld| internal| enabled| down | 2016-07-19T11:43| - |25|nova-consoleauth|node-7.domain.tld| internal| enabled| down | 2016-07-19T11:43| - |28|nova-scheduler |node-7.domain.tld| internal| enabled| down | 2016-07-19T11:43| - |31|nova-cert |node-8.domain.tld| internal| enabled| up | 2016-07-19T11:43| - |34|nova-consoleauth|node-8.domain.tld| internal| enabled| up | 2016-07-19T11:43| - |37|nova-conductor |node-7.domain.tld| internal| enabled| down | 2016-07-19T11:42| - |43|nova-scheduler |node-8.domain.tld| internal| enabled| up | 2016-07-19T11:43| - |49|nova-conductor |node-8.domain.tld| internal| enabled| up | 2016-07-19T11:42| - |64|nova-compute |node-9.domain.tld| nova | enabled| up | 2016-07-19T11:42| - +--+----------------+-----------------+---------+--------+-------+-----------------+ - root@node-6:~# cinder service-list - +----------------+-----------------------------+----+-------+-----+----------------+ - | Binary | Host |Zone| Status|State| Updated_at | - +----------------+-----------------------------+----+-------+-----+----------------+ - |cinder-backup | node-9.domain.tld |nova|enabled|up |2016-07-19T11:44| - |cinder-scheduler| node-6.domain.tld |nova|enabled|up |2016-07-19T11:43| - |cinder-scheduler| node-7.domain.tld |nova|enabled|down |2016-07-19T11:43| - |cinder-scheduler| node-8.domain.tld |nova|enabled|up |2016-07-19T11:44| - |cinder-volume |node-9.domain.tld@LVM-backend|nova|enabled|up |2016-07-19T11:44| - +----------------+-----------------------------+----+-------+-----+----------------+ - -#. Remove the services and/or agents that are reported failed on that node: - - .. code-block:: console - - root@node-6:~# nova service-delete <id of service to delete> - root@node-6:~# cinder service-disable <hostname> <binary> - root@node-6:~# neutron agent-delete <id of agent to delete> - -#. Restart the Collector on all the controller nodes: - - .. code-block:: console - - [root@node-1 ~]# crm resource restart log_collector - [root@node-1 ~]# crm resource restart metric_collector diff --git a/doc/user/source/index.rst b/doc/user/source/index.rst deleted file mode 100644 index 986ca228a..000000000 --- a/doc/user/source/index.rst +++ /dev/null @@ -1,50 +0,0 @@ -================================================================== -Welcome to the StackLight Collector plugin for Fuel documentation! -================================================================== - -Overview -~~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - intro - requirements - prerequisites - limitations - release_notes - licenses - references - -Installing StackLight Collector plugin for Fuel -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - install - -Configuring StackLight Collector plugin for Fuel -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - configure_plugin - -Configuring alarms -~~~~~~~~~~~~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - configure_alarms - -Appendix -~~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - appendix_metrics - appendix_alarms \ No newline at end of file diff --git a/doc/user/source/install.rst b/doc/user/source/install.rst deleted file mode 100644 index 080af8b28..000000000 --- a/doc/user/source/install.rst +++ /dev/null @@ -1,112 +0,0 @@ -.. _user_installation: - -Install using the RPM file of the Fuel plugins catalog ------------------------------------------------------- - -**To install the StackLight Collector Fuel plugin using the RPM file of the Fuel -plugins catalog:** - -#. Go to the `Fuel plugins catalog <https://www.mirantis.com/validated-solution-integrations/fuel-plugins/>`_. -#. From the :guilabel:`Filter` drop-down menu, select the Mirantis OpenStack - version you are using and the :guilabel:`Monitoring` category. -#. Download the RPM file. - -#. Copy the RPM file to the Fuel Master node: - - .. code-block:: console - - [root@home ~]# scp lma_collector-1.1-1.1.0-1.noarch.rpm \ - root@<Fuel Master node IP address>: - -#. Install the plugin using the - `Fuel Plugins CLI <http://docs.openstack.org/developer/fuel-docs/userdocs/fuel-user-guide/cli/cli_plugins.html>`_: - - .. code-block:: console - - [root@fuel ~]# fuel plugins --install lma_collector-1.1-1.1.0-1.noarch.rpm - -#. Verify that the plugin is installed correctly: - - .. code-block:: console - - [root@fuel ~]# fuel plugins --list - id | name | version | package_version - ---|----------------------|---------|---------------- - 1 | lma_collector | 1.1.0 | 4.0.0 - - -Install from source -------------------- - -Alternatively, you may want to build the plugin RPM file from source if, for -example, you want to test the latest features of the master branch or -customize the plugin. - -.. note:: Running a Fuel plugin that you built yourself is at your own risk - and will not be supported. - -To install the StackLight Collector Plugin from source, first prepare an -environment to build the RPM file. The recommended approach is to build the -RPM file directly onto the Fuel Master node so that you will not have to copy -that file later on. - -**To prepare an environment and build the plugin:** - -#. Install the standard Linux development tools: - - .. code-block:: console - - [root@home ~] yum install createrepo rpm rpm-build dpkg-devel - -#. Install the Fuel Plugin Builder. To do that, you should first get pip: - - .. code-block:: console - - [root@home ~] easy_install pip - -#. Then install the Fuel Plugin Builder (the `fpb` command line) with `pip`: - - .. code-block:: console - - [root@home ~] pip install fuel-plugin-builder - - .. note:: You may also need to build the Fuel Plugin Builder if the package - version of the plugin is higher than the package version supported by the - Fuel Plugin Builder you get from ``pypi``. For instructions on how to - build the Fuel Plugin Builder, see the *Install Fuel Plugin Builder* - section of the `Fuel Plugin SDK Guide <http://docs.openstack.org/developer/fuel-docs/plugindocs/fuel-plugin-sdk-guide/create-plugin/install-plugin-builder.html>`_. - -#. Clone the plugin repository: - - .. code-block:: console - - [root@home ~] git clone https://github.com/openstack/fuel-plugin-lma-collector.git - -#. Verify that the plugin is valid: - - .. code-block:: console - - [root@home ~] fpb --check ./fuel-plugin-lma-collector - -#. Build the plugin: - - .. code-block:: console - - [root@home ~] fpb --build ./fuel-plugin-lma-collector - -**To install the plugin:** - -#. Once you have created the RPM file, install the plugin: - - .. code-block:: console - - [root@fuel ~] fuel plugins --install ./fuel-plugin-lma-collector/*.noarch.rpm - -#. Verify that the plugin is installed correctly: - - .. code-block:: console - - [root@fuel ~]# fuel plugins --list - id | name | version | package_version - ---|----------------------|---------|---------------- - 1 | lma_collector | 1.1.0 | 4.0.0 diff --git a/doc/user/source/intro.rst b/doc/user/source/intro.rst deleted file mode 100644 index 6f64ec226..000000000 --- a/doc/user/source/intro.rst +++ /dev/null @@ -1,80 +0,0 @@ -.. _user_intro: - -Introduction ------------- - -The **StackLight Collector Plugin for Fuel** is used to install and configure -several software components that are used to collect and process all the data -that is relevant to provide deep operational insights about your OpenStack -environment. These finely integrated components are collectively referred to -as the **StackLight Collector**, or just **the Collector**. - -.. note:: The Collector has evolved over time, so the term *collector* is a - little bit of a misnomer since it is more of a *smart monitoring agent* - than a mere data *collector*. - -The Collector is the key component of the so-called -`Logging, Monitoring, and Alerting toolchain of Mirantis OpenStack -<https://launchpad.net/lma-toolchain>`_, also known as StackLight. - -.. image:: ../../images/toolchain_map.png - :align: center - :width: 440pt - -The Collector is installed on every node of your OpenStack environment. Each -Collector is individually responsible for supporting all the monitoring -functions of your OpenStack environment for both the operating system and the -services running on the node. The Collector running on the *primary controller* -(the controller which owns the management VIP) is called the **Aggregator** -since it performs additional aggregation and correlation functions. The -Aggregator is the central point of convergence for all the faults and -anomalies detected at the node level. The fundamental role of the Aggregator -is to issue an opinion about the health status of your OpenStack environment -at the cluster level. As such, the Collector may be viewed as a monitoring -agent for cloud infrastructure clusters. - -The main building blocks of the Collector are as follows: - -* The **collectd** daemon, which comes bundled with a collection of monitoring - plugins. Some of them are standard collectd plugins while others are - purpose-built plugins written in Python to perform various OpenStack - services checks. -* **Heka**, `a Golang data-processing multifunctional tool by Mozilla - <https://github.com/mozilla-services/heka>`_. Heka supports a number of - standard input and output plugins that allows to ingest data from a variety - of sources including collectd, log files, and RabbitMQ, as well as to - persist the operational data to external back-end servers like Elasticsearch, - InfluxDB, and Nagios for search and further processing. -* **A collection of Heka plugins** written in Lua, which perform the actual - data processing such as running metrics transformations, running alarms, and - logs parsing. - -.. note:: An important function of the Collector is to normalize - the operational data into an internal `Heka message structure - <https://hekad.readthedocs.io/en/stable/message/index.html>`_ - representation that can be ingested into the Heka's stream-processing - pipeline. The stream-processing pipeline uses matching policies to - route the Heka messages to the `Lua <http://www.lua.org/>`_ plugins that - perform the actual data-computation functions. - -The following Lua plugins were developed for the Collector: - -* **decoder plugins** sanitize and normalize the ingested data. -* **filter plugins** process the data. -* **encoder plugins** serialize the data that is sent to the back-end servers. - -The following are the types of data sent by the Collector (and the Aggregator) -to the back-end servers: - -* The logs and the notifications, which are referred to as events sent to - Elasticsearch for indexing. -* The metric's time-series sent to InfluxDB. -* The annotations sent to InfluxDB. -* The OpenStack environment clusters health status sent as *passive checks* - to Nagios. - -.. note:: The annotations are like notification messages that are exposed in - Grafana. They contain information about the anomalies and faults that have - been detected by the Collector. Annotations basically contain the same - information as the *passive checks* sent to Nagios. In addition, they may - contain hints on what can be the root cause of a problem. \ No newline at end of file diff --git a/doc/user/source/licenses.rst b/doc/user/source/licenses.rst deleted file mode 100644 index cddb3e9e1..000000000 --- a/doc/user/source/licenses.rst +++ /dev/null @@ -1,84 +0,0 @@ -.. _licenses: - -Licenses --------- - -Third-party components -++++++++++++++++++++++ - -+----------------------------+------------------------------------------+------------------------+ -| Name | Project website | License | -+============================+==========================================+========================+ -| Heka | https://github.com/mozilla-services/heka | Mozilla Public License | -+----------------------------+------------------------------------------+------------------------+ -| collectd | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::CPU | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Disk | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Df | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Interface | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Load | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Memory | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Processes | http://collectd.org/ | GPLv2 or later | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Swap | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::User | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::LogFile | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::User | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::WriteHttp | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::MySQL | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::DBI | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Apache | http://collectd.org/ | GPLv2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Python | http://collectd.org/ | MIT | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Python::RabbitMQ | http://collectd.org/ | Apache v2 | -+----------------------------+------------------------------------------+------------------------+ -| Collectd::Python::HAProxy | http://collectd.org/ | Permissive | -+----------------------------+------------------------------------------+------------------------+ - -Puppet modules -++++++++++++++ - -+-----------------------+-----------------------------------------------------+-----------+ -| Name | Project website | License | -+=======================+=====================================================+===========+ -| puppet-collectd | https://github.com/puppet-community/puppet-collectd | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| puppetlabs-apache | https://github.com/puppetlabs/puppetlabs-apache | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| puppetlabs-stdlib | https://github.com/puppetlabs/puppetlabs-stdlib | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| puppetlabs-inifile | https://github.com/puppetlabs/puppetlabs-inifile | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| puppetlabs-concat | https://github.com/puppetlabs/puppetlabs-concat | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| puppetlabs-firewall | https://github.com/puppetlabs/puppetlabs-firewall | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| openstack-cinder | https://github.com/openstack/puppet-cinder | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| openstack-glance | https://github.com/openstack/puppet-glance | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| openstack-heat | https://github.com/openstack/puppet-heat | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| openstack-keystone | https://github.com/openstack/puppet-keystone | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| openstack-neutron | https://github.com/openstack/puppet-neutron | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| openstack-nova | https://github.com/openstack/puppet-nova | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ -| openstack-openstacklib| https://github.com/openstack/puppet-openstacklib | Apache v2 | -+-----------------------+-----------------------------------------------------+-----------+ diff --git a/doc/user/source/limitations.rst b/doc/user/source/limitations.rst deleted file mode 100644 index d613ea428..000000000 --- a/doc/user/source/limitations.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. _plugin_limitations: - -Limitations ------------ - -The StackLight Collector plugin 1.1.0 has the following limitations: - -* The plugin is not compatible with an OpenStack environment deployed with - nova-network. - -* When you re-execute tasks on deployed nodes using the Fuel CLI, the - *collectd* processes will be restarted on these nodes during the - post-deployment phase. - See `bug #1570850 <https://bugs.launchpad.net/lma-toolchain/+bug/1570850>`_. diff --git a/doc/user/source/metrics/apache.rst b/doc/user/source/metrics/apache.rst deleted file mode 100644 index c914a2edf..000000000 --- a/doc/user/source/metrics/apache.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. _Apache_metrics: - -* ``apache_bytes``, the number of bytes per second transmitted by the server. -* ``apache_connections``, the current number of active connections. -* ``apache_idle_workers``, the current number of idle workers. -* ``apache_requests``, the number of requests processed per second. -* ``apache_workers_closing``, the number of workers in closing state. -* ``apache_workers_dnslookup``, the number of workers in DNS lookup state. -* ``apache_workers_finishing``, the number of workers in finishing state. -* ``apache_workers_idle_cleanup``, the number of workers in idle cleanup state. -* ``apache_workers_keepalive``, the number of workers in keepalive state. -* ``apache_workers_logging``, the number of workers in logging state. -* ``apache_workers_open``, the number of workers in open state. -* ``apache_workers_reading``, the number of workers in reading state. -* ``apache_workers_sending``, the number of workers in sending state. -* ``apache_workers_starting``, the number of workers in starting state. -* ``apache_workers_waiting``, the number of workers in waiting state. diff --git a/doc/user/source/metrics/ceph.rst b/doc/user/source/metrics/ceph.rst deleted file mode 100644 index 8b4746d97..000000000 --- a/doc/user/source/metrics/ceph.rst +++ /dev/null @@ -1,128 +0,0 @@ -.. _Ceph_metrics: - - -All Ceph metrics have a ``cluster`` field containing the name of the Ceph -cluster (*ceph* by default). - -For details, see -`Cluster monitoring <http://docs.ceph.com/docs/master/rados/operations/monitoring/>`_ -and `RADOS monitoring <http://docs.ceph.com/docs/master/rados/operations/monitoring-osd-pg/>`_. - -Cluster -^^^^^^^ - -* ``ceph_health``, the health status of the entire cluster where values - ``1``, ``2``, ``3`` represent ``OK``, ``WARNING`` and ``ERROR``, respectively. - -* ``ceph_monitor_count``, the number of ceph-mon processes. - -* ``ceph_quorum_count``, the number of ceph-mon processes participating in the - quorum. - -Pools -^^^^^ - -* ``ceph_pool_total_avail_bytes``, the total available size in bytes for all - pools. -* ``ceph_pool_total_bytes``, the total number of bytes for all pools. -* ``ceph_pool_total_number``, the total number of pools. -* ``ceph_pool_total_used_bytes``, the total used size in bytes by all pools. - -The following metrics have a ``pool`` field that contains the name of the -Ceph pool. - -* ``ceph_pool_bytes_used``, the amount of data in bytes used by the pool. -* ``ceph_pool_max_avail``, the available size in bytes for the pool. -* ``ceph_pool_objects``, the number of objects in the pool. -* ``ceph_pool_op_per_sec``, the number of operations per second for the pool. -* ``ceph_pool_pg_num``, the number of placement groups for the pool. -* ``ceph_pool_read_bytes_sec``, the number of bytes read by second for the pool. -* ``ceph_pool_size``, the number of data replications for the pool. -* ``ceph_pool_write_bytes_sec``, the number of bytes written by second for the - pool. - -Placement Groups -^^^^^^^^^^^^^^^^ - -* ``ceph_pg_bytes_avail``, the available size in bytes. -* ``ceph_pg_bytes_total``, the cluster total size in bytes. -* ``ceph_pg_bytes_used``, the data stored size in bytes. -* ``ceph_pg_data_bytes``, the stored data size in bytes before it is - replicated, cloned or snapshotted. -* ``ceph_pg_state``, the number of placement groups in a given state. The - metric contains a ``state`` field whose ``<state>`` value is a combination - separated by ``+`` of 2 or more states of this list: ``creating``, - ``active``, ``clean``, ``down``, ``replay``, ``splitting``, ``scrubbing``, - ``degraded``, ``inconsistent``, ``peering``, ``repair``, ``recovering``, - ``recovery_wait``, ``backfill``, ``backfill-wait``, ``backfill_toofull``, - ``incomplete``, ``stale``, ``remapped``. -* ``ceph_pg_total``, the total number of placement groups. - -OSD Daemons -^^^^^^^^^^^ - -* ``ceph_osd_down``, the number of OSD daemons DOWN. -* ``ceph_osd_in``, the number of OSD daemons IN. -* ``ceph_osd_out``, the number of OSD daemons OUT. -* ``ceph_osd_up``, the number of OSD daemons UP. - -The following metrics have an ``osd`` field that contains the OSD identifier: - -* ``ceph_osd_apply_latency``, apply latency in ms for the given OSD. -* ``ceph_osd_commit_latency``, commit latency in ms for the given OSD. -* ``ceph_osd_total``, the total size in bytes for the given OSD. -* ``ceph_osd_used``, the data stored size in bytes for the given OSD. - -OSD Performance -^^^^^^^^^^^^^^^ - -All the following metrics are retrieved per OSD daemon from the corresponding -``/var/run/ceph/ceph-osd.<ID>.asok`` socket by issuing the :command:`perf dump` -command. - -All metrics have an ``osd`` field that contains the OSD identifier. - -.. note:: These metrics are not collected when a node has both the ceph-osd - and controller roles. - -For details, see `OSD performance counters <http://ceph.com/docs/firefly/dev/perf_counters/>`_. - -* ``ceph_perf_osd_op``, the number of client operations. -* ``ceph_perf_osd_op_in_bytes``, the number of bytes received from clients for - write operations. -* ``ceph_perf_osd_op_latency``, the average latency in ms for client operations - (including queue time). -* ``ceph_perf_osd_op_out_bytes``, the number of bytes sent to clients for read - operations. -* ``ceph_perf_osd_op_process_latency``, the average latency in ms for client - operations (excluding queue time). -* ``ceph_perf_osd_op_r``, the number of client read operations. -* ``ceph_perf_osd_op_r_latency``, the average latency in ms for read operation - (including queue time). -* ``ceph_perf_osd_op_r_out_bytes``, the number of bytes sent to clients for - read operations. -* ``ceph_perf_osd_op_r_process_latency``, the average latency in ms for read - operation (excluding queue time). -* ``ceph_perf_osd_op_rw``, the number of client read-modify-write operations. -* ``ceph_perf_osd_op_rw_in_bytes``, the number of bytes per second received - from clients for read-modify-write operations. -* ``ceph_perf_osd_op_rw_latency``, the average latency in ms for - read-modify-write operations (including queue time). -* ``ceph_perf_osd_op_rw_out_bytes``, the number of bytes per second sent to - clients for read-modify-write operations. -* ``ceph_perf_osd_op_rw_process_latency``, the average latency in ms for - read-modify-write operations (excluding queue time). -* ``ceph_perf_osd_op_rw_rlat``, the average latency in ms for read-modify-write - operations with readable/applied. -* ``ceph_perf_osd_op_w``, the number of client write operations. -* ``ceph_perf_osd_op_wip``, the number of replication operations currently - being processed (primary). -* ``ceph_perf_osd_op_w_in_bytes``, the number of bytes received from clients - for write operations. -* ``ceph_perf_osd_op_w_latency``, the average latency in ms for write - operations (including queue time). -* ``ceph_perf_osd_op_w_process_latency``, the average latency in ms for write - operation (excluding queue time). -* ``ceph_perf_osd_op_w_rlat``, the average latency in ms for write operations - with readable/applied. -* ``ceph_perf_osd_recovery_ops``, the number of recovery operations in progress. \ No newline at end of file diff --git a/doc/user/source/metrics/checks.rst b/doc/user/source/metrics/checks.rst deleted file mode 100644 index d1c33bdf8..000000000 --- a/doc/user/source/metrics/checks.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _check-metrics: - -The check metrics are emitted to express the success or the failure of the -metric collections for the local services. -The value is ``1`` when successful and ``0`` if it fails. - -* ``apache_check``, for Apache. -* ``ceph_mon_check``, for Ceph monitor. -* ``ceph_osd_check``, for Ceph OSD. -* ``elasticsearch_check``, for Elasticsearch. -* ``haproxy_check``, for HAProxy. -* ``influxdb_check``, for InfluxDB. -* ``libvirt_check``, for Libvirt. -* ``mysql_check``, for MySQL. -* ``pacemaker_check``, for Pacemaker. -* ``rabbitmq_check``, for RabbitMQ. diff --git a/doc/user/source/metrics/clusters.rst b/doc/user/source/metrics/clusters.rst deleted file mode 100644 index 5b40ef2fd..000000000 --- a/doc/user/source/metrics/clusters.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. _cluster_metrics: - -The cluster metrics are emitted by the GSE plugins. For details, see -:ref:`Configuring alarms <configure_alarms>`. - -* ``cluster_node_status``, the status of the node cluster. The metric contains - a ``cluster_name`` field that identifies the node cluster. - -* ``cluster_service_status``, the status of the service cluster. The metric - contains a ``cluster_name`` field that identifies the service cluster. - -* ``cluster_status``, the status of the global cluster. The metric contains a - ``cluster_name`` field that identifies the global cluster. - -The supported values for these metrics are: - -* ``0`` for the *Okay* status. - -* ``1`` for the *Warning* status. - -* ``2`` for the *Unknown* status. - -* ``3`` for the *Critical* status. - -* ``4`` for the *Down* status. \ No newline at end of file diff --git a/doc/user/source/metrics/elasticsearch.rst b/doc/user/source/metrics/elasticsearch.rst deleted file mode 100644 index b7168e1cc..000000000 --- a/doc/user/source/metrics/elasticsearch.rst +++ /dev/null @@ -1,19 +0,0 @@ -.. _Elasticsearch: - -The following metrics represent the simple status on the health of the cluster. -For details, see `Cluster health <https://www.elastic.co/guide/en/elasticsearch/reference/1.7/cluster-health.html>`_. - -* ``elasticsearch_cluster_active_primary_shards``, the number of active primary - shards. -* ``elasticsearch_cluster_active_shards``, the number of active shards. -* ``elasticsearch_cluster_health``, the health status of the entire cluster - where values ``1``, ``2`` , ``3`` represent ``green``, ``yellow`` and - ``red``, respectively. The ``red`` status may also be reported when the - Elasticsearch API returns an unexpected result, for example, a network - failure. -* ``elasticsearch_cluster_initializing_shards``, the number of initializing - shards. -* ``elasticsearch_cluster_number_of_nodes``, the number of nodes in the cluster. -* ``elasticsearch_cluster_number_of_pending_tasks``, the number of pending tasks. -* ``elasticsearch_cluster_relocating_shards``, the number of relocating shards. -* ``elasticsearch_cluster_unassigned_shards``, the number of unassigned shards. \ No newline at end of file diff --git a/doc/user/source/metrics/haproxy.rst b/doc/user/source/metrics/haproxy.rst deleted file mode 100644 index 6bfded494..000000000 --- a/doc/user/source/metrics/haproxy.rst +++ /dev/null @@ -1,96 +0,0 @@ -.. _haproxy_metrics: - -The ``frontend`` and ``backend`` field values can be as follows: - -* cinder-api -* glance-api -* glance-registry-api -* heat-api -* heat-cfn-api -* heat-cloudwatch-api -* horizon-web (when Horizon is deployed without TLS) -* horizon-https (when Horizon is deployed with TLS) -* keystone-public-api -* keystone-admin-api -* mysqld-tcp -* murano-api -* neutron-api -* nova-api -* nova-metadata-api -* nova-novncproxy-websocket -* sahara-api -* swift-api - -Server -^^^^^^ - -* ``haproxy_connections``, the number of current connections. -* ``haproxy_pipes_free``, the number of free pipes. -* ``haproxy_pipes_used``, the number of used pipes. -* ``haproxy_run_queue``, the number of connections waiting in the queue. -* ``haproxy_ssl_connections``, the number of current SSL connections. -* ``haproxy_tasks``, the number of tasks. -* ``haproxy_uptime``, the HAProxy server uptime in seconds. - -Frontends -^^^^^^^^^ - -The following metrics have a ``frontend`` field that contains the name of the -front-end server: - -* ``haproxy_frontend_bytes_in``, the number of bytes received by the frontend. -* ``haproxy_frontend_bytes_out``, the number of bytes transmitted by the frontend. -* ``haproxy_frontend_denied_requests``, the number of denied requests. -* ``haproxy_frontend_denied_responses``, the number of denied responses. -* ``haproxy_frontend_error_requests``, the number of error requests. -* ``haproxy_frontend_response_1xx``, the number of HTTP responses with 1xx code. -* ``haproxy_frontend_response_2xx``, the number of HTTP responses with 2xx code. -* ``haproxy_frontend_response_3xx``, the number of HTTP responses with 3xx code. -* ``haproxy_frontend_response_4xx``, the number of HTTP responses with 4xx code. -* ``haproxy_frontend_response_5xx``, the number of HTTP responses with 5xx code. -* ``haproxy_frontend_response_other``, the number of HTTP responses with other code. -* ``haproxy_frontend_session_current``, the number of current sessions. -* ``haproxy_frontend_session_total``, the cumulative number of sessions. - -Backends -^^^^^^^^ -.. _haproxy_backend_metric: - -The following metrics have a ``backend`` field that contains the name of the -back-end server: - -* ``haproxy_backend_bytes_in``, the number of bytes received by the back end. -* ``haproxy_backend_bytes_out``, the number of bytes transmitted by the back end. -* ``haproxy_backend_denied_requests``, the number of denied requests. -* ``haproxy_backend_denied_responses``, the number of denied responses. -* ``haproxy_backend_downtime``, the total downtime in seconds. -* ``haproxy_backend_error_connection``, the number of error connections. -* ``haproxy_backend_error_responses``, the number of error responses. -* ``haproxy_backend_queue_current``, the number of requests in queue. -* ``haproxy_backend_redistributed``, the number of times a request was - redispatched to another server. -* ``haproxy_backend_response_1xx``, the number of HTTP responses with 1xx code. -* ``haproxy_backend_response_2xx``, the number of HTTP responses with 2xx code. -* ``haproxy_backend_response_3xx``, the number of HTTP responses with 3xx code. -* ``haproxy_backend_response_4xx``, the number of HTTP responses with 4xx code. -* ``haproxy_backend_response_5xx``, the number of HTTP responses with 5xx code. -* ``haproxy_backend_response_other``, the number of HTTP responses with other - code. -* ``haproxy_backend_retries``, the number of times a connection to a server - was retried. -* ``haproxy_backend_server``, the status of the backend server where values - ``0`` and ``1`` represent, respectively, ``DOWN`` and ``UP``. This metric - has two additional fields: a ``state`` field that contains the state of - the backend (either 'down' or 'up') and a ``server`` field that contains - the hostname of the backend server. -* ``haproxy_backend_servers``, the count of servers grouped by state. This - metric has an additional ``state`` field that contains the state of the - back ends (either 'down' or 'up'). -* ``haproxy_backend_servers_percent``, the percentage of servers by state. - This metric has an additional ``state`` field that contains the state of the - back ends (either 'down' or 'up'). -* ``haproxy_backend_session_current``, the number of current sessions. -* ``haproxy_backend_session_total``, the cumulative number of sessions. -* ``haproxy_backend_status``, the global back-end status where values ``0`` - and ``1`` represent, respectively, ``DOWN`` (all back ends are down) and ``UP`` - (at least one back end is up). diff --git a/doc/user/source/metrics/influxdb.rst b/doc/user/source/metrics/influxdb.rst deleted file mode 100644 index 81bc1acd8..000000000 --- a/doc/user/source/metrics/influxdb.rst +++ /dev/null @@ -1,62 +0,0 @@ -.. InfluxDB: - -The following metrics are extracted from the output of the :command:`show stats` -command. The values are reset to zero when InfluxDB is restarted. - -cluster -^^^^^^^ - -The following metrics are only available if there is more than one node in the -cluster: - -* ``influxdb_cluster_write_shard_points_requests``, the number of requests for - writing a time series points to a shard. -* ``influxdb_cluster_write_shard_requests``, the number of requests for writing - to a shard. - -httpd -^^^^^ - -* ``influxdb_httpd_failed_auths``, the number of failed authentications. -* ``influxdb_httpd_ping_requests``, the number of ping requests. -* ``influxdb_httpd_query_requests``, the number of query requests received. -* ``influxdb_httpd_query_response_bytes``, the number of bytes returned to the - client. -* ``influxdb_httpd_requests``, the number of requests received. -* ``influxdb_httpd_write_points_ok``, the number of points successfully written. -* ``influxdb_httpd_write_request_bytes``, the number of bytes received for - write requests. -* ``influxdb_httpd_write_requests``, the number of write requests received. - -write -^^^^^ - -* ``influxdb_write_local_point_requests``, the number of write points requests - from the local data node. -* ``influxdb_write_ok``, the number of successful writes of consistency level. -* ``influxdb_write_point_requests``, the number of write points requests across - all data nodes. -* ``influxdb_write_remote_point_requests``, the number of write points requests - to remote data nodes. -* ``influxdb_write_requests``, the number of write requests across all data - nodes. -* ``influxdb_write_sub_ok``, the number of successful points sent to - subscriptions. - -runtime -^^^^^^^ - -* ``influxdb_garbage_collections``, the number of garbage collections. -* ``influxdb_go_routines``, the number of Golang routines. -* ``influxdb_heap_idle``, the number of bytes in idle spans. -* ``influxdb_heap_in_use``, the number of bytes in non-idle spans. -* ``influxdb_heap_objects``, the total number of allocated objects. -* ``influxdb_heap_released``, the number of bytes released to the operating - system. -* ``influxdb_heap_system``, the number of bytes obtained from the system. -* ``influxdb_memory_alloc``, the number of bytes allocated and not yet freed. -* ``influxdb_memory_frees``, the number of free operations. -* ``influxdb_memory_lookups``, the number of pointer lookups. -* ``influxdb_memory_mallocs``, the number of malloc operations. -* ``influxdb_memory_system``, the number of bytes obtained from the system. -* ``influxdb_memory_total_alloc``, the number of bytes allocated (even if freed). \ No newline at end of file diff --git a/doc/user/source/metrics/libvirt.rst b/doc/user/source/metrics/libvirt.rst deleted file mode 100644 index 24cae1d7f..000000000 --- a/doc/user/source/metrics/libvirt.rst +++ /dev/null @@ -1,64 +0,0 @@ -.. _libvirt-metrics: - -Every metric contains an ``instance_id`` field, which is the UUID of the -instance for the Nova service. - -CPU -^^^ - -* ``virt_cpu_time``, the average amount of CPU time (in nanoseconds) allocated - to the virtual instance in a second. - -* ``virt_vcpu_time``, the average amount of CPU time (in nanoseconds) - allocated to the virtual CPU in a second. The metric contains a - ``vcpu_number`` field which is the virtual CPU number. - -Disk -^^^^ - -Metrics have a ``device`` field that contains the virtual disk device to which -the metric applies. For example, 'vda', 'vdb', and others. - -* ``virt_disk_octets_read``, the number of octets (bytes) read per second. - -* ``virt_disk_octets_write``, the number of octets (bytes) written per second. - -* ``virt_disk_ops_read``, the number of read operations per second. - -* ``virt_disk_ops_write``, the number of write operations per second. - -Memory -^^^^^^ - -* ``virt_memory_total``, the total amount of memory (in bytes) allocated to the - virtual instance. - -Network -^^^^^^^ - -Metrics have an ``interface`` field that contains the interface name to which -the metric applies. For example, 'tap0dc043a6-dd', 'tap769b123a-2e', and others. - -* ``virt_if_dropped_rx``, the number of dropped packets per second when - receiving from the interface. - -* ``virt_if_dropped_tx``, the number of dropped packets per second when - transmitting from the interface. - -* ``virt_if_errors_rx``, the number of errors per second detected when - receiving from the interface. - -* ``virt_if_errors_tx``, the number of errors per second detected when - transmitting from the interface. - -* ``virt_if_octets_rx``, the number of octets (bytes) received per second by - the interface. - -* ``virt_if_octets_tx``, the number of octets (bytes) transmitted per second by - the interface. - -* ``virt_if_packets_rx``, the number of packets received per second by the - interface. - -* ``virt_if_packets_tx``, the number of packets transmitted per second by the - interface. \ No newline at end of file diff --git a/doc/user/source/metrics/lma.rst b/doc/user/source/metrics/lma.rst deleted file mode 100644 index 6fd867a47..000000000 --- a/doc/user/source/metrics/lma.rst +++ /dev/null @@ -1,69 +0,0 @@ -.. _LMA_self-monitoring: - -System -^^^^^^ - -The metrics have a ``service`` field with the name of the service it applies -to. The values can be: ``hekad``, ``collectd``, ``influxd``, ``grafana-server`` -or ``elasticsearch``. - -* ``lma_components_count_processes``, the number of processes currently running. -* ``lma_components_count_threads``, the number of threads currently running. -* ``lma_components_cputime_syst``, the percentage of CPU time spent in system - mode by the service. It can be greater than 100% when the node has more than - one CPU. -* ``lma_components_cputime_user``, the percentage of CPU time spent in user - mode by the service. It can be greater than 100% when the node has more than - one CPU. -* ``lma_components_disk_bytes_read``, the number of bytes read from disk(s) per - second. -* ``lma_components_disk_bytes_write``, the number of bytes written to disk(s) - per second. -* ``lma_components_disk_ops_read``, the number of read operations from disk(s) - per second. -* ``lma_components_disk_ops_write``, the number of write operations to disk(s) - per second. -* ``lma_components_memory_code``, the physical memory devoted to executable code - in bytes. -* ``lma_components_memory_data``, the physical memory devoted to other than - executable code in bytes. -* ``lma_components_memory_rss``, the non-swapped physical memory used in bytes. -* ``lma_components_memory_vm``, the virtual memory size in bytes. -* ``lma_components_pagefaults_majflt``, major page faults per second. -* ``lma_components_pagefaults_minflt``, minor page faults per second. -* ``lma_components_stacksize``, the absolute value of the start address (the bottom) - of the stack minus the address of the current stack pointer. - -Heka pipeline -^^^^^^^^^^^^^ - -The metrics have two fields: ``name`` that contains the name of the decoder -or filter as defined by *Heka* and ``type`` that is either *decoder* or -*filter*. - -The metrics for both types are as follows: - -* ``hekad_memory``, the total memory in bytes used by the Sandbox. -* ``hekad_msg_avg_duration``, the average time in nanoseconds for processing - the message. -* ``hekad_msg_count``, the total number of messages processed by the decoder. - This resets to ``0`` when the process is restarted. - -Additional metrics for *filter* type: - -* ``heakd_timer_event_avg_duration``, the average time in nanoseconds for - executing the *timer_event* function. -* ``hekad_timer_event_count``, the total number of executions of the - *timer_event* function. This resets to ``0`` when the process is restarted. - -Back-end checks -^^^^^^^^^^^^^^^ - -* ``http_check``, the API status of the back end, ``1`` if it is responsive, - if not, then ``0``. The metric contains a ``service`` field that identifies - the LMA back-end service being checked. - -``<service>`` is one of the following values, depending on which Fuel plugins -are deployed in the environment: - -* 'influxdb' \ No newline at end of file diff --git a/doc/user/source/metrics/memcached.rst b/doc/user/source/metrics/memcached.rst deleted file mode 100644 index 8833b2e71..000000000 --- a/doc/user/source/metrics/memcached.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. _memcached_metrics: - -* ``memcached_command_flush``, the cumulative number of flush reqs. -* ``memcached_command_get``, the cumulative number of retrieval reqs. -* ``memcached_command_set``, the cumulative number of storage reqs. -* ``memcached_command_touch``, the cumulative number of touch reqs. -* ``memcached_connections_current``, the number of open connections. -* ``memcached_df_cache_free``, the current number of free bytes to store items. -* ``memcached_df_cache_used``, the current number of bytes used to store items. -* ``memcached_items_current``, the current number of items stored. -* ``memcached_octets_rx``, the total number of bytes read by this server from - the network. -* ``memcached_octets_tx``, the total number of bytes sent by this server to - the network. -* ``memcached_ops_decr_hits``, the number of successful decr reqs. -* ``memcached_ops_decr_misses``, the number of decr reqs against missing keys. -* ``memcached_ops_evictions``, the number of valid items removed from cache to - free memory for new items. -* ``memcached_ops_hits``, the number of keys that have been requested. -* ``memcached_ops_incr_hits``, the number of successful incr reqs. -* ``memcached_ops_incr_misses``, the number of successful incr reqs. -* ``memcached_ops_misses``, the number of items that have been requested and - not found. -* ``memcached_percent_hitratio``, the percentage of get command hits (in cache). -* ``memcached_ps_cputime_syst``, the percentage of CPU time spent in system - mode by memcached. It can be greater than 100% when the node has more than - one CPU. -* ``memcached_ps_cputime_user``, the percentage of CPU time spent in user mode - by memcached. It can be greater than 100% when the node has more than one CPU. - -For details, see the `Memcached documentation <https://github.com/memcached/memcached/blob/master/doc/protocol.txt#L488>`_. diff --git a/doc/user/source/metrics/mysql.rst b/doc/user/source/metrics/mysql.rst deleted file mode 100644 index 436457f33..000000000 --- a/doc/user/source/metrics/mysql.rst +++ /dev/null @@ -1,108 +0,0 @@ -.. _mysql_metrics: - -Commands -^^^^^^^^ - -``mysql_commands``, the number of times per second a given statement has been -executed. The metric has a ``statement`` field that contains the statement to -which it applies. The values can be as follows: - -* ``change_db`` for the USE statement. -* ``commit`` for the COMMIT statement. -* ``flush`` for the FLUSH statement. -* ``insert`` for the INSERT statement. -* ``rollback`` for the ROLLBACK statement. -* ``select`` for the SELECT statement. -* ``set_option`` for the SET statement. -* ``show_collations`` for the SHOW COLLATION statement. -* ``show_databases`` for the SHOW DATABASES statement. -* ``show_fields`` for the SHOW FIELDS statement. -* ``show_master_status`` for the SHOW MASTER STATUS statement. -* ``show_status`` for the SHOW STATUS statement. -* ``show_tables`` for the SHOW TABLES statement. -* ``show_variables`` for the SHOW VARIABLES statement. -* ``show_warnings`` for the SHOW WARNINGS statement. -* ``update`` for the UPDATE statement. - -Handlers -^^^^^^^^ - -``mysql_handler``, the number of times per second a given handler has been -executed. The metric has a ``handler`` field that contains the handler -it applies to. The values can be as follows: - -* ``commit`` for the internal COMMIT statements. -* ``delete`` for the internal DELETE statements. -* ``external_lock`` for the external locks. -* ``read_first`` for the requests that read the first entry in an index. -* ``read_key`` for the requests that read a row based on a key. -* ``read_next`` for the requests that read the next row in key order. -* ``read_prev`` for the requests that read the previous row in key order. -* ``read_rnd`` for the requests that read a row based on a fixed position. -* ``read_rnd_next`` for the requests that read the next row in the data file. -* ``rollback`` the requests that perform the rollback operation. -* ``update`` the requests that update a row in a table. -* ``write`` the requests that insert a row in a table. - -Locks -^^^^^ - -* ``mysql_locks_immediate``, the number of times per second the requests for - table locks could be granted immediately. -* ``mysql_locks_waited``, the number of times per second the requests for - table locks had to wait. - -Network -^^^^^^^ - -* ``mysql_octets_rx``, the number of bytes per second received by the server. -* ``mysql_octets_tx``, the number of bytes per second sent by the server. - -Threads -^^^^^^^ - -* ``mysql_threads_cached``, the number of threads in the thread cache. -* ``mysql_threads_connected``, the number of currently open connections. -* ``mysql_threads_created``, the number of threads created per second to - handle connections. -* ``mysql_threads_running``, the number of threads that are not sleeping. - -Cluster -^^^^^^^ - -The following metrics are collected with statement 'SHOW STATUS'. For details, -see `Percona documentation <http://www.percona.com/doc/percona-xtradb-cluster/5.6/wsrep-status-index.html>`_. - -* ``mysql_cluster_connected``, ``1`` when the node is connected to the cluster, - if not, then ``0``. -* ``mysql_cluster_local_cert_failures``, the number of write sets that failed - the certification test. -* ``mysql_cluster_local_commits``, the number of write sets committed on the - node. -* ``mysql_cluster_local_recv_queue``, the number of write sets waiting to be - applied. -* ``mysql_cluster_local_send_queue``, the number of write sets waiting to be - sent. -* ``mysql_cluster_ready``, ``1`` when the node is ready to accept queries, if - not, then ``0``. -* ``mysql_cluster_received``, the total number of write sets received from - other nodes. -* ``mysql_cluster_received_bytes``, the total size in bytes of write sets - received from other nodes. -* ``mysql_cluster_replicated``, the total number of write sets sent to other - nodes. -* ``mysql_cluster_replicated_bytes`` the total size in bytes of write sets sent - to other nodes. -* ``mysql_cluster_size``, the current number of nodes in the cluster. -* ``mysql_cluster_status``, ``1`` when the node is 'Primary', ``2`` if - 'Non-Primary', and ``3`` if 'Disconnected'. - -Slow queries -^^^^^^^^^^^^ - -The following metric is collected with statement -'SHOW STATUS where Variable_name = 'Slow_queries'. - -* ``mysql_slow_queries``, the number of queries that have taken more than X - seconds, depending on the MySQL configuration parameter 'long_query_time' - (10s per default). \ No newline at end of file diff --git a/doc/user/source/metrics/openstack.rst b/doc/user/source/metrics/openstack.rst deleted file mode 100644 index a73aaa7e2..000000000 --- a/doc/user/source/metrics/openstack.rst +++ /dev/null @@ -1,247 +0,0 @@ -.. _openstack_metrics: - -Service API checks -^^^^^^^^^^^^^^^^^^ -.. _service_api_checks: - -* ``openstack_check_api``, the service's API status through the load balancer - VIP, ``1`` if it is responsive, if not, then ``0``. - The metric contains a ``service`` field that identifies - the OpenStack service being checked. - -* ``openstack_check_local_api``, the service's API status checked locally. ``1`` - if it is responsive, if not, then ``0``. The metric contains a ``service`` - field that identifies ``<service>`` identifies the OpenStack service being - checked. - -``<service>`` is one of the following values with their respective resource -checks: - -* 'ceilometer-api': '/v2/capabilities' -* 'cinder-api': '/' -* 'cinder-v2-api': '/' -* 'glance-api': '/' -* 'heat-api': '/' -* 'heat-cfn-api': '/' -* 'keystone-public-api': '/' -* 'neutron-api': '/' -* 'nova-api': '/' -* 'swift-api': '/healthcheck' -* 'swift-s3-api': '/healthcheck' - -.. note:: All checks except for Ceilometer are performed without authentication. - -Compute -^^^^^^^ - -The following metrics are emitted per compute node: - -* ``openstack_nova_free_disk``, the disk space in GB available for new instances. -* ``openstack_nova_free_ram``, the memory in MB available for new instances. -* ``openstack_nova_free_vcpus``, the number of virtual CPU available for new - instances. -* ``openstack_nova_instance_creation_time``, the time in seconds it took to - launch a new instance. -* ``openstack_nova_running_instances``, the number of running instances. -* ``openstack_nova_running_tasks``, the number of tasks currently executed. -* ``openstack_nova_used_disk``, the disk space in GB used by the instances. -* ``openstack_nova_used_ram``, the memory in MB used by the instances. -* ``openstack_nova_used_vcpus``, the number of virtual CPU used by the - instances. - -If Nova aggregates are defined then the following metrics are emitted per -aggregate. These metrics contain a ``aggregate`` -field containing the aggregate name and a ``aggregate_id`` field containing the -ID (integer) of the aggregate. - -* ``openstack_nova_aggregate_free_disk``, the total amount of disk space in GB - available in given aggregate for new instances. -* ``openstack_nova_aggregate_free_ram``, the total amount of memory in MB available - in given aggregate for new instances. -* ``openstack_nova_aggregate_free_vcpus``, the total number of virtual CPU - available in given aggregate for new instances. -* ``openstack_nova_aggregate_running_instances``, the total number of running - instances in given aggregate. -* ``openstack_nova_aggregate_running_tasks``, the total number of tasks currently - executed in given aggregate. -* ``openstack_nova_aggregate_used_disk``, the total amount of disk space in GB - used by the instances in given aggregate. -* ``openstack_nova_aggregate_used_ram``, the total amount of memory in MB used by - the instances in given aggregate. -* ``openstack_nova_aggregate_used_vcpus``, the total number of virtual CPU used by - the instances in given aggregate. - -The following metrics are retrieved from the Nova API and represent the -aggregated values across all compute nodes. - -* ``openstack_nova_total_free_disk``, the total amount of disk space in GB - available for new instances. -* ``openstack_nova_total_free_ram``, the total amount of memory in MB available - for new instances. -* ``openstack_nova_total_free_vcpus``, the total number of virtual CPU - available for new instances. -* ``openstack_nova_total_running_instances``, the total number of running - instances. -* ``openstack_nova_total_running_tasks``, the total number of tasks currently - executed. -* ``openstack_nova_total_used_disk``, the total amount of disk space in GB - used by the instances. -* ``openstack_nova_total_used_ram``, the total amount of memory in MB used by - the instances. -* ``openstack_nova_total_used_vcpus``, the total number of virtual CPU used by - the instances. - -The following metrics are retrieved from the Nova API: - -* ``openstack_nova_instances``, the total count of instances in a given state. - The metric contains a ``state`` field which is one of 'active', 'deleted', - 'error', 'paused', 'resumed', 'rescued', 'resized', 'shelved_offloaded' or - 'suspended'. - -.. _compute-service-state-metrics: - -* ``openstack_nova_service``, the Nova service state (either ``0`` for 'up', - ``1`` for 'down' or ``2`` for 'disabled'). - The metric contains a ``service`` field (one of 'compute', 'conductor', - 'scheduler', 'cert' or 'consoleauth') and a ``state`` field (one of 'up', - 'down' or 'disabled'). - -* ``openstack_nova_services``, the total count of Nova - services by state. The metric contains a ``service`` field (one of 'compute', - 'conductor', 'scheduler', 'cert' or 'consoleauth') and a ``state`` field (one - of 'up', 'down', or 'disabled'). - -* ``openstack_nova_services_percent``, the percentage of Nova - services by state. The metric contains a ``service`` field (one of 'compute', - 'conductor', 'scheduler', 'cert' or 'consoleauth') and a ``state`` field (one - of 'up', 'down', or 'disabled'). - -Identity -^^^^^^^^ - -The following metrics are retrieved from the Keystone API: - -* ``openstack_keystone_roles``, the total number of roles. -* ``openstack_keystone_tenants``, the number of tenants by state. The metric - contains a ``state`` field (either 'enabled' or 'disabled'). -* ``openstack_keystone_users``, the number of users by state. The metric - contains a ``state`` field (either 'enabled' or 'disabled'). - -Volume -^^^^^^ - -The following metrics are emitted per volume node: - -* ``openstack_cinder_volume_attachement_time``, the time in seconds it took to - attach a volume to an instance. -* ``openstack_cinder_volume_creation_time``, the time in seconds it took to - create a new volume. - -.. note:: When using Ceph as the back end storage for volumes, the ``hostname`` - value is always set to ``rbd``. - -The following metrics are retrieved from the Cinder API: - -* ``openstack_cinder_snapshots``, the number of snapshots by state. The metric - contains a ``state`` field. -* ``openstack_cinder_snapshots_size``, the total size (in bytes) of snapshots - by state. The metric contains a ``state`` field. -* ``openstack_cinder_volumes``, the number of volumes by state. The metric - contains a ``state`` field. -* ``openstack_cinder_volumes_size``, the total size (in bytes) of volumes by - state. The metric contains a ``state`` field. - -``state`` is one of 'available', 'creating', 'attaching', 'in-use', 'deleting', -'backing-up', 'restoring-backup', 'error', 'error_deleting', 'error_restoring', -'error_extending'. - -.. _volume-service-state-metrics: - -* ``openstack_cinder_service``, the Cinder service state (either ``0`` for - 'up', ``1`` for 'down', or ``2`` for 'disabled'). The metric contains a - ``service`` field (one of 'volume', 'backup', 'scheduler') and a ``state`` - field (one of 'up', 'down' or 'disabled'). - -* ``openstack_cinder_services``, the total count of Cinder services by state. - The metric contains a ``service`` field (one of 'volume', 'backup', - 'scheduler') and a ``state`` field (one of 'up', 'down' or 'disabled'). - -* ``openstack_cinder_services_percent``, the percentage of Cinder - services by state. The metric contains a ``service`` field (one of 'volume', - 'backup', 'scheduler') and a ``state`` field (one of 'up', 'down', or - 'disabled'). - -Image -^^^^^ - -The following metrics are retrieved from the Glance API: - -* ``openstack_glance_images``, the number of images by state and visibility. - The metric contains ``state`` and ``visibility`` fields. -* ``openstack_glance_images_size``, the total size (in bytes) of images by - state and visibility. The metric contains ``state`` and ``visibility`` - fields. -* ``openstack_glance_snapshots``, the number of snapshot images by state and - visibility. The metric contains ``state`` and ``visibility`` fields. -* ``openstack_glance_snapshots_size``, the total size (in bytes) of snapshots - by state and visibility. The metric contains ``state`` and ``visibility`` - fields. - -``state`` is one of 'queued', 'saving', 'active', 'killed', 'deleted', -'pending_delete'. ``visibility`` is either 'public' or 'private'. - -Network -^^^^^^^ - -The following metrics are retrieved from the Neutron API: - -* ``openstack_neutron_floatingips``, the total number of floating IP addresses. -* ``openstack_neutron_networks``, the number of virtual networks by state. The - metric contains a ``state`` field. -* ``openstack_neutron_ports``, the number of virtual ports by owner and state. - The metric contains ``owner`` and ``state`` fields. -* ``openstack_neutron_routers``, the number of virtual routers by state. The - metric contains a ``state`` field. -* ``openstack_neutron_subnets``, the number of virtual subnets. - -``<state>`` is one of 'active', 'build', 'down' or 'error'. - -``<owner>`` is one of 'compute', 'dhcp', 'floatingip', 'floatingip_agent_gateway', 'router_interface', 'router_gateway', 'router_ha_interface', -'router_interface_distributed', or 'router_centralized_snat'. - -.. _network-agent-state-metrics: - -.. note:: These metrics are not collected when the Contrail plugin is deployed. - -* ``openstack_neutron_agent``, the Neutron agent state (either ``0`` for 'up', - ``1`` for 'down', or ``2`` for 'disabled'). - The metric contains a ``service`` field (one of 'dhcp', 'l3', 'metadata', or - 'openvswitch'), and a ``state`` field (one of 'up', 'down' or 'disabled'). - -* ``openstack_neutron_agents``, the total number of Neutron agents by service - and state. The metric contains ``service`` (one of 'dhcp', 'l3', 'metadata' - or 'openvswitch') and ``state`` (one of 'up', 'down' or 'disabled') fields. - -* ``openstack_neutron_agents_percent``, the percentage of Neutron - agents by state. The metric contains a ``service`` field (one of 'dhcp', - 'l3', 'metadata' or 'openvswitch') and a ``state`` field (one of 'up', - 'down', or 'disabled'). - -API response times -^^^^^^^^^^^^^^^^^^ - -* ``openstack_<service>_http_response_times``, HTTP response time statistics. - The statistics are ``min``, ``max``, ``sum``, ``count``, ``upper_90`` - (90 percentile) over 10 seconds. The metric contains an ``http_method`` field, - for example, 'GET', 'POST', and others, and an ``http_status`` field, for - example, '2xx', '4xx', and others. - -``<service>`` is one of 'cinder', 'glance', 'heat' 'keystone', 'neutron' or -'nova'. - -Logs -^^^^ - -* ``log_messages``, the number of log messages per second for the given - service and severity level. The metric contains ``service`` and ``level`` - (one of 'debug', 'info', and others) fields. diff --git a/doc/user/source/metrics/pacemaker.rst b/doc/user/source/metrics/pacemaker.rst deleted file mode 100644 index ee07ef341..000000000 --- a/doc/user/source/metrics/pacemaker.rst +++ /dev/null @@ -1,67 +0,0 @@ -.. _pacemaker-metrics: - -Cluster -^^^^^^^ - -* ``pacemaker_local_dc_active``, ``1`` when the Designated Controller (DC) is - the local host, if not, then ``0``. - -* ``pacemaker_dc`` [#f1]_, ``1`` when the Designated Controller (DC) is - present, if not, then ``0``. -* ``pacemaker_quorum_status`` [#f1]_, ``1`` when the cluster's quorum is - reached, if not, then ``0``. -* ``pacemaker_configured_nodes`` [#f1]_, the number of configured nodes in the - cluster. -* ``pacemaker_configured_resources`` [#f1]_, the number of configured nodes in - the cluster. - -.. [#f1] this metric is only emitted from the node that is the Designated - Controller (DC) of the Pacemaker cluster. - -Node -^^^^ -The following metrics are only emitted from the node that is the Designated -Controller (DC) of the Pacemaker cluster. They have a ``status`` field which is -one of 'offline', 'maintenance', or 'online': - -* ``pacemaker_node_status``, the status of the node, ``0`` when offline, ``1`` - when in maintenance or ``2`` when online. -* ``pacemaker_node_count``, the total number of nodes with the given - ``status``. -* ``pacemaker_node_percent``, the percentage of nodes with the given - ``status``. - -Resource -^^^^^^^^ - -* ``pacemaker_local_resource_active``, ``1`` when the resource is located on - the host reporting the metric, if not, then ``0``. The metric contains a - ``resource`` field which is one of 'vip__public', 'vip__management', - 'vip__vrouter_pub', or 'vip__vrouter'. - -* ``pacemaker_resource_failures`` [#f2]_, the total number of failures that - Pacemaker detected for the ``resource``. The counter is reset every time the - collector restarts. The metric contains a ``resource`` field which one of - 'vip__management', 'vip__public', 'vip__vrouter_pub', 'vip__vrouter', - 'rabbitmq', 'mysqld' or 'haproxy'. - -* ``pacemaker_resource_operations`` [#f2]_, the total number of operations that - Pacemaker applied to the ``resource``. The counter is reset every time the - collector restarts. The metric contains a ``resource`` field which one of - 'vip__management', 'vip__public', 'vip__vrouter_pub', 'vip__vrouter', - 'rabbitmq', 'mysqld' or 'haproxy'. - -The following metrics have ``resource`` and ``status`` fields. - -``status`` is one of 'offline', 'maintenance', or 'online'. - -``resource`` is one of 'vip__management', 'vip__public', 'vip__vrouter_pub', -'vip__vrouter', 'rabbitmq', 'mysqld' or 'haproxy'. - -* ``pacemaker_resource_count`` [#f2]_, the total number of instances for the given - ``status`` and ``resource``. -* ``pacemaker_resource_percent`` [#f2]_, the percentage of instances for the given - ``status`` and ``resource``. - -.. [#f2] this metric is only emitted from the node that is the Designated - Controller (DC) of the Pacemaker cluster. diff --git a/doc/user/source/metrics/rabbitmq.rst b/doc/user/source/metrics/rabbitmq.rst deleted file mode 100644 index b40761bd1..000000000 --- a/doc/user/source/metrics/rabbitmq.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. _RabbitMQ_metrics: - -Cluster -^^^^^^^ - -* ``rabbitmq_connections``, the total number of connections. -* ``rabbitmq_consumers``, the total number of consumers. -* ``rabbitmq_channels``, the total number of channels. -* ``rabbitmq_exchanges``, the total number of exchanges. -* ``rabbitmq_messages``, the total number of messages which are ready to be - consumed or not yet acknowledged. -* ``rabbitmq_queues``, the total number of queues. -* ``rabbitmq_running_nodes``, the total number of running nodes in the cluster. -* ``rabbitmq_disk_free``, the free disk space. -* ``rabbitmq_disk_free_limit``, the minimum amount of free disk space for - RabbitMQ. - When ``rabbitmq_disk_free`` drops below this value, all producers are blocked. -* ``rabbitmq_remaining_disk``, the difference between ``rabbitmq_disk_free`` - and ``rabbitmq_disk_free_limit``. -* ``rabbitmq_used_memory``, bytes of memory used by the whole RabbitMQ process. -* ``rabbitmq_vm_memory_limit``, the maximum amount of memory allocated for - RabbitMQ. When ``rabbitmq_used_memory`` uses more than this value, all - producers are blocked. -* ``rabbitmq_remaining_memory``, the difference between - ``rabbitmq_vm_memory_limit`` and ``rabbitmq_used_memory``. diff --git a/doc/user/source/metrics/system.rst b/doc/user/source/metrics/system.rst deleted file mode 100644 index 16bceaf92..000000000 --- a/doc/user/source/metrics/system.rst +++ /dev/null @@ -1,142 +0,0 @@ -.. _system_metrics: - -CPU -^^^ - -Metrics have a ``cpu_number`` field that contains the CPU number to which the -metric applies. - -* ``cpu_idle``, the percentage of CPU time spent in the idle task. -* ``cpu_interrupt``, the percentage of CPU time spent servicing interrupts. -* ``cpu_nice``, the percentage of CPU time spent in user mode with low - priority (nice). -* ``cpu_softirq``, the percentage of CPU time spent servicing soft interrupts. -* ``cpu_steal``, the percentage of CPU time spent in other operating systems. -* ``cpu_system``, the percentage of CPU time spent in system mode. -* ``cpu_user``, the percentage of CPU time spent in user mode. -* ``cpu_wait``, the percentage of CPU time spent waiting for I/O operations to - complete. - - -Disk -^^^^ - -Metrics have a ``device`` field that contains the disk device number the metric -applies to. For example, 'sda', 'sdb', and others. - -* ``disk_merged_read``, the number of read operations per second that could be - merged with already queued operations. -* ``disk_merged_write``, the number of write operations per second that could - be merged with already queued operations. -* ``disk_octets_read``, the number of octets (bytes) read per second. -* ``disk_octets_write``, the number of octets (bytes) written per second. -* ``disk_ops_read``, the number of read operations per second. -* ``disk_ops_write``, the number of write operations per second. -* ``disk_time_read``, the average time for a read operation to complete in the - last interval. -* ``disk_time_write``, the average time for a write operation to complete in - the last interval. - -File system -^^^^^^^^^^^ - -Metrics have a ``fs`` field that contains the partition's mount point to which -the metric applies. For example, '/', '/var/lib', and others. - -* ``fs_inodes_free``, the number of free inodes on the file system. -* ``fs_inodes_percent_free``, the percentage of free inodes on the file system. -* ``fs_inodes_percent_reserved``, the percentage of reserved inodes. -* ``fs_inodes_percent_used``, the percentage of used inodes. -* ``fs_inodes_reserved``, the number of reserved inodes. -* ``fs_inodes_used``, the number of used inodes. -* ``fs_space_free``, the number of free bytes. -* ``fs_space_percent_free``, the percentage of free bytes. -* ``fs_space_percent_reserved``, the percentage of reserved bytes. -* ``fs_space_percent_used``, the percentage of used bytes. -* ``fs_space_reserved``, the number of reserved bytes. -* ``fs_space_used``, the number of used bytes. - -System load -^^^^^^^^^^^ - -* ``load_longterm``, the system load average over the last 15 minutes. -* ``load_midterm``, the system load average over the last 5 minutes. -* ``load_shortterm``, the system load average over the last minute. - -Memory -^^^^^^ - -* ``memory_buffered``, the amount of buffered memory in bytes. -* ``memory_cached``, the amount of cached memory in bytes. -* ``memory_free``, the amount of free memory in bytes. -* ``memory_used``, the amount of used memory in bytes. - -Network -^^^^^^^ - -Metrics have an ``interface`` field that contains the interface name the -metric applies to. For example, 'eth0', 'eth1', and others. - -* ``if_collisions``, the number of collisions per second per interface. -* ``if_dropped_rx``, the number of dropped packets per second when receiving - from the interface. -* ``if_dropped_tx``, the number of dropped packets per second when transmitting - from the interface. -* ``if_errors_rx``, the number of errors per second detected when receiving - from the interface. -* ``if_errors_rx_crc``, the number of received frames with wrong CRC (cyclic - redundancy check) per second. -* ``if_errors_rx_fifo``, the number of received frames dropped per second due to - FIFO buffer overflows. -* ``if_errors_rx_frame``, the number of received frames with invalid frame - checksum (FCS). -* ``if_errors_rx_length``, the number of received frames with a length that - doesn't comply with the Ethernet specification. -* ``if_errors_rx_missed``, the number of missed packets when receiving from the - interface. -* ``if_errors_rx_over``, the number of received frames per second that were - dropped due to an hardware port receive buffer overflow. -* ``if_errors_tx``, the number of errors per second detected when transmitting - from the interface. -* ``if_errors_tx_aborted``, the number of aborted frames per second when - transmitting from the interface -* ``if_errors_tx_carrier``, the number of times per second the interface has - lost its link connection to the switch. -* ``if_errors_tx_fifo``, the number of transmitted frames per second dropped - due to FIFO buffer overflows. -* ``if_errors_tx_heartbeat``, the number of heartbeat errors per second. -* ``if_errors_tx_window``, the number of late collisions per second when - transmitting from the interface. -* ``if_multicast``, the number of multicast packets per second per interface. -* ``if_octets_rx``, the number of octets (bytes) received per second by the - interface. -* ``if_octets_tx``, the number of octets (bytes) transmitted per second by the - interface. -* ``if_packets_rx``, the number of packets received per second by the - interface. -* ``if_packets_tx``, the number of packets transmitted per second by the - interface. - -Processes -^^^^^^^^^ - -* ``processes_count``, the number of processes in a given state. The metric has - a ``state`` field (one of 'blocked', 'paging', 'running', 'sleeping', - 'stopped' or 'zombies'). -* ``processes_fork_rate``, the number of processes forked per second. - -Swap -^^^^ - -* ``swap_cached``, the amount of cached memory (in bytes) that is in the swap. -* ``swap_free``, the amount of free memory (in bytes) that is in the swap. -* ``swap_io_in``, the number of swap bytes written per second. -* ``swap_io_out``, the number of swap bytes read per second. -* ``swap_used``, the amount of used memory (in bytes) that is in the swap. -* ``swap_percent_used``, the amount of used memory (in percentages) that is in - the swap. - -Users -^^^^^ - -* ``logged_users``, the number of users currently logged in. diff --git a/doc/user/source/prerequisites.rst b/doc/user/source/prerequisites.rst deleted file mode 100644 index 6f5fcdc96..000000000 --- a/doc/user/source/prerequisites.rst +++ /dev/null @@ -1,29 +0,0 @@ -.. _plugin_prerequisites: - -Prerequisites -------------- - -Prior to installing the StackLight Collector plugin for Fuel, you may want to -install the back-end services the *collector* uses to store the data. These -back-end services include the following: - -* Elasticsearch -* InfluxDB -* Nagios - -There are two installation options: - -#. Install the back-end services automatically within a Fuel environment using - the following Fuel plugins: - - * `StackLight Elasticsearch-Kibana plugin - <http://fuel-plugin-elasticsearch-kibana.readthedocs.io/en/latest>`__ - * `StackLight InfluxDB-Grafana plugin - <http://fuel-plugin-influxdb-grafana.readthedocs.io/en/latest>`__ - * `StackLight Infrastructure Alerting plugin - <http://fuel-plugin-lma-infrastructure-alerting.readthedocs.io/en/latest/>`__ - -#. Install the back-end services manually outside of a Fuel environment. - In this case, the installation must comply with the - :ref:`requirements <plugin_requirements>` of the StackLight Collector - plugin. \ No newline at end of file diff --git a/doc/user/source/references.rst b/doc/user/source/references.rst deleted file mode 100644 index 05d65d420..000000000 --- a/doc/user/source/references.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _references: - -.. raw:: latex - - \pagebreak - -References ----------- - -* The `StackLight Collector plugin <https://github.com/openstack/fuel-plugin-lma-collector>`_ project at GitHub -* The `StackLight Elasticsearch-Kibana plugin <https://github.com/openstack/fuel-plugin-elasticsearch-kibana>`_ project at GitHub -* The `StackLight InfluxDB-Grafana plugin <https://github.com/openstack/fuel-plugin-influxdb-grafana>`_ project at GitHub -* The `StackLight Infrastructure Alerting plugin <https://github.com/openstack/fuel-plugin-lma-Infrastructure-alerting>`_ project at GitHub -* The official `Kibana documentation <https://www.elastic.co/guide/en/kibana/3.0/index.html>`_ -* The official `Elasticsearch documentation <https://www.elastic.co/guide/en/elasticsearch/reference/1.4/index.html>`_ -* The official `InfluxDB documentation <https://docs.influxdata.com/influxdb/v0.10/>`_ -* The official `Grafana documentation <http://docs.grafana.org/v2.6/>`_ -* The official `Nagios documentation <https://www.nagios.org/documentation/>`_ diff --git a/doc/user/source/release_notes.rst b/doc/user/source/release_notes.rst deleted file mode 100644 index c398b54cf..000000000 --- a/doc/user/source/release_notes.rst +++ /dev/null @@ -1,166 +0,0 @@ -.. _release_notes: - -.. raw:: latex - - \pagebreak - -Release notes -------------- - -Version 1.1.0 -+++++++++++++ - -Version 1.0.0 -+++++++++++++ - -The StackLight Collector plugin 1.0.0 for Fuel contains the following updates: - -New alarms: - - * Monitor RabbitMQ based on Pacemaker point-of-view - * Monitor all partitions and OSD disk(s) - * Horizon HTTP 5xx errors - * Keystone slow response times - * HDD errors - * SWAP percent usage - * Network packet drops - * Local OpenStack API checks - * Local checks for services: Apache, Memcached, MySQL, RabbitMQ, Pacemaker - * Monitor Nova resource utilization per aggregate (virtual CPUs, memory and disk) - -Alarm enhancements: - - * Added the ``group by`` attribute support for alarm rules - * Added support for ``pattern matching`` to filter metric dimensions - -Bug fixes: - - * Fixed the concurrent execution of logrotate. - See `#1455104 <https://bugs.launchpad.net/lma-toolchain/+bug/1455104>`_. - * Implemented the capability for the Elasticsearch bulk size to increase when - required. See `#1617211 <https://bugs.launchpad.net/lma-toolchain/+bug/1617211>`_. - * Implemented the capability to use RabbitMQ management API in place of the - :command:`rabbitmqctl` command. - * Enforce timezone setting in log processing. - See `#1633074 <https://bugs.launchpad.net/lma-toolchain/+bug/1633074>`_. - * Improve the resilience of the log_collector. - See `#1643280 <https://bugs.launchpad.net/lma-toolchain/+bug/1643280>`_. - * Support Oslo messaging v2 notifications - See `#1648479 <https://bugs.launchpad.net/lma-toolchain/+bug/1648479>`_. - - -Version 0.10.0 -++++++++++++++ - -Additionally to the bug fixes, the StackLight Collector plugin 0.10.0 for Fuel -contains the following updates: - -* Separated the processing pipeline for logs and metrics. - - Prior to StackLight version 0.10.0, there was one instance of the *hekad* - process running to process both the logs and the metrics. Starting with - StackLight version 0.10.0, the processing of the logs and notifications is - separated from the processing of the metrics in two different *hekad* - instances. This allows for better performance and control of the flow when - the maximum buffer size on disk has reached a limit. With the *hekad* - instance processing the metrics, the buffering policy mandates to drop the - metrics when the maximum buffer size is reached. With the *hekad* instance - processing the logs, the buffering policy mandates to block the entire - processing pipeline. This helps to avoid losing logs (and notifications) - when the Elasticsearch server is inaccessible for a long period of time. - As a result, the StackLight collector has now two processes running - on the node: - - * One for the *log_collector* service - * One for the *metric_collector* service - -* The metrics derived from logs are now aggregated by the *log_collector* - service. - - To avoid flooding the *metric_collector* with bursts of metrics derived from - logs, the *log_collector* service sends metrics by bulk to the - *metric_collector* service. An example of aggregated metric derived from - logs is the `openstack_<service>_http_response_time_stats - <http://fuel-plugin-lma-collector.readthedocs.io/en/latest/appendix_b.html#api-response-times>`_. - -* Added a diagnostic tool. - - A diagnostic tool is now available to help diagnose issues. The diagnostic - tool checks that the toolchain is properly installed and configured across - the entire LMA toolchain. For more information, see - :ref:`Diagnostic tool <diagnostic>`. - -Version 0.9.0 -+++++++++++++ - -The StackLight Collector plugin 0.9.0 for Fuel contains the following updates: - - * Upgraded to Heka *0.10.0*. - - * Added the capability to collect libvirt metrics on compute nodes. - - * Added the capability to detect spikes of errors in the OpenStack services - logs. - - * Added the capability to report OpenStack workers status per node. - - * Added support for multi-environment deployments. - - * Added support for Sahara logs and notifications. - -* Bug fixes: - - * Added the capability to reconnect to the local RabbitMQ instance if the - connection has been lost. - See `#1503251 <https://bugs.launchpad.net/lma-toolchain/+bug/1503251>`_. - - * Enabled buffering for Elasticsearch, InfluxDB, Nagios and TCP outputs to - reduce congestion in the Heka pipeline. - See `#1488717 <https://bugs.launchpad.net/lma-toolchain/+bug/1488717>`_, - `#1557388 <https://bugs.launchpad.net/lma-toolchain/+bug/1557388>`_. - - * Fixed the status for Nova when Midonet is used. - See `#1531541 <https://bugs.launchpad.net/lma-toolchain/+bug/1531541>`_. - - * Fixed the status for Neutron when Contrail is used. - See `#1546017 <https://bugs.launchpad.net/lma-toolchain/+bug/1546017>`_. - - * Increased the maximum number of file descriptors. - See `#1543289 <https://bugs.launchpad.net/lma-toolchain/+bug/1543289>`_. - - * The spawning of several hekad processes is now avoided. - See `#1561109 <https://bugs.launchpad.net/lma-toolchain/+bug/1561109>`_. - - * Removed the monitoring of individual queues of RabbitMQ. See `#1549721 - <https://bugs.launchpad.net/lma-toolchain/+bug/1549721>`_. - - * Added the capability to rotate hekad logs every 30 minutes if necessary. - See `#1561603 <https://bugs.launchpad.net/lma-toolchain/+bug/1561603>`_. - -Version 0.8.0 -+++++++++++++ - -The StackLight Collector plugin 0.8.0 for Fuel contains the following updates: - -* Added support for alerting in two different modes: - - * Email notifications - - * Integration with Nagios - -* Upgraded to InfluxDB 0.9.5. - -* Upgraded to Grafana 2.5. - -* Management of the LMA collector service by Pacemaker on the controller nodes - for improved reliability. - -* Monitoring of the LMA toolchain components (self-monitoring). - -* Added support for configurable alarm rules in the Collector. - - -Version 0.7.0 -+++++++++++++ - -The initial release of the StackLight Collector plugin. This is a beta version. diff --git a/doc/user/source/requirements.rst b/doc/user/source/requirements.rst deleted file mode 100644 index 2cad73c27..000000000 --- a/doc/user/source/requirements.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. _plugin_requirements: - -.. raw:: latex - - \pagebreak - -Requirements ------------- - -The StackLight Collector plugin 1.1.0 has the following requirements: - -+-------------------------------------------------------+-------------------------------------------------------------------+ -| Requirement | Version/Comment | -+=======================================================+===================================================================+ -| Mirantis OpenStack | 8.0, 9.x | -+-------------------------------------------------------+-------------------------------------------------------------------+ -| A running Elasticsearch server (for log analytics) | 1.7.4 or higher, the RESTful API must be enabled over port 9200 | -+-------------------------------------------------------+-------------------------------------------------------------------+ -| A running InfluxDB server (for metric analytics) | 0.10.0 or higher, the RESTful API must be enabled over port 8086 | -+-------------------------------------------------------+-------------------------------------------------------------------+ -| A running Nagios server (for infrastructure alerting) | 3.5 or higher, the command CGI must be enabled | -+-------------------------------------------------------+-------------------------------------------------------------------+ diff --git a/environment_config.yaml b/environment_config.yaml deleted file mode 100644 index 773b74dc2..000000000 --- a/environment_config.yaml +++ /dev/null @@ -1,89 +0,0 @@ -attributes: - metadata: - restrictions: - - condition: "cluster:net_provider != 'neutron'" - action: "hide" - - environment_label: - value: '' - label: 'Environment label' - description: 'Optional string to tag the data. If empty, it will default to "env-<environment id>".' - weight: 10 - type: "text" - - elasticsearch_mode: - type: "radio" - weight: 20 - value: "local" - label: "Events analytics (logs and notifications)" - values: - - data: "local" - label: "Local node (if deployed)" - - data: "remote" - label: "Remote server" - - elasticsearch_address: - value: '' - label: 'Elasticsearch address' - description: 'IP address or fully qualified domain name of the Elasticsearch server.' - weight: 40 - type: "text" - restrictions: - - condition: "settings:lma_collector.elasticsearch_mode.value != 'remote'" - action: "disable" - regex: &node_address_regex - source: '^[a-zA-Z\d][a-zA-Z\d_\-.]+$' - error: "Invalid address or name" - - influxdb_mode: - type: "radio" - weight: 60 - value: "local" - label: "Metrics analytics" - values: - - data: "local" - label: "Local node (if deployed)" - - data: "remote" - label: "Remote server" - - influxdb_address: - value: '' - label: 'InfluxDB address' - description: 'IP address or fully qualified domain name of the InfluxDB server.' - weight: 70 - type: "text" - regex: *node_address_regex - restrictions: - - condition: "settings:lma_collector.influxdb_mode.value != 'remote'" - action: "disable" - - influxdb_database: - value: 'lma' - label: 'InfluxDB database name' - description: '' - weight: 75 - type: "text" - regex: &not_empty_parameter - source: '\S' - error: "Invalid value" - restrictions: &disable_influxdb_parameters - - condition: "settings:lma_collector.influxdb_mode.value != 'remote'" - action: "disable" - - influxdb_user: - value: 'lma' - label: 'InfluxDB user' - description: '' - weight: 80 - type: "text" - regex: *not_empty_parameter - restrictions: *disable_influxdb_parameters - - influxdb_password: - value: 'lmapass' - label: 'InfluxDB password' - description: '' - weight: 85 - type: "password" - regex: *not_empty_parameter - restrictions: *disable_influxdb_parameters diff --git a/functions.sh b/functions.sh deleted file mode 100644 index 6268da3a2..000000000 --- a/functions.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -# Copyright 2015 Mirantis, Inc. -# -# 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. - -set -eux - -ROOT="$(dirname "$(readlink -f "$0")")" -MODULES_DIR="${ROOT}"/deployment_scripts/puppet/modules -RPM_REPO="${ROOT}"/repositories/centos/ -DEB_REPO="${ROOT}"/repositories/ubuntu/ - -function get_package_path { - FILE=$(basename "$1") - if [[ "$1" == *.deb ]]; then - echo "$DEB_REPO"/"$FILE" - elif [[ "$1" == *.rpm ]]; then - echo "$RPM_REPO"/"$FILE" - else - echo "Invalid URL for $1" - exit 1 - fi -} - -# Download RPM or DEB packages and store them in the local repository directory -function download_packages { - while [ $# -gt 0 ]; do - wget -qO - "$1" > "$(get_package_path "$1")" - shift - done -} - -# Download official Puppet module and store it in the local directory -function download_puppet_module { - rm -rf "${MODULES_DIR:?}"/"$1" - mkdir -p "${MODULES_DIR}"/"$1" - wget -qO- "$2" | tar -C "${MODULES_DIR}/$1" --strip-components=1 -xz -} - -function check_md5sum { - FILE="$(get_package_path "$1")" - echo "$2 $FILE" | md5sum --check --strict -} diff --git a/metadata.yaml b/metadata.yaml deleted file mode 100644 index 2e00e3425..000000000 --- a/metadata.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# Plugin name -name: lma_collector -# Human-readable name for your plugin -title: The StackLight Collector Plugin -# Plugin version -version: 1.1.0 -# Description -description: The StackLight Collector is the advanced monitoring agent of the so called Logging, Monitoring and Alerting (LMA) Toolchain of Mirantis OpenStack. -# Required fuel version -fuel_version: ['8.0', '9.0'] - -authors: [Mirantis Inc.] -licenses: [Apache License Version 2.0] -homepage: https://github.com/openstack/fuel-plugin-lma-collector -groups: ['monitoring'] -is_hotpluggable: true - -# The plugin is compatible with releases in the list -releases: - - os: ubuntu - version: liberty-8.0 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/ubuntu - - os: ubuntu - version: liberty-9.0 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/ubuntu - - os: ubuntu - version: mitaka-9.0 - mode: ['ha'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/ubuntu - -# Version of plugin package -package_version: '4.0.0' diff --git a/pre_build_hook b/pre_build_hook deleted file mode 100755 index ffa7e7c84..000000000 --- a/pre_build_hook +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -set -eux - -. "$(dirname "$(readlink -f "$0")")"/functions.sh -HEKA_VERSION="0.10.0" -COLLECTD_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppet-collectd-4.3.0.tar.gz" -APACHE_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-apache-1.4.0.tar.gz" -STDLIB_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-stdlib-4.7.0.tar.gz" -CONCAT_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-concat-1.2.4.tar.gz" -INIFILE_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-inifile-1.4.2.tar.gz" -FIREWALL_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-firewall-1.7.0.tar.gz" -CINDER_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/openstack-cinder-7.0.0.tar.gz" -GLANCE_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/openstack-glance-7.0.0.tar.gz" -HEAT_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/openstack-heat-7.0.0.tar.gz" -KEYSTONE_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/openstack-keystone-7.0.0.tar.gz" -NEUTRON_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/openstack-neutron-7.0.0.tar.gz" -NOVA_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/openstack-nova-7.0.0.tar.gz" -SAHARA_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/openstack-sahara-7.0.0.tar.gz" -OPENSTACKLIB_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/openstack-openstacklib-7.0.0.tar.gz" - -download_packages \ - https://github.com/elemoine/heka/releases/download/ratelimit-1/heka_${HEKA_VERSION}_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/f/fonts-dejavu/fonts-dejavu-core_2.34-1ubuntu1_all.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/f/fontconfig/fontconfig-config_2.11.0-0ubuntu4.2_all.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/f/fontconfig/libfontconfig1_2.11.0-0ubuntu4.2_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/p/pixman/libpixman-1-0_0.30.2-2ubuntu1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libx/libxcb/libxcb-render0_1.10-2ubuntu1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libx/libxcb/libxcb-shm0_1.10-2ubuntu1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libx/libxrender/libxrender1_0.9.8-1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/c/cairo/libcairo2_1.13.0~20140204-0ubuntu1.1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libd/libdatrie/libdatrie1_0.2.8-1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/g/graphite2/libgraphite2-3_1.2.4-1ubuntu1_amd64.deb \ - http://security.ubuntu.com/ubuntu/pool/main/h/harfbuzz/libharfbuzz0b_0.9.27-1ubuntu1.1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libt/libtool/libltdl7_2.4.2-1.7ubuntu1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libt/libthai/libthai-data_0.1.20-3_all.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libt/libthai/libthai0_0.1.20-3_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/f/fontconfig/fontconfig_2.11.0-0ubuntu4.2_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/p/pango1.0/libpango-1.0-0_1.36.3-1ubuntu1.1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/p/pango1.0/libpangoft2-1.0-0_1.36.3-1ubuntu1.1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/p/pango1.0/libpangocairo-1.0-0_1.36.3-1ubuntu1.1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/universe/c/collectd/collectd-core_5.4.0-3ubuntu2_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libd/libdbi/libdbi1_0.9.0-1_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/r/rrdtool/librrd4_1.4.7-2ubuntu5_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/universe/c/collectd/collectd_5.4.0-3ubuntu2_amd64.deb \ - http://mirrors.kernel.org/ubuntu/pool/main/libd/libdbi-drivers/libdbd-mysql_0.9.0-2ubuntu2_amd64.deb - -check_md5sum heka_${HEKA_VERSION}_amd64.deb 69514d94173181a8d1dcab769062fdac - -download_puppet_module "collectd" "${COLLECTD_TARBALL_URL}" -download_puppet_module "apache" "${APACHE_TARBALL_URL}" -download_puppet_module "stdlib" "${STDLIB_TARBALL_URL}" -download_puppet_module "concat" "${CONCAT_TARBALL_URL}" -download_puppet_module "inifile" "${INIFILE_TARBALL_URL}" -download_puppet_module "firewall" "${FIREWALL_TARBALL_URL}" -download_puppet_module "cinder" "${CINDER_TARBALL_URL}" -download_puppet_module "glance" "${GLANCE_TARBALL_URL}" -download_puppet_module "heat" "${HEAT_TARBALL_URL}" -download_puppet_module "keystone" "${KEYSTONE_TARBALL_URL}" -download_puppet_module "neutron" "${NEUTRON_TARBALL_URL}" -download_puppet_module "nova" "${NOVA_TARBALL_URL}" -download_puppet_module "sahara" "${SAHARA_TARBALL_URL}" -download_puppet_module "openstacklib" "${OPENSTACKLIB_TARBALL_URL}" diff --git a/repositories/centos/.gitignore b/repositories/centos/.gitignore deleted file mode 100644 index e7a9c1347..000000000 --- a/repositories/centos/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.rpm diff --git a/repositories/centos/.gitkeep b/repositories/centos/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/repositories/ubuntu/.gitignore b/repositories/ubuntu/.gitignore deleted file mode 100644 index c00df136d..000000000 --- a/repositories/ubuntu/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.deb diff --git a/repositories/ubuntu/.gitkeep b/repositories/ubuntu/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/specs/lma-collector-plugin-spec.rst b/specs/lma-collector-plugin-spec.rst deleted file mode 100644 index 96fb8a820..000000000 --- a/specs/lma-collector-plugin-spec.rst +++ /dev/null @@ -1,191 +0,0 @@ -.. - This work is licensed under a Creative Commons Attribution 3.0 Unported - License. - - http://creativecommons.org/licenses/by/3.0/legalcode - -============================================================== -Fuel plugin for the Logging, Monitoring and Alerting collector -============================================================== - -https://blueprints.launchpad.net/fuel/+spec/lma-collector-plugin - -The LMA (Logging, Monitoring & Alerting) collector is a service running on each -OpenStack node that collects metrics, logs and notifications. This data can be -sent to Elasticsearch [#]_ and/or InfluxDB [#]_ backends for diagnostic, -troubleshooting and alerting purposes. - -Problem description -=================== - -There is currently no comprehensive set of tools integrated with Fuel for -monitoring, diagnosing and troubleshooting the deployed OpenStack environments. - -The LMA collector aims at addressing the following use cases: - -* Send logs and notifications to Elasticsearch so operators can more easily - troubleshoot issues. - -* Send metrics to InfluxDB so operators can monitor and diagnose the usage - of resources. This will cover: - - + Operating system metrics (CPU, RAM, ...). - - + Service metrics (MySQL, RabbitMQ, ...). - - + OpenStack metrics (for instance, the number of free/used vCPUs). - - + Metrics extracted from logs and notifications (for instance, the HTTP - response times). - -Proposed change -=============== - -Implement a Fuel plugin that will install and configure the LMA collector -service on all the OpenStack nodes. - -The LMA collector service is based on 2 open source tools: - -* collectd [#]_ for collecting the system and service metrics. - -* Heka [#]_ for collecting the logs and notifications and for sending the data - to the storage backends. - -Alternatives ------------- - -It might have been implemented as part of Fuel core but we decided to make it -as a plugin for several reasons: - -* This isn't something that all operators may want to deploy. - -* Any new additional functionality makes the project's testing more difficult, - which is an additional risk for the Fuel release. - -* Ideally, this effort may be of interest for non-Fuel based deployments, too. - -We could also have leveraged the Zabbix implementation already available since -Fuel 5.1 but Zabbix doesn't cover the same use cases: - -* It isn't a log management solution. - -* It isn't particularly suited for storing timeseries. - - -Data model impact ------------------ - -None - -REST API impact ---------------- - -None - -Upgrade impact --------------- - -None - -Security impact ---------------- - -None - -Notifications impact --------------------- - -None - -Other end user impact ---------------------- - -None - -Performance Impact ------------------- - -Since the collector service runs as a daemon on all the nodes, it will consume -resources from the nodes. However the components it is built upon have a small -footprint both in terms of CPU usage and memory (collectd is written in C while -Heka is written in Go). - -Other deployer impact ---------------------- - -The deployer will have to run an Elasticsearch cluster and/or an InfluxDB -cluster to store the collected data. Eventually, these requirements will be -addressed by additional Fuel plugins once the custom role feature [#]_ gets -available. - -Developer impact ----------------- - -None - -Implementation -============== - -Assignee(s) ------------ - -Primary assignee: - Simon Pasquier <spasquier@mirantis.com> (feature lead, developer) - -Other contributors: - Guillaume Thouvenin <gthouvenin@mirantis.com> (developer) - Swann Croiset <scroiset@mirantis.com> (developer) - Irina Povolotskaya <ipovolotskaya@mirantis.com> (tech writer) - - -Work Items ----------- - -* Implement the Fuel plugin. - -* Implement the Puppet manifests. - -* Testing. - -* Write the documentation. - -Dependencies -============ - -* Fuel 6.0 and higher. - -Testing -======= - -* Prepare a test plan. - -* Test the plugin by deploying environments with all Fuel deployment modes. - -* Create integration tests with Elasticsearch and InfluxDB backends. - -Documentation Impact -==================== - -* Deployment Guide (how to install the storage backends, how to prepare an - environment for installation, how to install the plugin, how to deploy an - OpenStack environment with the plugin). - -* User Guide (which features the plugin provides, how to use them in the - deployed OpenStack environment). - -* Test Plan. - -* Test Report. - -References -========== - -.. [#] http://www.elasticsearch.org/ - -.. [#] http://www.influxdb.com/ - -.. [#] https://www.collectd.org/ - -.. [#] http://hekad.readthedocs.org/ - -.. [#] https://blueprints.launchpad.net/fuel/+spec/role-as-a-plugin diff --git a/tasks.yaml b/tasks.yaml deleted file mode 100644 index fe51488c7..000000000 --- a/tasks.yaml +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index 70e5d0a2f..000000000 --- a/test-requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ --e git+https://github.com/openstack/fuel-plugins.git#egg=fuel-plugin-builder -Sphinx -# Hacking already pins down pep8, pyflakes and flake8 -hacking<0.11,>=0.10.0 diff --git a/tox.ini b/tox.ini deleted file mode 100644 index fa4481474..000000000 --- a/tox.ini +++ /dev/null @@ -1,90 +0,0 @@ -[tox] -envlist = manifests,heka,fuel_lma_collector,lma_collector,docs,dev_docs,qa_docs,build_plugin,collectd_python -skipsdist = True - -[testenv] -deps = -r{toxinidir}/test-requirements.txt -passenv = HOME - -[testenv:manifests] -deps = -changedir = {toxinidir}/deployment_scripts/puppet/manifests -whitelist_externals = - bundle - mkdir -commands = - mkdir -p {toxinidir}/.bundled_gems - bundle install --path {toxinidir}/.bundled_gems - bundle exec rake test - -[testenv:heka] -deps = -changedir = {toxinidir}/deployment_scripts/puppet/modules/{envname} -whitelist_externals = - bundle - mkdir -commands = - mkdir -p {toxinidir}/.bundled_gems - bundle install --path {toxinidir}/.bundled_gems - bundle exec rake test - -[testenv:lma_collector] -deps = -changedir = {toxinidir}/deployment_scripts/puppet/modules/{envname} -whitelist_externals = - bundle - mkdir -commands = - mkdir -p {toxinidir}/.bundled_gems - bundle install --path {toxinidir}/.bundled_gems - bundle exec rake test - -[testenv:fuel_lma_collector] -deps = -changedir = {toxinidir}/deployment_scripts/puppet/modules/{envname} -whitelist_externals = - bundle - mkdir -commands = - mkdir -p {toxinidir}/.bundled_gems - bundle install --path {toxinidir}/.bundled_gems - bundle exec rake test - -[flake8] -ignore = H105,H201,E241,H401 -show-source = True - -[testenv:collectd_python] -changedir = {toxinidir}/deployment_scripts/puppet/modules/lma_collector/files/collectd -whitelist_externals = - flake8 -commands = - flake8 . - -[testenv:docs] -changedir = {toxinidir}/doc/user -whitelist_externals = make -commands = - make clean html SPHINXOPTS=-W - -[testenv:dev_docs] -changedir = {toxinidir}/doc/dev -whitelist_externals = make -commands = - make clean html SPHINXOPTS=-W - -[testenv:qa_docs] -changedir = {toxinidir}/doc/qa -whitelist_externals = make -commands = - make clean html SPHINXOPTS=-W - -[testenv:build_plugin] -changedir = {toxinidir} -whitelist_externals = - fpb - bash -commands = - bash -c "rm -rf .build repositories/ubuntu/*.deb repositories/centos/*.rpm" - fpb --check {toxinidir} --debug - fpb --build {toxinidir} --debug diff --git a/uninstall.sh b/uninstall.sh deleted file mode 100755 index c3c3f3f53..000000000 --- a/uninstall.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exit 0 \ No newline at end of file

=U%g;xRkF8|oa?UQVWan-z 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