summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/modules/cassandra
diff options
context:
space:
mode:
Diffstat (limited to '')
l---------src/go/collectors/go.d.plugin/modules/cassandra/README.md1
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/cassandra.go118
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/cassandra_test.go298
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/charts.go461
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/collect.go403
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/config_schema.json177
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/init.go25
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/integrations/cassandra.md278
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/jmx_exporter.yaml31
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/metadata.yaml410
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/metrics.go103
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/testdata/config.json20
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/testdata/config.yaml17
-rw-r--r--src/go/collectors/go.d.plugin/modules/cassandra/testdata/metrics.txt402
14 files changed, 2744 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/README.md b/src/go/collectors/go.d.plugin/modules/cassandra/README.md
new file mode 120000
index 000000000..99b5b9da5
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/README.md
@@ -0,0 +1 @@
+integrations/cassandra.md \ No newline at end of file
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/cassandra.go b/src/go/collectors/go.d.plugin/modules/cassandra/cassandra.go
new file mode 100644
index 000000000..ee39246d5
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/cassandra.go
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package cassandra
+
+import (
+ _ "embed"
+ "errors"
+ "time"
+
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/prometheus"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
+)
+
+//go:embed "config_schema.json"
+var configSchema string
+
+func init() {
+ module.Register("cassandra", module.Creator{
+ JobConfigSchema: configSchema,
+ Defaults: module.Defaults{
+ UpdateEvery: 5,
+ },
+ Create: func() module.Module { return New() },
+ Config: func() any { return &Config{} },
+ })
+}
+
+func New() *Cassandra {
+ return &Cassandra{
+ Config: Config{
+ HTTP: web.HTTP{
+ Request: web.Request{
+ URL: "http://127.0.0.1:7072/metrics",
+ },
+ Client: web.Client{
+ Timeout: web.Duration(time.Second * 5),
+ },
+ },
+ },
+ charts: baseCharts.Copy(),
+ validateMetrics: true,
+ mx: newCassandraMetrics(),
+ }
+}
+
+type Config struct {
+ UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
+ web.HTTP `yaml:",inline" json:""`
+}
+
+type Cassandra struct {
+ module.Base
+ Config `yaml:",inline" json:""`
+
+ charts *module.Charts
+
+ prom prometheus.Prometheus
+
+ validateMetrics bool
+
+ mx *cassandraMetrics
+}
+
+func (c *Cassandra) Configuration() any {
+ return c.Config
+}
+
+func (c *Cassandra) Init() error {
+ if err := c.validateConfig(); err != nil {
+ c.Errorf("error on validating config: %v", err)
+ return err
+ }
+
+ prom, err := c.initPrometheusClient()
+ if err != nil {
+ c.Errorf("error on init prometheus client: %v", err)
+ return err
+ }
+ c.prom = prom
+
+ return nil
+}
+
+func (c *Cassandra) Check() error {
+ mx, err := c.collect()
+ if err != nil {
+ c.Error(err)
+ return err
+ }
+ if len(mx) == 0 {
+ return errors.New("no metrics collected")
+
+ }
+ return nil
+}
+
+func (c *Cassandra) Charts() *module.Charts {
+ return c.charts
+}
+
+func (c *Cassandra) Collect() map[string]int64 {
+ mx, err := c.collect()
+ if err != nil {
+ c.Error(err)
+ }
+
+ if len(mx) == 0 {
+ return nil
+ }
+ return mx
+}
+
+func (c *Cassandra) Cleanup() {
+ if c.prom != nil && c.prom.HTTPClient() != nil {
+ c.prom.HTTPClient().CloseIdleConnections()
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/cassandra_test.go b/src/go/collectors/go.d.plugin/modules/cassandra/cassandra_test.go
new file mode 100644
index 000000000..650f79cd8
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/cassandra_test.go
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package cassandra
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "os"
+ "testing"
+
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+var (
+ dataConfigJSON, _ = os.ReadFile("testdata/config.json")
+ dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
+
+ dataExpectedMetrics, _ = os.ReadFile("testdata/metrics.txt")
+)
+
+func Test_testDataIsValid(t *testing.T) {
+ for name, data := range map[string][]byte{
+ "dataConfigJSON": dataConfigJSON,
+ "dataConfigYAML": dataConfigYAML,
+ "dataExpectedMetrics": dataExpectedMetrics,
+ } {
+ assert.NotNil(t, data, name)
+ }
+}
+
+func TestCassandra_ConfigurationSerialize(t *testing.T) {
+ module.TestConfigurationSerialize(t, &Cassandra{}, dataConfigJSON, dataConfigYAML)
+}
+
+func TestNew(t *testing.T) {
+ assert.IsType(t, (*Cassandra)(nil), New())
+}
+
+func TestCassandra_Init(t *testing.T) {
+ tests := map[string]struct {
+ config Config
+ wantFail bool
+ }{
+ "success if 'url' is set": {
+ config: Config{
+ HTTP: web.HTTP{Request: web.Request{URL: "http://127.0.0.1:7072"}}},
+ },
+ "success on default config": {
+ wantFail: false,
+ config: New().Config,
+ },
+ "fails if 'url' is unset": {
+ wantFail: true,
+ config: Config{HTTP: web.HTTP{Request: web.Request{URL: ""}}},
+ },
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ c := New()
+ c.Config = test.config
+
+ if test.wantFail {
+ assert.Error(t, c.Init())
+ } else {
+ assert.NoError(t, c.Init())
+ }
+ })
+ }
+}
+
+func TestCassandra_Check(t *testing.T) {
+ tests := map[string]struct {
+ prepare func() (c *Cassandra, cleanup func())
+ wantFail bool
+ }{
+ "success on valid response": {
+ prepare: prepareCassandra,
+ },
+ "fails if endpoint returns invalid data": {
+ wantFail: true,
+ prepare: prepareCassandraInvalidData,
+ },
+ "fails on connection refused": {
+ wantFail: true,
+ prepare: prepareCassandraConnectionRefused,
+ },
+ "fails on 404 response": {
+ wantFail: true,
+ prepare: prepareCassandraResponse404,
+ },
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ c, cleanup := test.prepare()
+ defer cleanup()
+
+ require.NoError(t, c.Init())
+
+ if test.wantFail {
+ assert.Error(t, c.Check())
+ } else {
+ assert.NoError(t, c.Check())
+ }
+ })
+ }
+}
+
+func TestCassandra_Charts(t *testing.T) {
+ assert.NotNil(t, New().Charts())
+}
+
+func TestCassandra_Collect(t *testing.T) {
+ tests := map[string]struct {
+ prepare func() (c *Cassandra, cleanup func())
+ wantCollected map[string]int64
+ }{
+ "success on valid response": {
+ prepare: prepareCassandra,
+ wantCollected: map[string]int64{
+ "client_request_failures_reads": 0,
+ "client_request_failures_writes": 0,
+ "client_request_latency_reads": 333316,
+ "client_request_latency_writes": 331841,
+ "client_request_read_latency_p50": 61,
+ "client_request_read_latency_p75": 88,
+ "client_request_read_latency_p95": 126,
+ "client_request_read_latency_p98": 182,
+ "client_request_read_latency_p99": 219,
+ "client_request_read_latency_p999": 454,
+ "client_request_timeouts_reads": 0,
+ "client_request_timeouts_writes": 0,
+ "client_request_total_latency_reads": 23688998,
+ "client_request_total_latency_writes": 14253267,
+ "client_request_unavailables_reads": 0,
+ "client_request_unavailables_writes": 0,
+ "client_request_write_latency_p50": 35,
+ "client_request_write_latency_p75": 61,
+ "client_request_write_latency_p95": 105,
+ "client_request_write_latency_p98": 126,
+ "client_request_write_latency_p99": 152,
+ "client_request_write_latency_p999": 315,
+ "compaction_bytes_compacted": 2532,
+ "compaction_completed_tasks": 1078,
+ "compaction_pending_tasks": 0,
+ "dropped_messages": 0,
+ "jvm_gc_cms_count": 1,
+ "jvm_gc_cms_time": 59,
+ "jvm_gc_parnew_count": 218,
+ "jvm_gc_parnew_time": 1617,
+ "jvm_memory_heap_used": 1134866288,
+ "jvm_memory_nonheap_used": 96565696,
+ "key_cache_hit_ratio": 87273,
+ "key_cache_hits": 1336427,
+ "key_cache_misses": 194890,
+ "key_cache_size": 196559936,
+ "key_cache_utilization": 20828,
+ "row_cache_hit_ratio": 0,
+ "row_cache_hits": 0,
+ "row_cache_misses": 0,
+ "row_cache_size": 0,
+ "row_cache_utilization": 0,
+ "storage_exceptions": 0,
+ "storage_load": 858272986,
+ "thread_pool_CacheCleanupExecutor_active_tasks": 0,
+ "thread_pool_CacheCleanupExecutor_blocked_tasks": 0,
+ "thread_pool_CacheCleanupExecutor_pending_tasks": 0,
+ "thread_pool_CacheCleanupExecutor_total_blocked_tasks": 0,
+ "thread_pool_CompactionExecutor_active_tasks": 0,
+ "thread_pool_CompactionExecutor_blocked_tasks": 0,
+ "thread_pool_CompactionExecutor_pending_tasks": 0,
+ "thread_pool_CompactionExecutor_total_blocked_tasks": 0,
+ "thread_pool_GossipStage_active_tasks": 0,
+ "thread_pool_GossipStage_blocked_tasks": 0,
+ "thread_pool_GossipStage_pending_tasks": 0,
+ "thread_pool_GossipStage_total_blocked_tasks": 0,
+ "thread_pool_HintsDispatcher_active_tasks": 0,
+ "thread_pool_HintsDispatcher_blocked_tasks": 0,
+ "thread_pool_HintsDispatcher_pending_tasks": 0,
+ "thread_pool_HintsDispatcher_total_blocked_tasks": 0,
+ "thread_pool_MemtableFlushWriter_active_tasks": 0,
+ "thread_pool_MemtableFlushWriter_blocked_tasks": 0,
+ "thread_pool_MemtableFlushWriter_pending_tasks": 0,
+ "thread_pool_MemtableFlushWriter_total_blocked_tasks": 0,
+ "thread_pool_MemtablePostFlush_active_tasks": 0,
+ "thread_pool_MemtablePostFlush_blocked_tasks": 0,
+ "thread_pool_MemtablePostFlush_pending_tasks": 0,
+ "thread_pool_MemtablePostFlush_total_blocked_tasks": 0,
+ "thread_pool_MemtableReclaimMemory_active_tasks": 0,
+ "thread_pool_MemtableReclaimMemory_blocked_tasks": 0,
+ "thread_pool_MemtableReclaimMemory_pending_tasks": 0,
+ "thread_pool_MemtableReclaimMemory_total_blocked_tasks": 0,
+ "thread_pool_MutationStage_active_tasks": 0,
+ "thread_pool_MutationStage_blocked_tasks": 0,
+ "thread_pool_MutationStage_pending_tasks": 0,
+ "thread_pool_MutationStage_total_blocked_tasks": 0,
+ "thread_pool_Native-Transport-Requests_active_tasks": 0,
+ "thread_pool_Native-Transport-Requests_blocked_tasks": 0,
+ "thread_pool_Native-Transport-Requests_pending_tasks": 0,
+ "thread_pool_Native-Transport-Requests_total_blocked_tasks": 0,
+ "thread_pool_PendingRangeCalculator_active_tasks": 0,
+ "thread_pool_PendingRangeCalculator_blocked_tasks": 0,
+ "thread_pool_PendingRangeCalculator_pending_tasks": 0,
+ "thread_pool_PendingRangeCalculator_total_blocked_tasks": 0,
+ "thread_pool_PerDiskMemtableFlushWriter_0_active_tasks": 0,
+ "thread_pool_PerDiskMemtableFlushWriter_0_blocked_tasks": 0,
+ "thread_pool_PerDiskMemtableFlushWriter_0_pending_tasks": 0,
+ "thread_pool_PerDiskMemtableFlushWriter_0_total_blocked_tasks": 0,
+ "thread_pool_ReadStage_active_tasks": 0,
+ "thread_pool_ReadStage_blocked_tasks": 0,
+ "thread_pool_ReadStage_pending_tasks": 0,
+ "thread_pool_ReadStage_total_blocked_tasks": 0,
+ "thread_pool_Sampler_active_tasks": 0,
+ "thread_pool_Sampler_blocked_tasks": 0,
+ "thread_pool_Sampler_pending_tasks": 0,
+ "thread_pool_Sampler_total_blocked_tasks": 0,
+ "thread_pool_SecondaryIndexManagement_active_tasks": 0,
+ "thread_pool_SecondaryIndexManagement_blocked_tasks": 0,
+ "thread_pool_SecondaryIndexManagement_pending_tasks": 0,
+ "thread_pool_SecondaryIndexManagement_total_blocked_tasks": 0,
+ "thread_pool_ValidationExecutor_active_tasks": 0,
+ "thread_pool_ValidationExecutor_blocked_tasks": 0,
+ "thread_pool_ValidationExecutor_pending_tasks": 0,
+ "thread_pool_ValidationExecutor_total_blocked_tasks": 0,
+ "thread_pool_ViewBuildExecutor_active_tasks": 0,
+ "thread_pool_ViewBuildExecutor_blocked_tasks": 0,
+ "thread_pool_ViewBuildExecutor_pending_tasks": 0,
+ "thread_pool_ViewBuildExecutor_total_blocked_tasks": 0,
+ },
+ },
+ "fails if endpoint returns invalid data": {
+ prepare: prepareCassandraInvalidData,
+ },
+ "fails on connection refused": {
+ prepare: prepareCassandraConnectionRefused,
+ },
+ "fails on 404 response": {
+ prepare: prepareCassandraResponse404,
+ },
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ c, cleanup := test.prepare()
+ defer cleanup()
+
+ require.NoError(t, c.Init())
+
+ mx := c.Collect()
+
+ assert.Equal(t, test.wantCollected, mx)
+ })
+ }
+}
+
+func prepareCassandra() (c *Cassandra, cleanup func()) {
+ ts := httptest.NewServer(http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ _, _ = w.Write(dataExpectedMetrics)
+ }))
+
+ c = New()
+ c.URL = ts.URL
+ return c, ts.Close
+}
+
+func prepareCassandraInvalidData() (c *Cassandra, cleanup func()) {
+ ts := httptest.NewServer(http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ _, _ = w.Write([]byte("hello and\n goodbye"))
+ }))
+
+ c = New()
+ c.URL = ts.URL
+ return c, ts.Close
+}
+
+func prepareCassandraConnectionRefused() (c *Cassandra, cleanup func()) {
+ c = New()
+ c.URL = "http://127.0.0.1:38001"
+ return c, func() {}
+}
+
+func prepareCassandraResponse404() (c *Cassandra, cleanup func()) {
+ ts := httptest.NewServer(http.HandlerFunc(
+ func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusNotFound)
+ }))
+
+ c = New()
+ c.URL = ts.URL
+ return c, ts.Close
+}
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/charts.go b/src/go/collectors/go.d.plugin/modules/cassandra/charts.go
new file mode 100644
index 000000000..8c3fc239a
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/charts.go
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package cassandra
+
+import (
+ "fmt"
+
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
+)
+
+const (
+ prioClientRequestsRate = module.Priority + iota
+
+ prioClientRequestReadLatency
+ prioClientRequestWriteLatency
+ prioClientRequestsLatency
+
+ prioKeyCacheHitRatio
+ prioRowCacheHitRatio
+ prioKeyCacheHitRate
+ prioRowCacheHitRate
+ prioKeyCacheUtilization
+ prioRowCacheUtilization
+ prioKeyCacheSize
+ prioRowCacheSize
+
+ prioStorageLiveDiskSpaceUsed
+
+ prioCompactionCompletedTasksRate
+ prioCompactionPendingTasksCount
+ prioCompactionBytesCompactedRate
+
+ prioThreadPoolActiveTasksCount
+ prioThreadPoolPendingTasksCount
+ prioThreadPoolBlockedTasksCount
+ prioThreadPoolBlockedTasksRate
+
+ prioJVMMemoryUsed
+ prioJVMGCCount
+ prioJVMGCTime
+
+ prioDroppedMessagesRate
+ prioRequestsTimeoutsRate
+ prioRequestsUnavailablesRate
+ prioRequestsFailuresRate
+ prioStorageExceptionsRate
+)
+
+var baseCharts = module.Charts{
+ chartClientRequestsRate.Copy(),
+
+ chartClientRequestsLatency.Copy(),
+ chartClientRequestReadLatencyHistogram.Copy(),
+ chartClientRequestWriteLatencyHistogram.Copy(),
+
+ chartKeyCacheHitRatio.Copy(),
+ chartRowCacheHitRatio.Copy(),
+ chartKeyCacheHitRate.Copy(),
+ chartRowCacheHitRate.Copy(),
+ chartKeyCacheUtilization.Copy(),
+ chartRowCacheUtilization.Copy(),
+ chartKeyCacheSize.Copy(),
+ chartRowCacheSize.Copy(),
+
+ chartStorageLiveDiskSpaceUsed.Copy(),
+
+ chartCompactionCompletedTasksRate.Copy(),
+ chartCompactionPendingTasksCount.Copy(),
+ chartCompactionBytesCompactedRate.Copy(),
+
+ chartJVMMemoryUsed.Copy(),
+ chartJVMGCRate.Copy(),
+ chartJVMGCTime.Copy(),
+
+ chartDroppedMessagesRate.Copy(),
+ chartClientRequestTimeoutsRate.Copy(),
+ chartClientRequestUnavailablesRate.Copy(),
+ chartClientRequestFailuresRate.Copy(),
+ chartStorageExceptionsRate.Copy(),
+}
+
+var (
+ chartClientRequestsRate = module.Chart{
+ ID: "client_requests_rate",
+ Title: "Client requests rate",
+ Units: "requests/s",
+ Fam: "throughput",
+ Ctx: "cassandra.client_requests_rate",
+ Priority: prioClientRequestsRate,
+ Dims: module.Dims{
+ {ID: "client_request_latency_reads", Name: "read", Algo: module.Incremental},
+ {ID: "client_request_latency_writes", Name: "write", Algo: module.Incremental, Mul: -1},
+ },
+ }
+)
+
+var (
+ chartClientRequestReadLatencyHistogram = module.Chart{
+ ID: "client_request_read_latency_histogram",
+ Title: "Client request read latency histogram",
+ Units: "seconds",
+ Fam: "latency",
+ Ctx: "cassandra.client_request_read_latency_histogram",
+ Priority: prioClientRequestReadLatency,
+ Dims: module.Dims{
+ {ID: "client_request_read_latency_p50", Name: "p50", Div: 1e6},
+ {ID: "client_request_read_latency_p75", Name: "p75", Div: 1e6},
+ {ID: "client_request_read_latency_p95", Name: "p95", Div: 1e6},
+ {ID: "client_request_read_latency_p98", Name: "p98", Div: 1e6},
+ {ID: "client_request_read_latency_p99", Name: "p99", Div: 1e6},
+ {ID: "client_request_read_latency_p999", Name: "p999", Div: 1e6},
+ },
+ }
+ chartClientRequestWriteLatencyHistogram = module.Chart{
+ ID: "client_request_write_latency_histogram",
+ Title: "Client request write latency histogram",
+ Units: "seconds",
+ Fam: "latency",
+ Ctx: "cassandra.client_request_write_latency_histogram",
+ Priority: prioClientRequestWriteLatency,
+ Dims: module.Dims{
+ {ID: "client_request_write_latency_p50", Name: "p50", Div: 1e6},
+ {ID: "client_request_write_latency_p75", Name: "p75", Div: 1e6},
+ {ID: "client_request_write_latency_p95", Name: "p95", Div: 1e6},
+ {ID: "client_request_write_latency_p98", Name: "p98", Div: 1e6},
+ {ID: "client_request_write_latency_p99", Name: "p99", Div: 1e6},
+ {ID: "client_request_write_latency_p999", Name: "p999", Div: 1e6},
+ },
+ }
+ chartClientRequestsLatency = module.Chart{
+ ID: "client_requests_latency",
+ Title: "Client requests total latency",
+ Units: "seconds",
+ Fam: "latency",
+ Ctx: "cassandra.client_requests_latency",
+ Priority: prioClientRequestsLatency,
+ Dims: module.Dims{
+ {ID: "client_request_total_latency_reads", Name: "read", Algo: module.Incremental, Div: 1e6},
+ {ID: "client_request_total_latency_writes", Name: "write", Algo: module.Incremental, Div: 1e6},
+ },
+ }
+)
+
+var (
+ chartKeyCacheHitRatio = module.Chart{
+ ID: "key_cache_hit_ratio",
+ Title: "Key cache hit ratio",
+ Units: "percentage",
+ Fam: "cache",
+ Ctx: "cassandra.key_cache_hit_ratio",
+ Priority: prioKeyCacheHitRatio,
+ Dims: module.Dims{
+ {ID: "key_cache_hit_ratio", Name: "hit_ratio", Div: 1000},
+ },
+ }
+ chartKeyCacheHitRate = module.Chart{
+ ID: "key_cache_hit_rate",
+ Title: "Key cache hit rate",
+ Units: "events/s",
+ Fam: "cache",
+ Ctx: "cassandra.key_cache_hit_rate",
+ Priority: prioKeyCacheHitRate,
+ Type: module.Stacked,
+ Dims: module.Dims{
+ {ID: "key_cache_hits", Name: "hits", Algo: module.Incremental},
+ {ID: "key_cache_misses", Name: "misses", Algo: module.Incremental},
+ },
+ }
+ chartKeyCacheUtilization = module.Chart{
+ ID: "key_cache_utilization",
+ Title: "Key cache utilization",
+ Units: "percentage",
+ Fam: "cache",
+ Ctx: "cassandra.key_cache_utilization",
+ Priority: prioKeyCacheUtilization,
+ Dims: module.Dims{
+ {ID: "key_cache_utilization", Name: "used", Div: 1000},
+ },
+ }
+ chartKeyCacheSize = module.Chart{
+ ID: "key_cache_size",
+ Title: "Key cache size",
+ Units: "bytes",
+ Fam: "cache",
+ Ctx: "cassandra.key_cache_size",
+ Priority: prioKeyCacheSize,
+ Dims: module.Dims{
+ {ID: "key_cache_size", Name: "size"},
+ },
+ }
+
+ chartRowCacheHitRatio = module.Chart{
+ ID: "row_cache_hit_ratio",
+ Title: "Row cache hit ratio",
+ Units: "percentage",
+ Fam: "cache",
+ Ctx: "cassandra.row_cache_hit_ratio",
+ Priority: prioRowCacheHitRatio,
+ Dims: module.Dims{
+ {ID: "row_cache_hit_ratio", Name: "hit_ratio", Div: 1000},
+ },
+ }
+ chartRowCacheHitRate = module.Chart{
+ ID: "row_cache_hit_rate",
+ Title: "Row cache hit rate",
+ Units: "events/s",
+ Fam: "cache",
+ Ctx: "cassandra.row_cache_hit_rate",
+ Priority: prioRowCacheHitRate,
+ Type: module.Stacked,
+ Dims: module.Dims{
+ {ID: "row_cache_hits", Name: "hits", Algo: module.Incremental},
+ {ID: "row_cache_misses", Name: "misses", Algo: module.Incremental},
+ },
+ }
+ chartRowCacheUtilization = module.Chart{
+ ID: "row_cache_utilization",
+ Title: "Row cache utilization",
+ Units: "percentage",
+ Fam: "cache",
+ Ctx: "cassandra.row_cache_utilization",
+ Priority: prioRowCacheUtilization,
+ Dims: module.Dims{
+ {ID: "row_cache_utilization", Name: "used", Div: 1000},
+ },
+ }
+ chartRowCacheSize = module.Chart{
+ ID: "row_cache_size",
+ Title: "Row cache size",
+ Units: "bytes",
+ Fam: "cache",
+ Ctx: "cassandra.row_cache_size",
+ Priority: prioRowCacheSize,
+ Dims: module.Dims{
+ {ID: "row_cache_size", Name: "size"},
+ },
+ }
+)
+
+var (
+ chartStorageLiveDiskSpaceUsed = module.Chart{
+ ID: "storage_live_disk_space_used",
+ Title: "Disk space used by live data",
+ Units: "bytes",
+ Fam: "disk usage",
+ Ctx: "cassandra.storage_live_disk_space_used",
+ Priority: prioStorageLiveDiskSpaceUsed,
+ Dims: module.Dims{
+ {ID: "storage_load", Name: "used"},
+ },
+ }
+)
+
+var (
+ chartCompactionCompletedTasksRate = module.Chart{
+ ID: "compaction_completed_tasks_rate",
+ Title: "Completed compactions rate",
+ Units: "tasks/s",
+ Fam: "compaction",
+ Ctx: "cassandra.compaction_completed_tasks_rate",
+ Priority: prioCompactionCompletedTasksRate,
+ Dims: module.Dims{
+ {ID: "compaction_completed_tasks", Name: "completed", Algo: module.Incremental},
+ },
+ }
+ chartCompactionPendingTasksCount = module.Chart{
+ ID: "compaction_pending_tasks_count",
+ Title: "Pending compactions",
+ Units: "tasks",
+ Fam: "compaction",
+ Ctx: "cassandra.compaction_pending_tasks_count",
+ Priority: prioCompactionPendingTasksCount,
+ Dims: module.Dims{
+ {ID: "compaction_pending_tasks", Name: "pending"},
+ },
+ }
+ chartCompactionBytesCompactedRate = module.Chart{
+ ID: "compaction_compacted_rate",
+ Title: "Compaction data rate",
+ Units: "bytes/s",
+ Fam: "compaction",
+ Ctx: "cassandra.compaction_compacted_rate",
+ Priority: prioCompactionBytesCompactedRate,
+ Dims: module.Dims{
+ {ID: "compaction_bytes_compacted", Name: "compacted", Algo: module.Incremental},
+ },
+ }
+)
+
+var (
+ chartsTmplThreadPool = module.Charts{
+ chartTmplThreadPoolActiveTasksCount.Copy(),
+ chartTmplThreadPoolPendingTasksCount.Copy(),
+ chartTmplThreadPoolBlockedTasksCount.Copy(),
+ chartTmplThreadPoolBlockedTasksRate.Copy(),
+ }
+
+ chartTmplThreadPoolActiveTasksCount = module.Chart{
+ ID: "thread_pool_%s_active_tasks_count",
+ Title: "Active tasks",
+ Units: "tasks",
+ Fam: "thread pools",
+ Ctx: "cassandra.thread_pool_active_tasks_count",
+ Priority: prioThreadPoolActiveTasksCount,
+ Dims: module.Dims{
+ {ID: "thread_pool_%s_active_tasks", Name: "active"},
+ },
+ }
+ chartTmplThreadPoolPendingTasksCount = module.Chart{
+ ID: "thread_pool_%s_pending_tasks_count",
+ Title: "Pending tasks",
+ Units: "tasks",
+ Fam: "thread pools",
+ Ctx: "cassandra.thread_pool_pending_tasks_count",
+ Priority: prioThreadPoolPendingTasksCount,
+ Dims: module.Dims{
+ {ID: "thread_pool_%s_pending_tasks", Name: "pending"},
+ },
+ }
+ chartTmplThreadPoolBlockedTasksCount = module.Chart{
+ ID: "thread_pool_%s_blocked_tasks_count",
+ Title: "Blocked tasks",
+ Units: "tasks",
+ Fam: "thread pools",
+ Ctx: "cassandra.thread_pool_blocked_tasks_count",
+ Priority: prioThreadPoolBlockedTasksCount,
+ Dims: module.Dims{
+ {ID: "thread_pool_%s_blocked_tasks", Name: "blocked"},
+ },
+ }
+ chartTmplThreadPoolBlockedTasksRate = module.Chart{
+ ID: "thread_pool_%s_blocked_tasks_rate",
+ Title: "Blocked tasks rate",
+ Units: "tasks/s",
+ Fam: "thread pools",
+ Ctx: "cassandra.thread_pool_blocked_tasks_rate",
+ Priority: prioThreadPoolBlockedTasksRate,
+ Dims: module.Dims{
+ {ID: "thread_pool_%s_total_blocked_tasks", Name: "blocked", Algo: module.Incremental},
+ },
+ }
+)
+
+var (
+ chartJVMMemoryUsed = module.Chart{
+ ID: "jvm_memory_used",
+ Title: "Memory used",
+ Units: "bytes",
+ Fam: "jvm runtime",
+ Ctx: "cassandra.jvm_memory_used",
+ Priority: prioJVMMemoryUsed,
+ Type: module.Stacked,
+ Dims: module.Dims{
+ {ID: "jvm_memory_heap_used", Name: "heap"},
+ {ID: "jvm_memory_nonheap_used", Name: "nonheap"},
+ },
+ }
+ chartJVMGCRate = module.Chart{
+ ID: "jvm_gc_rate",
+ Title: "Garbage collections rate",
+ Units: "gc/s",
+ Fam: "jvm runtime",
+ Ctx: "cassandra.jvm_gc_rate",
+ Priority: prioJVMGCCount,
+ Dims: module.Dims{
+ {ID: "jvm_gc_parnew_count", Name: "parnew", Algo: module.Incremental},
+ {ID: "jvm_gc_cms_count", Name: "cms", Algo: module.Incremental},
+ },
+ }
+ chartJVMGCTime = module.Chart{
+ ID: "jvm_gc_time",
+ Title: "Garbage collection time",
+ Units: "seconds",
+ Fam: "jvm runtime",
+ Ctx: "cassandra.jvm_gc_time",
+ Priority: prioJVMGCTime,
+ Dims: module.Dims{
+ {ID: "jvm_gc_parnew_time", Name: "parnew", Algo: module.Incremental, Div: 1e9},
+ {ID: "jvm_gc_cms_time", Name: "cms", Algo: module.Incremental, Div: 1e9},
+ },
+ }
+)
+
+var (
+ chartDroppedMessagesRate = module.Chart{
+ ID: "dropped_messages_rate",
+ Title: "Dropped messages rate",
+ Units: "messages/s",
+ Fam: "errors",
+ Ctx: "cassandra.dropped_messages_rate",
+ Priority: prioDroppedMessagesRate,
+ Dims: module.Dims{
+ {ID: "dropped_messages", Name: "dropped"},
+ },
+ }
+ chartClientRequestTimeoutsRate = module.Chart{
+ ID: "client_requests_timeouts_rate",
+ Title: "Client requests timeouts rate",
+ Units: "timeouts/s",
+ Fam: "errors",
+ Ctx: "cassandra.client_requests_timeouts_rate",
+ Priority: prioRequestsTimeoutsRate,
+ Dims: module.Dims{
+ {ID: "client_request_timeouts_reads", Name: "read", Algo: module.Incremental},
+ {ID: "client_request_timeouts_writes", Name: "write", Algo: module.Incremental, Mul: -1},
+ },
+ }
+ chartClientRequestUnavailablesRate = module.Chart{
+ ID: "client_requests_unavailables_rate",
+ Title: "Client requests unavailable exceptions rate",
+ Units: "exceptions/s",
+ Fam: "errors",
+ Ctx: "cassandra.client_requests_unavailables_rate",
+ Priority: prioRequestsUnavailablesRate,
+ Dims: module.Dims{
+ {ID: "client_request_unavailables_reads", Name: "read", Algo: module.Incremental},
+ {ID: "client_request_unavailables_writes", Name: "write", Algo: module.Incremental, Mul: -1},
+ },
+ }
+ chartClientRequestFailuresRate = module.Chart{
+ ID: "client_requests_failures_rate",
+ Title: "Client requests failures rate",
+ Units: "failures/s",
+ Fam: "errors",
+ Ctx: "cassandra.client_requests_failures_rate",
+ Priority: prioRequestsFailuresRate,
+ Dims: module.Dims{
+ {ID: "client_request_failures_reads", Name: "read", Algo: module.Incremental},
+ {ID: "client_request_failures_writes", Name: "write", Algo: module.Incremental, Mul: -1},
+ },
+ }
+ chartStorageExceptionsRate = module.Chart{
+ ID: "storage_exceptions_rate",
+ Title: "Storage exceptions rate",
+ Units: "exceptions/s",
+ Fam: "errors",
+ Ctx: "cassandra.storage_exceptions_rate",
+ Priority: prioStorageExceptionsRate,
+ Dims: module.Dims{
+ {ID: "storage_exceptions", Name: "storage", Algo: module.Incremental},
+ },
+ }
+)
+
+func (c *Cassandra) addThreadPoolCharts(pool *threadPoolMetrics) {
+ charts := chartsTmplThreadPool.Copy()
+
+ for _, chart := range *charts {
+ chart.ID = fmt.Sprintf(chart.ID, pool.name)
+ chart.Labels = []module.Label{
+ {Key: "thread_pool", Value: pool.name},
+ }
+ for _, dim := range chart.Dims {
+ dim.ID = fmt.Sprintf(dim.ID, pool.name)
+ }
+ }
+
+ if err := c.Charts().Add(*charts...); err != nil {
+ c.Warning(err)
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/collect.go b/src/go/collectors/go.d.plugin/modules/cassandra/collect.go
new file mode 100644
index 000000000..511aac642
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/collect.go
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package cassandra
+
+import (
+ "errors"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/prometheus"
+ "strings"
+)
+
+const (
+ suffixCount = "_count"
+ suffixValue = "_value"
+)
+
+func (c *Cassandra) collect() (map[string]int64, error) {
+ pms, err := c.prom.ScrapeSeries()
+ if err != nil {
+ return nil, err
+ }
+
+ if c.validateMetrics {
+ if !isCassandraMetrics(pms) {
+ return nil, errors.New("collected metrics aren't Cassandra metrics")
+ }
+ c.validateMetrics = false
+ }
+
+ mx := make(map[string]int64)
+
+ c.resetMetrics()
+ c.collectMetrics(pms)
+ c.processMetric(mx)
+
+ return mx, nil
+}
+
+func (c *Cassandra) resetMetrics() {
+ cm := newCassandraMetrics()
+ for key, p := range c.mx.threadPools {
+ cm.threadPools[key] = &threadPoolMetrics{
+ name: p.name,
+ hasCharts: p.hasCharts,
+ }
+ }
+ c.mx = cm
+}
+
+func (c *Cassandra) processMetric(mx map[string]int64) {
+ c.mx.clientReqTotalLatencyReads.write(mx, "client_request_total_latency_reads")
+ c.mx.clientReqTotalLatencyWrites.write(mx, "client_request_total_latency_writes")
+ c.mx.clientReqLatencyReads.write(mx, "client_request_latency_reads")
+ c.mx.clientReqLatencyWrites.write(mx, "client_request_latency_writes")
+ c.mx.clientReqTimeoutsReads.write(mx, "client_request_timeouts_reads")
+ c.mx.clientReqTimeoutsWrites.write(mx, "client_request_timeouts_writes")
+ c.mx.clientReqUnavailablesReads.write(mx, "client_request_unavailables_reads")
+ c.mx.clientReqUnavailablesWrites.write(mx, "client_request_unavailables_writes")
+ c.mx.clientReqFailuresReads.write(mx, "client_request_failures_reads")
+ c.mx.clientReqFailuresWrites.write(mx, "client_request_failures_writes")
+
+ c.mx.clientReqReadLatencyP50.write(mx, "client_request_read_latency_p50")
+ c.mx.clientReqReadLatencyP75.write(mx, "client_request_read_latency_p75")
+ c.mx.clientReqReadLatencyP95.write(mx, "client_request_read_latency_p95")
+ c.mx.clientReqReadLatencyP98.write(mx, "client_request_read_latency_p98")
+ c.mx.clientReqReadLatencyP99.write(mx, "client_request_read_latency_p99")
+ c.mx.clientReqReadLatencyP999.write(mx, "client_request_read_latency_p999")
+ c.mx.clientReqWriteLatencyP50.write(mx, "client_request_write_latency_p50")
+ c.mx.clientReqWriteLatencyP75.write(mx, "client_request_write_latency_p75")
+ c.mx.clientReqWriteLatencyP95.write(mx, "client_request_write_latency_p95")
+ c.mx.clientReqWriteLatencyP98.write(mx, "client_request_write_latency_p98")
+ c.mx.clientReqWriteLatencyP99.write(mx, "client_request_write_latency_p99")
+ c.mx.clientReqWriteLatencyP999.write(mx, "client_request_write_latency_p999")
+
+ c.mx.rowCacheHits.write(mx, "row_cache_hits")
+ c.mx.rowCacheMisses.write(mx, "row_cache_misses")
+ c.mx.rowCacheSize.write(mx, "row_cache_size")
+ if c.mx.rowCacheHits.isSet && c.mx.rowCacheMisses.isSet {
+ if s := c.mx.rowCacheHits.value + c.mx.rowCacheMisses.value; s > 0 {
+ mx["row_cache_hit_ratio"] = int64((c.mx.rowCacheHits.value * 100 / s) * 1000)
+ } else {
+ mx["row_cache_hit_ratio"] = 0
+ }
+ }
+ if c.mx.rowCacheCapacity.isSet && c.mx.rowCacheSize.isSet {
+ if s := c.mx.rowCacheCapacity.value; s > 0 {
+ mx["row_cache_utilization"] = int64((c.mx.rowCacheSize.value * 100 / s) * 1000)
+ } else {
+ mx["row_cache_utilization"] = 0
+ }
+ }
+
+ c.mx.keyCacheHits.write(mx, "key_cache_hits")
+ c.mx.keyCacheMisses.write(mx, "key_cache_misses")
+ c.mx.keyCacheSize.write(mx, "key_cache_size")
+ if c.mx.keyCacheHits.isSet && c.mx.keyCacheMisses.isSet {
+ if s := c.mx.keyCacheHits.value + c.mx.keyCacheMisses.value; s > 0 {
+ mx["key_cache_hit_ratio"] = int64((c.mx.keyCacheHits.value * 100 / s) * 1000)
+ } else {
+ mx["key_cache_hit_ratio"] = 0
+ }
+ }
+ if c.mx.keyCacheCapacity.isSet && c.mx.keyCacheSize.isSet {
+ if s := c.mx.keyCacheCapacity.value; s > 0 {
+ mx["key_cache_utilization"] = int64((c.mx.keyCacheSize.value * 100 / s) * 1000)
+ } else {
+ mx["key_cache_utilization"] = 0
+ }
+ }
+
+ c.mx.droppedMessages.write1k(mx, "dropped_messages")
+
+ c.mx.storageLoad.write(mx, "storage_load")
+ c.mx.storageExceptions.write(mx, "storage_exceptions")
+
+ c.mx.compactionBytesCompacted.write(mx, "compaction_bytes_compacted")
+ c.mx.compactionPendingTasks.write(mx, "compaction_pending_tasks")
+ c.mx.compactionCompletedTasks.write(mx, "compaction_completed_tasks")
+
+ c.mx.jvmMemoryHeapUsed.write(mx, "jvm_memory_heap_used")
+ c.mx.jvmMemoryNonHeapUsed.write(mx, "jvm_memory_nonheap_used")
+ c.mx.jvmGCParNewCount.write(mx, "jvm_gc_parnew_count")
+ c.mx.jvmGCParNewTime.write1k(mx, "jvm_gc_parnew_time")
+ c.mx.jvmGCCMSCount.write(mx, "jvm_gc_cms_count")
+ c.mx.jvmGCCMSTime.write1k(mx, "jvm_gc_cms_time")
+
+ for _, p := range c.mx.threadPools {
+ if !p.hasCharts {
+ p.hasCharts = true
+ c.addThreadPoolCharts(p)
+ }
+
+ px := "thread_pool_" + p.name + "_"
+ p.activeTasks.write(mx, px+"active_tasks")
+ p.pendingTasks.write(mx, px+"pending_tasks")
+ p.blockedTasks.write(mx, px+"blocked_tasks")
+ p.totalBlockedTasks.write(mx, px+"total_blocked_tasks")
+ }
+}
+
+func (c *Cassandra) collectMetrics(pms prometheus.Series) {
+ c.collectClientRequestMetrics(pms)
+ c.collectDroppedMessagesMetrics(pms)
+ c.collectThreadPoolsMetrics(pms)
+ c.collectStorageMetrics(pms)
+ c.collectCacheMetrics(pms)
+ c.collectJVMMetrics(pms)
+ c.collectCompactionMetrics(pms)
+}
+
+func (c *Cassandra) collectClientRequestMetrics(pms prometheus.Series) {
+ const metric = "org_apache_cassandra_metrics_clientrequest"
+
+ var rw struct{ read, write *metricValue }
+ for _, pm := range pms.FindByName(metric + suffixCount) {
+ name := pm.Labels.Get("name")
+ scope := pm.Labels.Get("scope")
+
+ switch name {
+ case "TotalLatency":
+ rw.read, rw.write = &c.mx.clientReqTotalLatencyReads, &c.mx.clientReqTotalLatencyWrites
+ case "Latency":
+ rw.read, rw.write = &c.mx.clientReqLatencyReads, &c.mx.clientReqLatencyWrites
+ case "Timeouts":
+ rw.read, rw.write = &c.mx.clientReqTimeoutsReads, &c.mx.clientReqTimeoutsWrites
+ case "Unavailables":
+ rw.read, rw.write = &c.mx.clientReqUnavailablesReads, &c.mx.clientReqUnavailablesWrites
+ case "Failures":
+ rw.read, rw.write = &c.mx.clientReqFailuresReads, &c.mx.clientReqFailuresWrites
+ default:
+ continue
+ }
+
+ switch scope {
+ case "Read":
+ rw.read.add(pm.Value)
+ case "Write":
+ rw.write.add(pm.Value)
+ }
+ }
+
+ rw = struct{ read, write *metricValue }{}
+
+ for _, pm := range pms.FindByNames(
+ metric+"_50thpercentile",
+ metric+"_75thpercentile",
+ metric+"_95thpercentile",
+ metric+"_98thpercentile",
+ metric+"_99thpercentile",
+ metric+"_999thpercentile",
+ ) {
+ name := pm.Labels.Get("name")
+ scope := pm.Labels.Get("scope")
+
+ if name != "Latency" {
+ continue
+ }
+
+ switch {
+ case strings.HasSuffix(pm.Name(), "_50thpercentile"):
+ rw.read, rw.write = &c.mx.clientReqReadLatencyP50, &c.mx.clientReqWriteLatencyP50
+ case strings.HasSuffix(pm.Name(), "_75thpercentile"):
+ rw.read, rw.write = &c.mx.clientReqReadLatencyP75, &c.mx.clientReqWriteLatencyP75
+ case strings.HasSuffix(pm.Name(), "_95thpercentile"):
+ rw.read, rw.write = &c.mx.clientReqReadLatencyP95, &c.mx.clientReqWriteLatencyP95
+ case strings.HasSuffix(pm.Name(), "_98thpercentile"):
+ rw.read, rw.write = &c.mx.clientReqReadLatencyP98, &c.mx.clientReqWriteLatencyP98
+ case strings.HasSuffix(pm.Name(), "_99thpercentile"):
+ rw.read, rw.write = &c.mx.clientReqReadLatencyP99, &c.mx.clientReqWriteLatencyP99
+ case strings.HasSuffix(pm.Name(), "_999thpercentile"):
+ rw.read, rw.write = &c.mx.clientReqReadLatencyP999, &c.mx.clientReqWriteLatencyP999
+ default:
+ continue
+ }
+
+ switch scope {
+ case "Read":
+ rw.read.add(pm.Value)
+ case "Write":
+ rw.write.add(pm.Value)
+ }
+ }
+}
+
+func (c *Cassandra) collectCacheMetrics(pms prometheus.Series) {
+ const metric = "org_apache_cassandra_metrics_cache"
+
+ var hm struct{ hits, misses *metricValue }
+ for _, pm := range pms.FindByName(metric + suffixCount) {
+ name := pm.Labels.Get("name")
+ scope := pm.Labels.Get("scope")
+
+ switch scope {
+ case "KeyCache":
+ hm.hits, hm.misses = &c.mx.keyCacheHits, &c.mx.keyCacheMisses
+ case "RowCache":
+ hm.hits, hm.misses = &c.mx.rowCacheHits, &c.mx.rowCacheMisses
+ default:
+ continue
+ }
+
+ switch name {
+ case "Hits":
+ hm.hits.add(pm.Value)
+ case "Misses":
+ hm.misses.add(pm.Value)
+ }
+ }
+
+ var cs struct{ cap, size *metricValue }
+ for _, pm := range pms.FindByName(metric + suffixValue) {
+ name := pm.Labels.Get("name")
+ scope := pm.Labels.Get("scope")
+
+ switch scope {
+ case "KeyCache":
+ cs.cap, cs.size = &c.mx.keyCacheCapacity, &c.mx.keyCacheSize
+ case "RowCache":
+ cs.cap, cs.size = &c.mx.rowCacheCapacity, &c.mx.rowCacheSize
+ default:
+ continue
+ }
+
+ switch name {
+ case "Capacity":
+ cs.cap.add(pm.Value)
+ case "Size":
+ cs.size.add(pm.Value)
+ }
+ }
+}
+
+func (c *Cassandra) collectThreadPoolsMetrics(pms prometheus.Series) {
+ const metric = "org_apache_cassandra_metrics_threadpools"
+
+ for _, pm := range pms.FindByName(metric + suffixValue) {
+ name := pm.Labels.Get("name")
+ scope := pm.Labels.Get("scope")
+ pool := c.getThreadPoolMetrics(scope)
+
+ switch name {
+ case "ActiveTasks":
+ pool.activeTasks.add(pm.Value)
+ case "PendingTasks":
+ pool.pendingTasks.add(pm.Value)
+ }
+ }
+ for _, pm := range pms.FindByName(metric + suffixCount) {
+ name := pm.Labels.Get("name")
+ scope := pm.Labels.Get("scope")
+ pool := c.getThreadPoolMetrics(scope)
+
+ switch name {
+ case "CompletedTasks":
+ pool.totalBlockedTasks.add(pm.Value)
+ case "TotalBlockedTasks":
+ pool.totalBlockedTasks.add(pm.Value)
+ case "CurrentlyBlockedTasks":
+ pool.blockedTasks.add(pm.Value)
+ }
+ }
+}
+
+func (c *Cassandra) collectStorageMetrics(pms prometheus.Series) {
+ const metric = "org_apache_cassandra_metrics_storage"
+
+ for _, pm := range pms.FindByName(metric + suffixCount) {
+ name := pm.Labels.Get("name")
+
+ switch name {
+ case "Load":
+ c.mx.storageLoad.add(pm.Value)
+ case "Exceptions":
+ c.mx.storageExceptions.add(pm.Value)
+ }
+ }
+}
+
+func (c *Cassandra) collectDroppedMessagesMetrics(pms prometheus.Series) {
+ const metric = "org_apache_cassandra_metrics_droppedmessage"
+
+ for _, pm := range pms.FindByName(metric + suffixCount) {
+ c.mx.droppedMessages.add(pm.Value)
+ }
+}
+
+func (c *Cassandra) collectJVMMetrics(pms prometheus.Series) {
+ const metricMemUsed = "jvm_memory_bytes_used"
+ const metricGC = "jvm_gc_collection_seconds"
+
+ for _, pm := range pms.FindByName(metricMemUsed) {
+ area := pm.Labels.Get("area")
+
+ switch area {
+ case "heap":
+ c.mx.jvmMemoryHeapUsed.add(pm.Value)
+ case "nonheap":
+ c.mx.jvmMemoryNonHeapUsed.add(pm.Value)
+ }
+ }
+
+ for _, pm := range pms.FindByName(metricGC + suffixCount) {
+ gc := pm.Labels.Get("gc")
+
+ switch gc {
+ case "ParNew":
+ c.mx.jvmGCParNewCount.add(pm.Value)
+ case "ConcurrentMarkSweep":
+ c.mx.jvmGCCMSCount.add(pm.Value)
+ }
+ }
+
+ for _, pm := range pms.FindByName(metricGC + "_sum") {
+ gc := pm.Labels.Get("gc")
+
+ switch gc {
+ case "ParNew":
+ c.mx.jvmGCParNewTime.add(pm.Value)
+ case "ConcurrentMarkSweep":
+ c.mx.jvmGCCMSTime.add(pm.Value)
+ }
+ }
+}
+
+func (c *Cassandra) collectCompactionMetrics(pms prometheus.Series) {
+ const metric = "org_apache_cassandra_metrics_compaction"
+
+ for _, pm := range pms.FindByName(metric + suffixValue) {
+ name := pm.Labels.Get("name")
+
+ switch name {
+ case "CompletedTasks":
+ c.mx.compactionCompletedTasks.add(pm.Value)
+ case "PendingTasks":
+ c.mx.compactionPendingTasks.add(pm.Value)
+ }
+ }
+ for _, pm := range pms.FindByName(metric + suffixCount) {
+ name := pm.Labels.Get("name")
+
+ switch name {
+ case "BytesCompacted":
+ c.mx.compactionBytesCompacted.add(pm.Value)
+ }
+ }
+}
+
+func (c *Cassandra) getThreadPoolMetrics(name string) *threadPoolMetrics {
+ pool, ok := c.mx.threadPools[name]
+ if !ok {
+ pool = &threadPoolMetrics{name: name}
+ c.mx.threadPools[name] = pool
+ }
+ return pool
+}
+
+func isCassandraMetrics(pms prometheus.Series) bool {
+ for _, pm := range pms {
+ if strings.HasPrefix(pm.Name(), "org_apache_cassandra_metrics") {
+ return true
+ }
+ }
+ return false
+}
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/config_schema.json b/src/go/collectors/go.d.plugin/modules/cassandra/config_schema.json
new file mode 100644
index 000000000..d6309d739
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/config_schema.json
@@ -0,0 +1,177 @@
+{
+ "jsonSchema": {
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Cassandra collector configuration.",
+ "type": "object",
+ "properties": {
+ "update_every": {
+ "title": "Update every",
+ "description": "Data collection interval, measured in seconds.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 5
+ },
+ "url": {
+ "title": "URL",
+ "description": "The URL of the Cassandra [JMX exporter](https://github.com/prometheus/jmx_exporter) metrics endpoint.",
+ "type": "string",
+ "default": "http://127.0.0.1:7072/metrics",
+ "format": "uri"
+ },
+ "timeout": {
+ "title": "Timeout",
+ "description": "The timeout in seconds for the HTTP request.",
+ "type": "number",
+ "minimum": 0.5,
+ "default": 5
+ },
+ "not_follow_redirects": {
+ "title": "Not follow redirects",
+ "description": "If set, the client will not follow HTTP redirects automatically.",
+ "type": "boolean"
+ },
+ "username": {
+ "title": "Username",
+ "description": "The username for basic authentication.",
+ "type": "string",
+ "sensitive": true
+ },
+ "password": {
+ "title": "Password",
+ "description": "The password for basic authentication.",
+ "type": "string",
+ "sensitive": true
+ },
+ "proxy_url": {
+ "title": "Proxy URL",
+ "description": "The URL of the proxy server.",
+ "type": "string"
+ },
+ "proxy_username": {
+ "title": "Proxy username",
+ "description": "The username for proxy authentication.",
+ "type": "string",
+ "sensitive": true
+ },
+ "proxy_password": {
+ "title": "Proxy password",
+ "description": "The password for proxy authentication.",
+ "type": "string",
+ "sensitive": true
+ },
+ "headers": {
+ "title": "Headers",
+ "description": "Additional HTTP headers to include in the request.",
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "tls_skip_verify": {
+ "title": "Skip TLS verification",
+ "description": "If set, TLS certificate verification will be skipped.",
+ "type": "boolean"
+ },
+ "tls_ca": {
+ "title": "TLS CA",
+ "description": "The path to the CA certificate file for TLS verification.",
+ "type": "string",
+ "pattern": "^$|^/"
+ },
+ "tls_cert": {
+ "title": "TLS certificate",
+ "description": "The path to the client certificate file for TLS authentication.",
+ "type": "string",
+ "pattern": "^$|^/"
+ },
+ "tls_key": {
+ "title": "TLS key",
+ "description": "The path to the client key file for TLS authentication.",
+ "type": "string",
+ "pattern": "^$|^/"
+ },
+ "body": {
+ "title": "Body",
+ "type": "string"
+ },
+ "method": {
+ "title": "Method",
+ "type": "string"
+ }
+ },
+ "required": [
+ "url"
+ ],
+ "additionalProperties": false,
+ "patternProperties": {
+ "^name$": {}
+ }
+ },
+ "uiSchema": {
+ "ui:flavour": "tabs",
+ "ui:options": {
+ "tabs": [
+ {
+ "title": "Base",
+ "fields": [
+ "update_every",
+ "url",
+ "timeout",
+ "not_follow_redirects"
+ ]
+ },
+ {
+ "title": "Auth",
+ "fields": [
+ "username",
+ "password"
+ ]
+ },
+ {
+ "title": "TLS",
+ "fields": [
+ "tls_skip_verify",
+ "tls_ca",
+ "tls_cert",
+ "tls_key"
+ ]
+ },
+ {
+ "title": "Proxy",
+ "fields": [
+ "proxy_url",
+ "proxy_username",
+ "proxy_password"
+ ]
+ },
+ {
+ "title": "Headers",
+ "fields": [
+ "headers"
+ ]
+ }
+ ]
+ },
+ "uiOptions": {
+ "fullPage": true
+ },
+ "body": {
+ "ui:widget": "hidden"
+ },
+ "method": {
+ "ui:widget": "hidden"
+ },
+ "timeout": {
+ "ui:help": "Accepts decimals for precise control (e.g., type 1.5 for 1.5 seconds)."
+ },
+ "password": {
+ "ui:widget": "password"
+ },
+ "proxy_password": {
+ "ui:widget": "password"
+ }
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/init.go b/src/go/collectors/go.d.plugin/modules/cassandra/init.go
new file mode 100644
index 000000000..7248681d8
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/init.go
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package cassandra
+
+import (
+ "errors"
+
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/prometheus"
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
+)
+
+func (c *Cassandra) validateConfig() error {
+ if c.URL == "" {
+ return errors.New("'url' is not set")
+ }
+ return nil
+}
+
+func (c *Cassandra) initPrometheusClient() (prometheus.Prometheus, error) {
+ client, err := web.NewHTTPClient(c.Client)
+ if err != nil {
+ return nil, err
+ }
+ return prometheus.New(client, c.Request), nil
+}
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/integrations/cassandra.md b/src/go/collectors/go.d.plugin/modules/cassandra/integrations/cassandra.md
new file mode 100644
index 000000000..76b623012
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/integrations/cassandra.md
@@ -0,0 +1,278 @@
+<!--startmeta
+custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/go/collectors/go.d.plugin/modules/cassandra/README.md"
+meta_yaml: "https://github.com/netdata/netdata/edit/master/src/go/collectors/go.d.plugin/modules/cassandra/metadata.yaml"
+sidebar_label: "Cassandra"
+learn_status: "Published"
+learn_rel_path: "Collecting Metrics/Databases"
+most_popular: False
+message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE COLLECTOR'S metadata.yaml FILE"
+endmeta-->
+
+# Cassandra
+
+
+<img src="https://netdata.cloud/img/cassandra.svg" width="150"/>
+
+
+Plugin: go.d.plugin
+Module: cassandra
+
+<img src="https://img.shields.io/badge/maintained%20by-Netdata-%2300ab44" />
+
+## Overview
+
+This collector gathers metrics about client requests, cache hits, and many more, while also providing metrics per each thread pool.
+
+
+The [JMX Exporter](https://github.com/prometheus/jmx_exporter) is used to fetch metrics from a Cassandra instance and make them available at an endpoint like `http://127.0.0.1:7072/metrics`.
+
+
+This collector is supported on all platforms.
+
+This collector supports collecting metrics from multiple instances of this integration, including remote instances.
+
+
+### Default Behavior
+
+#### Auto-Detection
+
+This collector discovers instances running on the local host that provide metrics on port 7072.
+
+On startup, it tries to collect metrics from:
+
+- http://127.0.0.1:7072/metrics
+
+
+#### Limits
+
+The default configuration for this integration does not impose any limits on data collection.
+
+#### Performance Impact
+
+The default configuration for this integration is not expected to impose a significant performance impact on the system.
+
+
+## Metrics
+
+Metrics grouped by *scope*.
+
+The scope defines the instance that the metric belongs to. An instance is uniquely identified by a set of labels.
+
+
+
+### Per Cassandra instance
+
+These metrics refer to the entire monitored application.
+
+This scope has no labels.
+
+Metrics:
+
+| Metric | Dimensions | Unit |
+|:------|:----------|:----|
+| cassandra.client_requests_rate | read, write | requests/s |
+| cassandra.client_request_read_latency_histogram | p50, p75, p95, p98, p99, p999 | seconds |
+| cassandra.client_request_write_latency_histogram | p50, p75, p95, p98, p99, p999 | seconds |
+| cassandra.client_requests_latency | read, write | seconds |
+| cassandra.row_cache_hit_ratio | hit_ratio | percentage |
+| cassandra.row_cache_hit_rate | hits, misses | events/s |
+| cassandra.row_cache_utilization | used | percentage |
+| cassandra.row_cache_size | size | bytes |
+| cassandra.key_cache_hit_ratio | hit_ratio | percentage |
+| cassandra.key_cache_hit_rate | hits, misses | events/s |
+| cassandra.key_cache_utilization | used | percentage |
+| cassandra.key_cache_size | size | bytes |
+| cassandra.storage_live_disk_space_used | used | bytes |
+| cassandra.compaction_completed_tasks_rate | completed | tasks/s |
+| cassandra.compaction_pending_tasks_count | pending | tasks |
+| cassandra.compaction_compacted_rate | compacted | bytes/s |
+| cassandra.jvm_memory_used | heap, nonheap | bytes |
+| cassandra.jvm_gc_rate | parnew, cms | gc/s |
+| cassandra.jvm_gc_time | parnew, cms | seconds |
+| cassandra.dropped_messages_rate | dropped | messages/s |
+| cassandra.client_requests_timeouts_rate | read, write | timeout/s |
+| cassandra.client_requests_unavailables_rate | read, write | exceptions/s |
+| cassandra.client_requests_failures_rate | read, write | failures/s |
+| cassandra.storage_exceptions_rate | storage | exceptions/s |
+
+### Per thread pool
+
+Metrics related to Cassandra's thread pools. Each thread pool provides its own set of the following metrics.
+
+Labels:
+
+| Label | Description |
+|:-----------|:----------------|
+| thread_pool | thread pool name |
+
+Metrics:
+
+| Metric | Dimensions | Unit |
+|:------|:----------|:----|
+| cassandra.thread_pool_active_tasks_count | active | tasks |
+| cassandra.thread_pool_pending_tasks_count | pending | tasks |
+| cassandra.thread_pool_blocked_tasks_count | blocked | tasks |
+| cassandra.thread_pool_blocked_tasks_rate | blocked | tasks/s |
+
+
+
+## Alerts
+
+There are no alerts configured by default for this integration.
+
+
+## Setup
+
+### Prerequisites
+
+#### Configure Cassandra with Prometheus JMX Exporter
+
+To configure Cassandra with the [JMX Exporter](https://github.com/prometheus/jmx_exporter):
+
+> **Note**: paths can differ depends on your setup.
+
+- Download latest [jmx_exporter](https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/) jar file
+ and install it in a directory where Cassandra can access it.
+- Add
+ the [jmx_exporter.yaml](https://raw.githubusercontent.com/netdata/go.d.plugin/master/modules/cassandra/jmx_exporter.yaml)
+ file to `/etc/cassandra`.
+- Add the following line to `/etc/cassandra/cassandra-env.sh`
+ ```
+ JVM_OPTS="$JVM_OPTS $JVM_EXTRA_OPTS -javaagent:/opt/jmx_exporter/jmx_exporter.jar=7072:/etc/cassandra/jmx_exporter.yaml
+ ```
+- Restart cassandra service.
+
+
+
+### Configuration
+
+#### File
+
+The configuration file name for this integration is `go.d/cassandra.conf`.
+
+
+You can edit the configuration file using the `edit-config` script from the
+Netdata [config directory](/docs/netdata-agent/configuration/README.md#the-netdata-config-directory).
+
+```bash
+cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
+sudo ./edit-config go.d/cassandra.conf
+```
+#### Options
+
+The following options can be defined globally: update_every, autodetection_retry.
+
+
+<details open><summary>Config options</summary>
+
+| Name | Description | Default | Required |
+|:----|:-----------|:-------|:--------:|
+| update_every | Data collection frequency. | 5 | no |
+| autodetection_retry | Recheck interval in seconds. Zero means no recheck will be scheduled. | 0 | no |
+| url | Server URL. | http://127.0.0.1:7072/metrics | yes |
+| username | Username for basic HTTP authentication. | | no |
+| password | Password for basic HTTP authentication. | | no |
+| proxy_url | Proxy URL. | | no |
+| proxy_username | Username for proxy basic HTTP authentication. | | no |
+| proxy_password | Password for proxy basic HTTP authentication. | | no |
+| timeout | HTTP request timeout. | 2 | no |
+| not_follow_redirects | Redirect handling policy. Controls whether the client follows redirects. | no | no |
+| tls_skip_verify | Server certificate chain and hostname validation policy. Controls whether the client performs this check. | no | no |
+| tls_ca | Certification authority that the client uses when verifying the server's certificates. | | no |
+| tls_cert | Client TLS certificate. | | no |
+| tls_key | Client TLS key. | | no |
+
+</details>
+
+#### Examples
+
+##### Basic
+
+A basic example configuration.
+
+```yaml
+jobs:
+ - name: local
+ url: http://127.0.0.1:7072/metrics
+
+```
+##### HTTP authentication
+
+Local server with basic HTTP authentication.
+
+<details open><summary>Config</summary>
+
+```yaml
+jobs:
+ - name: local
+ url: http://127.0.0.1:7072/metrics
+ username: foo
+ password: bar
+
+```
+</details>
+
+##### HTTPS with self-signed certificate
+
+Local server with enabled HTTPS and self-signed certificate.
+
+<details open><summary>Config</summary>
+
+```yaml
+jobs:
+ - name: local
+ url: https://127.0.0.1:7072/metrics
+ tls_skip_verify: yes
+
+```
+</details>
+
+##### Multi-instance
+
+> **Note**: When you define multiple jobs, their names must be unique.
+
+Collecting metrics from local and remote instances.
+
+
+<details open><summary>Config</summary>
+
+```yaml
+jobs:
+ - name: local
+ url: http://127.0.0.1:7072/metrics
+
+ - name: remote
+ url: http://192.0.2.1:7072/metrics
+
+```
+</details>
+
+
+
+## Troubleshooting
+
+### Debug Mode
+
+To troubleshoot issues with the `cassandra` collector, run the `go.d.plugin` with the debug option enabled. The output
+should give you clues as to why the collector isn't working.
+
+- Navigate to the `plugins.d` directory, usually at `/usr/libexec/netdata/plugins.d/`. If that's not the case on
+ your system, open `netdata.conf` and look for the `plugins` setting under `[directories]`.
+
+ ```bash
+ cd /usr/libexec/netdata/plugins.d/
+ ```
+
+- Switch to the `netdata` user.
+
+ ```bash
+ sudo -u netdata -s
+ ```
+
+- Run the `go.d.plugin` to debug the collector:
+
+ ```bash
+ ./go.d.plugin -d -m cassandra
+ ```
+
+
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/jmx_exporter.yaml b/src/go/collectors/go.d.plugin/modules/cassandra/jmx_exporter.yaml
new file mode 100644
index 000000000..983f6f9b2
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/jmx_exporter.yaml
@@ -0,0 +1,31 @@
+lowercaseOutputLabelNames: true
+lowercaseOutputName: true
+whitelistObjectNames: ["org.apache.cassandra.metrics:*"]
+blacklistObjectNames:
+ - "org.apache.cassandra.metrics:type=ColumnFamily,*"
+ - "org.apache.cassandra.metrics:type=Table,*"
+rules:
+ # Throughput and Latency
+ - pattern: org.apache.cassandra.metrics<type=(ClientRequest), scope=(Write|Read), name=(TotalLatency|Latency|Timeouts|Unavailables|Failures)><>(Count)
+ - pattern: org.apache.cassandra.metrics<type=(ClientRequest), scope=(Write|Read), name=(Latency)><>(\S*Percentile)
+
+ # Dropped messages
+ - pattern: org.apache.cassandra.metrics<type=(DroppedMessage), scope=(\S*), name=(Dropped)><>(Count)
+
+ # Cache
+ - pattern: org.apache.cassandra.metrics<type=Cache, scope=(KeyCache|RowCache), name=(Hits|Misses)><>(Count)
+ - pattern: org.apache.cassandra.metrics<type=Cache, scope=(KeyCache|RowCache), name=(Capacity|Size)><>(Value)
+
+ # Storage
+ - pattern: org.apache.cassandra.metrics<type=(Storage), name=(Load|Exceptions)><>(Count)
+
+ # Tables
+ # - pattern: org.apache.cassandra.metrics<type=(Table), keyspace=(\S*), scope=(\S*), name=(TotalDiskSpaceUsed)><>(Count)
+
+ # Compaction
+ - pattern: org.apache.cassandra.metrics<type=(Compaction), name=(CompletedTasks|PendingTasks)><>(Value)
+ - pattern: org.apache.cassandra.metrics<type=(Compaction), name=(BytesCompacted)><>(Count)
+
+ # Thread Pools
+ - pattern: org.apache.cassandra.metrics<type=(ThreadPools), path=(\S*), scope=(\S*), name=(ActiveTasks|PendingTasks)><>(Value)
+ - pattern: org.apache.cassandra.metrics<type=(ThreadPools), path=(\S*), scope=(\S*), name=(CurrentlyBlockedTasks|TotalBlockedTasks)><>(Count)
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/metadata.yaml b/src/go/collectors/go.d.plugin/modules/cassandra/metadata.yaml
new file mode 100644
index 000000000..ef9458c03
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/metadata.yaml
@@ -0,0 +1,410 @@
+plugin_name: go.d.plugin
+modules:
+ - meta:
+ id: collector-go.d.plugin-cassandra
+ module_name: cassandra
+ plugin_name: go.d.plugin
+ monitored_instance:
+ categories:
+ - data-collection.database-servers
+ icon_filename: cassandra.svg
+ name: Cassandra
+ link: https://cassandra.apache.org/_/index.html
+ alternative_monitored_instances: []
+ keywords:
+ - nosql
+ - dbms
+ - db
+ - database
+ related_resources:
+ integrations:
+ list: []
+ info_provided_to_referring_integrations:
+ description: ""
+ most_popular: false
+ overview:
+ data_collection:
+ metrics_description: |
+ This collector gathers metrics about client requests, cache hits, and many more, while also providing metrics per each thread pool.
+ method_description: |
+ The [JMX Exporter](https://github.com/prometheus/jmx_exporter) is used to fetch metrics from a Cassandra instance and make them available at an endpoint like `http://127.0.0.1:7072/metrics`.
+ supported_platforms:
+ include: []
+ exclude: []
+ multi_instance: true
+ additional_permissions:
+ description: ""
+ default_behavior:
+ auto_detection:
+ description: |
+ This collector discovers instances running on the local host that provide metrics on port 7072.
+
+ On startup, it tries to collect metrics from:
+
+ - http://127.0.0.1:7072/metrics
+ limits:
+ description: ""
+ performance_impact:
+ description: ""
+ setup:
+ prerequisites:
+ list:
+ - title: Configure Cassandra with Prometheus JMX Exporter
+ description: |
+ To configure Cassandra with the [JMX Exporter](https://github.com/prometheus/jmx_exporter):
+
+ > **Note**: paths can differ depends on your setup.
+
+ - Download latest [jmx_exporter](https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/) jar file
+ and install it in a directory where Cassandra can access it.
+ - Add
+ the [jmx_exporter.yaml](https://raw.githubusercontent.com/netdata/go.d.plugin/master/modules/cassandra/jmx_exporter.yaml)
+ file to `/etc/cassandra`.
+ - Add the following line to `/etc/cassandra/cassandra-env.sh`
+ ```
+ JVM_OPTS="$JVM_OPTS $JVM_EXTRA_OPTS -javaagent:/opt/jmx_exporter/jmx_exporter.jar=7072:/etc/cassandra/jmx_exporter.yaml
+ ```
+ - Restart cassandra service.
+ configuration:
+ file:
+ name: go.d/cassandra.conf
+ options:
+ description: |
+ The following options can be defined globally: update_every, autodetection_retry.
+ folding:
+ title: Config options
+ enabled: true
+ list:
+ - name: update_every
+ description: Data collection frequency.
+ default_value: 5
+ required: false
+ - name: autodetection_retry
+ description: Recheck interval in seconds. Zero means no recheck will be scheduled.
+ default_value: 0
+ required: false
+ - name: url
+ description: Server URL.
+ default_value: http://127.0.0.1:7072/metrics
+ required: true
+ - name: username
+ description: Username for basic HTTP authentication.
+ default_value: ""
+ required: false
+ - name: password
+ description: Password for basic HTTP authentication.
+ default_value: ""
+ required: false
+ - name: proxy_url
+ description: Proxy URL.
+ default_value: ""
+ required: false
+ - name: proxy_username
+ description: Username for proxy basic HTTP authentication.
+ default_value: ""
+ required: false
+ - name: proxy_password
+ description: Password for proxy basic HTTP authentication.
+ default_value: ""
+ required: false
+ - name: timeout
+ description: HTTP request timeout.
+ default_value: 2
+ required: false
+ - name: not_follow_redirects
+ description: Redirect handling policy. Controls whether the client follows redirects.
+ default_value: false
+ required: false
+ - name: tls_skip_verify
+ description: Server certificate chain and hostname validation policy. Controls whether the client performs this check.
+ default_value: false
+ required: false
+ - name: tls_ca
+ description: Certification authority that the client uses when verifying the server's certificates.
+ default_value: ""
+ required: false
+ - name: tls_cert
+ description: Client TLS certificate.
+ default_value: ""
+ required: false
+ - name: tls_key
+ description: Client TLS key.
+ default_value: ""
+ required: false
+ examples:
+ folding:
+ title: Config
+ enabled: true
+ list:
+ - name: Basic
+ folding:
+ enabled: false
+ description: A basic example configuration.
+ config: |
+ jobs:
+ - name: local
+ url: http://127.0.0.1:7072/metrics
+ - name: HTTP authentication
+ description: Local server with basic HTTP authentication.
+ config: |
+ jobs:
+ - name: local
+ url: http://127.0.0.1:7072/metrics
+ username: foo
+ password: bar
+ - name: HTTPS with self-signed certificate
+ description: Local server with enabled HTTPS and self-signed certificate.
+ config: |
+ jobs:
+ - name: local
+ url: https://127.0.0.1:7072/metrics
+ tls_skip_verify: yes
+ - name: Multi-instance
+ description: |
+ > **Note**: When you define multiple jobs, their names must be unique.
+
+ Collecting metrics from local and remote instances.
+ config: |
+ jobs:
+ - name: local
+ url: http://127.0.0.1:7072/metrics
+
+ - name: remote
+ url: http://192.0.2.1:7072/metrics
+ troubleshooting:
+ problems:
+ list: []
+ alerts: []
+ metrics:
+ folding:
+ title: Metrics
+ enabled: false
+ description: ""
+ availability: []
+ scopes:
+ - name: global
+ description: These metrics refer to the entire monitored application.
+ labels: []
+ metrics:
+ - name: cassandra.client_requests_rate
+ availability: []
+ description: Client requests rate
+ unit: requests/s
+ chart_type: line
+ dimensions:
+ - name: read
+ - name: write
+ - name: cassandra.client_request_read_latency_histogram
+ availability: []
+ description: Client request read latency histogram
+ unit: seconds
+ chart_type: line
+ dimensions:
+ - name: p50
+ - name: p75
+ - name: p95
+ - name: p98
+ - name: p99
+ - name: p999
+ - name: cassandra.client_request_write_latency_histogram
+ availability: []
+ description: Client request write latency histogram
+ unit: seconds
+ chart_type: line
+ dimensions:
+ - name: p50
+ - name: p75
+ - name: p95
+ - name: p98
+ - name: p99
+ - name: p999
+ - name: cassandra.client_requests_latency
+ availability: []
+ description: Client requests total latency
+ unit: seconds
+ chart_type: line
+ dimensions:
+ - name: read
+ - name: write
+ - name: cassandra.row_cache_hit_ratio
+ availability: []
+ description: Key cache hit ratio
+ unit: percentage
+ chart_type: line
+ dimensions:
+ - name: hit_ratio
+ - name: cassandra.row_cache_hit_rate
+ availability: []
+ description: Key cache hit rate
+ unit: events/s
+ chart_type: stacked
+ dimensions:
+ - name: hits
+ - name: misses
+ - name: cassandra.row_cache_utilization
+ availability: []
+ description: Key cache utilization
+ unit: percentage
+ chart_type: line
+ dimensions:
+ - name: used
+ - name: cassandra.row_cache_size
+ availability: []
+ description: Key cache size
+ unit: bytes
+ chart_type: line
+ dimensions:
+ - name: size
+ - name: cassandra.key_cache_hit_ratio
+ availability: []
+ description: Row cache hit ratio
+ unit: percentage
+ chart_type: line
+ dimensions:
+ - name: hit_ratio
+ - name: cassandra.key_cache_hit_rate
+ availability: []
+ description: Row cache hit rate
+ unit: events/s
+ chart_type: stacked
+ dimensions:
+ - name: hits
+ - name: misses
+ - name: cassandra.key_cache_utilization
+ availability: []
+ description: Row cache utilization
+ unit: percentage
+ chart_type: line
+ dimensions:
+ - name: used
+ - name: cassandra.key_cache_size
+ availability: []
+ description: Row cache size
+ unit: bytes
+ chart_type: line
+ dimensions:
+ - name: size
+ - name: cassandra.storage_live_disk_space_used
+ availability: []
+ description: Disk space used by live data
+ unit: bytes
+ chart_type: line
+ dimensions:
+ - name: used
+ - name: cassandra.compaction_completed_tasks_rate
+ availability: []
+ description: Completed compactions rate
+ unit: tasks/s
+ chart_type: line
+ dimensions:
+ - name: completed
+ - name: cassandra.compaction_pending_tasks_count
+ availability: []
+ description: Pending compactions
+ unit: tasks
+ chart_type: line
+ dimensions:
+ - name: pending
+ - name: cassandra.compaction_compacted_rate
+ availability: []
+ description: Compaction data rate
+ unit: bytes/s
+ chart_type: line
+ dimensions:
+ - name: compacted
+ - name: cassandra.jvm_memory_used
+ availability: []
+ description: Memory used
+ unit: bytes
+ chart_type: stacked
+ dimensions:
+ - name: heap
+ - name: nonheap
+ - name: cassandra.jvm_gc_rate
+ availability: []
+ description: Garbage collections rate
+ unit: gc/s
+ chart_type: line
+ dimensions:
+ - name: parnew
+ - name: cms
+ - name: cassandra.jvm_gc_time
+ availability: []
+ description: Garbage collection time
+ unit: seconds
+ chart_type: line
+ dimensions:
+ - name: parnew
+ - name: cms
+ - name: cassandra.dropped_messages_rate
+ availability: []
+ description: Dropped messages rate
+ unit: messages/s
+ chart_type: line
+ dimensions:
+ - name: dropped
+ - name: cassandra.client_requests_timeouts_rate
+ availability: []
+ description: Client requests timeouts rate
+ unit: timeout/s
+ chart_type: line
+ dimensions:
+ - name: read
+ - name: write
+ - name: cassandra.client_requests_unavailables_rate
+ availability: []
+ description: Client requests unavailable exceptions rate
+ unit: exceptions/s
+ chart_type: line
+ dimensions:
+ - name: read
+ - name: write
+ - name: cassandra.client_requests_failures_rate
+ availability: []
+ description: Client requests failures rate
+ unit: failures/s
+ chart_type: line
+ dimensions:
+ - name: read
+ - name: write
+ - name: cassandra.storage_exceptions_rate
+ availability: []
+ description: Storage exceptions rate
+ unit: exceptions/s
+ chart_type: line
+ dimensions:
+ - name: storage
+ - name: thread pool
+ description: Metrics related to Cassandra's thread pools. Each thread pool provides its own set of the following metrics.
+ labels:
+ - name: thread_pool
+ description: thread pool name
+ metrics:
+ - name: cassandra.thread_pool_active_tasks_count
+ availability: []
+ description: Active tasks
+ unit: tasks
+ chart_type: line
+ dimensions:
+ - name: active
+ - name: cassandra.thread_pool_pending_tasks_count
+ availability: []
+ description: Pending tasks
+ unit: tasks
+ chart_type: line
+ dimensions:
+ - name: pending
+ - name: cassandra.thread_pool_blocked_tasks_count
+ availability: []
+ description: Blocked tasks
+ unit: tasks
+ chart_type: line
+ dimensions:
+ - name: blocked
+ - name: cassandra.thread_pool_blocked_tasks_rate
+ availability: []
+ description: Blocked tasks rate
+ unit: tasks/s
+ chart_type: line
+ dimensions:
+ - name: blocked
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/metrics.go b/src/go/collectors/go.d.plugin/modules/cassandra/metrics.go
new file mode 100644
index 000000000..6533c694c
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/metrics.go
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package cassandra
+
+// https://cassandra.apache.org/doc/latest/cassandra/operating/metrics.html#table-metrics
+// https://www.datadoghq.com/blog/how-to-collect-cassandra-metrics/
+// https://docs.opennms.com/horizon/29/deployment/time-series-storage/newts/cassandra-jmx.html
+
+func newCassandraMetrics() *cassandraMetrics {
+ return &cassandraMetrics{
+ threadPools: make(map[string]*threadPoolMetrics),
+ }
+}
+
+type cassandraMetrics struct {
+ clientReqTotalLatencyReads metricValue
+ clientReqTotalLatencyWrites metricValue
+ clientReqLatencyReads metricValue
+ clientReqLatencyWrites metricValue
+ clientReqTimeoutsReads metricValue
+ clientReqTimeoutsWrites metricValue
+ clientReqUnavailablesReads metricValue
+ clientReqUnavailablesWrites metricValue
+ clientReqFailuresReads metricValue
+ clientReqFailuresWrites metricValue
+
+ clientReqReadLatencyP50 metricValue
+ clientReqReadLatencyP75 metricValue
+ clientReqReadLatencyP95 metricValue
+ clientReqReadLatencyP98 metricValue
+ clientReqReadLatencyP99 metricValue
+ clientReqReadLatencyP999 metricValue
+ clientReqWriteLatencyP50 metricValue
+ clientReqWriteLatencyP75 metricValue
+ clientReqWriteLatencyP95 metricValue
+ clientReqWriteLatencyP98 metricValue
+ clientReqWriteLatencyP99 metricValue
+ clientReqWriteLatencyP999 metricValue
+
+ rowCacheHits metricValue
+ rowCacheMisses metricValue
+ rowCacheCapacity metricValue
+ rowCacheSize metricValue
+ keyCacheHits metricValue
+ keyCacheMisses metricValue
+ keyCacheCapacity metricValue
+ keyCacheSize metricValue
+
+ // https://cassandra.apache.org/doc/latest/cassandra/operating/metrics.html#dropped-metrics
+ droppedMessages metricValue
+
+ // https://cassandra.apache.org/doc/latest/cassandra/operating/metrics.html#storage-metrics
+ storageLoad metricValue
+ storageExceptions metricValue
+
+ // https://cassandra.apache.org/doc/latest/cassandra/operating/metrics.html#compaction-metrics
+ compactionBytesCompacted metricValue
+ compactionPendingTasks metricValue
+ compactionCompletedTasks metricValue
+
+ // https://cassandra.apache.org/doc/latest/cassandra/operating/metrics.html#memory
+ jvmMemoryHeapUsed metricValue
+ jvmMemoryNonHeapUsed metricValue
+ // https://cassandra.apache.org/doc/latest/cassandra/operating/metrics.html#garbagecollector
+ jvmGCParNewCount metricValue
+ jvmGCParNewTime metricValue
+ jvmGCCMSCount metricValue
+ jvmGCCMSTime metricValue
+
+ threadPools map[string]*threadPoolMetrics
+}
+
+type threadPoolMetrics struct {
+ name string
+ hasCharts bool
+
+ activeTasks metricValue
+ pendingTasks metricValue
+ blockedTasks metricValue
+ totalBlockedTasks metricValue
+}
+
+type metricValue struct {
+ isSet bool
+ value float64
+}
+
+func (mv *metricValue) add(v float64) {
+ mv.isSet = true
+ mv.value += v
+}
+
+func (mv *metricValue) write(mx map[string]int64, key string) {
+ if mv.isSet {
+ mx[key] = int64(mv.value)
+ }
+}
+
+func (mv *metricValue) write1k(mx map[string]int64, key string) {
+ if mv.isSet {
+ mx[key] = int64(mv.value * 1000)
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/testdata/config.json b/src/go/collectors/go.d.plugin/modules/cassandra/testdata/config.json
new file mode 100644
index 000000000..984c3ed6e
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/testdata/config.json
@@ -0,0 +1,20 @@
+{
+ "update_every": 123,
+ "url": "ok",
+ "body": "ok",
+ "method": "ok",
+ "headers": {
+ "ok": "ok"
+ },
+ "username": "ok",
+ "password": "ok",
+ "proxy_url": "ok",
+ "proxy_username": "ok",
+ "proxy_password": "ok",
+ "timeout": 123.123,
+ "not_follow_redirects": true,
+ "tls_ca": "ok",
+ "tls_cert": "ok",
+ "tls_key": "ok",
+ "tls_skip_verify": true
+}
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/testdata/config.yaml b/src/go/collectors/go.d.plugin/modules/cassandra/testdata/config.yaml
new file mode 100644
index 000000000..8558b61cc
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/testdata/config.yaml
@@ -0,0 +1,17 @@
+update_every: 123
+url: "ok"
+body: "ok"
+method: "ok"
+headers:
+ ok: "ok"
+username: "ok"
+password: "ok"
+proxy_url: "ok"
+proxy_username: "ok"
+proxy_password: "ok"
+timeout: 123.123
+not_follow_redirects: yes
+tls_ca: "ok"
+tls_cert: "ok"
+tls_key: "ok"
+tls_skip_verify: yes
diff --git a/src/go/collectors/go.d.plugin/modules/cassandra/testdata/metrics.txt b/src/go/collectors/go.d.plugin/modules/cassandra/testdata/metrics.txt
new file mode 100644
index 000000000..663a68080
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/cassandra/testdata/metrics.txt
@@ -0,0 +1,402 @@
+# HELP jvm_threads_current Current thread count of a JVM
+# TYPE jvm_threads_current gauge
+jvm_threads_current 93.0
+# HELP jvm_threads_daemon Daemon thread count of a JVM
+# TYPE jvm_threads_daemon gauge
+jvm_threads_daemon 82.0
+# HELP jvm_threads_peak Peak thread count of a JVM
+# TYPE jvm_threads_peak gauge
+jvm_threads_peak 94.0
+# HELP jvm_threads_started_total Started thread count of a JVM
+# TYPE jvm_threads_started_total counter
+jvm_threads_started_total 1860.0
+# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers
+# TYPE jvm_threads_deadlocked gauge
+jvm_threads_deadlocked 0.0
+# HELP jvm_threads_deadlocked_monitor Cycles of JVM-threads that are in deadlock waiting to acquire object monitors
+# TYPE jvm_threads_deadlocked_monitor gauge
+jvm_threads_deadlocked_monitor 0.0
+# HELP jvm_threads_state Current count of threads by state
+# TYPE jvm_threads_state gauge
+jvm_threads_state{state="NEW",} 0.0
+jvm_threads_state{state="TERMINATED",} 0.0
+jvm_threads_state{state="RUNNABLE",} 16.0
+jvm_threads_state{state="BLOCKED",} 0.0
+jvm_threads_state{state="WAITING",} 46.0
+jvm_threads_state{state="TIMED_WAITING",} 31.0
+jvm_threads_state{state="UNKNOWN",} 0.0
+# HELP jvm_memory_pool_allocated_bytes_total Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.
+# TYPE jvm_memory_pool_allocated_bytes_total counter
+jvm_memory_pool_allocated_bytes_total{pool="Par Survivor Space",} 1.52801872E8
+jvm_memory_pool_allocated_bytes_total{pool="CMS Old Gen",} 8.55035344E8
+jvm_memory_pool_allocated_bytes_total{pool="CodeHeap 'profiled nmethods'",} 2.4841216E7
+jvm_memory_pool_allocated_bytes_total{pool="CodeHeap 'non-profiled nmethods'",} 1.3023104E7
+jvm_memory_pool_allocated_bytes_total{pool="Compressed Class Space",} 6640584.0
+jvm_memory_pool_allocated_bytes_total{pool="Metaspace",} 5.3862968E7
+jvm_memory_pool_allocated_bytes_total{pool="Par Eden Space",} 7.3147804328E10
+jvm_memory_pool_allocated_bytes_total{pool="CodeHeap 'non-nmethods'",} 1530112.0
+# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.
+# TYPE jvm_gc_collection_seconds summary
+jvm_gc_collection_seconds_count{gc="ParNew",} 218.0
+jvm_gc_collection_seconds_sum{gc="ParNew",} 1.617
+jvm_gc_collection_seconds_count{gc="ConcurrentMarkSweep",} 1.0
+jvm_gc_collection_seconds_sum{gc="ConcurrentMarkSweep",} 0.059
+# HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM
+# TYPE jvm_classes_currently_loaded gauge
+jvm_classes_currently_loaded 9663.0
+# HELP jvm_classes_loaded_total The total number of classes that have been loaded since the JVM has started execution
+# TYPE jvm_classes_loaded_total counter
+jvm_classes_loaded_total 9663.0
+# HELP jvm_classes_unloaded_total The total number of classes that have been unloaded since the JVM has started execution
+# TYPE jvm_classes_unloaded_total counter
+jvm_classes_unloaded_total 0.0
+# HELP jmx_config_reload_success_total Number of times configuration have successfully been reloaded.
+# TYPE jmx_config_reload_success_total counter
+jmx_config_reload_success_total 0.0
+# HELP jmx_config_reload_failure_total Number of times configuration have failed to be reloaded.
+# TYPE jmx_config_reload_failure_total counter
+jmx_config_reload_failure_total 0.0
+# HELP org_apache_cassandra_metrics_clientrequest_50thpercentile Attribute exposed for management org.apache.cassandra.metrics:name=Latency,type=ClientRequest,attribute=50thPercentile
+# TYPE org_apache_cassandra_metrics_clientrequest_50thpercentile untyped
+org_apache_cassandra_metrics_clientrequest_50thpercentile{scope="Read",name="Latency",} 61.214
+org_apache_cassandra_metrics_clientrequest_50thpercentile{scope="Write",name="Latency",} 35.425000000000004
+# HELP org_apache_cassandra_metrics_clientrequest_95thpercentile Attribute exposed for management org.apache.cassandra.metrics:name=Latency,type=ClientRequest,attribute=95thPercentile
+# TYPE org_apache_cassandra_metrics_clientrequest_95thpercentile untyped
+org_apache_cassandra_metrics_clientrequest_95thpercentile{scope="Read",name="Latency",} 126.934
+org_apache_cassandra_metrics_clientrequest_95thpercentile{scope="Write",name="Latency",} 105.778
+# HELP org_apache_cassandra_metrics_cache_count Attribute exposed for management org.apache.cassandra.metrics:name=Misses,type=Cache,attribute=Count
+# TYPE org_apache_cassandra_metrics_cache_count untyped
+org_apache_cassandra_metrics_cache_count{scope="KeyCache",name="Misses",} 194890.0
+org_apache_cassandra_metrics_cache_count{scope="KeyCache",name="Hits",} 1336427.0
+org_apache_cassandra_metrics_cache_count{scope="RowCache",name="Hits",} 0.0
+org_apache_cassandra_metrics_cache_count{scope="RowCache",name="Misses",} 0.0
+# HELP org_apache_cassandra_metrics_storage_count Attribute exposed for management org.apache.cassandra.metrics:name=Exceptions,type=Storage,attribute=Count
+# TYPE org_apache_cassandra_metrics_storage_count untyped
+org_apache_cassandra_metrics_storage_count{name="Exceptions",} 0.0
+org_apache_cassandra_metrics_storage_count{name="Load",} 8.58272986E8
+# HELP org_apache_cassandra_metrics_compaction_count Attribute exposed for management org.apache.cassandra.metrics:name=BytesCompacted,type=Compaction,attribute=Count
+# TYPE org_apache_cassandra_metrics_compaction_count untyped
+org_apache_cassandra_metrics_compaction_count{name="BytesCompacted",} 2532.0
+# HELP org_apache_cassandra_metrics_clientrequest_count Attribute exposed for management org.apache.cassandra.metrics:name=Timeouts,type=ClientRequest,attribute=Count
+# TYPE org_apache_cassandra_metrics_clientrequest_count untyped
+org_apache_cassandra_metrics_clientrequest_count{scope="Write",name="Timeouts",} 0.0
+org_apache_cassandra_metrics_clientrequest_count{scope="Read",name="Latency",} 333316.0
+org_apache_cassandra_metrics_clientrequest_count{scope="Read",name="Unavailables",} 0.0
+org_apache_cassandra_metrics_clientrequest_count{scope="Write",name="TotalLatency",} 1.4253267E7
+org_apache_cassandra_metrics_clientrequest_count{scope="Read",name="Timeouts",} 0.0
+org_apache_cassandra_metrics_clientrequest_count{scope="Write",name="Failures",} 0.0
+org_apache_cassandra_metrics_clientrequest_count{scope="Write",name="Latency",} 331841.0
+org_apache_cassandra_metrics_clientrequest_count{scope="Read",name="Failures",} 0.0
+org_apache_cassandra_metrics_clientrequest_count{scope="Read",name="TotalLatency",} 2.3688998E7
+org_apache_cassandra_metrics_clientrequest_count{scope="Write",name="Unavailables",} 0.0
+# HELP org_apache_cassandra_metrics_cache_value Attribute exposed for management org.apache.cassandra.metrics:name=Size,type=Cache,attribute=Value
+# TYPE org_apache_cassandra_metrics_cache_value untyped
+org_apache_cassandra_metrics_cache_value{scope="RowCache",name="Size",} 0.0
+org_apache_cassandra_metrics_cache_value{scope="KeyCache",name="Size",} 1.96559936E8
+org_apache_cassandra_metrics_cache_value{scope="RowCache",name="Capacity",} 0.0
+org_apache_cassandra_metrics_cache_value{scope="KeyCache",name="Capacity",} 9.437184E8
+# HELP org_apache_cassandra_metrics_clientrequest_75thpercentile Attribute exposed for management org.apache.cassandra.metrics:name=Latency,type=ClientRequest,attribute=75thPercentile
+# TYPE org_apache_cassandra_metrics_clientrequest_75thpercentile untyped
+org_apache_cassandra_metrics_clientrequest_75thpercentile{scope="Read",name="Latency",} 88.148
+org_apache_cassandra_metrics_clientrequest_75thpercentile{scope="Write",name="Latency",} 61.214
+# HELP org_apache_cassandra_metrics_clientrequest_999thpercentile Attribute exposed for management org.apache.cassandra.metrics:name=Latency,type=ClientRequest,attribute=999thPercentile
+# TYPE org_apache_cassandra_metrics_clientrequest_999thpercentile untyped
+org_apache_cassandra_metrics_clientrequest_999thpercentile{scope="Read",name="Latency",} 454.826
+org_apache_cassandra_metrics_clientrequest_999thpercentile{scope="Write",name="Latency",} 315.85200000000003
+# HELP org_apache_cassandra_metrics_clientrequest_99thpercentile Attribute exposed for management org.apache.cassandra.metrics:name=Latency,type=ClientRequest,attribute=99thPercentile
+# TYPE org_apache_cassandra_metrics_clientrequest_99thpercentile untyped
+org_apache_cassandra_metrics_clientrequest_99thpercentile{scope="Read",name="Latency",} 219.342
+org_apache_cassandra_metrics_clientrequest_99thpercentile{scope="Write",name="Latency",} 152.321
+# HELP org_apache_cassandra_metrics_threadpools_value Attribute exposed for management org.apache.cassandra.metrics:name=ActiveTasks,type=ThreadPools,attribute=Value
+# TYPE org_apache_cassandra_metrics_threadpools_value untyped
+org_apache_cassandra_metrics_threadpools_value{path="transport",scope="Native-Transport-Requests",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="HintsDispatcher",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="transport",scope="Native-Transport-Requests",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="MemtableFlushWriter",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="CompactionExecutor",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="Sampler",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="MemtableReclaimMemory",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="ViewBuildExecutor",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="MemtableReclaimMemory",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="PerDiskMemtableFlushWriter_0",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="MemtablePostFlush",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="SecondaryIndexManagement",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="ValidationExecutor",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="Sampler",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="MemtableFlushWriter",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="ValidationExecutor",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="HintsDispatcher",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="SecondaryIndexManagement",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="request",scope="MutationStage",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="request",scope="ReadStage",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="GossipStage",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="CacheCleanupExecutor",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="CompactionExecutor",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="request",scope="MutationStage",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="PendingRangeCalculator",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="CacheCleanupExecutor",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="MemtablePostFlush",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="ViewBuildExecutor",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="request",scope="ReadStage",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="PerDiskMemtableFlushWriter_0",name="PendingTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="PendingRangeCalculator",name="ActiveTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_value{path="internal",scope="GossipStage",name="ActiveTasks",} 0.0
+# HELP org_apache_cassandra_metrics_droppedmessage_count Attribute exposed for management org.apache.cassandra.metrics:name=Dropped,type=DroppedMessage,attribute=Count
+# TYPE org_apache_cassandra_metrics_droppedmessage_count untyped
+org_apache_cassandra_metrics_droppedmessage_count{scope="FINALIZE_PROPOSE_MSG",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="COUNTER_MUTATION_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="BATCH_REMOVE",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="MUTATION_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SCHEMA_PULL_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="READ_REPAIR",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="_TEST_2",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="BATCH_STORE_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PAXOS_COMMIT_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PAXOS_PROPOSE_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="RANGE_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SNAPSHOT_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SCHEMA_VERSION_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PING_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SNAPSHOT_MSG",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="VALIDATION_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="GOSSIP_DIGEST_SYN",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="HINT_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="FINALIZE_PROMISE_MSG",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="GOSSIP_SHUTDOWN",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PAXOS_PROPOSE_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="RANGE_SLICE",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="REPAIR_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="COUNTER_MUTATION_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="MUTATION",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="_TRACE",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PING_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="CLEANUP_MSG",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="BATCH_STORE",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="REQUEST_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="BATCH_STORE_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="ECHO_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="READ_REPAIR_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="READ_REPAIR_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="STATUS_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="REPLICATION_DONE_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="REQUEST_RESPONSE",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PREPARE_CONSISTENT_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="_SAMPLE",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SCHEMA_VERSION_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="FAILURE_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="GOSSIP_DIGEST_ACK2",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SYNC_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="TRUNCATE_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="COUNTER_MUTATION",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="UNUSED_CUSTOM_VERB",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="READ_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PREPARE_MSG",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="BATCH_REMOVE_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="ECHO_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="FAILED_SESSION_MSG",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PAXOS_PREPARE_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="STATUS_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="_TEST_1",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="HINT",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SCHEMA_PUSH_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PREPARE_CONSISTENT_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="REPLICATION_DONE_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="MUTATION_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SCHEMA_PULL_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="READ_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="GOSSIP_DIGEST_ACK",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="FINALIZE_COMMIT_MSG",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="RANGE_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SYNC_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="INTERNAL_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="TRUNCATE_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PAXOS_COMMIT_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="READ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="BATCH_REMOVE_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="HINT_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SNAPSHOT_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="PAXOS_PREPARE_REQ",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="VALIDATION_RSP",name="Dropped",} 0.0
+org_apache_cassandra_metrics_droppedmessage_count{scope="SCHEMA_PUSH_RSP",name="Dropped",} 0.0
+# HELP org_apache_cassandra_metrics_clientrequest_98thpercentile Attribute exposed for management org.apache.cassandra.metrics:name=Latency,type=ClientRequest,attribute=98thPercentile
+# TYPE org_apache_cassandra_metrics_clientrequest_98thpercentile untyped
+org_apache_cassandra_metrics_clientrequest_98thpercentile{scope="Read",name="Latency",} 182.785
+org_apache_cassandra_metrics_clientrequest_98thpercentile{scope="Write",name="Latency",} 126.934
+# HELP org_apache_cassandra_metrics_threadpools_count Attribute exposed for management org.apache.cassandra.metrics:name=TotalBlockedTasks,type=ThreadPools,attribute=Count
+# TYPE org_apache_cassandra_metrics_threadpools_count untyped
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="HintsDispatcher",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="request",scope="MutationStage",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="Sampler",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="GossipStage",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="MemtableFlushWriter",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="Sampler",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="PerDiskMemtableFlushWriter_0",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="MemtableFlushWriter",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="CacheCleanupExecutor",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="ValidationExecutor",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="MemtableReclaimMemory",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="GossipStage",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="MemtablePostFlush",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="ViewBuildExecutor",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="CacheCleanupExecutor",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="PendingRangeCalculator",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="MemtableReclaimMemory",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="HintsDispatcher",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="CompactionExecutor",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="transport",scope="Native-Transport-Requests",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="transport",scope="Native-Transport-Requests",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="SecondaryIndexManagement",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="MemtablePostFlush",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="request",scope="MutationStage",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="ValidationExecutor",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="PerDiskMemtableFlushWriter_0",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="request",scope="ReadStage",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="ViewBuildExecutor",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="SecondaryIndexManagement",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="PendingRangeCalculator",name="CurrentlyBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="internal",scope="CompactionExecutor",name="TotalBlockedTasks",} 0.0
+org_apache_cassandra_metrics_threadpools_count{path="request",scope="ReadStage",name="TotalBlockedTasks",} 0.0
+# HELP org_apache_cassandra_metrics_compaction_value Attribute exposed for management org.apache.cassandra.metrics:name=CompletedTasks,type=Compaction,attribute=Value
+# TYPE org_apache_cassandra_metrics_compaction_value untyped
+org_apache_cassandra_metrics_compaction_value{name="CompletedTasks",} 1078.0
+org_apache_cassandra_metrics_compaction_value{name="PendingTasks",} 0.0
+# HELP jmx_scrape_duration_seconds Time this JMX scrape took, in seconds.
+# TYPE jmx_scrape_duration_seconds gauge
+jmx_scrape_duration_seconds 0.102931999
+# HELP jmx_scrape_error Non-zero if this scrape failed.
+# TYPE jmx_scrape_error gauge
+jmx_scrape_error 0.0
+# HELP jmx_scrape_cached_beans Number of beans with their matching rule cached
+# TYPE jmx_scrape_cached_beans gauge
+jmx_scrape_cached_beans 0.0
+# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
+# TYPE process_cpu_seconds_total counter
+process_cpu_seconds_total 155.0
+# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
+# TYPE process_start_time_seconds gauge
+process_start_time_seconds 1.666810482687E9
+# HELP process_open_fds Number of open file descriptors.
+# TYPE process_open_fds gauge
+process_open_fds 213.0
+# HELP process_max_fds Maximum number of open file descriptors.
+# TYPE process_max_fds gauge
+process_max_fds 100000.0
+# HELP process_virtual_memory_bytes Virtual memory size in bytes.
+# TYPE process_virtual_memory_bytes gauge
+process_virtual_memory_bytes 5.105344512E9
+# HELP process_resident_memory_bytes Resident memory size in bytes.
+# TYPE process_resident_memory_bytes gauge
+process_resident_memory_bytes 3.464957952E9
+# HELP jvm_memory_objects_pending_finalization The number of objects waiting in the finalizer queue.
+# TYPE jvm_memory_objects_pending_finalization gauge
+jvm_memory_objects_pending_finalization 0.0
+# HELP jvm_memory_bytes_used Used bytes of a given JVM memory area.
+# TYPE jvm_memory_bytes_used gauge
+jvm_memory_bytes_used{area="heap",} 1.134866288E9
+jvm_memory_bytes_used{area="nonheap",} 9.6565696E7
+# HELP jvm_memory_bytes_committed Committed (bytes) of a given JVM memory area.
+# TYPE jvm_memory_bytes_committed gauge
+jvm_memory_bytes_committed{area="heap",} 2.0447232E9
+jvm_memory_bytes_committed{area="nonheap",} 1.01838848E8
+# HELP jvm_memory_bytes_max Max (bytes) of a given JVM memory area.
+# TYPE jvm_memory_bytes_max gauge
+jvm_memory_bytes_max{area="heap",} 2.0447232E9
+jvm_memory_bytes_max{area="nonheap",} -1.0
+# HELP jvm_memory_bytes_init Initial bytes of a given JVM memory area.
+# TYPE jvm_memory_bytes_init gauge
+jvm_memory_bytes_init{area="heap",} 2.08666624E9
+jvm_memory_bytes_init{area="nonheap",} 7667712.0
+# HELP jvm_memory_pool_bytes_used Used bytes of a given JVM memory pool.
+# TYPE jvm_memory_pool_bytes_used gauge
+jvm_memory_pool_bytes_used{pool="CodeHeap 'non-nmethods'",} 1443712.0
+jvm_memory_pool_bytes_used{pool="Metaspace",} 5.386508E7
+jvm_memory_pool_bytes_used{pool="CodeHeap 'profiled nmethods'",} 2.2212992E7
+jvm_memory_pool_bytes_used{pool="Compressed Class Space",} 6640584.0
+jvm_memory_pool_bytes_used{pool="Par Eden Space",} 2.6869912E8
+jvm_memory_pool_bytes_used{pool="Par Survivor Space",} 1.1131824E7
+jvm_memory_pool_bytes_used{pool="CodeHeap 'non-profiled nmethods'",} 1.2403328E7
+jvm_memory_pool_bytes_used{pool="CMS Old Gen",} 8.55035344E8
+# HELP jvm_memory_pool_bytes_committed Committed bytes of a given JVM memory pool.
+# TYPE jvm_memory_pool_bytes_committed gauge
+jvm_memory_pool_bytes_committed{pool="CodeHeap 'non-nmethods'",} 2555904.0
+jvm_memory_pool_bytes_committed{pool="Metaspace",} 5.574656E7
+jvm_memory_pool_bytes_committed{pool="CodeHeap 'profiled nmethods'",} 2.3724032E7
+jvm_memory_pool_bytes_committed{pool="Compressed Class Space",} 7360512.0
+jvm_memory_pool_bytes_committed{pool="Par Eden Space",} 3.3554432E8
+jvm_memory_pool_bytes_committed{pool="Par Survivor Space",} 4.194304E7
+jvm_memory_pool_bytes_committed{pool="CodeHeap 'non-profiled nmethods'",} 1.245184E7
+jvm_memory_pool_bytes_committed{pool="CMS Old Gen",} 1.66723584E9
+# HELP jvm_memory_pool_bytes_max Max bytes of a given JVM memory pool.
+# TYPE jvm_memory_pool_bytes_max gauge
+jvm_memory_pool_bytes_max{pool="CodeHeap 'non-nmethods'",} 5832704.0
+jvm_memory_pool_bytes_max{pool="Metaspace",} -1.0
+jvm_memory_pool_bytes_max{pool="CodeHeap 'profiled nmethods'",} 1.22912768E8
+jvm_memory_pool_bytes_max{pool="Compressed Class Space",} 1.073741824E9
+jvm_memory_pool_bytes_max{pool="Par Eden Space",} 3.3554432E8
+jvm_memory_pool_bytes_max{pool="Par Survivor Space",} 4.194304E7
+jvm_memory_pool_bytes_max{pool="CodeHeap 'non-profiled nmethods'",} 1.22912768E8
+jvm_memory_pool_bytes_max{pool="CMS Old Gen",} 1.66723584E9
+# HELP jvm_memory_pool_bytes_init Initial bytes of a given JVM memory pool.
+# TYPE jvm_memory_pool_bytes_init gauge
+jvm_memory_pool_bytes_init{pool="CodeHeap 'non-nmethods'",} 2555904.0
+jvm_memory_pool_bytes_init{pool="Metaspace",} 0.0
+jvm_memory_pool_bytes_init{pool="CodeHeap 'profiled nmethods'",} 2555904.0
+jvm_memory_pool_bytes_init{pool="Compressed Class Space",} 0.0
+jvm_memory_pool_bytes_init{pool="Par Eden Space",} 3.3554432E8
+jvm_memory_pool_bytes_init{pool="Par Survivor Space",} 4.194304E7
+jvm_memory_pool_bytes_init{pool="CodeHeap 'non-profiled nmethods'",} 2555904.0
+jvm_memory_pool_bytes_init{pool="CMS Old Gen",} 1.66723584E9
+# HELP jvm_memory_pool_collection_used_bytes Used bytes after last collection of a given JVM memory pool.
+# TYPE jvm_memory_pool_collection_used_bytes gauge
+jvm_memory_pool_collection_used_bytes{pool="Par Eden Space",} 0.0
+jvm_memory_pool_collection_used_bytes{pool="Par Survivor Space",} 1.1131824E7
+jvm_memory_pool_collection_used_bytes{pool="CMS Old Gen",} 0.0
+# HELP jvm_memory_pool_collection_committed_bytes Committed after last collection bytes of a given JVM memory pool.
+# TYPE jvm_memory_pool_collection_committed_bytes gauge
+jvm_memory_pool_collection_committed_bytes{pool="Par Eden Space",} 3.3554432E8
+jvm_memory_pool_collection_committed_bytes{pool="Par Survivor Space",} 4.194304E7
+jvm_memory_pool_collection_committed_bytes{pool="CMS Old Gen",} 1.66723584E9
+# HELP jvm_memory_pool_collection_max_bytes Max bytes after last collection of a given JVM memory pool.
+# TYPE jvm_memory_pool_collection_max_bytes gauge
+jvm_memory_pool_collection_max_bytes{pool="Par Eden Space",} 3.3554432E8
+jvm_memory_pool_collection_max_bytes{pool="Par Survivor Space",} 4.194304E7
+jvm_memory_pool_collection_max_bytes{pool="CMS Old Gen",} 1.66723584E9
+# HELP jvm_memory_pool_collection_init_bytes Initial after last collection bytes of a given JVM memory pool.
+# TYPE jvm_memory_pool_collection_init_bytes gauge
+jvm_memory_pool_collection_init_bytes{pool="Par Eden Space",} 3.3554432E8
+jvm_memory_pool_collection_init_bytes{pool="Par Survivor Space",} 4.194304E7
+jvm_memory_pool_collection_init_bytes{pool="CMS Old Gen",} 1.66723584E9
+# HELP jvm_info VM version info
+# TYPE jvm_info gauge
+jvm_info{runtime="OpenJDK Runtime Environment",vendor="Debian",version="11.0.16+8-post-Debian-1deb11u1",} 1.0
+# HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool.
+# TYPE jvm_buffer_pool_used_bytes gauge
+jvm_buffer_pool_used_bytes{pool="mapped",} 9.20360582E8
+jvm_buffer_pool_used_bytes{pool="direct",} 5.1679788E7
+# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.
+# TYPE jvm_buffer_pool_capacity_bytes gauge
+jvm_buffer_pool_capacity_bytes{pool="mapped",} 9.20360582E8
+jvm_buffer_pool_capacity_bytes{pool="direct",} 5.1679786E7
+# HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool.
+# TYPE jvm_buffer_pool_used_buffers gauge
+jvm_buffer_pool_used_buffers{pool="mapped",} 74.0
+jvm_buffer_pool_used_buffers{pool="direct",} 34.0
+# HELP jmx_exporter_build_info A metric with a constant '1' value labeled with the version of the JMX exporter.
+# TYPE jmx_exporter_build_info gauge
+jmx_exporter_build_info{version="0.17.2",name="jmx_prometheus_javaagent",} 1.0
+# HELP jmx_config_reload_failure_created Number of times configuration have failed to be reloaded.
+# TYPE jmx_config_reload_failure_created gauge
+jmx_config_reload_failure_created 1.666810482756E9
+# HELP jmx_config_reload_success_created Number of times configuration have successfully been reloaded.
+# TYPE jmx_config_reload_success_created gauge
+jmx_config_reload_success_created 1.666810482755E9
+# HELP jvm_memory_pool_allocated_bytes_created Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.
+# TYPE jvm_memory_pool_allocated_bytes_created gauge
+jvm_memory_pool_allocated_bytes_created{pool="Par Survivor Space",} 1.666810483789E9
+jvm_memory_pool_allocated_bytes_created{pool="CMS Old Gen",} 1.666810484715E9
+jvm_memory_pool_allocated_bytes_created{pool="CodeHeap 'profiled nmethods'",} 1.666810483788E9
+jvm_memory_pool_allocated_bytes_created{pool="CodeHeap 'non-profiled nmethods'",} 1.666810483789E9
+jvm_memory_pool_allocated_bytes_created{pool="Compressed Class Space",} 1.666810483789E9
+jvm_memory_pool_allocated_bytes_created{pool="Metaspace",} 1.666810483789E9
+jvm_memory_pool_allocated_bytes_created{pool="Par Eden Space",} 1.666810483789E9
+jvm_memory_pool_allocated_bytes_created{pool="CodeHeap 'non-nmethods'",} 1.666810483789E9 \ No newline at end of file