@cryptotaxi247 / netdata-1 / commits / a78abaa19

Improve MSSQL (Part III) (#20230)

thiagoftsm committed May 13, 2025 at 22:29 UTC a78abaa1999b6d40e53dc60824881924235f39f3
2 files changed +288 -183
src/collectors/windows.plugin/metadata.yaml
+91 -8
@@ -1609,34 +1609,117 @@ modules:
1609 default_behavior:
1610 auto_detection:
1611 description: |
1612 - The collector automatically detects all of the metrics, no further configuration is required.
1612 + The collector automatically detects some metrics, but transaction metrics require configuration.
1613 limits:
1614 description: ""
1615 performance_impact:
1616 description: ""
1617 setup:
1618 prerequisites:
1619 - list: []
1619 + list:
1620 + - title: Create netdata user
1621 + description: |
1622 + Create an SQL Server user with the necessary permissions to collect monitoring data:
1623 +
1624 + ```tsql
1625 + USE master;
1626 + CREATE LOGIN netdata_user WITH PASSWORD = '1ReallyStrongPasswordShouldBeInsertedHere';
1627 + CREATE USER netdata_user FOR LOGIN netdata_user;
1628 + GRANT CONNECT SQL TO netdata_user;
1629 + GRANT VIEW SERVER STATE TO netdata_user;
1630 + GO
1631 + ```
1632 +
1633 + Additionally, enable the [Query Store](https://learn.microsoft.com/en-us/sql/relational-databases/performance/monitoring-performance-by-using-the-query-store?view=sql-server-ver16)
1634 + on each database you want to monitor:
1635 +
1636 + ```tsql
1637 + DECLARE @dbname NVARCHAR(max)
1638 + DECLARE nd_user_cursor CURSOR FOR SELECT name
1639 + FROM master.dbo.sysdatabases
1640 + WHERE name NOT IN ('master', 'tempdb')
1641 +
1642 + OPEN nd_user_cursor
1643 + FETCH NEXT FROM nd_user_cursor INTO @dbname
1644 + WHILE @@FETCH_STATUS = 0
1645 + BEGIN
1646 + EXECUTE ("USE "+ @dbname+"; CREATE USER netdata_user FOR LOGIN netdata_user; ALTER DATABASE "+@dbname+" SET QUERY_STORE = ON ( QUERY_CAPTURE_MODE = ALL, DATA_FLUSH_INTERVAL_SECONDS = 900 )");
1647 + FETCH next FROM nd_user_cursor INTO @dbname;
1648 + END
1649 + CLOSE nd_user_cursor
1650 + DEALLOCATE nd_user_cursor
1651 + GO
1652 + ```
1653 configuration:
1654 file:
1655 name: "netdata.conf"
1623 - section_name: "[plugin:windows]"
1656 + section_name: "[plugin:windows:PerflibMSSQL]"
1657 description: "The Netdata main configuration file"
1658 options:
1626 - description: ""
1659 + description: "These options allow the collector to connect to your MSSQL instance and collect transaction data from it."
1660 folding:
1661 title: "Config option"
1662 enabled: false
1663 list:
1631 - - name: PerflibMSSQL
1632 - description: An option to enable or disable the data collection.
1633 - default_value: yes
1664 + - name: driver
1665 + description: ODBC driver used to connect to the SQL Server.
1666 + default_value: SQL Server
1667 + required: false
1668 + - name: server
1669 + description: Server address or instance name.
1670 + default_value: empty
1671 + required: true
1672 + - name: address
1673 + description: Alternative to `server`; supports named pipes if the server supports them.
1674 + default_value: empty
1675 + required: true
1676 + - name: uid
1677 + description: SQL Server user identifier.
1678 + default_value: empty
1679 + required: true
1680 + - name: pwd
1681 + description: Password for the specified user.
1682 + default_value: empty
1683 + required: true
1684 + - name: additional instances
1685 + description: Number of additional SQL Server instances to monitor.
1686 + default_value: 0
1687 + required: false
1688 + - name: windows authentication
1689 + description: Set to yes to use Windows credentials instead of SQL Server authentication.
1690 + default_value: no
1691 required: false
1692 examples:
1693 folding:
1694 enabled: true
1695 title: ""
1639 - list: []
1696 + list:
1697 + - name: One Instance
1698 + description: An example configuration.
1699 + folding:
1700 + enabled: false
1701 + config: |
1702 + [plugin:windows:PerflibMSSQL]
1703 + driver = SQL Server
1704 + server = 127.0.0.1\\Dev, 1433
1705 + uid = netdata_user
1706 + pwd = 1ReallyStrongPasswordShouldBeInsertedHere
1707 + - name: Two Instances
1708 + description: An example configuration with two instances.
1709 + folding:
1710 + enabled: false
1711 + config: |
1712 + [plugin:windows:PerflibMSSQL]
1713 + driver = SQL Server
1714 + server = 127.0.0.1\\Dev, 1433
1715 + uid = netdata_user
1716 + pwd = 1ReallyStrongPasswordShouldBeInsertedHere
1717 + additional instances = 1
1718 + [plugin:windows:PerflibMSSQL1]
1719 + driver = SQL Server
1720 + server = 127.0.0.1\\Production, 1434
1721 + uid = netdata_user
1722 + pwd = AnotherReallyStrongPasswordShouldBeInsertedHere2
1723 troubleshooting:
1724 problems:
1725 list: []
src/collectors/windows.plugin/perflib-mssql.c
+197 -175
@@ -16,6 +16,7 @@
16 #define NETDATA_MSSQL_NEXT_TRY (60)
17
18 BOOL is_sqlexpress = FALSE;
19 +ND_THREAD *mssql_query_thread = NULL;
20
21 struct netdata_mssql_conn {
22 const char *driver;
@@ -319,8 +320,8 @@ static ULONGLONG netdata_MSSQL_fill_long_value(SQLHSTMT *stmt, const char *mask,
320
321 void dict_mssql_fill_transactions(struct mssql_db_instance *mdi, const char *dbname)
322 {
322 - char object_name[NETDATA_MAX_INSTANCE_OBJECT + 1];
323 - long value;
323 + char object_name[NETDATA_MAX_INSTANCE_OBJECT + 1] = {};
324 + long value = 0;
325 SQLLEN col_object_len = 0, col_value_len = 0;
326
327 SQLCHAR query[sizeof(NETDATA_QUERY_TRANSACTIONS_MASK) + 2 * NETDATA_MAX_INSTANCE_OBJECT + 1];
@@ -745,8 +746,6 @@ void dict_mssql_insert_locks_cb(const DICTIONARY_ITEM *item __maybe_unused, void
746 // https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-locks-object
747 struct mssql_lock_instance *ptr = value;
748 ptr->resourceID = strdupz(resource);
748 - ptr->deadLocks.key = "Number of Deadlocks/sec";
749 - ptr->lockWait.key = "Lock Waits/sec";
749 }
750
751 void dict_mssql_insert_databases_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
@@ -846,6 +845,7 @@ void dict_mssql_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *valu
845 {
846 struct mssql_instance *mi = value;
847 const char *instance = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
848 + bool *create_thread = data;
849
850 if (!mi->locks_instances) {
851 mi->locks_instances = dictionary_create_advanced(
@@ -863,8 +863,11 @@ void dict_mssql_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *valu
863 initialize_mssql_keys(mi);
864 netdata_read_config_options(&mi->conn);
865
866 - if (mi->conn.connectionString)
866 + if (mi->conn.connectionString) {
867 mi->conn.is_connected = netdata_MSSQL_initialize_conection(&mi->conn);
868 + if (mi->conn.is_connected)
869 + *create_thread = true;
870 + }
871 }
872
873 static int mssql_fill_dictionary()
@@ -913,17 +916,75 @@ endMSSQLFillDict:
916 return (ret == ERROR_SUCCESS) ? 0 : -1;
917 }
918
916 -static int initialize(void)
919 +int netdata_mssql_reset_value(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
920 +{
921 + struct mssql_db_instance *mdi = value;
922 +
923 + mdi->collecting_data = false;
924 +
925 + return 1;
926 +}
927 +
928 +int dict_mssql_query_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
929 +{
930 + struct mssql_instance *mi = value;
931 + static long have_perm = 1;
932 +
933 + if (mi->conn.is_connected && have_perm) {
934 + have_perm = metdata_mssql_check_permission(mi);
935 + if (!have_perm) {
936 + nd_log(
937 + NDLS_COLLECTORS,
938 + NDLP_ERR,
939 + "User %s does not have permission to run queries on %s",
940 + mi->conn.username,
941 + mi->instanceID);
942 + } else {
943 + metdata_mssql_fill_dictionary_from_db(mi);
944 + dictionary_sorted_walkthrough_read(mi->databases, dict_mssql_databases_run_queries, NULL);
945 + }
946 + } else {
947 + dictionary_sorted_walkthrough_read(mi->databases, netdata_mssql_reset_value, NULL);
948 + }
949 +
950 + return 1;
951 +}
952 +
953 +void *netdata_mssql_queries(void *ptr __maybe_unused)
954 +{
955 + heartbeat_t hb;
956 + int update_every = *((int *)ptr);
957 + heartbeat_init(&hb, update_every * USEC_PER_SEC);
958 +
959 + while (service_running(SERVICE_COLLECTORS)) {
960 + (void)heartbeat_next(&hb);
961 +
962 + if (unlikely(!service_running(SERVICE_COLLECTORS)))
963 + break;
964 +
965 + dictionary_sorted_walkthrough_read(mssql_instances, dict_mssql_query_cb, &update_every);
966 + }
967 +
968 + return NULL;
969 +}
970 +
971 +static int initialize(int update_every)
972 {
973 + static bool create_thread = false;
974 mssql_instances = dictionary_create_advanced(
975 DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct mssql_instance));
976
921 - dictionary_register_insert_callback(mssql_instances, dict_mssql_insert_cb, NULL);
977 + dictionary_register_insert_callback(mssql_instances, dict_mssql_insert_cb, &create_thread);
978
979 if (mssql_fill_dictionary()) {
980 return -1;
981 }
982
983 + if (create_thread)
984 + mssql_query_thread = nd_thread_create("mssql_queries",
985 + NETDATA_THREAD_OPTION_DEFAULT,
986 + netdata_mssql_queries, &update_every);
987 +
988 return 0;
989 }
990
@@ -1437,17 +1498,17 @@ static void do_mssql_locks(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *m
1498 rrdset_done(mi->st_deadLocks);
1499 }
1500
1440 -static void mssql_database_backup_restore_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1501 +static void mssql_database_backup_restore_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1502 {
1442 - if (unlikely(!mli->parent->conn.is_connected))
1503 + if (unlikely(!mdi->parent->conn.is_connected))
1504 return;
1505
1506 char id[RRD_ID_LENGTH_MAX + 1];
1507
1447 - if (!mli->st_db_backup_restore_operations) {
1448 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_backup_restore_operations", db, mli->parent->instanceID);
1508 + if (!mdi->st_db_backup_restore_operations) {
1509 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_backup_restore_operations", db, mdi->parent->instanceID);
1510 netdata_fix_chart_name(id);
1450 - mli->st_db_backup_restore_operations = rrdset_create_localhost(
1511 + mdi->st_db_backup_restore_operations = rrdset_create_localhost(
1512 "mssql",
1513 id,
1514 NULL,
@@ -1462,37 +1523,35 @@ static void mssql_database_backup_restore_chart(struct mssql_db_instance *mli, c
1523 RRDSET_TYPE_LINE);
1524
1525 rrdlabels_add(
1465 - mli->st_db_backup_restore_operations->rrdlabels,
1526 + mdi->st_db_backup_restore_operations->rrdlabels,
1527 "mssql_instance",
1467 - mli->parent->instanceID,
1528 + mdi->parent->instanceID,
1529 RRDLABEL_SRC_AUTO);
1469 - rrdlabels_add(mli->st_db_backup_restore_operations->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1470 - }
1530 + rrdlabels_add(mdi->st_db_backup_restore_operations->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1531
1472 - if (!mli->rd_db_backup_restore_operations) {
1473 - mli->rd_db_backup_restore_operations =
1474 - rrddim_add(mli->st_db_backup_restore_operations, "backup", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1532 + mdi->rd_db_backup_restore_operations =
1533 + rrddim_add(mdi->st_db_backup_restore_operations, "backup", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1534 }
1535
1536 rrddim_set_by_pointer(
1478 - mli->st_db_backup_restore_operations,
1479 - mli->rd_db_backup_restore_operations,
1480 - (collected_number)mli->MSSQLDatabaseBackupRestoreOperations.current.Data);
1537 + mdi->st_db_backup_restore_operations,
1538 + mdi->rd_db_backup_restore_operations,
1539 + (collected_number)mdi->MSSQLDatabaseBackupRestoreOperations.current.Data);
1540
1482 - rrdset_done(mli->st_db_backup_restore_operations);
1541 + rrdset_done(mdi->st_db_backup_restore_operations);
1542 }
1543
1485 -static void mssql_database_log_flushes_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1544 +static void mssql_database_log_flushes_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1545 {
1487 - if (unlikely(!mli->parent->conn.is_connected))
1546 + if (unlikely(!mdi->parent->conn.is_connected))
1547 return;
1548
1549 char id[RRD_ID_LENGTH_MAX + 1];
1550
1492 - if (!mli->st_db_log_flushes) {
1493 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_log_flushes", db, mli->parent->instanceID);
1551 + if (!mdi->st_db_log_flushes) {
1552 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_log_flushes", db, mdi->parent->instanceID);
1553 netdata_fix_chart_name(id);
1495 - mli->st_db_log_flushes = rrdset_create_localhost(
1554 + mdi->st_db_log_flushes = rrdset_create_localhost(
1555 "mssql",
1556 id,
1557 NULL,
@@ -1506,31 +1565,31 @@ static void mssql_database_log_flushes_chart(struct mssql_db_instance *mli, cons
1565 update_every,
1566 RRDSET_TYPE_LINE);
1567
1509 - rrdlabels_add(mli->st_db_log_flushes->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1510 - rrdlabels_add(mli->st_db_log_flushes->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1568 + rrdlabels_add(mdi->st_db_log_flushes->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1569 + rrdlabels_add(mdi->st_db_log_flushes->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1570 }
1571
1513 - if (!mli->rd_db_log_flushes) {
1514 - mli->rd_db_log_flushes = rrddim_add(mli->st_db_log_flushes, "flushes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1572 + if (!mdi->rd_db_log_flushes) {
1573 + mdi->rd_db_log_flushes = rrddim_add(mdi->st_db_log_flushes, "flushes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1574 }
1575
1576 rrddim_set_by_pointer(
1518 - mli->st_db_log_flushes, mli->rd_db_log_flushes, (collected_number)mli->MSSQLDatabaseLogFlushes.current.Data);
1577 + mdi->st_db_log_flushes, mdi->rd_db_log_flushes, (collected_number)mdi->MSSQLDatabaseLogFlushes.current.Data);
1578
1520 - rrdset_done(mli->st_db_log_flushes);
1579 + rrdset_done(mdi->st_db_log_flushes);
1580 }
1581
1523 -static void mssql_database_log_flushed_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1582 +static void mssql_database_log_flushed_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1583 {
1525 - if (unlikely(!mli->parent->conn.is_connected))
1584 + if (unlikely(!mdi->parent->conn.is_connected))
1585 return;
1586
1587 char id[RRD_ID_LENGTH_MAX + 1];
1588
1530 - if (!mli->st_db_log_flushed) {
1531 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_log_flushed", db, mli->parent->instanceID);
1589 + if (!mdi->st_db_log_flushed) {
1590 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_log_flushed", db, mdi->parent->instanceID);
1591 netdata_fix_chart_name(id);
1533 - mli->st_db_log_flushed = rrdset_create_localhost(
1592 + mdi->st_db_log_flushed = rrdset_create_localhost(
1593 "mssql",
1594 id,
1595 NULL,
@@ -1544,31 +1603,29 @@ static void mssql_database_log_flushed_chart(struct mssql_db_instance *mli, cons
1603 update_every,
1604 RRDSET_TYPE_LINE);
1605
1547 - rrdlabels_add(mli->st_db_log_flushed->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1548 - rrdlabels_add(mli->st_db_log_flushed->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1549 - }
1606 + rrdlabels_add(mdi->st_db_log_flushed->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1607 + rrdlabels_add(mdi->st_db_log_flushed->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1608
1551 - if (!mli->rd_db_log_flushed) {
1552 - mli->rd_db_log_flushed = rrddim_add(mli->st_db_log_flushed, "flushed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1609 + mdi->rd_db_log_flushed = rrddim_add(mdi->st_db_log_flushed, "flushed", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1610 }
1611
1612 rrddim_set_by_pointer(
1556 - mli->st_db_log_flushed, mli->rd_db_log_flushed, (collected_number)mli->MSSQLDatabaseLogFlushed.current.Data);
1613 + mdi->st_db_log_flushed, mdi->rd_db_log_flushed, (collected_number)mdi->MSSQLDatabaseLogFlushed.current.Data);
1614
1558 - rrdset_done(mli->st_db_log_flushed);
1615 + rrdset_done(mdi->st_db_log_flushed);
1616 }
1617
1561 -static void mssql_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1618 +static void mssql_transactions_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1619 {
1563 - if (unlikely(!mli->parent->conn.is_connected))
1620 + if (unlikely(!mdi->parent->conn.is_connected))
1621 return;
1622
1623 char id[RRD_ID_LENGTH_MAX + 1];
1624
1568 - if (!mli->st_db_transactions) {
1569 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_transactions", db, mli->parent->instanceID);
1625 + if (!mdi->st_db_transactions) {
1626 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_transactions", db, mdi->parent->instanceID);
1627 netdata_fix_chart_name(id);
1571 - mli->st_db_transactions = rrdset_create_localhost(
1628 + mdi->st_db_transactions = rrdset_create_localhost(
1629 "mssql",
1630 id,
1631 NULL,
@@ -1582,34 +1639,32 @@ static void mssql_transactions_chart(struct mssql_db_instance *mli, const char *
1639 update_every,
1640 RRDSET_TYPE_LINE);
1641
1585 - rrdlabels_add(mli->st_db_transactions->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1586 - rrdlabels_add(mli->st_db_transactions->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1587 - }
1642 + rrdlabels_add(mdi->st_db_transactions->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1643 + rrdlabels_add(mdi->st_db_transactions->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1644
1589 - if (!mli->rd_db_transactions) {
1590 - mli->rd_db_transactions =
1591 - rrddim_add(mli->st_db_transactions, "transactions", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1645 + mdi->rd_db_transactions =
1646 + rrddim_add(mdi->st_db_transactions, "transactions", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1647 }
1648
1649 rrddim_set_by_pointer(
1595 - mli->st_db_transactions,
1596 - mli->rd_db_transactions,
1597 - (collected_number)mli->MSSQLDatabaseTransactions.current.Data);
1650 + mdi->st_db_transactions,
1651 + mdi->rd_db_transactions,
1652 + (collected_number)mdi->MSSQLDatabaseTransactions.current.Data);
1653
1599 - rrdset_done(mli->st_db_transactions);
1654 + rrdset_done(mdi->st_db_transactions);
1655 }
1656
1602 -static void mssql_write_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1657 +static void mssql_write_transactions_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1658 {
1604 - if (unlikely(!mli->parent->conn.is_connected))
1659 + if (unlikely(!mdi->parent->conn.is_connected))
1660 return;
1661
1662 char id[RRD_ID_LENGTH_MAX + 1];
1663
1609 - if (!mli->st_db_write_transactions) {
1610 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_write_transactions", db, mli->parent->instanceID);
1664 + if (!mdi->st_db_write_transactions) {
1665 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_write_transactions", db, mdi->parent->instanceID);
1666 netdata_fix_chart_name(id);
1612 - mli->st_db_write_transactions = rrdset_create_localhost(
1667 + mdi->st_db_write_transactions = rrdset_create_localhost(
1668 "mssql",
1669 id,
1670 NULL,
@@ -1624,34 +1679,32 @@ static void mssql_write_transactions_chart(struct mssql_db_instance *mli, const
1679 RRDSET_TYPE_LINE);
1680
1681 rrdlabels_add(
1627 - mli->st_db_write_transactions->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1628 - rrdlabels_add(mli->st_db_write_transactions->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1629 - }
1682 + mdi->st_db_write_transactions->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1683 + rrdlabels_add(mdi->st_db_write_transactions->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1684
1631 - if (!mli->rd_db_write_transactions) {
1632 - mli->rd_db_write_transactions =
1633 - rrddim_add(mli->st_db_write_transactions, "write", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1685 + mdi->rd_db_write_transactions =
1686 + rrddim_add(mdi->st_db_write_transactions, "write", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1687 }
1688
1689 rrddim_set_by_pointer(
1637 - mli->st_db_write_transactions,
1638 - mli->rd_db_write_transactions,
1639 - (collected_number)mli->MSSQLDatabaseWriteTransactions.current.Data);
1690 + mdi->st_db_write_transactions,
1691 + mdi->rd_db_write_transactions,
1692 + (collected_number)mdi->MSSQLDatabaseWriteTransactions.current.Data);
1693
1641 - rrdset_done(mli->st_db_write_transactions);
1694 + rrdset_done(mdi->st_db_write_transactions);
1695 }
1696
1644 -static void mssql_lockwait_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1697 +static void mssql_lockwait_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1698 {
1646 - if (unlikely(!mli->parent->conn.is_connected))
1699 + if (unlikely(!mdi->parent->conn.is_connected))
1700 return;
1701
1702 char id[RRD_ID_LENGTH_MAX + 1];
1703
1651 - if (!mli->st_db_lockwait) {
1652 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_lockwait", db, mli->parent->instanceID);
1704 + if (!mdi->st_db_lockwait) {
1705 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_lockwait", db, mdi->parent->instanceID);
1706 netdata_fix_chart_name(id);
1654 - mli->st_db_lockwait = rrdset_create_localhost(
1707 + mdi->st_db_lockwait = rrdset_create_localhost(
1708 "mssql",
1709 id,
1710 NULL,
@@ -1665,29 +1718,29 @@ static void mssql_lockwait_chart(struct mssql_db_instance *mli, const char *db,
1718 update_every,
1719 RRDSET_TYPE_LINE);
1720
1668 - rrdlabels_add(mli->st_db_lockwait->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1669 - rrdlabels_add(mli->st_db_lockwait->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1721 + rrdlabels_add(mdi->st_db_lockwait->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1722 + rrdlabels_add(mdi->st_db_lockwait->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1723
1671 - mli->rd_db_lockwait = rrddim_add(mli->st_db_lockwait, "lock", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1724 + mdi->rd_db_lockwait = rrddim_add(mdi->st_db_lockwait, "lock", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1725 }
1726
1727 rrddim_set_by_pointer(
1675 - mli->st_db_lockwait, mli->rd_db_lockwait, (collected_number)mli->MSSQLDatabaseLockWaitSec.current.Data);
1728 + mdi->st_db_lockwait, mdi->rd_db_lockwait, (collected_number)mdi->MSSQLDatabaseLockWaitSec.current.Data);
1729
1677 - rrdset_done(mli->st_db_lockwait);
1730 + rrdset_done(mdi->st_db_lockwait);
1731 }
1732
1680 -static void mssql_deadlock_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1733 +static void mssql_deadlock_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1734 {
1682 - if (unlikely(!mli->parent->conn.is_connected))
1735 + if (unlikely(!mdi->parent->conn.is_connected))
1736 return;
1737
1738 char id[RRD_ID_LENGTH_MAX + 1];
1739
1687 - if (!mli->st_db_deadlock) {
1688 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_deadlocks", db, mli->parent->instanceID);
1740 + if (!mdi->st_db_deadlock) {
1741 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_deadlocks", db, mdi->parent->instanceID);
1742 netdata_fix_chart_name(id);
1690 - mli->st_db_deadlock = rrdset_create_localhost(
1743 + mdi->st_db_deadlock = rrdset_create_localhost(
1744 "mssql",
1745 id,
1746 NULL,
@@ -1701,29 +1754,29 @@ static void mssql_deadlock_chart(struct mssql_db_instance *mli, const char *db,
1754 update_every,
1755 RRDSET_TYPE_LINE);
1756
1704 - rrdlabels_add(mli->st_db_deadlock->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1705 - rrdlabels_add(mli->st_db_deadlock->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1757 + rrdlabels_add(mdi->st_db_deadlock->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1758 + rrdlabels_add(mdi->st_db_deadlock->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1759
1707 - mli->rd_db_deadlock = rrddim_add(mli->st_db_deadlock, "deadlocks", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1760 + mdi->rd_db_deadlock = rrddim_add(mdi->st_db_deadlock, "deadlocks", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1761 }
1762
1763 rrddim_set_by_pointer(
1711 - mli->st_db_deadlock, mli->rd_db_deadlock, (collected_number)mli->MSSQLDatabaseDeadLockSec.current.Data);
1764 + mdi->st_db_deadlock, mdi->rd_db_deadlock, (collected_number)mdi->MSSQLDatabaseDeadLockSec.current.Data);
1765
1713 - rrdset_done(mli->st_db_deadlock);
1766 + rrdset_done(mdi->st_db_deadlock);
1767 }
1768
1716 -static void mssql_lock_request_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1769 +static void mssql_lock_request_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1770 {
1718 - if (unlikely(!mli->parent->conn.is_connected))
1771 + if (unlikely(!mdi->parent->conn.is_connected))
1772 return;
1773
1774 char id[RRD_ID_LENGTH_MAX + 1];
1775
1723 - if (!mli->st_lock_requests) {
1724 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_lock_requests", db, mli->parent->instanceID);
1776 + if (!mdi->st_lock_requests) {
1777 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_lock_requests", db, mdi->parent->instanceID);
1778 netdata_fix_chart_name(id);
1726 - mli->st_lock_requests = rrdset_create_localhost(
1779 + mdi->st_lock_requests = rrdset_create_localhost(
1780 "mssql",
1781 id,
1782 NULL,
@@ -1737,29 +1790,29 @@ static void mssql_lock_request_chart(struct mssql_db_instance *mli, const char *
1790 update_every,
1791 RRDSET_TYPE_LINE);
1792
1740 - rrdlabels_add(mli->st_lock_requests->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1741 - rrdlabels_add(mli->st_lock_requests->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1793 + rrdlabels_add(mdi->st_lock_requests->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1794 + rrdlabels_add(mdi->st_lock_requests->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1795
1743 - mli->rd_lock_requests = rrddim_add(mli->st_lock_requests, "requests", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1796 + mdi->rd_lock_requests = rrddim_add(mdi->st_lock_requests, "requests", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1797 }
1798
1799 rrddim_set_by_pointer(
1747 - mli->st_lock_requests, mli->rd_lock_requests, (collected_number)mli->MSSQLDatabaseLockRequestsSec.current.Data);
1800 + mdi->st_lock_requests, mdi->rd_lock_requests, (collected_number)mdi->MSSQLDatabaseLockRequestsSec.current.Data);
1801
1749 - rrdset_done(mli->st_lock_requests);
1802 + rrdset_done(mdi->st_lock_requests);
1803 }
1804
1752 -static void mssql_lock_timeout_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1805 +static void mssql_lock_timeout_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1806 {
1754 - if (unlikely(!mli->parent->conn.is_connected))
1807 + if (unlikely(!mdi->parent->conn.is_connected))
1808 return;
1809
1810 char id[RRD_ID_LENGTH_MAX + 1];
1811
1759 - if (!mli->st_lock_timeouts) {
1760 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_lock_timeouts", db, mli->parent->instanceID);
1812 + if (!mdi->st_lock_timeouts) {
1813 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_lock_timeouts", db, mdi->parent->instanceID);
1814 netdata_fix_chart_name(id);
1762 - mli->st_lock_timeouts = rrdset_create_localhost(
1815 + mdi->st_lock_timeouts = rrdset_create_localhost(
1816 "mssql",
1817 id,
1818 NULL,
@@ -1773,29 +1826,29 @@ static void mssql_lock_timeout_chart(struct mssql_db_instance *mli, const char *
1826 update_every,
1827 RRDSET_TYPE_LINE);
1828
1776 - rrdlabels_add(mli->st_lock_timeouts->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1777 - rrdlabels_add(mli->st_lock_timeouts->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1829 + rrdlabels_add(mdi->st_lock_timeouts->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1830 + rrdlabels_add(mdi->st_lock_timeouts->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1831
1779 - mli->rd_lock_timeouts = rrddim_add(mli->st_lock_timeouts, "timeouts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1832 + mdi->rd_lock_timeouts = rrddim_add(mdi->st_lock_timeouts, "timeouts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1833 }
1834
1835 rrddim_set_by_pointer(
1783 - mli->st_lock_timeouts, mli->rd_lock_timeouts, (collected_number)mli->MSSQLDatabaseLockTimeoutsSec.current.Data);
1836 + mdi->st_lock_timeouts, mdi->rd_lock_timeouts, (collected_number)mdi->MSSQLDatabaseLockTimeoutsSec.current.Data);
1837
1785 - rrdset_done(mli->st_lock_timeouts);
1838 + rrdset_done(mdi->st_lock_timeouts);
1839 }
1840
1788 -static void mssql_active_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1841 +static void mssql_active_transactions_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1842 {
1790 - if (unlikely(!mli->parent->conn.is_connected))
1843 + if (unlikely(!mdi->parent->conn.is_connected))
1844 return;
1845
1846 char id[RRD_ID_LENGTH_MAX + 1];
1847
1795 - if (!mli->st_db_active_transactions) {
1796 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_active_transactions", db, mli->parent->instanceID);
1848 + if (!mdi->st_db_active_transactions) {
1849 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_active_transactions", db, mdi->parent->instanceID);
1850 netdata_fix_chart_name(id);
1798 - mli->st_db_active_transactions = rrdset_create_localhost(
1851 + mdi->st_db_active_transactions = rrdset_create_localhost(
1852 "mssql",
1853 id,
1854 NULL,
@@ -1810,34 +1863,32 @@ static void mssql_active_transactions_chart(struct mssql_db_instance *mli, const
1863 RRDSET_TYPE_LINE);
1864
1865 rrdlabels_add(
1813 - mli->st_db_active_transactions->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1814 - rrdlabels_add(mli->st_db_active_transactions->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1815 - }
1866 + mdi->st_db_active_transactions->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1867 + rrdlabels_add(mdi->st_db_active_transactions->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1868
1817 - if (!mli->rd_db_active_transactions) {
1818 - mli->rd_db_active_transactions =
1819 - rrddim_add(mli->st_db_active_transactions, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1869 + mdi->rd_db_active_transactions =
1870 + rrddim_add(mdi->st_db_active_transactions, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1871 }
1872
1873 rrddim_set_by_pointer(
1823 - mli->st_db_active_transactions,
1824 - mli->rd_db_active_transactions,
1825 - (collected_number)mli->MSSQLDatabaseActiveTransactions.current.Data);
1874 + mdi->st_db_active_transactions,
1875 + mdi->rd_db_active_transactions,
1876 + (collected_number)mdi->MSSQLDatabaseActiveTransactions.current.Data);
1877
1827 - rrdset_done(mli->st_db_active_transactions);
1878 + rrdset_done(mdi->st_db_active_transactions);
1879 }
1880
1830 -static inline void mssql_data_file_size_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1881 +static inline void mssql_data_file_size_chart(struct mssql_db_instance *mdi, const char *db, int update_every)
1882 {
1832 - if (unlikely(!mli->parent->conn.is_connected))
1883 + if (unlikely(!mdi->parent->conn.is_connected))
1884 return;
1885
1886 char id[RRD_ID_LENGTH_MAX + 1];
1887
1837 - if (unlikely(!mli->st_db_data_file_size)) {
1838 - snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_data_files_size", db, mli->parent->instanceID);
1888 + if (unlikely(!mdi->st_db_data_file_size)) {
1889 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_data_files_size", db, mdi->parent->instanceID);
1890 netdata_fix_chart_name(id);
1840 - mli->st_db_data_file_size = rrdset_create_localhost(
1891 + mdi->st_db_data_file_size = rrdset_create_localhost(
1892 "mssql",
1893 id,
1894 NULL,
@@ -1852,26 +1903,24 @@ static inline void mssql_data_file_size_chart(struct mssql_db_instance *mli, con
1903 RRDSET_TYPE_LINE);
1904
1905 rrdlabels_add(
1855 - mli->st_db_data_file_size->rrdlabels, "mssql_instance", mli->parent->instanceID, RRDLABEL_SRC_AUTO);
1856 - rrdlabels_add(mli->st_db_data_file_size->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1857 - }
1906 + mdi->st_db_data_file_size->rrdlabels, "mssql_instance", mdi->parent->instanceID, RRDLABEL_SRC_AUTO);
1907 + rrdlabels_add(mdi->st_db_data_file_size->rrdlabels, "database", db, RRDLABEL_SRC_AUTO);
1908
1859 - if (unlikely(!mli->rd_db_data_file_size)) {
1860 - mli->rd_db_data_file_size = rrddim_add(mli->st_db_data_file_size, "size", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1909 + mdi->rd_db_data_file_size = rrddim_add(mdi->st_db_data_file_size, "size", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1910 }
1911
1863 - collected_number data = mli->MSSQLDatabaseDataFileSize.current.Data;
1864 - rrddim_set_by_pointer(mli->st_db_data_file_size, mli->rd_db_data_file_size, data);
1912 + collected_number data = mdi->MSSQLDatabaseDataFileSize.current.Data;
1913 + rrddim_set_by_pointer(mdi->st_db_data_file_size, mdi->rd_db_data_file_size, data);
1914
1866 - rrdset_done(mli->st_db_data_file_size);
1915 + rrdset_done(mdi->st_db_data_file_size);
1916 }
1917
1918 int dict_mssql_databases_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
1919 {
1871 - struct mssql_db_instance *mli = value;
1920 + struct mssql_db_instance *mdi = value;
1921 const char *db = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
1922
1874 - if (!mli->collecting_data) {
1923 + if (!mdi->collecting_data) {
1924 goto endchartcb;
1925 }
1926
@@ -1895,7 +1944,7 @@ int dict_mssql_databases_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, v
1944
1945 int i;
1946 for (i = 0; transaction_chart[i]; i++) {
1898 - transaction_chart[i](mli, db, *update_every);
1947 + transaction_chart[i](mdi, db, *update_every);
1948 }
1949
1950 endchartcb:
@@ -2064,38 +2113,11 @@ static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instan
2113 }
2114 }
2115
2067 -int netdata_mssql_reset_value(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
2068 -{
2069 - struct mssql_db_instance *mdi = value;
2070 -
2071 - mdi->collecting_data = false;
2072 -
2073 - return 1;
2074 -}
2075 -
2116 int dict_mssql_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
2117 {
2118 struct mssql_instance *mi = value;
2079 - static long have_perm = 1;
2119 int *update_every = data;
2120
2082 - if (mi->conn.is_connected && have_perm) {
2083 - have_perm = metdata_mssql_check_permission(mi);
2084 - if (!have_perm) {
2085 - nd_log(
2086 - NDLS_COLLECTORS,
2087 - NDLP_ERR,
2088 - "User %s does not have permission to run queries on %s",
2089 - mi->conn.username,
2090 - mi->instanceID);
2091 - } else {
2092 - metdata_mssql_fill_dictionary_from_db(mi);
2093 - dictionary_sorted_walkthrough_read(mi->databases, dict_mssql_databases_run_queries, NULL);
2094 - }
2095 - } else {
2096 - dictionary_sorted_walkthrough_read(mi->databases, netdata_mssql_reset_value, NULL);
2097 - }
2098 -
2121 static void (*doMSSQL[])(PERF_DATA_BLOCK *, struct mssql_instance *, int) = {
2122 do_mssql_general_stats,
2123 do_mssql_errors,
@@ -2132,7 +2154,7 @@ int do_PerflibMSSQL(int update_every, usec_t dt __maybe_unused)
2154 static bool initialized = false;
2155
2156 if (unlikely(!initialized)) {
2135 - if (initialize())
2157 + if (initialize(update_every))
2158 return -1;
2159
2160 initialized = true;