scraper.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package mysqlreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver"
  4. import (
  5. "context"
  6. "errors"
  7. "strconv"
  8. "time"
  9. "go.opentelemetry.io/collector/component"
  10. "go.opentelemetry.io/collector/pdata/pcommon"
  11. "go.opentelemetry.io/collector/pdata/pmetric"
  12. "go.opentelemetry.io/collector/receiver"
  13. "go.opentelemetry.io/collector/receiver/scrapererror"
  14. "go.uber.org/zap"
  15. "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver/internal/metadata"
  16. )
  17. const (
  18. picosecondsInNanoseconds int64 = 1000
  19. )
  20. type mySQLScraper struct {
  21. sqlclient client
  22. logger *zap.Logger
  23. config *Config
  24. mb *metadata.MetricsBuilder
  25. // Feature gates regarding resource attributes
  26. renameCommands bool
  27. }
  28. func newMySQLScraper(
  29. settings receiver.CreateSettings,
  30. config *Config,
  31. ) *mySQLScraper {
  32. return &mySQLScraper{
  33. logger: settings.Logger,
  34. config: config,
  35. mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, settings),
  36. }
  37. }
  38. // start starts the scraper by initializing the db client connection.
  39. func (m *mySQLScraper) start(_ context.Context, _ component.Host) error {
  40. sqlclient, err := newMySQLClient(m.config)
  41. if err != nil {
  42. return err
  43. }
  44. err = sqlclient.Connect()
  45. if err != nil {
  46. return err
  47. }
  48. m.sqlclient = sqlclient
  49. return nil
  50. }
  51. // shutdown closes the db connection
  52. func (m *mySQLScraper) shutdown(context.Context) error {
  53. if m.sqlclient == nil {
  54. return nil
  55. }
  56. return m.sqlclient.Close()
  57. }
  58. // scrape scrapes the mysql db metric stats, transforms them and labels them into a metric slices.
  59. func (m *mySQLScraper) scrape(context.Context) (pmetric.Metrics, error) {
  60. if m.sqlclient == nil {
  61. return pmetric.Metrics{}, errors.New("failed to connect to http client")
  62. }
  63. now := pcommon.NewTimestampFromTime(time.Now())
  64. // collect innodb metrics.
  65. innodbStats, innoErr := m.sqlclient.getInnodbStats()
  66. if innoErr != nil {
  67. m.logger.Error("Failed to fetch InnoDB stats", zap.Error(innoErr))
  68. }
  69. errs := &scrapererror.ScrapeErrors{}
  70. for k, v := range innodbStats {
  71. if k != "buffer_pool_size" {
  72. continue
  73. }
  74. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolLimitDataPoint(now, v))
  75. }
  76. // collect io_waits metrics.
  77. m.scrapeTableIoWaitsStats(now, errs)
  78. m.scrapeIndexIoWaitsStats(now, errs)
  79. // collect performance event statements metrics.
  80. m.scrapeStatementEventsStats(now, errs)
  81. // collect lock table events metrics
  82. m.scrapeTableLockWaitEventStats(now, errs)
  83. // collect global status metrics.
  84. m.scrapeGlobalStats(now, errs)
  85. // colect replicas status metrics.
  86. m.scrapeReplicaStatusStats(now)
  87. rb := m.mb.NewResourceBuilder()
  88. rb.SetMysqlInstanceEndpoint(m.config.Endpoint)
  89. m.mb.EmitForResource(metadata.WithResource(rb.Emit()))
  90. return m.mb.Emit(), errs.Combine()
  91. }
  92. func (m *mySQLScraper) scrapeGlobalStats(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
  93. globalStats, err := m.sqlclient.getGlobalStats()
  94. if err != nil {
  95. m.logger.Error("Failed to fetch global stats", zap.Error(err))
  96. errs.AddPartial(66, err)
  97. return
  98. }
  99. m.recordDataPages(now, globalStats, errs)
  100. m.recordDataUsage(now, globalStats, errs)
  101. for k, v := range globalStats {
  102. switch k {
  103. // bytes transmission
  104. case "Bytes_received":
  105. addPartialIfError(errs, m.mb.RecordMysqlClientNetworkIoDataPoint(now, v, metadata.AttributeDirectionReceived))
  106. case "Bytes_sent":
  107. addPartialIfError(errs, m.mb.RecordMysqlClientNetworkIoDataPoint(now, v, metadata.AttributeDirectionSent))
  108. // buffer_pool.pages
  109. case "Innodb_buffer_pool_pages_data":
  110. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolPagesDataPoint(now, v,
  111. metadata.AttributeBufferPoolPagesData))
  112. case "Innodb_buffer_pool_pages_free":
  113. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolPagesDataPoint(now, v,
  114. metadata.AttributeBufferPoolPagesFree))
  115. case "Innodb_buffer_pool_pages_misc":
  116. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolPagesDataPoint(now, v,
  117. metadata.AttributeBufferPoolPagesMisc))
  118. // buffer_pool.page_flushes
  119. case "Innodb_buffer_pool_pages_flushed":
  120. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolPageFlushesDataPoint(now, v))
  121. // buffer_pool.operations
  122. case "Innodb_buffer_pool_read_ahead_rnd":
  123. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolOperationsDataPoint(now, v,
  124. metadata.AttributeBufferPoolOperationsReadAheadRnd))
  125. case "Innodb_buffer_pool_read_ahead":
  126. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolOperationsDataPoint(now, v,
  127. metadata.AttributeBufferPoolOperationsReadAhead))
  128. case "Innodb_buffer_pool_read_ahead_evicted":
  129. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolOperationsDataPoint(now, v,
  130. metadata.AttributeBufferPoolOperationsReadAheadEvicted))
  131. case "Innodb_buffer_pool_read_requests":
  132. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolOperationsDataPoint(now, v,
  133. metadata.AttributeBufferPoolOperationsReadRequests))
  134. case "Innodb_buffer_pool_reads":
  135. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolOperationsDataPoint(now, v,
  136. metadata.AttributeBufferPoolOperationsReads))
  137. case "Innodb_buffer_pool_wait_free":
  138. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolOperationsDataPoint(now, v,
  139. metadata.AttributeBufferPoolOperationsWaitFree))
  140. case "Innodb_buffer_pool_write_requests":
  141. addPartialIfError(errs, m.mb.RecordMysqlBufferPoolOperationsDataPoint(now, v,
  142. metadata.AttributeBufferPoolOperationsWriteRequests))
  143. // connection.errors
  144. case "Connection_errors_accept":
  145. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  146. metadata.AttributeConnectionErrorAccept))
  147. case "Connection_errors_internal":
  148. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  149. metadata.AttributeConnectionErrorInternal))
  150. case "Connection_errors_max_connections":
  151. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  152. metadata.AttributeConnectionErrorMaxConnections))
  153. case "Connection_errors_peer_address":
  154. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  155. metadata.AttributeConnectionErrorPeerAddress))
  156. case "Connection_errors_select":
  157. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  158. metadata.AttributeConnectionErrorSelect))
  159. case "Connection_errors_tcpwrap":
  160. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  161. metadata.AttributeConnectionErrorTcpwrap))
  162. case "Aborted_clients":
  163. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  164. metadata.AttributeConnectionErrorAbortedClients))
  165. case "Aborted_connects":
  166. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  167. metadata.AttributeConnectionErrorAborted))
  168. case "Locked_connects":
  169. addPartialIfError(errs, m.mb.RecordMysqlConnectionErrorsDataPoint(now, v,
  170. metadata.AttributeConnectionErrorLocked))
  171. // connection
  172. case "Connections":
  173. addPartialIfError(errs, m.mb.RecordMysqlConnectionCountDataPoint(now, v))
  174. // prepared_statements_commands
  175. case "Com_stmt_execute":
  176. addPartialIfError(errs, m.mb.RecordMysqlPreparedStatementsDataPoint(now, v,
  177. metadata.AttributePreparedStatementsCommandExecute))
  178. case "Com_stmt_close":
  179. addPartialIfError(errs, m.mb.RecordMysqlPreparedStatementsDataPoint(now, v,
  180. metadata.AttributePreparedStatementsCommandClose))
  181. case "Com_stmt_fetch":
  182. addPartialIfError(errs, m.mb.RecordMysqlPreparedStatementsDataPoint(now, v,
  183. metadata.AttributePreparedStatementsCommandFetch))
  184. case "Com_stmt_prepare":
  185. addPartialIfError(errs, m.mb.RecordMysqlPreparedStatementsDataPoint(now, v,
  186. metadata.AttributePreparedStatementsCommandPrepare))
  187. case "Com_stmt_reset":
  188. addPartialIfError(errs, m.mb.RecordMysqlPreparedStatementsDataPoint(now, v,
  189. metadata.AttributePreparedStatementsCommandReset))
  190. case "Com_stmt_send_long_data":
  191. addPartialIfError(errs, m.mb.RecordMysqlPreparedStatementsDataPoint(now, v,
  192. metadata.AttributePreparedStatementsCommandSendLongData))
  193. // commands
  194. case "Com_delete":
  195. addPartialIfError(errs, m.mb.RecordMysqlCommandsDataPoint(now, v, metadata.AttributeCommandDelete))
  196. case "Com_insert":
  197. addPartialIfError(errs, m.mb.RecordMysqlCommandsDataPoint(now, v, metadata.AttributeCommandInsert))
  198. case "Com_select":
  199. addPartialIfError(errs, m.mb.RecordMysqlCommandsDataPoint(now, v, metadata.AttributeCommandSelect))
  200. case "Com_update":
  201. addPartialIfError(errs, m.mb.RecordMysqlCommandsDataPoint(now, v, metadata.AttributeCommandUpdate))
  202. // created tmps
  203. case "Created_tmp_disk_tables":
  204. addPartialIfError(errs, m.mb.RecordMysqlTmpResourcesDataPoint(now, v, metadata.AttributeTmpResourceDiskTables))
  205. case "Created_tmp_files":
  206. addPartialIfError(errs, m.mb.RecordMysqlTmpResourcesDataPoint(now, v, metadata.AttributeTmpResourceFiles))
  207. case "Created_tmp_tables":
  208. addPartialIfError(errs, m.mb.RecordMysqlTmpResourcesDataPoint(now, v, metadata.AttributeTmpResourceTables))
  209. // handlers
  210. case "Handler_commit":
  211. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerCommit))
  212. case "Handler_delete":
  213. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerDelete))
  214. case "Handler_discover":
  215. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerDiscover))
  216. case "Handler_external_lock":
  217. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerExternalLock))
  218. case "Handler_mrr_init":
  219. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerMrrInit))
  220. case "Handler_prepare":
  221. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerPrepare))
  222. case "Handler_read_first":
  223. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerReadFirst))
  224. case "Handler_read_key":
  225. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerReadKey))
  226. case "Handler_read_last":
  227. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerReadLast))
  228. case "Handler_read_next":
  229. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerReadNext))
  230. case "Handler_read_prev":
  231. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerReadPrev))
  232. case "Handler_read_rnd":
  233. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerReadRnd))
  234. case "Handler_read_rnd_next":
  235. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerReadRndNext))
  236. case "Handler_rollback":
  237. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerRollback))
  238. case "Handler_savepoint":
  239. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerSavepoint))
  240. case "Handler_savepoint_rollback":
  241. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerSavepointRollback))
  242. case "Handler_update":
  243. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerUpdate))
  244. case "Handler_write":
  245. addPartialIfError(errs, m.mb.RecordMysqlHandlersDataPoint(now, v, metadata.AttributeHandlerWrite))
  246. // double_writes
  247. case "Innodb_dblwr_pages_written":
  248. addPartialIfError(errs, m.mb.RecordMysqlDoubleWritesDataPoint(now, v, metadata.AttributeDoubleWritesPagesWritten))
  249. case "Innodb_dblwr_writes":
  250. addPartialIfError(errs, m.mb.RecordMysqlDoubleWritesDataPoint(now, v, metadata.AttributeDoubleWritesWrites))
  251. // log_operations
  252. case "Innodb_log_waits":
  253. addPartialIfError(errs, m.mb.RecordMysqlLogOperationsDataPoint(now, v, metadata.AttributeLogOperationsWaits))
  254. case "Innodb_log_write_requests":
  255. addPartialIfError(errs, m.mb.RecordMysqlLogOperationsDataPoint(now, v, metadata.AttributeLogOperationsWriteRequests))
  256. case "Innodb_log_writes":
  257. addPartialIfError(errs, m.mb.RecordMysqlLogOperationsDataPoint(now, v, metadata.AttributeLogOperationsWrites))
  258. // operations
  259. case "Innodb_data_fsyncs":
  260. addPartialIfError(errs, m.mb.RecordMysqlOperationsDataPoint(now, v, metadata.AttributeOperationsFsyncs))
  261. case "Innodb_data_reads":
  262. addPartialIfError(errs, m.mb.RecordMysqlOperationsDataPoint(now, v, metadata.AttributeOperationsReads))
  263. case "Innodb_data_writes":
  264. addPartialIfError(errs, m.mb.RecordMysqlOperationsDataPoint(now, v, metadata.AttributeOperationsWrites))
  265. // page_operations
  266. case "Innodb_pages_created":
  267. addPartialIfError(errs, m.mb.RecordMysqlPageOperationsDataPoint(now, v, metadata.AttributePageOperationsCreated))
  268. case "Innodb_pages_read":
  269. addPartialIfError(errs, m.mb.RecordMysqlPageOperationsDataPoint(now, v,
  270. metadata.AttributePageOperationsRead))
  271. case "Innodb_pages_written":
  272. addPartialIfError(errs, m.mb.RecordMysqlPageOperationsDataPoint(now, v,
  273. metadata.AttributePageOperationsWritten))
  274. // row_locks
  275. case "Innodb_row_lock_waits":
  276. addPartialIfError(errs, m.mb.RecordMysqlRowLocksDataPoint(now, v, metadata.AttributeRowLocksWaits))
  277. case "Innodb_row_lock_time":
  278. addPartialIfError(errs, m.mb.RecordMysqlRowLocksDataPoint(now, v, metadata.AttributeRowLocksTime))
  279. // row_operations
  280. case "Innodb_rows_deleted":
  281. addPartialIfError(errs, m.mb.RecordMysqlRowOperationsDataPoint(now, v, metadata.AttributeRowOperationsDeleted))
  282. case "Innodb_rows_inserted":
  283. addPartialIfError(errs, m.mb.RecordMysqlRowOperationsDataPoint(now, v, metadata.AttributeRowOperationsInserted))
  284. case "Innodb_rows_read":
  285. addPartialIfError(errs, m.mb.RecordMysqlRowOperationsDataPoint(now, v,
  286. metadata.AttributeRowOperationsRead))
  287. case "Innodb_rows_updated":
  288. addPartialIfError(errs, m.mb.RecordMysqlRowOperationsDataPoint(now, v,
  289. metadata.AttributeRowOperationsUpdated))
  290. // locks
  291. case "Table_locks_immediate":
  292. addPartialIfError(errs, m.mb.RecordMysqlLocksDataPoint(now, v, metadata.AttributeLocksImmediate))
  293. case "Table_locks_waited":
  294. addPartialIfError(errs, m.mb.RecordMysqlLocksDataPoint(now, v, metadata.AttributeLocksWaited))
  295. // joins
  296. case "Select_full_join":
  297. addPartialIfError(errs, m.mb.RecordMysqlJoinsDataPoint(now, v, metadata.AttributeJoinKindFull))
  298. case "Select_full_range_join":
  299. addPartialIfError(errs, m.mb.RecordMysqlJoinsDataPoint(now, v, metadata.AttributeJoinKindFullRange))
  300. case "Select_range":
  301. addPartialIfError(errs, m.mb.RecordMysqlJoinsDataPoint(now, v, metadata.AttributeJoinKindRange))
  302. case "Select_range_check":
  303. addPartialIfError(errs, m.mb.RecordMysqlJoinsDataPoint(now, v, metadata.AttributeJoinKindRangeCheck))
  304. case "Select_scan":
  305. addPartialIfError(errs, m.mb.RecordMysqlJoinsDataPoint(now, v, metadata.AttributeJoinKindScan))
  306. // open cache
  307. case "Table_open_cache_hits":
  308. addPartialIfError(errs, m.mb.RecordMysqlTableOpenCacheDataPoint(now, v, metadata.AttributeCacheStatusHit))
  309. case "Table_open_cache_misses":
  310. addPartialIfError(errs, m.mb.RecordMysqlTableOpenCacheDataPoint(now, v, metadata.AttributeCacheStatusMiss))
  311. case "Table_open_cache_overflows":
  312. addPartialIfError(errs, m.mb.RecordMysqlTableOpenCacheDataPoint(now, v, metadata.AttributeCacheStatusOverflow))
  313. // queries
  314. case "Queries":
  315. addPartialIfError(errs, m.mb.RecordMysqlQueryCountDataPoint(now, v))
  316. case "Questions":
  317. addPartialIfError(errs, m.mb.RecordMysqlQueryClientCountDataPoint(now, v))
  318. case "Slow_queries":
  319. addPartialIfError(errs, m.mb.RecordMysqlQuerySlowCountDataPoint(now, v))
  320. // sorts
  321. case "Sort_merge_passes":
  322. addPartialIfError(errs, m.mb.RecordMysqlSortsDataPoint(now, v, metadata.AttributeSortsMergePasses))
  323. case "Sort_range":
  324. addPartialIfError(errs, m.mb.RecordMysqlSortsDataPoint(now, v, metadata.AttributeSortsRange))
  325. case "Sort_rows":
  326. addPartialIfError(errs, m.mb.RecordMysqlSortsDataPoint(now, v, metadata.AttributeSortsRows))
  327. case "Sort_scan":
  328. addPartialIfError(errs, m.mb.RecordMysqlSortsDataPoint(now, v, metadata.AttributeSortsScan))
  329. // threads
  330. case "Threads_cached":
  331. addPartialIfError(errs, m.mb.RecordMysqlThreadsDataPoint(now, v, metadata.AttributeThreadsCached))
  332. case "Threads_connected":
  333. addPartialIfError(errs, m.mb.RecordMysqlThreadsDataPoint(now, v, metadata.AttributeThreadsConnected))
  334. case "Threads_created":
  335. addPartialIfError(errs, m.mb.RecordMysqlThreadsDataPoint(now, v, metadata.AttributeThreadsCreated))
  336. case "Threads_running":
  337. addPartialIfError(errs, m.mb.RecordMysqlThreadsDataPoint(now, v, metadata.AttributeThreadsRunning))
  338. // opened resources
  339. case "Opened_files":
  340. addPartialIfError(errs, m.mb.RecordMysqlOpenedResourcesDataPoint(now, v, metadata.AttributeOpenedResourcesFile))
  341. case "Opened_tables":
  342. addPartialIfError(errs, m.mb.RecordMysqlOpenedResourcesDataPoint(now, v, metadata.AttributeOpenedResourcesTable))
  343. case "Opened_table_definitions":
  344. addPartialIfError(errs, m.mb.RecordMysqlOpenedResourcesDataPoint(now, v, metadata.AttributeOpenedResourcesTableDefinition))
  345. // mysqlx_worker_threads
  346. case "Mysqlx_worker_threads":
  347. addPartialIfError(errs, m.mb.RecordMysqlMysqlxWorkerThreadsDataPoint(now, v, metadata.AttributeMysqlxThreadsAvailable))
  348. case "Mysqlx_worker_threads_active":
  349. addPartialIfError(errs, m.mb.RecordMysqlMysqlxWorkerThreadsDataPoint(now, v, metadata.AttributeMysqlxThreadsActive))
  350. // mysqlx_connections
  351. case "Mysqlx_connections_accepted":
  352. addPartialIfError(errs, m.mb.RecordMysqlMysqlxConnectionsDataPoint(now, v, metadata.AttributeConnectionStatusAccepted))
  353. case "Mysqlx_connections_closed":
  354. addPartialIfError(errs, m.mb.RecordMysqlMysqlxConnectionsDataPoint(now, v, metadata.AttributeConnectionStatusClosed))
  355. case "Mysqlx_connections_rejected":
  356. addPartialIfError(errs, m.mb.RecordMysqlMysqlxConnectionsDataPoint(now, v, metadata.AttributeConnectionStatusRejected))
  357. // uptime
  358. case "Uptime":
  359. addPartialIfError(errs, m.mb.RecordMysqlUptimeDataPoint(now, v))
  360. }
  361. }
  362. }
  363. func (m *mySQLScraper) scrapeTableIoWaitsStats(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
  364. tableIoWaitsStats, err := m.sqlclient.getTableIoWaitsStats()
  365. if err != nil {
  366. m.logger.Error("Failed to fetch table io_waits stats", zap.Error(err))
  367. errs.AddPartial(8, err)
  368. return
  369. }
  370. for i := 0; i < len(tableIoWaitsStats); i++ {
  371. s := tableIoWaitsStats[i]
  372. // counts
  373. m.mb.RecordMysqlTableIoWaitCountDataPoint(now, s.countDelete, metadata.AttributeIoWaitsOperationsDelete, s.name, s.schema)
  374. m.mb.RecordMysqlTableIoWaitCountDataPoint(now, s.countFetch, metadata.AttributeIoWaitsOperationsFetch, s.name, s.schema)
  375. m.mb.RecordMysqlTableIoWaitCountDataPoint(now, s.countInsert, metadata.AttributeIoWaitsOperationsInsert, s.name, s.schema)
  376. m.mb.RecordMysqlTableIoWaitCountDataPoint(now, s.countUpdate, metadata.AttributeIoWaitsOperationsUpdate, s.name, s.schema)
  377. // times
  378. m.mb.RecordMysqlTableIoWaitTimeDataPoint(
  379. now, s.timeDelete/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsDelete, s.name, s.schema,
  380. )
  381. m.mb.RecordMysqlTableIoWaitTimeDataPoint(
  382. now, s.timeFetch/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsFetch, s.name, s.schema,
  383. )
  384. m.mb.RecordMysqlTableIoWaitTimeDataPoint(
  385. now, s.timeInsert/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsInsert, s.name, s.schema,
  386. )
  387. m.mb.RecordMysqlTableIoWaitTimeDataPoint(
  388. now, s.timeUpdate/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsUpdate, s.name, s.schema,
  389. )
  390. }
  391. }
  392. func (m *mySQLScraper) scrapeIndexIoWaitsStats(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
  393. indexIoWaitsStats, err := m.sqlclient.getIndexIoWaitsStats()
  394. if err != nil {
  395. m.logger.Error("Failed to fetch index io_waits stats", zap.Error(err))
  396. errs.AddPartial(8, err)
  397. return
  398. }
  399. for i := 0; i < len(indexIoWaitsStats); i++ {
  400. s := indexIoWaitsStats[i]
  401. // counts
  402. m.mb.RecordMysqlIndexIoWaitCountDataPoint(now, s.countDelete, metadata.AttributeIoWaitsOperationsDelete, s.name, s.schema, s.index)
  403. m.mb.RecordMysqlIndexIoWaitCountDataPoint(now, s.countFetch, metadata.AttributeIoWaitsOperationsFetch, s.name, s.schema, s.index)
  404. m.mb.RecordMysqlIndexIoWaitCountDataPoint(now, s.countInsert, metadata.AttributeIoWaitsOperationsInsert, s.name, s.schema, s.index)
  405. m.mb.RecordMysqlIndexIoWaitCountDataPoint(now, s.countUpdate, metadata.AttributeIoWaitsOperationsUpdate, s.name, s.schema, s.index)
  406. // times
  407. m.mb.RecordMysqlIndexIoWaitTimeDataPoint(
  408. now, s.timeDelete/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsDelete, s.name, s.schema, s.index,
  409. )
  410. m.mb.RecordMysqlIndexIoWaitTimeDataPoint(
  411. now, s.timeFetch/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsFetch, s.name, s.schema, s.index,
  412. )
  413. m.mb.RecordMysqlIndexIoWaitTimeDataPoint(
  414. now, s.timeInsert/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsInsert, s.name, s.schema, s.index,
  415. )
  416. m.mb.RecordMysqlIndexIoWaitTimeDataPoint(
  417. now, s.timeUpdate/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsUpdate, s.name, s.schema, s.index,
  418. )
  419. }
  420. }
  421. func (m *mySQLScraper) scrapeStatementEventsStats(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
  422. statementEventsStats, err := m.sqlclient.getStatementEventsStats()
  423. if err != nil {
  424. m.logger.Error("Failed to fetch index io_waits stats", zap.Error(err))
  425. errs.AddPartial(8, err)
  426. return
  427. }
  428. for i := 0; i < len(statementEventsStats); i++ {
  429. s := statementEventsStats[i]
  430. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countCreatedTmpDiskTables, s.schema, s.digest, s.digestText, metadata.AttributeEventStateCreatedTmpDiskTables)
  431. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countCreatedTmpTables, s.schema, s.digest, s.digestText, metadata.AttributeEventStateCreatedTmpTables)
  432. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countErrors, s.schema, s.digest, s.digestText, metadata.AttributeEventStateErrors)
  433. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countNoIndexUsed, s.schema, s.digest, s.digestText, metadata.AttributeEventStateNoIndexUsed)
  434. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countRowsAffected, s.schema, s.digest, s.digestText, metadata.AttributeEventStateRowsAffected)
  435. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countRowsExamined, s.schema, s.digest, s.digestText, metadata.AttributeEventStateRowsExamined)
  436. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countRowsSent, s.schema, s.digest, s.digestText, metadata.AttributeEventStateRowsSent)
  437. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countSortMergePasses, s.schema, s.digest, s.digestText, metadata.AttributeEventStateSortMergePasses)
  438. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countSortRows, s.schema, s.digest, s.digestText, metadata.AttributeEventStateSortRows)
  439. m.mb.RecordMysqlStatementEventCountDataPoint(now, s.countWarnings, s.schema, s.digest, s.digestText, metadata.AttributeEventStateWarnings)
  440. m.mb.RecordMysqlStatementEventWaitTimeDataPoint(now, s.sumTimerWait/picosecondsInNanoseconds, s.schema, s.digest, s.digestText)
  441. }
  442. }
  443. func (m *mySQLScraper) scrapeTableLockWaitEventStats(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
  444. tableLockWaitEventStats, err := m.sqlclient.getTableLockWaitEventStats()
  445. if err != nil {
  446. m.logger.Error("Failed to fetch index io_waits stats", zap.Error(err))
  447. errs.AddPartial(8, err)
  448. return
  449. }
  450. for i := 0; i < len(tableLockWaitEventStats); i++ {
  451. s := tableLockWaitEventStats[i]
  452. // read data points
  453. m.mb.RecordMysqlTableLockWaitReadCountDataPoint(now, s.countReadNormal, s.schema, s.name, metadata.AttributeReadLockTypeNormal)
  454. m.mb.RecordMysqlTableLockWaitReadCountDataPoint(now, s.countReadWithSharedLocks, s.schema, s.name, metadata.AttributeReadLockTypeWithSharedLocks)
  455. m.mb.RecordMysqlTableLockWaitReadCountDataPoint(now, s.countReadHighPriority, s.schema, s.name, metadata.AttributeReadLockTypeHighPriority)
  456. m.mb.RecordMysqlTableLockWaitReadCountDataPoint(now, s.countReadNoInsert, s.schema, s.name, metadata.AttributeReadLockTypeNoInsert)
  457. m.mb.RecordMysqlTableLockWaitReadCountDataPoint(now, s.countReadExternal, s.schema, s.name, metadata.AttributeReadLockTypeExternal)
  458. // read time data points
  459. m.mb.RecordMysqlTableLockWaitReadTimeDataPoint(now, s.sumTimerReadNormal/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeReadLockTypeNormal)
  460. m.mb.RecordMysqlTableLockWaitReadTimeDataPoint(now, s.sumTimerReadWithSharedLocks/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeReadLockTypeWithSharedLocks)
  461. m.mb.RecordMysqlTableLockWaitReadTimeDataPoint(now, s.sumTimerReadHighPriority/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeReadLockTypeHighPriority)
  462. m.mb.RecordMysqlTableLockWaitReadTimeDataPoint(now, s.sumTimerReadNoInsert/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeReadLockTypeNoInsert)
  463. m.mb.RecordMysqlTableLockWaitReadTimeDataPoint(now, s.sumTimerReadExternal/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeReadLockTypeExternal)
  464. // write data points
  465. m.mb.RecordMysqlTableLockWaitWriteCountDataPoint(now, s.countWriteAllowWrite, s.schema, s.name, metadata.AttributeWriteLockTypeAllowWrite)
  466. m.mb.RecordMysqlTableLockWaitWriteCountDataPoint(now, s.countWriteConcurrentInsert, s.schema, s.name, metadata.AttributeWriteLockTypeConcurrentInsert)
  467. m.mb.RecordMysqlTableLockWaitWriteCountDataPoint(now, s.countWriteLowPriority, s.schema, s.name, metadata.AttributeWriteLockTypeLowPriority)
  468. m.mb.RecordMysqlTableLockWaitWriteCountDataPoint(now, s.countWriteNormal, s.schema, s.name, metadata.AttributeWriteLockTypeNormal)
  469. m.mb.RecordMysqlTableLockWaitWriteCountDataPoint(now, s.countWriteExternal, s.schema, s.name, metadata.AttributeWriteLockTypeExternal)
  470. // write time data points
  471. m.mb.RecordMysqlTableLockWaitWriteTimeDataPoint(now, s.sumTimerWriteAllowWrite/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeWriteLockTypeAllowWrite)
  472. m.mb.RecordMysqlTableLockWaitWriteTimeDataPoint(now, s.sumTimerWriteConcurrentInsert/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeWriteLockTypeConcurrentInsert)
  473. m.mb.RecordMysqlTableLockWaitWriteTimeDataPoint(now, s.sumTimerWriteLowPriority/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeWriteLockTypeLowPriority)
  474. m.mb.RecordMysqlTableLockWaitWriteTimeDataPoint(now, s.sumTimerWriteNormal/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeWriteLockTypeNormal)
  475. m.mb.RecordMysqlTableLockWaitWriteTimeDataPoint(now, s.sumTimerWriteExternal/picosecondsInNanoseconds, s.schema, s.name, metadata.AttributeWriteLockTypeExternal)
  476. }
  477. }
  478. func (m *mySQLScraper) scrapeReplicaStatusStats(now pcommon.Timestamp) {
  479. replicaStatusStats, err := m.sqlclient.getReplicaStatusStats()
  480. if err != nil {
  481. m.logger.Info("Failed to fetch replica status stats", zap.Error(err))
  482. return
  483. }
  484. for i := 0; i < len(replicaStatusStats); i++ {
  485. s := replicaStatusStats[i]
  486. val, _ := s.secondsBehindSource.Value()
  487. if val != nil {
  488. m.mb.RecordMysqlReplicaTimeBehindSourceDataPoint(now, val.(int64))
  489. }
  490. m.mb.RecordMysqlReplicaSQLDelayDataPoint(now, s.sqlDelay)
  491. }
  492. }
  493. func addPartialIfError(errors *scrapererror.ScrapeErrors, err error) {
  494. if err != nil {
  495. errors.AddPartial(1, err)
  496. }
  497. }
  498. func (m *mySQLScraper) recordDataPages(now pcommon.Timestamp, globalStats map[string]string, errors *scrapererror.ScrapeErrors) {
  499. dirty, err := parseInt(globalStats["Innodb_buffer_pool_pages_dirty"])
  500. if err != nil {
  501. errors.AddPartial(2, err) // we need dirty to calculate free, so 2 data points lost here
  502. return
  503. }
  504. m.mb.RecordMysqlBufferPoolDataPagesDataPoint(now, dirty, metadata.AttributeBufferPoolDataDirty)
  505. data, err := parseInt(globalStats["Innodb_buffer_pool_pages_data"])
  506. if err != nil {
  507. errors.AddPartial(1, err)
  508. return
  509. }
  510. m.mb.RecordMysqlBufferPoolDataPagesDataPoint(now, data-dirty, metadata.AttributeBufferPoolDataClean)
  511. }
  512. func (m *mySQLScraper) recordDataUsage(now pcommon.Timestamp, globalStats map[string]string, errors *scrapererror.ScrapeErrors) {
  513. dirty, err := parseInt(globalStats["Innodb_buffer_pool_bytes_dirty"])
  514. if err != nil {
  515. errors.AddPartial(2, err) // we need dirty to calculate free, so 2 data points lost here
  516. return
  517. }
  518. m.mb.RecordMysqlBufferPoolUsageDataPoint(now, dirty, metadata.AttributeBufferPoolDataDirty)
  519. data, err := parseInt(globalStats["Innodb_buffer_pool_bytes_data"])
  520. if err != nil {
  521. errors.AddPartial(1, err)
  522. return
  523. }
  524. m.mb.RecordMysqlBufferPoolUsageDataPoint(now, data-dirty, metadata.AttributeBufferPoolDataClean)
  525. }
  526. // parseInt converts string to int64.
  527. func parseInt(value string) (int64, error) {
  528. return strconv.ParseInt(value, 10, 64)
  529. }