diff --git a/.chloggen/drosiek-mysqlx-worker-threads.yaml b/.chloggen/drosiek-mysqlx-worker-threads.yaml new file mode 100755 index 000000000000..49a4c267c6b3 --- /dev/null +++ b/.chloggen/drosiek-mysqlx-worker-threads.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.mysqlx_worker_threads + +# 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 0da6b9f32955..6d31029765ef 100644 --- a/receiver/mysqlreceiver/documentation.md +++ b/receiver/mysqlreceiver/documentation.md @@ -22,6 +22,7 @@ These are the metrics available for this scraper. | **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.mysqlx_worker_threads** | The number of worker threads available. This metric is specific for MySQL working as Document Store (X-Plugin). [more docs](https://dev.mysql.com/doc/refman/8.0/en/document-store.html) | 1 | Sum(Int) | | | **mysql.opened_resources** | The number of opened resources. | 1 | Sum(Int) | | | **mysql.operations** | The number of InnoDB operations. | 1 | Sum(Int) | | | **mysql.page_operations** | The number of InnoDB page operations. | 1 | Sum(Int) | | @@ -62,6 +63,7 @@ metrics: | io_waits_operations (operation) | The io_waits operation type. | delete, fetch, insert, update | | locks (kind) | The table locks type. | immediate, waited | | log_operations (operation) | The log operation types. | waits, write_requests, writes | +| mysqlx_threads (kind) | The worker thread count kind. | available, active | | opened_resources (kind) | The kind of the resource. | file, table_definition, table | | operations (operation) | The operation types. | fsyncs, reads, writes | | page_operations (operation) | The page operation types. | created, read, written | diff --git a/receiver/mysqlreceiver/internal/metadata/generated_metrics.go b/receiver/mysqlreceiver/internal/metadata/generated_metrics.go index 20be4f749087..c22f3d185711 100644 --- a/receiver/mysqlreceiver/internal/metadata/generated_metrics.go +++ b/receiver/mysqlreceiver/internal/metadata/generated_metrics.go @@ -33,6 +33,7 @@ type MetricsSettings struct { MysqlLockedConnects MetricSettings `mapstructure:"mysql.locked_connects"` MysqlLocks MetricSettings `mapstructure:"mysql.locks"` MysqlLogOperations MetricSettings `mapstructure:"mysql.log_operations"` + MysqlMysqlxWorkerThreads MetricSettings `mapstructure:"mysql.mysqlx_worker_threads"` MysqlOpenedResources MetricSettings `mapstructure:"mysql.opened_resources"` MysqlOperations MetricSettings `mapstructure:"mysql.operations"` MysqlPageOperations MetricSettings `mapstructure:"mysql.page_operations"` @@ -89,6 +90,9 @@ func DefaultMetricsSettings() MetricsSettings { MysqlLogOperations: MetricSettings{ Enabled: true, }, + MysqlMysqlxWorkerThreads: MetricSettings{ + Enabled: true, + }, MysqlOpenedResources: MetricSettings{ Enabled: true, }, @@ -472,6 +476,32 @@ var MapAttributeLogOperations = map[string]AttributeLogOperations{ "writes": AttributeLogOperationsWrites, } +// AttributeMysqlxThreads specifies the a value mysqlx_threads attribute. +type AttributeMysqlxThreads int + +const ( + _ AttributeMysqlxThreads = iota + AttributeMysqlxThreadsAvailable + AttributeMysqlxThreadsActive +) + +// String returns the string representation of the AttributeMysqlxThreads. +func (av AttributeMysqlxThreads) String() string { + switch av { + case AttributeMysqlxThreadsAvailable: + return "available" + case AttributeMysqlxThreadsActive: + return "active" + } + return "" +} + +// MapAttributeMysqlxThreads is a helper map of string to AttributeMysqlxThreads attribute value. +var MapAttributeMysqlxThreads = map[string]AttributeMysqlxThreads{ + "available": AttributeMysqlxThreadsAvailable, + "active": AttributeMysqlxThreadsActive, +} + // AttributeOpenedResources specifies the a value opened_resources attribute. type AttributeOpenedResources int @@ -1462,6 +1492,59 @@ func newMetricMysqlLogOperations(settings MetricSettings) metricMysqlLogOperatio return m } +type metricMysqlMysqlxWorkerThreads 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.mysqlx_worker_threads metric with initial data. +func (m *metricMysqlMysqlxWorkerThreads) init() { + m.data.SetName("mysql.mysqlx_worker_threads") + m.data.SetDescription("The number of worker threads available.") + m.data.SetUnit("1") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricMysqlMysqlxWorkerThreads) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, mysqlxThreadsAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("kind", mysqlxThreadsAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricMysqlMysqlxWorkerThreads) 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 *metricMysqlMysqlxWorkerThreads) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricMysqlMysqlxWorkerThreads(settings MetricSettings) metricMysqlMysqlxWorkerThreads { + m := metricMysqlMysqlxWorkerThreads{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricMysqlOpenedResources struct { data pmetric.Metric // data buffer for generated metric. settings MetricSettings // metric settings provided by user. @@ -2018,6 +2101,7 @@ type MetricsBuilder struct { metricMysqlLockedConnects metricMysqlLockedConnects metricMysqlLocks metricMysqlLocks metricMysqlLogOperations metricMysqlLogOperations + metricMysqlMysqlxWorkerThreads metricMysqlMysqlxWorkerThreads metricMysqlOpenedResources metricMysqlOpenedResources metricMysqlOperations metricMysqlOperations metricMysqlPageOperations metricMysqlPageOperations @@ -2059,6 +2143,7 @@ func NewMetricsBuilder(settings MetricsSettings, buildInfo component.BuildInfo, metricMysqlLockedConnects: newMetricMysqlLockedConnects(settings.MysqlLockedConnects), metricMysqlLocks: newMetricMysqlLocks(settings.MysqlLocks), metricMysqlLogOperations: newMetricMysqlLogOperations(settings.MysqlLogOperations), + metricMysqlMysqlxWorkerThreads: newMetricMysqlMysqlxWorkerThreads(settings.MysqlMysqlxWorkerThreads), metricMysqlOpenedResources: newMetricMysqlOpenedResources(settings.MysqlOpenedResources), metricMysqlOperations: newMetricMysqlOperations(settings.MysqlOperations), metricMysqlPageOperations: newMetricMysqlPageOperations(settings.MysqlPageOperations), @@ -2142,6 +2227,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricMysqlLockedConnects.emit(ils.Metrics()) mb.metricMysqlLocks.emit(ils.Metrics()) mb.metricMysqlLogOperations.emit(ils.Metrics()) + mb.metricMysqlMysqlxWorkerThreads.emit(ils.Metrics()) mb.metricMysqlOpenedResources.emit(ils.Metrics()) mb.metricMysqlOperations.emit(ils.Metrics()) mb.metricMysqlPageOperations.emit(ils.Metrics()) @@ -2291,6 +2377,16 @@ func (mb *MetricsBuilder) RecordMysqlLogOperationsDataPoint(ts pcommon.Timestamp return nil } +// RecordMysqlMysqlxWorkerThreadsDataPoint adds a data point to mysql.mysqlx_worker_threads metric. +func (mb *MetricsBuilder) RecordMysqlMysqlxWorkerThreadsDataPoint(ts pcommon.Timestamp, inputVal string, mysqlxThreadsAttributeValue AttributeMysqlxThreads) error { + val, err := strconv.ParseInt(inputVal, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse int64 for MysqlMysqlxWorkerThreads, value was %s: %w", inputVal, err) + } + mb.metricMysqlMysqlxWorkerThreads.recordDataPoint(mb.startTime, ts, val, mysqlxThreadsAttributeValue.String()) + return nil +} + // RecordMysqlOpenedResourcesDataPoint adds a data point to mysql.opened_resources metric. func (mb *MetricsBuilder) RecordMysqlOpenedResourcesDataPoint(ts pcommon.Timestamp, inputVal string, openedResourcesAttributeValue AttributeOpenedResources) error { val, err := strconv.ParseInt(inputVal, 10, 64) diff --git a/receiver/mysqlreceiver/metadata.yaml b/receiver/mysqlreceiver/metadata.yaml index e1d37d71db2e..9e39d7d0f1b8 100644 --- a/receiver/mysqlreceiver/metadata.yaml +++ b/receiver/mysqlreceiver/metadata.yaml @@ -83,6 +83,10 @@ attributes: value: resource description: The kind of temporary resources. enum: [disk_tables, files, tables] + mysqlx_threads: + value: kind + description: The worker thread count kind. + enum: [available, active] metrics: mysql.buffer_pool.pages: @@ -316,3 +320,14 @@ metrics: monotonic: true aggregation: cumulative attributes: [tmp_resource] + mysql.mysqlx_worker_threads: + enabled: true + description: The number of worker threads available. + unit: 1 + extended_documentation: This metric is specific for MySQL working as Document Store (X-Plugin). [more docs](https://dev.mysql.com/doc/refman/8.0/en/document-store.html) + sum: + value_type: int + input_type: string + monotonic: false + aggregation: cumulative + attributes: [mysqlx_threads] diff --git a/receiver/mysqlreceiver/scraper.go b/receiver/mysqlreceiver/scraper.go index 4e0a07fd7e04..9336d1a8f666 100644 --- a/receiver/mysqlreceiver/scraper.go +++ b/receiver/mysqlreceiver/scraper.go @@ -305,6 +305,12 @@ func (m *mySQLScraper) scrapeGlobalStats(now pcommon.Timestamp, errs *scrapererr addPartialIfError(errs, m.mb.RecordMysqlOpenedResourcesDataPoint(now, v, metadata.AttributeOpenedResourcesTable)) case "Opened_table_definitions": addPartialIfError(errs, m.mb.RecordMysqlOpenedResourcesDataPoint(now, v, metadata.AttributeOpenedResourcesTableDefinition)) + + // mysqlx_worker_threads + case "Mysqlx_worker_threads": + addPartialIfError(errs, m.mb.RecordMysqlMysqlxWorkerThreadsDataPoint(now, v, metadata.AttributeMysqlxThreadsAvailable)) + case "Mysqlx_worker_threads_active": + addPartialIfError(errs, m.mb.RecordMysqlMysqlxWorkerThreadsDataPoint(now, v, metadata.AttributeMysqlxThreadsActive)) } } } diff --git a/receiver/mysqlreceiver/testdata/scraper/expected.json b/receiver/mysqlreceiver/testdata/scraper/expected.json index 18eed4b5e54a..2653251f0a4f 100644 --- a/receiver/mysqlreceiver/testdata/scraper/expected.json +++ b/receiver/mysqlreceiver/testdata/scraper/expected.json @@ -1537,6 +1537,43 @@ }, "unit": "ns" }, + { + "description": "The number of worker threads available.", + "name": "mysql.mysqlx_worker_threads", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "363", + "attributes": [ + { + "key": "kind", + "value": { + "stringValue": "available" + } + } + ], + "startTimeUnixNano": "1644862687825728000", + "timeUnixNano": "1644862687825772000" + }, + { + "asInt": "364", + "attributes": [ + { + "key": "kind", + "value": { + "stringValue": "active" + } + } + ], + "startTimeUnixNano": "1644862687825728000", + "timeUnixNano": "1644862687825772000" + } + ], + "isMonotonic": false + }, + "unit": "1" + }, { "description": "The number of opened resources.", "name": "mysql.opened_resources",