@cryptotaxi247 / netdata-1 / commits / 30b532952

MSSQL Metrics (Part II). (#18689)

thiagoftsm committed Oct 9, 2024 at 15:16 UTC 30b532952ac89db2bae650baedce153ff7dcffc4
2 files changed +754 -26
src/collectors/windows.plugin/perflib-mssql.c
+737 -26
@@ -15,7 +15,6 @@ enum netdata_mssql_metrics {
15 NETDATA_MSSQL_MEMORY,
16 NETDATA_MSSQL_BUFFER_MANAGEMENT,
17 NETDATA_MSSQL_SQL_STATS,
18 - NETDATA_MSSQL_TRANSACTIONS,
18 NETDATA_MSSQL_ACCESS_METHODS,
19
20 NETDATA_MSSQL_METRICS_END
@@ -66,6 +65,30 @@ struct mssql_instance {
65 RRDSET *st_sql_errors;
66 RRDDIM *rd_sql_errors;
67
68 + RRDSET *st_lockWait;
69 + RRDSET *st_deadLocks;
70 + DICTIONARY *locks_instances;
71 +
72 + RRDSET *st_db_data_file_size;
73 + RRDSET *st_db_active_transactions;
74 + RRDSET *st_db_backup_restore_operations;
75 + RRDSET *st_db_log_flushed;
76 + RRDSET *st_db_log_flushes;
77 + RRDSET *st_db_transactions;
78 + RRDSET *st_db_write_transactions;
79 + DICTIONARY *databases;
80 +
81 + RRDSET *st_conn_memory;
82 + RRDDIM *rd_conn_memory;
83 +
84 + RRDSET *st_ext_benefit_mem;
85 + RRDDIM *rd_ext_benefit_mem;
86 +
87 + RRDSET *st_pending_mem_grant;
88 + RRDDIM *rd_pending_mem_grant;
89 +
90 + RRDSET *st_mem_tot_server;
91 + RRDDIM *rd_mem_tot_server;
92
93 COUNTER_DATA MSSQLAccessMethodPageSplits;
94 COUNTER_DATA MSSQLBufferCacheHits;
@@ -75,8 +98,6 @@ struct mssql_instance {
98 COUNTER_DATA MSSQLBufferPageWrites;
99 COUNTER_DATA MSSQLBlockedProcesses;
100 COUNTER_DATA MSSQLUserConnections;
78 - COUNTER_DATA MSSQLLockWait;
79 - COUNTER_DATA MSSQLDeadlocks;
101 COUNTER_DATA MSSQLConnectionMemoryBytes;
102 COUNTER_DATA MSSQLExternalBenefitOfMemory;
103 COUNTER_DATA MSSQLPendingMemoryGrants;
@@ -87,6 +108,20 @@ struct mssql_instance {
108 COUNTER_DATA MSSQLStatSafeAutoParameterization;
109 COUNTER_DATA MSSQLCompilations;
110 COUNTER_DATA MSSQLRecompilations;
111 +};
112 +
113 +struct mssql_lock_instance {
114 + struct mssql_instance *parent;
115 +
116 + COUNTER_DATA lockWait;
117 + COUNTER_DATA deadLocks;
118 +
119 + RRDDIM *rd_lockWait;
120 + RRDDIM *rd_deadLocks;
121 +};
122 +
123 +struct mssql_db_instance {
124 + struct mssql_instance *parent;
125
126 COUNTER_DATA MSSQLDatabaseActiveTransactions;
127 COUNTER_DATA MSSQLDatabaseBackupRestoreOperations;
@@ -95,6 +130,14 @@ struct mssql_instance {
130 COUNTER_DATA MSSQLDatabaseLogFlushes;
131 COUNTER_DATA MSSQLDatabaseTransactions;
132 COUNTER_DATA MSSQLDatabaseWriteTransactions;
133 +
134 + RRDDIM *rd_db_data_file_size;
135 + RRDDIM *rd_db_active_transactions;
136 + RRDDIM *rd_db_backup_restore_operations;
137 + RRDDIM *rd_db_log_flushed;
138 + RRDDIM *rd_db_log_flushes;
139 + RRDDIM *rd_db_transactions;
140 + RRDDIM *rd_db_write_transactions;
141 };
142
143 static DICTIONARY *mssql_instances = NULL;
@@ -118,9 +161,6 @@ static void initialize_mssql_objects(struct mssql_instance *p, const char *insta
161 strncpyz(&name[length], "Databases", sizeof(name) - length);
162 p->objectName[NETDATA_MSSQL_DATABASE] = strdup(name);
163
121 - strncpyz(&name[length], "Transactions", sizeof(name) - length);
122 - p->objectName[NETDATA_MSSQL_TRANSACTIONS] = strdup(name);
123 -
164 strncpyz(&name[length], "SQL Statistics", sizeof(name) - length);
165 p->objectName[NETDATA_MSSQL_SQL_STATS] = strdup(name);
166
@@ -165,28 +205,49 @@ static inline void initialize_mssql_keys(struct mssql_instance *p) {
205 // Errors
206 p->MSSQLSQLErrorsTotal.key = "Errors/sec";
207
168 - /*
169 - p->MSSQLLockWait.key = "";
170 - p->MSSQLDeadlocks.key = "";
171 - p->MSSQLConnectionMemoryBytes.key = "";
172 - p->MSSQLExternalBenefitOfMemory.key = "";
173 - p->MSSQLPendingMemoryGrants.key = "";
174 - p->MSSQLTotalServerMemory.key = "";
175 -
176 - p->MSSQLDatabaseActiveTransactions.key = "";
177 - p->MSSQLDatabaseBackupRestoreOperations.key = "";
178 - p->MSSQLDatabaseDataFileSize.key = "";
179 - p->MSSQLDatabaseLogFlushed.key = "";
180 - p->MSSQLDatabaseLogFlushes.key = "";
181 - p->MSSQLDatabaseTransactions.key = "";
182 - p->MSSQLDatabaseWriteTransactions.key = "";
183 - */
208 + p->MSSQLConnectionMemoryBytes.key = "Connection Memory (KB)";
209 + p->MSSQLExternalBenefitOfMemory.key = "External benefit of memory";
210 + p->MSSQLPendingMemoryGrants.key = "Memory Grants Pending";
211 + p->MSSQLTotalServerMemory.key = "Total Server Memory (KB)";
212 +}
213 +
214 +void dict_mssql_insert_locks_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
215 + struct mssql_lock_instance *ptr = value;
216 + ptr->deadLocks.key = "Number of Deadlocks/sec";
217 + ptr->lockWait.key = "Lock Waits/sec";
218 +}
219 +
220 +void dict_mssql_insert_databases_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
221 + struct mssql_db_instance *ptr = value;
222 +
223 + ptr->MSSQLDatabaseDataFileSize.key = "Data File(s) Size (KB)";
224 +
225 + ptr->MSSQLDatabaseActiveTransactions.key = "Active Transactions";
226 + ptr->MSSQLDatabaseBackupRestoreOperations.key = "Backup/Restore Throughput/sec";
227 + ptr->MSSQLDatabaseLogFlushed.key = "Log Bytes Flushed/sec";
228 + ptr->MSSQLDatabaseLogFlushes.key = "Log Flushes/sec";
229 + ptr->MSSQLDatabaseTransactions.key = "Transactions/sec";
230 + ptr->MSSQLDatabaseWriteTransactions.key = "Write Transactions/sec";
231 }
232
233 void dict_mssql_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
234 struct mssql_instance *p = value;
235 const char *instance = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
236
237 + if (!p->locks_instances) {
238 + p->locks_instances = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
239 + DICT_OPTION_FIXED_SIZE,
240 + NULL, sizeof(struct mssql_lock_instance));
241 + dictionary_register_insert_callback(p->locks_instances, dict_mssql_insert_locks_cb, NULL);
242 + }
243 +
244 + if (!p->databases) {
245 + p->databases = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
246 + DICT_OPTION_FIXED_SIZE,
247 + NULL, sizeof(struct mssql_db_instance));
248 + dictionary_register_insert_callback(p->databases, dict_mssql_insert_databases_cb, NULL);
249 + }
250 +
251 initialize_mssql_objects(p, instance);
252 initialize_mssql_keys(p);
253 }
@@ -554,7 +615,7 @@ static void do_mssql_buffer_management(PERF_DATA_BLOCK *pDataBlock, struct mssql
615 snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_bufman_checkpoint_pages", p->instanceID);
616 p->rd_buff_checkpoint_pages = rrddim_add(p->st_buff_checkpoint_pages,
617 id,
557 - "flushed",
618 + "log",
619 1,
620 1,
621 RRD_ALGORITHM_INCREMENTAL);
@@ -703,7 +764,7 @@ static void do_mssql_errors(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *
764 , id, NULL
765 , "Errors"
766 , "mssql.instance_sql_errors"
706 - , "Errors"
767 + , "errors"
768 , "errors/s"
769 , PLUGIN_WINDOWS_NAME
770 , "PerflibMSSQL"
@@ -730,6 +791,655 @@ static void do_mssql_errors(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *
791 }
792 }
793
794 +int dict_mssql_locks_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
795 + char id[RRD_ID_LENGTH_MAX + 1];
796 + struct mssql_lock_instance *mli = value;
797 + const char *instance = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
798 +
799 + int *update_every = data;
800 +
801 + if (!mli->parent->st_lockWait) {
802 + snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_locks_lock_wait", mli->parent->instanceID);
803 + mli->parent->st_lockWait = rrdset_create_localhost("mssql"
804 + , id, NULL
805 + , "locks"
806 + , "mssql.instance_locks_lock_wait"
807 + , "Lock requests that required the caller to wait."
808 + , "locks/s"
809 + , PLUGIN_WINDOWS_NAME
810 + , "PerflibMSSQL"
811 + , PRIO_MSSQL_LOCKS_WAIT
812 + , *update_every
813 + , RRDSET_TYPE_LINE
814 + );
815 +
816 + rrdlabels_add(mli->parent->st_lockWait->rrdlabels, "mssql_instance", instance, RRDLABEL_SRC_AUTO);
817 + }
818 +
819 + if (!mli->rd_lockWait) {
820 + snprintfz(id,
821 + RRD_ID_LENGTH_MAX,
822 + "mssql_instance_%s_resource_%s_locks_lock_wait_seconds",
823 + mli->parent->instanceID,
824 + instance);
825 +
826 + mli->rd_lockWait = rrddim_add(mli->parent->st_lockWait,
827 + id,
828 + instance,
829 + 1,
830 + 1,
831 + RRD_ALGORITHM_INCREMENTAL);
832 + }
833 +
834 + rrddim_set_by_pointer(mli->parent->st_lockWait,
835 + mli->rd_lockWait,
836 + (collected_number)mli->lockWait.current.Data);
837 +
838 + if (!mli->parent->st_deadLocks) {
839 + snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_locks_deadlocks", mli->parent->instanceID);
840 + mli->parent->st_deadLocks = rrdset_create_localhost("mssql"
841 + , id, NULL
842 + , "locks"
843 + , "mssql.instance_locks_deadlocks"
844 + , "Lock requests that resulted in deadlock."
845 + , "locks/s"
846 + , PLUGIN_WINDOWS_NAME
847 + , "PerflibMSSQL"
848 + , PRIO_MSSQL_LOCKS_DEADLOCK
849 + , *update_every
850 + , RRDSET_TYPE_LINE
851 + );
852 + rrdlabels_add(mli->parent->st_deadLocks->rrdlabels, "mssql_instance", instance, RRDLABEL_SRC_AUTO);
853 + }
854 +
855 + if (!mli->rd_deadLocks) {
856 + snprintfz(id,
857 + RRD_ID_LENGTH_MAX,
858 + "mssql_instance_%s_resource_%s_locks_deadlocks",
859 + mli->parent->instanceID,
860 + instance);
861 +
862 + mli->rd_deadLocks = rrddim_add(mli->parent->st_deadLocks,
863 + id,
864 + instance,
865 + 1,
866 + 1,
867 + RRD_ALGORITHM_INCREMENTAL);
868 + }
869 +
870 + rrddim_set_by_pointer(mli->parent->st_deadLocks,
871 + mli->rd_deadLocks,
872 + (collected_number)mli->deadLocks.current.Data);
873 +}
874 +
875 +static void do_mssql_locks(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
876 +{
877 + char id[RRD_ID_LENGTH_MAX + 1];
878 + PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_LOCKS]);
879 + if (!pObjectType) return;
880 +
881 + PERF_INSTANCE_DEFINITION *pi = NULL;
882 + for(LONG i = 0; i < pObjectType->NumInstances ; i++) {
883 + pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
884 + if(!pi) break;
885 +
886 + if(!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
887 + strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
888 +
889 + if(!strcasecmp(windows_shared_buffer, "_Total"))
890 + continue;
891 +
892 + netdata_fix_chart_name(windows_shared_buffer);
893 + struct mssql_lock_instance *mli = dictionary_set(p->locks_instances,
894 + windows_shared_buffer,
895 + NULL,
896 + sizeof(*mli));
897 + if (!mli)
898 + continue;
899 +
900 + if (!mli->parent) {
901 + mli->parent = p;
902 + }
903 +
904 + perflibGetObjectCounter(pDataBlock, pObjectType, &mli->lockWait);
905 + perflibGetObjectCounter(pDataBlock, pObjectType, &mli->deadLocks);
906 + }
907 +
908 + dictionary_sorted_walkthrough_read(p->locks_instances, dict_mssql_locks_charts_cb, &update_every);
909 + rrdset_done(p->st_lockWait);
910 + rrdset_done(p->st_deadLocks);
911 +}
912 +
913 +static void mssql_database_backup_restore_chart(struct mssql_db_instance *mli, const char *db, int update_every)
914 +{
915 + char id[RRD_ID_LENGTH_MAX + 1];
916 + if (!mli->parent->st_db_backup_restore_operations) {
917 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_backup_restore_operations", db, mli->parent->instanceID);
918 + mli->parent->st_db_backup_restore_operations = rrdset_create_localhost("mssql",
919 + id,
920 + NULL,
921 + "transactions",
922 + "mssql.database_backup_restore_operations",
923 + "Backup IO per database",
924 + "operations/s",
925 + PLUGIN_WINDOWS_NAME,
926 + "PerflibMSSQL",
927 + PRIO_MSSQL_DATABASE_BACKUP_RESTORE_OPERATIONS,
928 + update_every,
929 + RRDSET_TYPE_LINE);
930 +
931 + rrdlabels_add(mli->parent->st_db_backup_restore_operations->rrdlabels,
932 + "mssql_instance",
933 + mli->parent->instanceID,
934 + RRDLABEL_SRC_AUTO);
935 +
936 + rrdlabels_add(mli->parent->st_db_backup_restore_operations->rrdlabels,
937 + "database",
938 + db,
939 + RRDLABEL_SRC_AUTO);
940 + }
941 +
942 + if (!mli->rd_db_backup_restore_operations) {
943 + snprintfz(id,
944 + RRD_ID_LENGTH_MAX,
945 + "mssql_db_%s_instance_%s_backup_restore_operations",
946 + db,
947 + mli->parent->instanceID);
948 +
949 + mli->rd_db_backup_restore_operations = rrddim_add(mli->parent->st_db_backup_restore_operations, id, db,
950 + 1, 1, RRD_ALGORITHM_INCREMENTAL);
951 + }
952 +
953 + rrddim_set_by_pointer(mli->parent->st_db_backup_restore_operations,
954 + mli->rd_db_backup_restore_operations,
955 + (collected_number)mli->MSSQLDatabaseBackupRestoreOperations.current.Data);
956 +}
957 +
958 +static void mssql_database_log_flushes_chart(struct mssql_db_instance *mli, const char *db, int update_every)
959 +{
960 + char id[RRD_ID_LENGTH_MAX + 1];
961 + if (!mli->parent->st_db_log_flushes) {
962 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_log_flushes", db, mli->parent->instanceID);
963 + mli->parent->st_db_log_flushes = rrdset_create_localhost("mssql",
964 + id,
965 + NULL,
966 + "transactions",
967 + "mssql.database_log_flushes",
968 + "Log flushes",
969 + "flushes/s",
970 + PLUGIN_WINDOWS_NAME,
971 + "PerflibMSSQL",
972 + PRIO_MSSQL_DATABASE_LOG_FLUSHES,
973 + update_every,
974 + RRDSET_TYPE_LINE);
975 +
976 + rrdlabels_add(mli->parent->st_db_log_flushes->rrdlabels,
977 + "mssql_instance",
978 + mli->parent->instanceID,
979 + RRDLABEL_SRC_AUTO);
980 +
981 + rrdlabels_add(mli->parent->st_db_log_flushes->rrdlabels,
982 + "database",
983 + db,
984 + RRDLABEL_SRC_AUTO);
985 + }
986 +
987 + if (!mli->rd_db_log_flushes) {
988 + snprintfz(id,
989 + RRD_ID_LENGTH_MAX,
990 + "mssql_db_%s_instance_%s_log_flushes_bytes",
991 + db,
992 + mli->parent->instanceID);
993 +
994 + mli->rd_db_log_flushes = rrddim_add(mli->parent->st_db_log_flushes, id, db,
995 + 1, 1, RRD_ALGORITHM_INCREMENTAL);
996 + }
997 +
998 + rrddim_set_by_pointer(mli->parent->st_db_log_flushes,
999 + mli->rd_db_log_flushes,
1000 + (collected_number)mli->MSSQLDatabaseLogFlushes.current.Data);
1001 +}
1002 +
1003 +static void mssql_database_log_flushed_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1004 +{
1005 + char id[RRD_ID_LENGTH_MAX + 1];
1006 + if (!mli->parent->st_db_log_flushed) {
1007 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_log_flushed", db, mli->parent->instanceID);
1008 + mli->parent->st_db_log_flushed = rrdset_create_localhost("mssql",
1009 + id,
1010 + NULL,
1011 + "transactions",
1012 + "mssql.database_log_flushed",
1013 + "Log flushed",
1014 + "bytes/s",
1015 + PLUGIN_WINDOWS_NAME,
1016 + "PerflibMSSQL",
1017 + PRIO_MSSQL_DATABASE_LOG_FLUSHED,
1018 + update_every,
1019 + RRDSET_TYPE_LINE);
1020 +
1021 + rrdlabels_add(mli->parent->st_db_log_flushed->rrdlabels,
1022 + "mssql_instance",
1023 + mli->parent->instanceID,
1024 + RRDLABEL_SRC_AUTO);
1025 +
1026 + rrdlabels_add(mli->parent->st_db_log_flushed->rrdlabels,
1027 + "database",
1028 + db,
1029 + RRDLABEL_SRC_AUTO);
1030 + }
1031 +
1032 + if (!mli->rd_db_log_flushed) {
1033 + snprintfz(id,
1034 + RRD_ID_LENGTH_MAX,
1035 + "mssql_db_%s_instance_%s_log_flushed_bytes",
1036 + db,
1037 + mli->parent->instanceID);
1038 +
1039 + mli->rd_db_log_flushed = rrddim_add(mli->parent->st_db_log_flushed, id, db,
1040 + 1, 1, RRD_ALGORITHM_INCREMENTAL);
1041 + }
1042 +
1043 + rrddim_set_by_pointer(mli->parent->st_db_log_flushed,
1044 + mli->rd_db_log_flushed,
1045 + (collected_number)mli->MSSQLDatabaseLogFlushed.current.Data);
1046 +}
1047 +
1048 +static void mssql_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1049 +{
1050 + char id[RRD_ID_LENGTH_MAX + 1];
1051 + if (!mli->parent->st_db_transactions) {
1052 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_transactions", db, mli->parent->instanceID);
1053 + mli->parent->st_db_transactions = rrdset_create_localhost("mssql",
1054 + id,
1055 + NULL,
1056 + "transactions",
1057 + "mssql.database_transactions",
1058 + "Transactions",
1059 + "transactions/s",
1060 + PLUGIN_WINDOWS_NAME,
1061 + "PerflibMSSQL",
1062 + PRIO_MSSQL_DATABASE_TRANSACTIONS,
1063 + update_every,
1064 + RRDSET_TYPE_LINE);
1065 +
1066 + rrdlabels_add(mli->parent->st_db_transactions->rrdlabels,
1067 + "mssql_instance",
1068 + mli->parent->instanceID,
1069 + RRDLABEL_SRC_AUTO);
1070 +
1071 + rrdlabels_add(mli->parent->st_db_transactions->rrdlabels,
1072 + "database",
1073 + db,
1074 + RRDLABEL_SRC_AUTO);
1075 + }
1076 +
1077 + if (!mli->rd_db_transactions) {
1078 + snprintfz(id,
1079 + RRD_ID_LENGTH_MAX,
1080 + "mssql_db_%s_instance_%s_transactions",
1081 + db,
1082 + mli->parent->instanceID);
1083 +
1084 + mli->rd_db_transactions = rrddim_add(mli->parent->st_db_transactions, id, db,
1085 + 1, 1, RRD_ALGORITHM_INCREMENTAL);
1086 + }
1087 +
1088 + rrddim_set_by_pointer(mli->parent->st_db_transactions,
1089 + mli->rd_db_transactions,
1090 + (collected_number)mli->MSSQLDatabaseTransactions.current.Data);
1091 +}
1092 +
1093 +static void mssql_write_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1094 +{
1095 + char id[RRD_ID_LENGTH_MAX + 1];
1096 + if (!mli->parent->st_db_write_transactions) {
1097 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_write_transactions", db, mli->parent->instanceID);
1098 + mli->parent->st_db_write_transactions = rrdset_create_localhost("mssql",
1099 + id,
1100 + NULL,
1101 + "transactions",
1102 + "mssql.database_write_transactions",
1103 + "Write transactions",
1104 + "transactions/s",
1105 + PLUGIN_WINDOWS_NAME,
1106 + "PerflibMSSQL",
1107 + PRIO_MSSQL_DATABASE_WRITE_TRANSACTIONS,
1108 + update_every,
1109 + RRDSET_TYPE_LINE);
1110 +
1111 + rrdlabels_add(mli->parent->st_db_write_transactions->rrdlabels,
1112 + "mssql_instance",
1113 + mli->parent->instanceID,
1114 + RRDLABEL_SRC_AUTO);
1115 +
1116 + rrdlabels_add(mli->parent->st_db_write_transactions->rrdlabels,
1117 + "database",
1118 + db,
1119 + RRDLABEL_SRC_AUTO);
1120 + }
1121 +
1122 + if (!mli->rd_db_write_transactions) {
1123 + snprintfz(id,
1124 + RRD_ID_LENGTH_MAX,
1125 + "mssql_db_%s_instance_%s_write_transactions",
1126 + db,
1127 + mli->parent->instanceID);
1128 +
1129 + mli->rd_db_write_transactions = rrddim_add(mli->parent->st_db_write_transactions, id, db,
1130 + 1, 1, RRD_ALGORITHM_INCREMENTAL);
1131 + }
1132 +
1133 + rrddim_set_by_pointer(mli->parent->st_db_write_transactions,
1134 + mli->rd_db_write_transactions,
1135 + (collected_number)mli->MSSQLDatabaseWriteTransactions.current.Data);
1136 +}
1137 +
1138 +static void mssql_active_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1139 +{
1140 + char id[RRD_ID_LENGTH_MAX + 1];
1141 + if (!mli->parent->st_db_active_transactions) {
1142 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_active_transactions", db, mli->parent->instanceID);
1143 + mli->parent->st_db_active_transactions = rrdset_create_localhost("mssql",
1144 + id,
1145 + NULL,
1146 + "transactions",
1147 + "mssql.database_active_transactions",
1148 + "Active transactions per database",
1149 + "transactions",
1150 + PLUGIN_WINDOWS_NAME,
1151 + "PerflibMSSQL",
1152 + PRIO_MSSQL_DATABASE_ACTIVE_TRANSACTIONS,
1153 + update_every,
1154 + RRDSET_TYPE_LINE);
1155 +
1156 + rrdlabels_add(mli->parent->st_db_active_transactions->rrdlabels,
1157 + "mssql_instance",
1158 + mli->parent->instanceID,
1159 + RRDLABEL_SRC_AUTO);
1160 +
1161 + rrdlabels_add(mli->parent->st_db_active_transactions->rrdlabels,
1162 + "database",
1163 + db,
1164 + RRDLABEL_SRC_AUTO);
1165 + }
1166 +
1167 + if (!mli->rd_db_active_transactions) {
1168 + snprintfz(id,
1169 + RRD_ID_LENGTH_MAX,
1170 + "mssql_db_%s_instance_%s_active_transactions",
1171 + db,
1172 + mli->parent->instanceID);
1173 +
1174 + mli->rd_db_active_transactions = rrddim_add(mli->parent->st_db_active_transactions, id, db,
1175 + 1, 1, RRD_ALGORITHM_ABSOLUTE);
1176 + }
1177 +
1178 + rrddim_set_by_pointer(mli->parent->st_db_active_transactions,
1179 + mli->rd_db_active_transactions,
1180 + (collected_number)mli->MSSQLDatabaseActiveTransactions.current.Data);
1181 +}
1182 +
1183 +static void mssql_data_file_size_chart(struct mssql_db_instance *mli, const char *db, int update_every)
1184 +{
1185 + char id[RRD_ID_LENGTH_MAX + 1];
1186 + if (!mli->parent->st_db_data_file_size) {
1187 + snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_data_files_size", db, mli->parent->instanceID);
1188 + mli->parent->st_db_data_file_size = rrdset_create_localhost("mssql",
1189 + id,
1190 + NULL,
1191 + "size",
1192 + "mssql.database_data_files_size",
1193 + "Current database size.",
1194 + "bytes",
1195 + PLUGIN_WINDOWS_NAME,
1196 + "PerflibMSSQL",
1197 + PRIO_MSSQL_DATABASE_DATA_FILE_SIZE,
1198 + update_every,
1199 + RRDSET_TYPE_LINE);
1200 +
1201 + rrdlabels_add(mli->parent->st_db_data_file_size->rrdlabels,
1202 + "mssql_instance",
1203 + mli->parent->instanceID,
1204 + RRDLABEL_SRC_AUTO);
1205 +
1206 + rrdlabels_add(mli->parent->st_db_data_file_size->rrdlabels,
1207 + "database",
1208 + db,
1209 + RRDLABEL_SRC_AUTO);
1210 + }
1211 +
1212 + if (!mli->rd_db_data_file_size) {
1213 + snprintfz(id,
1214 + RRD_ID_LENGTH_MAX,
1215 + "mssql_db_%s_instance_%s_data_files_size_bytes",
1216 + db,
1217 + mli->parent->instanceID);
1218 +
1219 + mli->rd_db_data_file_size = rrddim_add(mli->parent->st_db_data_file_size, id, db,
1220 + 1, 1, RRD_ALGORITHM_ABSOLUTE);
1221 + }
1222 +
1223 + rrddim_set_by_pointer(mli->parent->st_db_data_file_size,
1224 + mli->rd_db_data_file_size,
1225 + (collected_number)mli->MSSQLDatabaseDataFileSize.current.Data*1024);
1226 +
1227 +}
1228 +
1229 +int dict_mssql_databases_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
1230 +{
1231 + struct mssql_db_instance *mli = value;
1232 + const char *db = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
1233 +
1234 + int *update_every = data;
1235 +
1236 + void (*transaction_chart[])(struct mssql_db_instance *, const char *, int) = {
1237 + mssql_data_file_size_chart,
1238 + mssql_transactions_chart,
1239 + mssql_database_backup_restore_chart,
1240 + mssql_database_log_flushed_chart,
1241 + mssql_database_log_flushes_chart,
1242 + mssql_active_transactions_chart,
1243 + mssql_write_transactions_chart,
1244 +
1245 + // Last function pointer must be NULL
1246 + NULL
1247 + };
1248 +
1249 + int i;
1250 + for (i = 0; transaction_chart[i]; i++) {
1251 + transaction_chart[i](mli, db, *update_every);
1252 + }
1253 +}
1254 +
1255 +static void do_mssql_databases(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
1256 +{
1257 + char id[RRD_ID_LENGTH_MAX + 1];
1258 + PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_DATABASE]);
1259 + if (!pObjectType) return;
1260 +
1261 + PERF_INSTANCE_DEFINITION *pi = NULL;
1262 + for(LONG i = 0; i < pObjectType->NumInstances ; i++) {
1263 + pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
1264 + if(!pi) break;
1265 +
1266 + if(!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
1267 + strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
1268 +
1269 + if(!strcasecmp(windows_shared_buffer, "_Total"))
1270 + continue;
1271 +
1272 + netdata_fix_chart_name(windows_shared_buffer);
1273 + struct mssql_db_instance *mdi = dictionary_set(p->databases,
1274 + windows_shared_buffer,
1275 + NULL,
1276 + sizeof(*mdi));
1277 + if (!mdi)
1278 + continue;
1279 +
1280 + if (!mdi->parent) {
1281 + mdi->parent = p;
1282 + }
1283 +
1284 + perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseDataFileSize);
1285 + perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseActiveTransactions);
1286 + perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseBackupRestoreOperations);
1287 + perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseLogFlushed);
1288 + perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseLogFlushes);
1289 + perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseTransactions);
1290 + perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseWriteTransactions);
1291 + }
1292 +
1293 + dictionary_sorted_walkthrough_read(p->databases, dict_mssql_databases_charts_cb, &update_every);
1294 + rrdset_done(p->st_db_data_file_size);
1295 + rrdset_done(p->st_db_active_transactions);
1296 + rrdset_done(p->st_db_backup_restore_operations);
1297 + rrdset_done(p->st_db_log_flushed);
1298 + rrdset_done(p->st_db_log_flushes);
1299 + rrdset_done(p->st_db_transactions);
1300 + rrdset_done(p->st_db_write_transactions);
1301 +}
1302 +
1303 +static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
1304 +{
1305 + char id[RRD_ID_LENGTH_MAX + 1];
1306 + PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_MEMORY]);
1307 + if (!pObjectType)
1308 + return;
1309 +
1310 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLConnectionMemoryBytes)) {
1311 + snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_connection_memory_bytes", p->instanceID);
1312 + if (!p->st_conn_memory) {
1313 + p->st_conn_memory = rrdset_create_localhost("mssql"
1314 + , id, NULL
1315 + , "memory"
1316 + , "mssql.instance_memmgr_connection_memory_bytes"
1317 + , "Amount of dynamic memory to maintain connections"
1318 + , "bytes"
1319 + , PLUGIN_WINDOWS_NAME
1320 + , "PerflibMSSQL"
1321 + , PRIO_MSSQL_MEMMGR_CONNECTION_MEMORY_BYTES
1322 + , update_every
1323 + , RRDSET_TYPE_LINE
1324 + );
1325 +
1326 + snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_memmgr_connection_memory_bytes", p->instanceID);
1327 + p->rd_conn_memory = rrddim_add(p->st_conn_memory,
1328 + id,
1329 + "memory",
1330 + 1,
1331 + 1,
1332 + RRD_ALGORITHM_ABSOLUTE);
1333 +
1334 + rrdlabels_add(p->st_conn_memory->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1335 + }
1336 +
1337 + rrddim_set_by_pointer(p->st_conn_memory,
1338 + p->rd_conn_memory,
1339 + (collected_number)(p->MSSQLConnectionMemoryBytes.current.Data*1024));
1340 + rrdset_done(p->st_conn_memory);
1341 + }
1342 +
1343 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLExternalBenefitOfMemory)) {
1344 + snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_external_benefit_of_memory", p->instanceID);
1345 + if (!p->st_ext_benefit_mem) {
1346 + p->st_ext_benefit_mem = rrdset_create_localhost("mssql"
1347 + , id, NULL
1348 + , "memory"
1349 + , "mssql.instance_memmgr_external_benefit_of_memory"
1350 + , "Performance benefit from adding memory to a specific cache"
1351 + , "bytes"
1352 + , PLUGIN_WINDOWS_NAME
1353 + , "PerflibMSSQL"
1354 + , PRIO_MSSQL_MEMMGR_EXTERNAL_BENEFIT_OF_MEMORY
1355 + , update_every
1356 + , RRDSET_TYPE_LINE
1357 + );
1358 +
1359 + snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_memmgr_external_benefit_of_memory", p->instanceID);
1360 + p->rd_ext_benefit_mem = rrddim_add(p->st_ext_benefit_mem,
1361 + id,
1362 + "benefit",
1363 + 1,
1364 + 1,
1365 + RRD_ALGORITHM_INCREMENTAL);
1366 +
1367 + rrdlabels_add(p->st_ext_benefit_mem->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1368 + }
1369 +
1370 + rrddim_set_by_pointer(p->st_ext_benefit_mem,
1371 + p->rd_ext_benefit_mem,
1372 + (collected_number)p->MSSQLExternalBenefitOfMemory.current.Data);
1373 + rrdset_done(p->st_ext_benefit_mem);
1374 + }
1375 +
1376 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLPendingMemoryGrants)) {
1377 + snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_pending_memory_grants", p->instanceID);
1378 + if (!p->st_pending_mem_grant) {
1379 + p->st_pending_mem_grant = rrdset_create_localhost("mssql"
1380 + , id, NULL
1381 + , "memory"
1382 + , "mssql.instance_memmgr_pending_memory_grants"
1383 + , "Process waiting for memory grant"
1384 + , "process"
1385 + , PLUGIN_WINDOWS_NAME
1386 + , "PerflibMSSQL"
1387 + , PRIO_MSSQL_MEMMGR_PENDING_MEMORY_GRANTS
1388 + , update_every
1389 + , RRDSET_TYPE_LINE
1390 + );
1391 +
1392 + snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_memmgr_pending_memory_grants", p->instanceID);
1393 + p->rd_pending_mem_grant = rrddim_add(p->st_pending_mem_grant,
1394 + id,
1395 + "pending",
1396 + 1,
1397 + 1,
1398 + RRD_ALGORITHM_ABSOLUTE);
1399 +
1400 + rrdlabels_add(p->st_pending_mem_grant->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1401 + }
1402 +
1403 + rrddim_set_by_pointer(p->st_pending_mem_grant,
1404 + p->rd_pending_mem_grant,
1405 + (collected_number)p->MSSQLPendingMemoryGrants.current.Data);
1406 + rrdset_done(p->st_pending_mem_grant);
1407 + }
1408 +
1409 + if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLTotalServerMemory)) {
1410 + snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_server_memory", p->instanceID);
1411 + if (!p->st_mem_tot_server) {
1412 + p->st_mem_tot_server = rrdset_create_localhost("mssql"
1413 + , id, NULL
1414 + , "memory"
1415 + , "mssql.instance_memmgr_server_memory"
1416 + , "Memory committed"
1417 + , "bytes"
1418 + , PLUGIN_WINDOWS_NAME
1419 + , "PerflibMSSQL"
1420 + , PRIO_MSSQL_MEMMGR_TOTAL_SERVER
1421 + , update_every
1422 + , RRDSET_TYPE_LINE
1423 + );
1424 +
1425 + snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_memmgr_total_server_memory_bytes", p->instanceID);
1426 + p->rd_mem_tot_server = rrddim_add(p->st_mem_tot_server,
1427 + id,
1428 + "memory",
1429 + 1,
1430 + 1,
1431 + RRD_ALGORITHM_ABSOLUTE);
1432 +
1433 + rrdlabels_add(p->st_mem_tot_server->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
1434 + }
1435 +
1436 + rrddim_set_by_pointer(p->st_mem_tot_server,
1437 + p->rd_mem_tot_server,
1438 + (collected_number)(p->MSSQLTotalServerMemory.current.Data*1024));
1439 + rrdset_done(p->st_mem_tot_server);
1440 + }
1441 +}
1442 +
1443 int dict_mssql_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
1444 struct mssql_instance *p = value;
1445 int *update_every = data;
@@ -737,10 +1447,11 @@ int dict_mssql_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value
1447 static void (*doMSSQL[])(PERF_DATA_BLOCK *, struct mssql_instance *, int) = {
1448 do_mssql_general_stats,
1449 do_mssql_errors,
740 - NULL, NULL, NULL,
1450 + do_mssql_databases,
1451 + do_mssql_locks,
1452 + do_mssql_memory_mgr,
1453 do_mssql_buffer_management,
1454 do_mssql_sql_statistics,
743 - NULL,
1455 do_mssql_access_methods
1456 };
1457
src/collectors/windows.plugin/windows_plugin.h
+17
@@ -43,6 +43,15 @@ enum PERFLIB_PRIO {
43
44 PRIO_MSSQL_USER_CONNECTIONS,
45
46 + PRIO_MSSQL_DATABASE_TRANSACTIONS,
47 + PRIO_MSSQL_DATABASE_ACTIVE_TRANSACTIONS,
48 + PRIO_MSSQL_DATABASE_WRITE_TRANSACTIONS,
49 + PRIO_MSSQL_DATABASE_BACKUP_RESTORE_OPERATIONS,
50 + PRIO_MSSQL_DATABASE_LOG_FLUSHES,
51 + PRIO_MSSQL_DATABASE_LOG_FLUSHED,
52 +
53 + PRIO_MSSQL_DATABASE_DATA_FILE_SIZE,
54 +
55 PRIO_MSSQL_STATS_BATCH_REQUEST,
56 PRIO_MSSQL_STATS_COMPILATIONS,
57 PRIO_MSSQL_STATS_RECOMPILATIONS,
@@ -57,6 +66,14 @@ enum PERFLIB_PRIO {
66 PRIO_MSSQL_BUFF_METHODS_PAGE_SPLIT,
67 PRIO_MSSQL_BUFF_PAGE_LIFE_EXPECTANCY,
68
69 + PRIO_MSSQL_MEMMGR_CONNECTION_MEMORY_BYTES,
70 + PRIO_MSSQL_MEMMGR_TOTAL_SERVER,
71 + PRIO_MSSQL_MEMMGR_EXTERNAL_BENEFIT_OF_MEMORY,
72 + PRIO_MSSQL_MEMMGR_PENDING_MEMORY_GRANTS,
73 +
74 + PRIO_MSSQL_LOCKS_WAIT,
75 + PRIO_MSSQL_LOCKS_DEADLOCK,
76 +
77 PRIO_MSSQL_SQL_ERRORS
78 };
79