summaryrefslogtreecommitdiffstats
path: root/collectors/python.d.plugin/springboot
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--collectors/python.d.plugin/springboot/Makefile.inc13
-rw-r--r--collectors/python.d.plugin/springboot/README.md129
-rw-r--r--collectors/python.d.plugin/springboot/springboot.chart.py (renamed from python.d/springboot.chart.py)96
-rw-r--r--collectors/python.d.plugin/springboot/springboot.conf (renamed from conf.d/python.d/springboot.conf)0
4 files changed, 194 insertions, 44 deletions
diff --git a/collectors/python.d.plugin/springboot/Makefile.inc b/collectors/python.d.plugin/springboot/Makefile.inc
new file mode 100644
index 000000000..06775f937
--- /dev/null
+++ b/collectors/python.d.plugin/springboot/Makefile.inc
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# THIS IS NOT A COMPLETE Makefile
+# IT IS INCLUDED BY ITS PARENT'S Makefile.am
+# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT
+
+# install these files
+dist_python_DATA += springboot/springboot.chart.py
+dist_pythonconfig_DATA += springboot/springboot.conf
+
+# do not install these files, but include them in the distribution
+dist_noinst_DATA += springboot/README.md springboot/Makefile.inc
+
diff --git a/collectors/python.d.plugin/springboot/README.md b/collectors/python.d.plugin/springboot/README.md
new file mode 100644
index 000000000..008436a4f
--- /dev/null
+++ b/collectors/python.d.plugin/springboot/README.md
@@ -0,0 +1,129 @@
+# springboot
+
+This module will monitor one or more Java Spring-boot applications depending on configuration.
+
+It produces following charts:
+
+1. **Response Codes** in requests/s
+ * 1xx
+ * 2xx
+ * 3xx
+ * 4xx
+ * 5xx
+ * others
+
+2. **Threads**
+ * daemon
+ * total
+
+3. **GC Time** in milliseconds and **GC Operations** in operations/s
+ * Copy
+ * MarkSweep
+ * ...
+
+4. **Heap Mmeory Usage** in KB
+ * used
+ * committed
+
+### configuration
+
+Please see the [Monitoring Java Spring Boot Applications](https://github.com/netdata/netdata/wiki/Monitoring-Java-Spring-Boot-Applications) page for detailed info about module configuration.
+
+---
+
+# Monitoring Java Spring Boot Applications
+
+Netdata can be used to monitor running Java [Spring Boot](https://spring.io/) applications that expose their metrics with the use of the **Spring Boot Actuator** included in Spring Boot library.
+
+The Spring Boot Actuator exposes these metrics over HTTP and is very easy to use:
+* add `org.springframework.boot:spring-boot-starter-actuator` to your application dependencies
+* set `endpoints.metrics.sensitive=false` in your `application.properties`
+
+You can create custom Metrics by add and inject a PublicMetrics in your application.
+This is a example to add custom metrics:
+```java
+package com.example;
+
+import org.springframework.boot.actuate.endpoint.PublicMetrics;
+import org.springframework.boot.actuate.metrics.Metric;
+import org.springframework.stereotype.Service;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.util.ArrayList;
+import java.util.Collection;
+
+@Service
+public class HeapPoolMetrics implements PublicMetrics {
+
+ private static final String PREFIX = "mempool.";
+ private static final String KEY_EDEN = PREFIX + "eden";
+ private static final String KEY_SURVIVOR = PREFIX + "survivor";
+ private static final String KEY_TENURED = PREFIX + "tenured";
+
+ @Override
+ public Collection<Metric<?>> metrics() {
+ Collection<Metric<?>> result = new ArrayList<>(4);
+ for (MemoryPoolMXBean mem : ManagementFactory.getMemoryPoolMXBeans()) {
+ String poolName = mem.getName();
+ String name = null;
+ if (poolName.indexOf("Eden Space") != -1) {
+ name = KEY_EDEN;
+ } else if (poolName.indexOf("Survivor Space") != -1) {
+ name = KEY_SURVIVOR;
+ } else if (poolName.indexOf("Tenured Gen") != -1 || poolName.indexOf("Old Gen") != -1) {
+ name = KEY_TENURED;
+ }
+
+ if (name != null) {
+ result.add(newMemoryMetric(name, mem.getUsage().getMax()));
+ result.add(newMemoryMetric(name + ".init", mem.getUsage().getInit()));
+ result.add(newMemoryMetric(name + ".committed", mem.getUsage().getCommitted()));
+ result.add(newMemoryMetric(name + ".used", mem.getUsage().getUsed()));
+ }
+ }
+ return result;
+ }
+
+ private Metric<Long> newMemoryMetric(String name, long bytes) {
+ return new Metric<>(name, bytes / 1024);
+ }
+}
+```
+
+Please refer [Spring Boot Actuator: Production-ready features](https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready.html) and [81. Actuator - Part IX. ‘How-to’ guides](https://docs.spring.io/spring-boot/docs/current/reference/html/howto-actuator.html) for more information.
+
+## Using netdata springboot module
+
+The springboot module is enabled by default. It looks up `http://localhost:8080/metrics` and `http://127.0.0.1:8080/metrics` to detect Spring Boot application by default. You can change it by editing `/etc/netdata/python.d/springboot.conf` (to edit it on your system run `/etc/netdata/edit-config python.d/springboot.conf`).
+
+This module defines some common charts, and you can add custom charts by change the configurations.
+
+The configuration format is like:
+```yaml
+<id>:
+ name: '<name>'
+ url: '<metrics endpoint>' # ex. http://localhost:8080/metrics
+ user: '<username>' # optional
+ pass: '<password>' # optional
+ defaults:
+ [<chart-id>]: true|false
+ extras:
+ - id: '<chart-id>'
+ options:
+ title: '***'
+ units: '***'
+ family: '***'
+ context: 'springboot.***'
+ charttype: 'stacked' | 'area' | 'line'
+ lines:
+ - { dimension: 'myapp_ok', name: 'ok', algorithm: 'absolute', multiplier: 1, divisor: 1} # it shows "myapp.ok" metrics
+ - { dimension: 'myapp_ng', name: 'ng', algorithm: 'absolute', multiplier: 1, divisor: 1} # it shows "myapp.ng" metrics
+```
+
+By default, it creates `response_code`, `threads`, `gc_time`, `gc_ope` abd `heap` charts.
+You can disable the default charts by set `defaults.<chart-id>: false`.
+
+The dimension name of extras charts should replace `.` to `_`.
+
+Please check [springboot.conf](springboot.conf) for more examples. \ No newline at end of file
diff --git a/python.d/springboot.chart.py b/collectors/python.d.plugin/springboot/springboot.chart.py
index 60ad0cccb..7df37e1d0 100644
--- a/python.d/springboot.chart.py
+++ b/collectors/python.d.plugin/springboot/springboot.chart.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Description: tomcat netdata python.d module
# Author: Wing924
+# SPDX-License-Identifier: GPL-3.0-or-later
import json
from bases.FrameworkServices.UrlService import UrlService
@@ -17,54 +18,61 @@ DEFAULT_CHARTS = {
'response_code': {
'options': [None, "Response Codes", "requests/s", "response", "springboot.response_code", "stacked"],
'lines': [
- ["resp_other", 'Other', 'incremental'],
- ["resp_1xx", '1xx', 'incremental'],
- ["resp_2xx", '2xx', 'incremental'],
- ["resp_3xx", '3xx', 'incremental'],
- ["resp_4xx", '4xx', 'incremental'],
- ["resp_5xx", '5xx', 'incremental'],
- ]},
+ ["resp_other", 'Other', 'incremental'],
+ ["resp_1xx", '1xx', 'incremental'],
+ ["resp_2xx", '2xx', 'incremental'],
+ ["resp_3xx", '3xx', 'incremental'],
+ ["resp_4xx", '4xx', 'incremental'],
+ ["resp_5xx", '5xx', 'incremental'],
+ ]
+ },
'threads': {
'options': [None, "Threads", "current threads", "threads", "springboot.threads", "area"],
'lines': [
["threads_daemon", 'daemon', 'absolute'],
["threads", 'total', 'absolute'],
- ]},
+ ]
+ },
'gc_time': {
'options': [None, "GC Time", "milliseconds", "garbage collection", "springboot.gc_time", "stacked"],
'lines': [
- ["gc_copy_time", 'Copy', 'incremental'],
- ["gc_marksweepcompact_time", 'MarkSweepCompact', 'incremental'],
- ["gc_parnew_time", 'ParNew', 'incremental'],
- ["gc_concurrentmarksweep_time", 'ConcurrentMarkSweep', 'incremental'],
- ["gc_ps_scavenge_time", 'PS Scavenge', 'incremental'],
- ["gc_ps_marksweep_time", 'PS MarkSweep', 'incremental'],
- ["gc_g1_young_generation_time", 'G1 Young Generation', 'incremental'],
- ["gc_g1_old_generation_time", 'G1 Old Generation', 'incremental'],
- ]},
+ ["gc_copy_time", 'Copy', 'incremental'],
+ ["gc_marksweepcompact_time", 'MarkSweepCompact', 'incremental'],
+ ["gc_parnew_time", 'ParNew', 'incremental'],
+ ["gc_concurrentmarksweep_time", 'ConcurrentMarkSweep', 'incremental'],
+ ["gc_ps_scavenge_time", 'PS Scavenge', 'incremental'],
+ ["gc_ps_marksweep_time", 'PS MarkSweep', 'incremental'],
+ ["gc_g1_young_generation_time", 'G1 Young Generation', 'incremental'],
+ ["gc_g1_old_generation_time", 'G1 Old Generation', 'incremental'],
+ ]
+ },
'gc_ope': {
'options': [None, "GC Operations", "operations/s", "garbage collection", "springboot.gc_ope", "stacked"],
'lines': [
- ["gc_copy_count", 'Copy', 'incremental'],
- ["gc_marksweepcompact_count", 'MarkSweepCompact', 'incremental'],
- ["gc_parnew_count", 'ParNew', 'incremental'],
- ["gc_concurrentmarksweep_count", 'ConcurrentMarkSweep', 'incremental'],
- ["gc_ps_scavenge_count", 'PS Scavenge', 'incremental'],
- ["gc_ps_marksweep_count", 'PS MarkSweep', 'incremental'],
- ["gc_g1_young_generation_count", 'G1 Young Generation', 'incremental'],
- ["gc_g1_old_generation_count", 'G1 Old Generation', 'incremental'],
- ]},
+ ["gc_copy_count", 'Copy', 'incremental'],
+ ["gc_marksweepcompact_count", 'MarkSweepCompact', 'incremental'],
+ ["gc_parnew_count", 'ParNew', 'incremental'],
+ ["gc_concurrentmarksweep_count", 'ConcurrentMarkSweep', 'incremental'],
+ ["gc_ps_scavenge_count", 'PS Scavenge', 'incremental'],
+ ["gc_ps_marksweep_count", 'PS MarkSweep', 'incremental'],
+ ["gc_g1_young_generation_count", 'G1 Young Generation', 'incremental'],
+ ["gc_g1_old_generation_count", 'G1 Old Generation', 'incremental'],
+ ]
+ },
'heap': {
'options': [None, "Heap Memory Usage", "KB", "heap memory", "springboot.heap", "area"],
'lines': [
["heap_committed", 'committed', "absolute"],
["heap_used", 'used', "absolute"],
- ]},
+ ]
+ }
}
+
class ExtraChartError(ValueError):
pass
+
class Service(UrlService):
def __init__(self, configuration=None, name=None):
UrlService.__init__(self, configuration=configuration, name=name)
@@ -87,11 +95,11 @@ class Service(UrlService):
return None
result = {
- 'resp_1xx': 0,
- 'resp_2xx': 0,
- 'resp_3xx': 0,
- 'resp_4xx': 0,
- 'resp_5xx': 0,
+ 'resp_1xx': 0,
+ 'resp_2xx': 0,
+ 'resp_3xx': 0,
+ 'resp_4xx': 0,
+ 'resp_5xx': 0,
'resp_other': 0,
}
@@ -121,14 +129,14 @@ class Service(UrlService):
self.order.append(extra['id'])
def _add_extra_chart(self, chart):
- chart_id = chart.get('id', None) or die('id is not defined in extra chart')
- options = chart.get('options', None) or die('option is not defined in extra chart: %s' % chart_id)
- lines = chart.get('lines', None) or die('lines is not defined in extra chart: %s' % chart_id)
-
- title = options.get('title', None) or die('title is missing: %s' % chart_id)
- units = options.get('units', None) or die('units is missing: %s' % chart_id)
- family = options.get('family', title)
- context = options.get('context', 'springboot.' + title)
+ chart_id = chart.get('id', None) or self.die('id is not defined in extra chart')
+ options = chart.get('options', None) or self.die('option is not defined in extra chart: %s' % chart_id)
+ lines = chart.get('lines', None) or self.die('lines is not defined in extra chart: %s' % chart_id)
+
+ title = options.get('title', None) or self.die('title is missing: %s' % chart_id)
+ units = options.get('units', None) or self.die('units is missing: %s' % chart_id)
+ family = options.get('family', title)
+ context = options.get('context', 'springboot.' + title)
charttype = options.get('charttype', 'line')
result = {
@@ -137,11 +145,11 @@ class Service(UrlService):
}
for line in lines:
- dimension = line.get('dimension', None) or die('dimension is missing: %s' % chart_id)
- name = line.get('name', dimension)
- algorithm = line.get('algorithm', 'absolute')
+ dimension = line.get('dimension', None) or self.die('dimension is missing: %s' % chart_id)
+ name = line.get('name', dimension)
+ algorithm = line.get('algorithm', 'absolute')
multiplier = line.get('multiplier', 1)
- divisor = line.get('divisor', 1)
+ divisor = line.get('divisor', 1)
result['lines'].append([dimension, name, algorithm, multiplier, divisor])
self.definitions[chart_id] = result
diff --git a/conf.d/python.d/springboot.conf b/collectors/python.d.plugin/springboot/springboot.conf
index 40b5fb437..40b5fb437 100644
--- a/conf.d/python.d/springboot.conf
+++ b/collectors/python.d.plugin/springboot/springboot.conf