From fd4b221e1f2f6ec9adaf2f66738b585967f05ec1 Mon Sep 17 00:00:00 2001
From: Dominik Rosiek <58699848+sumo-drosiek@users.noreply.github.com>
Date: Fri, 7 Oct 2022 17:13:15 +0200
Subject: [PATCH] [receiver/mysql]: add mysql.locked_connects metric (#14745)
feat(mysqlreceiver): add mysql.locked_connects metric
---
...drosiek-uptime-innodb-row-lock-metric.yaml | 16 +++++
receiver/mysqlreceiver/documentation.md | 1 +
.../internal/metadata/generated_metrics.go | 68 +++++++++++++++++++
receiver/mysqlreceiver/metadata.yaml | 9 +++
receiver/mysqlreceiver/scraper.go | 4 ++
.../testdata/scraper/expected.json | 16 +++++
6 files changed, 114 insertions(+)
create mode 100755 .chloggen/drosiek-uptime-innodb-row-lock-metric.yaml
diff --git a/.chloggen/drosiek-uptime-innodb-row-lock-metric.yaml b/.chloggen/drosiek-uptime-innodb-row-lock-metric.yaml
new file mode 100755
index 000000000000..b3c85b33efb6
--- /dev/null
+++ b/.chloggen/drosiek-uptime-innodb-row-lock-metric.yaml
@@ -0,0 +1,16 @@
+# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
+change_type: enhancement
+
+# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
+component: mysqlreceiver
+
+# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
+note: add mysql.locked_connects metric
+
+# One or more tracking issues related to the change
+issues: [14138]
+
+# (Optional) One or more lines of additional information to render under the primary note.
+# These lines will be padded with 2 spaces and then inserted directly into the document.
+# Use pipe (|) for multiline entries.
+subtext:
diff --git a/receiver/mysqlreceiver/documentation.md b/receiver/mysqlreceiver/documentation.md
index 9b35170ee455..7f9a58f3d265 100644
--- a/receiver/mysqlreceiver/documentation.md
+++ b/receiver/mysqlreceiver/documentation.md
@@ -19,6 +19,7 @@ These are the metrics available for this scraper.
| **mysql.handlers** | The number of requests to various MySQL handlers. | 1 | Sum(Int) |
|
| **mysql.index.io.wait.count** | The total count of I/O wait events for an index. | 1 | Sum(Int) | - io_waits_operations
- table_name
- schema
- index_name
|
| **mysql.index.io.wait.time** | The total time of I/O wait events for an index. | ns | Sum(Int) | - io_waits_operations
- table_name
- schema
- index_name
|
+| **mysql.locked_connects** | The number of attempts to connect to locked user accounts. | 1 | Sum(Int) | |
| **mysql.locks** | The number of MySQL locks. | 1 | Sum(Int) | |
| **mysql.log_operations** | The number of InnoDB log operations. | 1 | Sum(Int) | |
| **mysql.operations** | The number of InnoDB operations. | 1 | Sum(Int) | |
diff --git a/receiver/mysqlreceiver/internal/metadata/generated_metrics.go b/receiver/mysqlreceiver/internal/metadata/generated_metrics.go
index bd607f400d3c..10968cbf18ff 100644
--- a/receiver/mysqlreceiver/internal/metadata/generated_metrics.go
+++ b/receiver/mysqlreceiver/internal/metadata/generated_metrics.go
@@ -30,6 +30,7 @@ type MetricsSettings struct {
MysqlHandlers MetricSettings `mapstructure:"mysql.handlers"`
MysqlIndexIoWaitCount MetricSettings `mapstructure:"mysql.index.io.wait.count"`
MysqlIndexIoWaitTime MetricSettings `mapstructure:"mysql.index.io.wait.time"`
+ MysqlLockedConnects MetricSettings `mapstructure:"mysql.locked_connects"`
MysqlLocks MetricSettings `mapstructure:"mysql.locks"`
MysqlLogOperations MetricSettings `mapstructure:"mysql.log_operations"`
MysqlOperations MetricSettings `mapstructure:"mysql.operations"`
@@ -78,6 +79,9 @@ func DefaultMetricsSettings() MetricsSettings {
MysqlIndexIoWaitTime: MetricSettings{
Enabled: true,
},
+ MysqlLockedConnects: MetricSettings{
+ Enabled: true,
+ },
MysqlLocks: MetricSettings{
Enabled: true,
},
@@ -1267,6 +1271,57 @@ func newMetricMysqlIndexIoWaitTime(settings MetricSettings) metricMysqlIndexIoWa
return m
}
+type metricMysqlLockedConnects struct {
+ data pmetric.Metric // data buffer for generated metric.
+ settings MetricSettings // metric settings provided by user.
+ capacity int // max observed number of data points added to the metric.
+}
+
+// init fills mysql.locked_connects metric with initial data.
+func (m *metricMysqlLockedConnects) init() {
+ m.data.SetName("mysql.locked_connects")
+ m.data.SetDescription("The number of attempts to connect to locked user accounts.")
+ m.data.SetUnit("1")
+ m.data.SetEmptySum()
+ m.data.Sum().SetIsMonotonic(true)
+ m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative)
+}
+
+func (m *metricMysqlLockedConnects) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) {
+ if !m.settings.Enabled {
+ return
+ }
+ dp := m.data.Sum().DataPoints().AppendEmpty()
+ dp.SetStartTimestamp(start)
+ dp.SetTimestamp(ts)
+ dp.SetIntValue(val)
+}
+
+// updateCapacity saves max length of data point slices that will be used for the slice capacity.
+func (m *metricMysqlLockedConnects) updateCapacity() {
+ if m.data.Sum().DataPoints().Len() > m.capacity {
+ m.capacity = m.data.Sum().DataPoints().Len()
+ }
+}
+
+// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points.
+func (m *metricMysqlLockedConnects) emit(metrics pmetric.MetricSlice) {
+ if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 {
+ m.updateCapacity()
+ m.data.MoveTo(metrics.AppendEmpty())
+ m.init()
+ }
+}
+
+func newMetricMysqlLockedConnects(settings MetricSettings) metricMysqlLockedConnects {
+ m := metricMysqlLockedConnects{settings: settings}
+ if settings.Enabled {
+ m.data = pmetric.NewMetric()
+ m.init()
+ }
+ return m
+}
+
type metricMysqlLocks struct {
data pmetric.Metric // data buffer for generated metric.
settings MetricSettings // metric settings provided by user.
@@ -1873,6 +1928,7 @@ type MetricsBuilder struct {
metricMysqlHandlers metricMysqlHandlers
metricMysqlIndexIoWaitCount metricMysqlIndexIoWaitCount
metricMysqlIndexIoWaitTime metricMysqlIndexIoWaitTime
+ metricMysqlLockedConnects metricMysqlLockedConnects
metricMysqlLocks metricMysqlLocks
metricMysqlLogOperations metricMysqlLogOperations
metricMysqlOperations metricMysqlOperations
@@ -1912,6 +1968,7 @@ func NewMetricsBuilder(settings MetricsSettings, buildInfo component.BuildInfo,
metricMysqlHandlers: newMetricMysqlHandlers(settings.MysqlHandlers),
metricMysqlIndexIoWaitCount: newMetricMysqlIndexIoWaitCount(settings.MysqlIndexIoWaitCount),
metricMysqlIndexIoWaitTime: newMetricMysqlIndexIoWaitTime(settings.MysqlIndexIoWaitTime),
+ metricMysqlLockedConnects: newMetricMysqlLockedConnects(settings.MysqlLockedConnects),
metricMysqlLocks: newMetricMysqlLocks(settings.MysqlLocks),
metricMysqlLogOperations: newMetricMysqlLogOperations(settings.MysqlLogOperations),
metricMysqlOperations: newMetricMysqlOperations(settings.MysqlOperations),
@@ -1993,6 +2050,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) {
mb.metricMysqlHandlers.emit(ils.Metrics())
mb.metricMysqlIndexIoWaitCount.emit(ils.Metrics())
mb.metricMysqlIndexIoWaitTime.emit(ils.Metrics())
+ mb.metricMysqlLockedConnects.emit(ils.Metrics())
mb.metricMysqlLocks.emit(ils.Metrics())
mb.metricMysqlLogOperations.emit(ils.Metrics())
mb.metricMysqlOperations.emit(ils.Metrics())
@@ -2113,6 +2171,16 @@ func (mb *MetricsBuilder) RecordMysqlIndexIoWaitTimeDataPoint(ts pcommon.Timesta
mb.metricMysqlIndexIoWaitTime.recordDataPoint(mb.startTime, ts, val, ioWaitsOperationsAttributeValue.String(), tableNameAttributeValue, schemaAttributeValue, indexNameAttributeValue)
}
+// RecordMysqlLockedConnectsDataPoint adds a data point to mysql.locked_connects metric.
+func (mb *MetricsBuilder) RecordMysqlLockedConnectsDataPoint(ts pcommon.Timestamp, inputVal string) error {
+ val, err := strconv.ParseInt(inputVal, 10, 64)
+ if err != nil {
+ return fmt.Errorf("failed to parse int64 for MysqlLockedConnects, value was %s: %w", inputVal, err)
+ }
+ mb.metricMysqlLockedConnects.recordDataPoint(mb.startTime, ts, val)
+ return nil
+}
+
// RecordMysqlLocksDataPoint adds a data point to mysql.locks metric.
func (mb *MetricsBuilder) RecordMysqlLocksDataPoint(ts pcommon.Timestamp, inputVal string, locksAttributeValue AttributeLocks) error {
val, err := strconv.ParseInt(inputVal, 10, 64)
diff --git a/receiver/mysqlreceiver/metadata.yaml b/receiver/mysqlreceiver/metadata.yaml
index 8d919bdafd28..be320db787c3 100644
--- a/receiver/mysqlreceiver/metadata.yaml
+++ b/receiver/mysqlreceiver/metadata.yaml
@@ -283,6 +283,15 @@ metrics:
monotonic: false
aggregation: cumulative
attributes: [threads]
+ mysql.locked_connects:
+ enabled: true
+ description: The number of attempts to connect to locked user accounts.
+ unit: 1
+ sum:
+ value_type: int
+ input_type: string
+ monotonic: true
+ aggregation: cumulative
mysql.tmp_resources:
enabled: true
description: The number of created temporary resources.
diff --git a/receiver/mysqlreceiver/scraper.go b/receiver/mysqlreceiver/scraper.go
index 9b7163505547..985ad4b1d33d 100644
--- a/receiver/mysqlreceiver/scraper.go
+++ b/receiver/mysqlreceiver/scraper.go
@@ -274,6 +274,10 @@ func (m *mySQLScraper) scrapeGlobalStats(now pcommon.Timestamp, errs *scrapererr
case "Table_locks_waited":
addPartialIfError(errs, m.mb.RecordMysqlLocksDataPoint(now, v, metadata.AttributeLocksWaited))
+ // locked_connects
+ case "Locked_connects":
+ addPartialIfError(errs, m.mb.RecordMysqlLockedConnectsDataPoint(now, v))
+
// sorts
case "Sort_merge_passes":
addPartialIfError(errs, m.mb.RecordMysqlSortsDataPoint(now, v, metadata.AttributeSortsMergePasses))
diff --git a/receiver/mysqlreceiver/testdata/scraper/expected.json b/receiver/mysqlreceiver/testdata/scraper/expected.json
index bed533c47f10..cbd541e5f401 100644
--- a/receiver/mysqlreceiver/testdata/scraper/expected.json
+++ b/receiver/mysqlreceiver/testdata/scraper/expected.json
@@ -1537,6 +1537,22 @@
},
"unit": "ns"
},
+ {
+ "description": "The number of attempts to connect to locked user accounts.",
+ "name": "mysql.locked_connects",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "dataPoints": [
+ {
+ "asInt": "293",
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ],
+ "isMonotonic": true
+ },
+ "unit": "1"
+ },
{
"description": "The number of created temporary resources.",
"name": "mysql.tmp_resources",