diff --git a/README.rst b/README.rst index 917bf8f..5d4826b 100644 --- a/README.rst +++ b/README.rst @@ -7,6 +7,7 @@ NewRelic platform. Currently supported backend systems are: - Alternative PHP Cache - Apache HTTP Server - CouchDB +- Couchbase - Elasticsearch - HAProxy - Memcached @@ -19,6 +20,12 @@ NewRelic platform. Currently supported backend systems are: - Redis - Riak - uWSGI +- NagioRelic + + + this is not a backend + + it just executes programs (usually bash scripts) in a directory + + the program name is used as the metric name + + the output of the program must be numeric Base Requirements ----------------- @@ -298,6 +305,12 @@ Configuration Example #username: foo #password: bar + couchbase: + name: localhost + host: localhost + port: 8091 + path: pools/default/buckets + elasticsearch: name: clustername host: localhost @@ -407,6 +420,9 @@ Configuration Example port: 8098 #verify_ssl_cert: true + nagiorelic: + path: /etc/newrelic/nagiorelic + Daemon: user: newrelic pidfile: /var/run/newrelic/newrelic-plugin-agent.pid diff --git a/docker/base/newrelic-plugin-agent.cfg b/docker/base/newrelic-plugin-agent.cfg index f957d04..a0b1695 100644 --- a/docker/base/newrelic-plugin-agent.cfg +++ b/docker/base/newrelic-plugin-agent.cfg @@ -22,6 +22,12 @@ Application: # username: foo # password: bar + #couchbase: + # name: localhost + # host: localhost + # port: 8091 + # path: pools/default/buckets + #elasticsearch: # name: Clustername # host: localhost @@ -151,6 +157,9 @@ Application: # port: 1717 # path: /path/to/unix/socket + #nagiorelic: + # path: /etc/newrelic/nagiorelic + Daemon: user: newrelic pidfile: /var/run/newrelic/newrelic-plugin-agent.pid diff --git a/etc/newrelic/newrelic-plugin-agent.cfg b/etc/newrelic/newrelic-plugin-agent.cfg index f957d04..a0b1695 100644 --- a/etc/newrelic/newrelic-plugin-agent.cfg +++ b/etc/newrelic/newrelic-plugin-agent.cfg @@ -22,6 +22,12 @@ Application: # username: foo # password: bar + #couchbase: + # name: localhost + # host: localhost + # port: 8091 + # path: pools/default/buckets + #elasticsearch: # name: Clustername # host: localhost @@ -151,6 +157,9 @@ Application: # port: 1717 # path: /path/to/unix/socket + #nagiorelic: + # path: /etc/newrelic/nagiorelic + Daemon: user: newrelic pidfile: /var/run/newrelic/newrelic-plugin-agent.pid diff --git a/newrelic_plugin_agent/plugins/__init__.py b/newrelic_plugin_agent/plugins/__init__.py index 98c5cb9..5b80596 100644 --- a/newrelic_plugin_agent/plugins/__init__.py +++ b/newrelic_plugin_agent/plugins/__init__.py @@ -6,6 +6,7 @@ available = { 'apache_httpd': 'newrelic_plugin_agent.plugins.apache_httpd.ApacheHTTPD', 'couchdb': 'newrelic_plugin_agent.plugins.couchdb.CouchDB', + 'couchbase': 'newrelic_plugin_agent.plugins.couchbase.Couchbase', 'edgecast': 'newrelic_plugin_agent.plugins.edgecast.Edgecast', 'elasticsearch': 'newrelic_plugin_agent.plugins.elasticsearch.ElasticSearch', @@ -20,4 +21,5 @@ 'rabbitmq': 'newrelic_plugin_agent.plugins.rabbitmq.RabbitMQ', 'redis': 'newrelic_plugin_agent.plugins.redis.Redis', 'riak': 'newrelic_plugin_agent.plugins.riak.Riak', - 'uwsgi': 'newrelic_plugin_agent.plugins.uwsgi.uWSGI'} + 'uwsgi': 'newrelic_plugin_agent.plugins.uwsgi.uWSGI', + 'nagiorelic': 'newrelic_plugin_agent.plugins.nagiorelic.NagioRelic'} diff --git a/newrelic_plugin_agent/plugins/base.py b/newrelic_plugin_agent/plugins/base.py index 2aa3980..7341f74 100644 --- a/newrelic_plugin_agent/plugins/base.py +++ b/newrelic_plugin_agent/plugins/base.py @@ -345,7 +345,7 @@ def http_get(self, url=None): :rtype: requests.models.Response """ - LOGGER.debug('Polling %s Stats at %s', + LOGGER.info('Polling %s Stats at %s', self.__class__.__name__, url or self.stats_url) req_kwargs = self.request_kwargs req_kwargs.update({'url': url} if url else {}) diff --git a/newrelic_plugin_agent/plugins/couchbase.py b/newrelic_plugin_agent/plugins/couchbase.py new file mode 100644 index 0000000..35c3f72 --- /dev/null +++ b/newrelic_plugin_agent/plugins/couchbase.py @@ -0,0 +1,60 @@ +""" +couchbase + +""" + +from newrelic_plugin_agent.plugins import base + + +class Couchbase(base.JSONStatsPlugin): + + GUID = 'com.meetme.couchbase' + + def add_datapoints(self, stats): + for bucket_data in stats: + bucket_name = bucket_data['name'] + bucket_stats = bucket_data['basicStats'] + if bucket_stats: + """ Example JSON + "basicStats":{ + "quotaPercentUsed":7.548735046386719, + "opsPerSec":0, + "diskFetches":0, + "itemCount":2222, + "diskUsed":229366539, + "dataUsed":203511808, + "memUsed":79154224 + } + """ + self.add_gauge_bucket_metric( + bucket_name, 'quotaPercentUsed', 'percent', bucket_stats['quotaPercentUsed'] + ) + self.add_gauge_bucket_metric( + bucket_name, 'opsPerSec', 'ops', bucket_stats['opsPerSec'] + ) + self.add_gauge_bucket_metric( + bucket_name, 'diskFetches', 'count', bucket_stats['diskFetches'] + ) + self.add_gauge_bucket_metric( + bucket_name, 'itemCount', 'count', bucket_stats['itemCount'] + ) + self.add_gauge_bucket_metric( + bucket_name, 'diskUsed', 'Byte', bucket_stats['diskUsed'] + ) + self.add_gauge_bucket_metric( + bucket_name, 'dataUsed', 'Byte', bucket_stats['dataUsed'] + ) + self.add_gauge_bucket_metric( + bucket_name, 'memUsed', 'Byte', bucket_stats['memUsed'] + ) + + # Summary metrics + self.add_gauge_value('Summary/%s/quotaPercentUsed' % bucket_name, 'percent', + bucket_stats['quotaPercentUsed'], + min_val=0, max_val=0) + self.add_gauge_value('Summary/%s/diskUsed' % bucket_name, 'byte', + bucket_stats['diskUsed']) + + def add_gauge_bucket_metric(self, bucket_name, metric_name, units, metric_value): + if metric_value: + self.add_gauge_value('%s/%s' % (bucket_name, metric_name), units, metric_value) diff --git a/newrelic_plugin_agent/plugins/nagiorelic.py b/newrelic_plugin_agent/plugins/nagiorelic.py new file mode 100644 index 0000000..f0d4011 --- /dev/null +++ b/newrelic_plugin_agent/plugins/nagiorelic.py @@ -0,0 +1,35 @@ +""" +Nagiorelic Plugin + +""" +import logging +import os +import subprocess +from subprocess import CalledProcessError + +from newrelic_plugin_agent.plugins import base + + +LOGGER = logging.getLogger(__name__) + + +class NagioRelic(base.Plugin): + + GUID = 'com.meetme.nagiorelic' + + def poll(self): + self.initialize() + + root = self.config['path'] + for script in os.listdir(root): + try: + output = subprocess.check_output(os.path.join(root, script)).decode().strip() + if output.isdigit(): + metric = '%s' % (os.path.splitext(os.path.basename(script))[0]) + self.add_gauge_value(metric, None, int(output)) + else: + LOGGER.error('command did not return a number %s: %s' % (script, output)) + except CalledProcessError as e: + LOGGER.error('command returned an error %s: %s: %s' % (script, e.returncode, e.output)) + + self.finish()