0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-04-28 14:42:31 +00:00

MSSQL Metrics (Part II). ()

This commit is contained in:
thiagoftsm 2024-10-09 15:16:38 +00:00 committed by GitHub
parent 260f718cd2
commit 30b532952a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 753 additions and 25 deletions
src/collectors/windows.plugin

View file

@ -15,7 +15,6 @@ enum netdata_mssql_metrics {
NETDATA_MSSQL_MEMORY,
NETDATA_MSSQL_BUFFER_MANAGEMENT,
NETDATA_MSSQL_SQL_STATS,
NETDATA_MSSQL_TRANSACTIONS,
NETDATA_MSSQL_ACCESS_METHODS,
NETDATA_MSSQL_METRICS_END
@ -66,6 +65,30 @@ struct mssql_instance {
RRDSET *st_sql_errors;
RRDDIM *rd_sql_errors;
RRDSET *st_lockWait;
RRDSET *st_deadLocks;
DICTIONARY *locks_instances;
RRDSET *st_db_data_file_size;
RRDSET *st_db_active_transactions;
RRDSET *st_db_backup_restore_operations;
RRDSET *st_db_log_flushed;
RRDSET *st_db_log_flushes;
RRDSET *st_db_transactions;
RRDSET *st_db_write_transactions;
DICTIONARY *databases;
RRDSET *st_conn_memory;
RRDDIM *rd_conn_memory;
RRDSET *st_ext_benefit_mem;
RRDDIM *rd_ext_benefit_mem;
RRDSET *st_pending_mem_grant;
RRDDIM *rd_pending_mem_grant;
RRDSET *st_mem_tot_server;
RRDDIM *rd_mem_tot_server;
COUNTER_DATA MSSQLAccessMethodPageSplits;
COUNTER_DATA MSSQLBufferCacheHits;
@ -75,8 +98,6 @@ struct mssql_instance {
COUNTER_DATA MSSQLBufferPageWrites;
COUNTER_DATA MSSQLBlockedProcesses;
COUNTER_DATA MSSQLUserConnections;
COUNTER_DATA MSSQLLockWait;
COUNTER_DATA MSSQLDeadlocks;
COUNTER_DATA MSSQLConnectionMemoryBytes;
COUNTER_DATA MSSQLExternalBenefitOfMemory;
COUNTER_DATA MSSQLPendingMemoryGrants;
@ -87,6 +108,20 @@ struct mssql_instance {
COUNTER_DATA MSSQLStatSafeAutoParameterization;
COUNTER_DATA MSSQLCompilations;
COUNTER_DATA MSSQLRecompilations;
};
struct mssql_lock_instance {
struct mssql_instance *parent;
COUNTER_DATA lockWait;
COUNTER_DATA deadLocks;
RRDDIM *rd_lockWait;
RRDDIM *rd_deadLocks;
};
struct mssql_db_instance {
struct mssql_instance *parent;
COUNTER_DATA MSSQLDatabaseActiveTransactions;
COUNTER_DATA MSSQLDatabaseBackupRestoreOperations;
@ -95,6 +130,14 @@ struct mssql_instance {
COUNTER_DATA MSSQLDatabaseLogFlushes;
COUNTER_DATA MSSQLDatabaseTransactions;
COUNTER_DATA MSSQLDatabaseWriteTransactions;
RRDDIM *rd_db_data_file_size;
RRDDIM *rd_db_active_transactions;
RRDDIM *rd_db_backup_restore_operations;
RRDDIM *rd_db_log_flushed;
RRDDIM *rd_db_log_flushes;
RRDDIM *rd_db_transactions;
RRDDIM *rd_db_write_transactions;
};
static DICTIONARY *mssql_instances = NULL;
@ -118,9 +161,6 @@ static void initialize_mssql_objects(struct mssql_instance *p, const char *insta
strncpyz(&name[length], "Databases", sizeof(name) - length);
p->objectName[NETDATA_MSSQL_DATABASE] = strdup(name);
strncpyz(&name[length], "Transactions", sizeof(name) - length);
p->objectName[NETDATA_MSSQL_TRANSACTIONS] = strdup(name);
strncpyz(&name[length], "SQL Statistics", sizeof(name) - length);
p->objectName[NETDATA_MSSQL_SQL_STATS] = strdup(name);
@ -165,28 +205,49 @@ static inline void initialize_mssql_keys(struct mssql_instance *p) {
// Errors
p->MSSQLSQLErrorsTotal.key = "Errors/sec";
/*
p->MSSQLLockWait.key = "";
p->MSSQLDeadlocks.key = "";
p->MSSQLConnectionMemoryBytes.key = "";
p->MSSQLExternalBenefitOfMemory.key = "";
p->MSSQLPendingMemoryGrants.key = "";
p->MSSQLTotalServerMemory.key = "";
p->MSSQLConnectionMemoryBytes.key = "Connection Memory (KB)";
p->MSSQLExternalBenefitOfMemory.key = "External benefit of memory";
p->MSSQLPendingMemoryGrants.key = "Memory Grants Pending";
p->MSSQLTotalServerMemory.key = "Total Server Memory (KB)";
}
p->MSSQLDatabaseActiveTransactions.key = "";
p->MSSQLDatabaseBackupRestoreOperations.key = "";
p->MSSQLDatabaseDataFileSize.key = "";
p->MSSQLDatabaseLogFlushed.key = "";
p->MSSQLDatabaseLogFlushes.key = "";
p->MSSQLDatabaseTransactions.key = "";
p->MSSQLDatabaseWriteTransactions.key = "";
*/
void dict_mssql_insert_locks_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
struct mssql_lock_instance *ptr = value;
ptr->deadLocks.key = "Number of Deadlocks/sec";
ptr->lockWait.key = "Lock Waits/sec";
}
void dict_mssql_insert_databases_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
struct mssql_db_instance *ptr = value;
ptr->MSSQLDatabaseDataFileSize.key = "Data File(s) Size (KB)";
ptr->MSSQLDatabaseActiveTransactions.key = "Active Transactions";
ptr->MSSQLDatabaseBackupRestoreOperations.key = "Backup/Restore Throughput/sec";
ptr->MSSQLDatabaseLogFlushed.key = "Log Bytes Flushed/sec";
ptr->MSSQLDatabaseLogFlushes.key = "Log Flushes/sec";
ptr->MSSQLDatabaseTransactions.key = "Transactions/sec";
ptr->MSSQLDatabaseWriteTransactions.key = "Write Transactions/sec";
}
void dict_mssql_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
struct mssql_instance *p = value;
const char *instance = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
if (!p->locks_instances) {
p->locks_instances = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
DICT_OPTION_FIXED_SIZE,
NULL, sizeof(struct mssql_lock_instance));
dictionary_register_insert_callback(p->locks_instances, dict_mssql_insert_locks_cb, NULL);
}
if (!p->databases) {
p->databases = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
DICT_OPTION_FIXED_SIZE,
NULL, sizeof(struct mssql_db_instance));
dictionary_register_insert_callback(p->databases, dict_mssql_insert_databases_cb, NULL);
}
initialize_mssql_objects(p, instance);
initialize_mssql_keys(p);
}
@ -554,7 +615,7 @@ static void do_mssql_buffer_management(PERF_DATA_BLOCK *pDataBlock, struct mssql
snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_bufman_checkpoint_pages", p->instanceID);
p->rd_buff_checkpoint_pages = rrddim_add(p->st_buff_checkpoint_pages,
id,
"flushed",
"log",
1,
1,
RRD_ALGORITHM_INCREMENTAL);
@ -703,7 +764,7 @@ static void do_mssql_errors(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *
, id, NULL
, "Errors"
, "mssql.instance_sql_errors"
, "Errors"
, "errors"
, "errors/s"
, PLUGIN_WINDOWS_NAME
, "PerflibMSSQL"
@ -730,6 +791,655 @@ static void do_mssql_errors(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *
}
}
int dict_mssql_locks_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
char id[RRD_ID_LENGTH_MAX + 1];
struct mssql_lock_instance *mli = value;
const char *instance = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
int *update_every = data;
if (!mli->parent->st_lockWait) {
snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_locks_lock_wait", mli->parent->instanceID);
mli->parent->st_lockWait = rrdset_create_localhost("mssql"
, id, NULL
, "locks"
, "mssql.instance_locks_lock_wait"
, "Lock requests that required the caller to wait."
, "locks/s"
, PLUGIN_WINDOWS_NAME
, "PerflibMSSQL"
, PRIO_MSSQL_LOCKS_WAIT
, *update_every
, RRDSET_TYPE_LINE
);
rrdlabels_add(mli->parent->st_lockWait->rrdlabels, "mssql_instance", instance, RRDLABEL_SRC_AUTO);
}
if (!mli->rd_lockWait) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_instance_%s_resource_%s_locks_lock_wait_seconds",
mli->parent->instanceID,
instance);
mli->rd_lockWait = rrddim_add(mli->parent->st_lockWait,
id,
instance,
1,
1,
RRD_ALGORITHM_INCREMENTAL);
}
rrddim_set_by_pointer(mli->parent->st_lockWait,
mli->rd_lockWait,
(collected_number)mli->lockWait.current.Data);
if (!mli->parent->st_deadLocks) {
snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_locks_deadlocks", mli->parent->instanceID);
mli->parent->st_deadLocks = rrdset_create_localhost("mssql"
, id, NULL
, "locks"
, "mssql.instance_locks_deadlocks"
, "Lock requests that resulted in deadlock."
, "locks/s"
, PLUGIN_WINDOWS_NAME
, "PerflibMSSQL"
, PRIO_MSSQL_LOCKS_DEADLOCK
, *update_every
, RRDSET_TYPE_LINE
);
rrdlabels_add(mli->parent->st_deadLocks->rrdlabels, "mssql_instance", instance, RRDLABEL_SRC_AUTO);
}
if (!mli->rd_deadLocks) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_instance_%s_resource_%s_locks_deadlocks",
mli->parent->instanceID,
instance);
mli->rd_deadLocks = rrddim_add(mli->parent->st_deadLocks,
id,
instance,
1,
1,
RRD_ALGORITHM_INCREMENTAL);
}
rrddim_set_by_pointer(mli->parent->st_deadLocks,
mli->rd_deadLocks,
(collected_number)mli->deadLocks.current.Data);
}
static void do_mssql_locks(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_LOCKS]);
if (!pObjectType) return;
PERF_INSTANCE_DEFINITION *pi = NULL;
for(LONG i = 0; i < pObjectType->NumInstances ; i++) {
pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
if(!pi) break;
if(!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
if(!strcasecmp(windows_shared_buffer, "_Total"))
continue;
netdata_fix_chart_name(windows_shared_buffer);
struct mssql_lock_instance *mli = dictionary_set(p->locks_instances,
windows_shared_buffer,
NULL,
sizeof(*mli));
if (!mli)
continue;
if (!mli->parent) {
mli->parent = p;
}
perflibGetObjectCounter(pDataBlock, pObjectType, &mli->lockWait);
perflibGetObjectCounter(pDataBlock, pObjectType, &mli->deadLocks);
}
dictionary_sorted_walkthrough_read(p->locks_instances, dict_mssql_locks_charts_cb, &update_every);
rrdset_done(p->st_lockWait);
rrdset_done(p->st_deadLocks);
}
static void mssql_database_backup_restore_chart(struct mssql_db_instance *mli, const char *db, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
if (!mli->parent->st_db_backup_restore_operations) {
snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_backup_restore_operations", db, mli->parent->instanceID);
mli->parent->st_db_backup_restore_operations = rrdset_create_localhost("mssql",
id,
NULL,
"transactions",
"mssql.database_backup_restore_operations",
"Backup IO per database",
"operations/s",
PLUGIN_WINDOWS_NAME,
"PerflibMSSQL",
PRIO_MSSQL_DATABASE_BACKUP_RESTORE_OPERATIONS,
update_every,
RRDSET_TYPE_LINE);
rrdlabels_add(mli->parent->st_db_backup_restore_operations->rrdlabels,
"mssql_instance",
mli->parent->instanceID,
RRDLABEL_SRC_AUTO);
rrdlabels_add(mli->parent->st_db_backup_restore_operations->rrdlabels,
"database",
db,
RRDLABEL_SRC_AUTO);
}
if (!mli->rd_db_backup_restore_operations) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_db_%s_instance_%s_backup_restore_operations",
db,
mli->parent->instanceID);
mli->rd_db_backup_restore_operations = rrddim_add(mli->parent->st_db_backup_restore_operations, id, db,
1, 1, RRD_ALGORITHM_INCREMENTAL);
}
rrddim_set_by_pointer(mli->parent->st_db_backup_restore_operations,
mli->rd_db_backup_restore_operations,
(collected_number)mli->MSSQLDatabaseBackupRestoreOperations.current.Data);
}
static void mssql_database_log_flushes_chart(struct mssql_db_instance *mli, const char *db, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
if (!mli->parent->st_db_log_flushes) {
snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_log_flushes", db, mli->parent->instanceID);
mli->parent->st_db_log_flushes = rrdset_create_localhost("mssql",
id,
NULL,
"transactions",
"mssql.database_log_flushes",
"Log flushes",
"flushes/s",
PLUGIN_WINDOWS_NAME,
"PerflibMSSQL",
PRIO_MSSQL_DATABASE_LOG_FLUSHES,
update_every,
RRDSET_TYPE_LINE);
rrdlabels_add(mli->parent->st_db_log_flushes->rrdlabels,
"mssql_instance",
mli->parent->instanceID,
RRDLABEL_SRC_AUTO);
rrdlabels_add(mli->parent->st_db_log_flushes->rrdlabels,
"database",
db,
RRDLABEL_SRC_AUTO);
}
if (!mli->rd_db_log_flushes) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_db_%s_instance_%s_log_flushes_bytes",
db,
mli->parent->instanceID);
mli->rd_db_log_flushes = rrddim_add(mli->parent->st_db_log_flushes, id, db,
1, 1, RRD_ALGORITHM_INCREMENTAL);
}
rrddim_set_by_pointer(mli->parent->st_db_log_flushes,
mli->rd_db_log_flushes,
(collected_number)mli->MSSQLDatabaseLogFlushes.current.Data);
}
static void mssql_database_log_flushed_chart(struct mssql_db_instance *mli, const char *db, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
if (!mli->parent->st_db_log_flushed) {
snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_log_flushed", db, mli->parent->instanceID);
mli->parent->st_db_log_flushed = rrdset_create_localhost("mssql",
id,
NULL,
"transactions",
"mssql.database_log_flushed",
"Log flushed",
"bytes/s",
PLUGIN_WINDOWS_NAME,
"PerflibMSSQL",
PRIO_MSSQL_DATABASE_LOG_FLUSHED,
update_every,
RRDSET_TYPE_LINE);
rrdlabels_add(mli->parent->st_db_log_flushed->rrdlabels,
"mssql_instance",
mli->parent->instanceID,
RRDLABEL_SRC_AUTO);
rrdlabels_add(mli->parent->st_db_log_flushed->rrdlabels,
"database",
db,
RRDLABEL_SRC_AUTO);
}
if (!mli->rd_db_log_flushed) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_db_%s_instance_%s_log_flushed_bytes",
db,
mli->parent->instanceID);
mli->rd_db_log_flushed = rrddim_add(mli->parent->st_db_log_flushed, id, db,
1, 1, RRD_ALGORITHM_INCREMENTAL);
}
rrddim_set_by_pointer(mli->parent->st_db_log_flushed,
mli->rd_db_log_flushed,
(collected_number)mli->MSSQLDatabaseLogFlushed.current.Data);
}
static void mssql_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
if (!mli->parent->st_db_transactions) {
snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_transactions", db, mli->parent->instanceID);
mli->parent->st_db_transactions = rrdset_create_localhost("mssql",
id,
NULL,
"transactions",
"mssql.database_transactions",
"Transactions",
"transactions/s",
PLUGIN_WINDOWS_NAME,
"PerflibMSSQL",
PRIO_MSSQL_DATABASE_TRANSACTIONS,
update_every,
RRDSET_TYPE_LINE);
rrdlabels_add(mli->parent->st_db_transactions->rrdlabels,
"mssql_instance",
mli->parent->instanceID,
RRDLABEL_SRC_AUTO);
rrdlabels_add(mli->parent->st_db_transactions->rrdlabels,
"database",
db,
RRDLABEL_SRC_AUTO);
}
if (!mli->rd_db_transactions) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_db_%s_instance_%s_transactions",
db,
mli->parent->instanceID);
mli->rd_db_transactions = rrddim_add(mli->parent->st_db_transactions, id, db,
1, 1, RRD_ALGORITHM_INCREMENTAL);
}
rrddim_set_by_pointer(mli->parent->st_db_transactions,
mli->rd_db_transactions,
(collected_number)mli->MSSQLDatabaseTransactions.current.Data);
}
static void mssql_write_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
if (!mli->parent->st_db_write_transactions) {
snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_write_transactions", db, mli->parent->instanceID);
mli->parent->st_db_write_transactions = rrdset_create_localhost("mssql",
id,
NULL,
"transactions",
"mssql.database_write_transactions",
"Write transactions",
"transactions/s",
PLUGIN_WINDOWS_NAME,
"PerflibMSSQL",
PRIO_MSSQL_DATABASE_WRITE_TRANSACTIONS,
update_every,
RRDSET_TYPE_LINE);
rrdlabels_add(mli->parent->st_db_write_transactions->rrdlabels,
"mssql_instance",
mli->parent->instanceID,
RRDLABEL_SRC_AUTO);
rrdlabels_add(mli->parent->st_db_write_transactions->rrdlabels,
"database",
db,
RRDLABEL_SRC_AUTO);
}
if (!mli->rd_db_write_transactions) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_db_%s_instance_%s_write_transactions",
db,
mli->parent->instanceID);
mli->rd_db_write_transactions = rrddim_add(mli->parent->st_db_write_transactions, id, db,
1, 1, RRD_ALGORITHM_INCREMENTAL);
}
rrddim_set_by_pointer(mli->parent->st_db_write_transactions,
mli->rd_db_write_transactions,
(collected_number)mli->MSSQLDatabaseWriteTransactions.current.Data);
}
static void mssql_active_transactions_chart(struct mssql_db_instance *mli, const char *db, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
if (!mli->parent->st_db_active_transactions) {
snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_active_transactions", db, mli->parent->instanceID);
mli->parent->st_db_active_transactions = rrdset_create_localhost("mssql",
id,
NULL,
"transactions",
"mssql.database_active_transactions",
"Active transactions per database",
"transactions",
PLUGIN_WINDOWS_NAME,
"PerflibMSSQL",
PRIO_MSSQL_DATABASE_ACTIVE_TRANSACTIONS,
update_every,
RRDSET_TYPE_LINE);
rrdlabels_add(mli->parent->st_db_active_transactions->rrdlabels,
"mssql_instance",
mli->parent->instanceID,
RRDLABEL_SRC_AUTO);
rrdlabels_add(mli->parent->st_db_active_transactions->rrdlabels,
"database",
db,
RRDLABEL_SRC_AUTO);
}
if (!mli->rd_db_active_transactions) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_db_%s_instance_%s_active_transactions",
db,
mli->parent->instanceID);
mli->rd_db_active_transactions = rrddim_add(mli->parent->st_db_active_transactions, id, db,
1, 1, RRD_ALGORITHM_ABSOLUTE);
}
rrddim_set_by_pointer(mli->parent->st_db_active_transactions,
mli->rd_db_active_transactions,
(collected_number)mli->MSSQLDatabaseActiveTransactions.current.Data);
}
static void mssql_data_file_size_chart(struct mssql_db_instance *mli, const char *db, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
if (!mli->parent->st_db_data_file_size) {
snprintfz(id, RRD_ID_LENGTH_MAX, "db_%s_instance_%s_data_files_size", db, mli->parent->instanceID);
mli->parent->st_db_data_file_size = rrdset_create_localhost("mssql",
id,
NULL,
"size",
"mssql.database_data_files_size",
"Current database size.",
"bytes",
PLUGIN_WINDOWS_NAME,
"PerflibMSSQL",
PRIO_MSSQL_DATABASE_DATA_FILE_SIZE,
update_every,
RRDSET_TYPE_LINE);
rrdlabels_add(mli->parent->st_db_data_file_size->rrdlabels,
"mssql_instance",
mli->parent->instanceID,
RRDLABEL_SRC_AUTO);
rrdlabels_add(mli->parent->st_db_data_file_size->rrdlabels,
"database",
db,
RRDLABEL_SRC_AUTO);
}
if (!mli->rd_db_data_file_size) {
snprintfz(id,
RRD_ID_LENGTH_MAX,
"mssql_db_%s_instance_%s_data_files_size_bytes",
db,
mli->parent->instanceID);
mli->rd_db_data_file_size = rrddim_add(mli->parent->st_db_data_file_size, id, db,
1, 1, RRD_ALGORITHM_ABSOLUTE);
}
rrddim_set_by_pointer(mli->parent->st_db_data_file_size,
mli->rd_db_data_file_size,
(collected_number)mli->MSSQLDatabaseDataFileSize.current.Data*1024);
}
int dict_mssql_databases_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
{
struct mssql_db_instance *mli = value;
const char *db = dictionary_acquired_item_name((DICTIONARY_ITEM *)item);
int *update_every = data;
void (*transaction_chart[])(struct mssql_db_instance *, const char *, int) = {
mssql_data_file_size_chart,
mssql_transactions_chart,
mssql_database_backup_restore_chart,
mssql_database_log_flushed_chart,
mssql_database_log_flushes_chart,
mssql_active_transactions_chart,
mssql_write_transactions_chart,
// Last function pointer must be NULL
NULL
};
int i;
for (i = 0; transaction_chart[i]; i++) {
transaction_chart[i](mli, db, *update_every);
}
}
static void do_mssql_databases(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_DATABASE]);
if (!pObjectType) return;
PERF_INSTANCE_DEFINITION *pi = NULL;
for(LONG i = 0; i < pObjectType->NumInstances ; i++) {
pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
if(!pi) break;
if(!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
if(!strcasecmp(windows_shared_buffer, "_Total"))
continue;
netdata_fix_chart_name(windows_shared_buffer);
struct mssql_db_instance *mdi = dictionary_set(p->databases,
windows_shared_buffer,
NULL,
sizeof(*mdi));
if (!mdi)
continue;
if (!mdi->parent) {
mdi->parent = p;
}
perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseDataFileSize);
perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseActiveTransactions);
perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseBackupRestoreOperations);
perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseLogFlushed);
perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseLogFlushes);
perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseTransactions);
perflibGetObjectCounter(pDataBlock, pObjectType, &mdi->MSSQLDatabaseWriteTransactions);
}
dictionary_sorted_walkthrough_read(p->databases, dict_mssql_databases_charts_cb, &update_every);
rrdset_done(p->st_db_data_file_size);
rrdset_done(p->st_db_active_transactions);
rrdset_done(p->st_db_backup_restore_operations);
rrdset_done(p->st_db_log_flushed);
rrdset_done(p->st_db_log_flushes);
rrdset_done(p->st_db_transactions);
rrdset_done(p->st_db_write_transactions);
}
static void do_mssql_memory_mgr(PERF_DATA_BLOCK *pDataBlock, struct mssql_instance *p, int update_every)
{
char id[RRD_ID_LENGTH_MAX + 1];
PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->objectName[NETDATA_MSSQL_MEMORY]);
if (!pObjectType)
return;
if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLConnectionMemoryBytes)) {
snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_connection_memory_bytes", p->instanceID);
if (!p->st_conn_memory) {
p->st_conn_memory = rrdset_create_localhost("mssql"
, id, NULL
, "memory"
, "mssql.instance_memmgr_connection_memory_bytes"
, "Amount of dynamic memory to maintain connections"
, "bytes"
, PLUGIN_WINDOWS_NAME
, "PerflibMSSQL"
, PRIO_MSSQL_MEMMGR_CONNECTION_MEMORY_BYTES
, update_every
, RRDSET_TYPE_LINE
);
snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_memmgr_connection_memory_bytes", p->instanceID);
p->rd_conn_memory = rrddim_add(p->st_conn_memory,
id,
"memory",
1,
1,
RRD_ALGORITHM_ABSOLUTE);
rrdlabels_add(p->st_conn_memory->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
}
rrddim_set_by_pointer(p->st_conn_memory,
p->rd_conn_memory,
(collected_number)(p->MSSQLConnectionMemoryBytes.current.Data*1024));
rrdset_done(p->st_conn_memory);
}
if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLExternalBenefitOfMemory)) {
snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_external_benefit_of_memory", p->instanceID);
if (!p->st_ext_benefit_mem) {
p->st_ext_benefit_mem = rrdset_create_localhost("mssql"
, id, NULL
, "memory"
, "mssql.instance_memmgr_external_benefit_of_memory"
, "Performance benefit from adding memory to a specific cache"
, "bytes"
, PLUGIN_WINDOWS_NAME
, "PerflibMSSQL"
, PRIO_MSSQL_MEMMGR_EXTERNAL_BENEFIT_OF_MEMORY
, update_every
, RRDSET_TYPE_LINE
);
snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_memmgr_external_benefit_of_memory", p->instanceID);
p->rd_ext_benefit_mem = rrddim_add(p->st_ext_benefit_mem,
id,
"benefit",
1,
1,
RRD_ALGORITHM_INCREMENTAL);
rrdlabels_add(p->st_ext_benefit_mem->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
}
rrddim_set_by_pointer(p->st_ext_benefit_mem,
p->rd_ext_benefit_mem,
(collected_number)p->MSSQLExternalBenefitOfMemory.current.Data);
rrdset_done(p->st_ext_benefit_mem);
}
if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLPendingMemoryGrants)) {
snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_pending_memory_grants", p->instanceID);
if (!p->st_pending_mem_grant) {
p->st_pending_mem_grant = rrdset_create_localhost("mssql"
, id, NULL
, "memory"
, "mssql.instance_memmgr_pending_memory_grants"
, "Process waiting for memory grant"
, "process"
, PLUGIN_WINDOWS_NAME
, "PerflibMSSQL"
, PRIO_MSSQL_MEMMGR_PENDING_MEMORY_GRANTS
, update_every
, RRDSET_TYPE_LINE
);
snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_memmgr_pending_memory_grants", p->instanceID);
p->rd_pending_mem_grant = rrddim_add(p->st_pending_mem_grant,
id,
"pending",
1,
1,
RRD_ALGORITHM_ABSOLUTE);
rrdlabels_add(p->st_pending_mem_grant->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
}
rrddim_set_by_pointer(p->st_pending_mem_grant,
p->rd_pending_mem_grant,
(collected_number)p->MSSQLPendingMemoryGrants.current.Data);
rrdset_done(p->st_pending_mem_grant);
}
if (perflibGetObjectCounter(pDataBlock, pObjectType, &p->MSSQLTotalServerMemory)) {
snprintfz(id, RRD_ID_LENGTH_MAX, "instance_%s_memmgr_server_memory", p->instanceID);
if (!p->st_mem_tot_server) {
p->st_mem_tot_server = rrdset_create_localhost("mssql"
, id, NULL
, "memory"
, "mssql.instance_memmgr_server_memory"
, "Memory committed"
, "bytes"
, PLUGIN_WINDOWS_NAME
, "PerflibMSSQL"
, PRIO_MSSQL_MEMMGR_TOTAL_SERVER
, update_every
, RRDSET_TYPE_LINE
);
snprintfz(id, RRD_ID_LENGTH_MAX, "mssql_instance_%s_memmgr_total_server_memory_bytes", p->instanceID);
p->rd_mem_tot_server = rrddim_add(p->st_mem_tot_server,
id,
"memory",
1,
1,
RRD_ALGORITHM_ABSOLUTE);
rrdlabels_add(p->st_mem_tot_server->rrdlabels, "mssql_instance", p->instanceID, RRDLABEL_SRC_AUTO);
}
rrddim_set_by_pointer(p->st_mem_tot_server,
p->rd_mem_tot_server,
(collected_number)(p->MSSQLTotalServerMemory.current.Data*1024));
rrdset_done(p->st_mem_tot_server);
}
}
int dict_mssql_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
struct mssql_instance *p = value;
int *update_every = data;
@ -737,10 +1447,11 @@ int dict_mssql_charts_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value
static void (*doMSSQL[])(PERF_DATA_BLOCK *, struct mssql_instance *, int) = {
do_mssql_general_stats,
do_mssql_errors,
NULL, NULL, NULL,
do_mssql_databases,
do_mssql_locks,
do_mssql_memory_mgr,
do_mssql_buffer_management,
do_mssql_sql_statistics,
NULL,
do_mssql_access_methods
};

View file

@ -43,6 +43,15 @@ enum PERFLIB_PRIO {
PRIO_MSSQL_USER_CONNECTIONS,
PRIO_MSSQL_DATABASE_TRANSACTIONS,
PRIO_MSSQL_DATABASE_ACTIVE_TRANSACTIONS,
PRIO_MSSQL_DATABASE_WRITE_TRANSACTIONS,
PRIO_MSSQL_DATABASE_BACKUP_RESTORE_OPERATIONS,
PRIO_MSSQL_DATABASE_LOG_FLUSHES,
PRIO_MSSQL_DATABASE_LOG_FLUSHED,
PRIO_MSSQL_DATABASE_DATA_FILE_SIZE,
PRIO_MSSQL_STATS_BATCH_REQUEST,
PRIO_MSSQL_STATS_COMPILATIONS,
PRIO_MSSQL_STATS_RECOMPILATIONS,
@ -57,6 +66,14 @@ enum PERFLIB_PRIO {
PRIO_MSSQL_BUFF_METHODS_PAGE_SPLIT,
PRIO_MSSQL_BUFF_PAGE_LIFE_EXPECTANCY,
PRIO_MSSQL_MEMMGR_CONNECTION_MEMORY_BYTES,
PRIO_MSSQL_MEMMGR_TOTAL_SERVER,
PRIO_MSSQL_MEMMGR_EXTERNAL_BENEFIT_OF_MEMORY,
PRIO_MSSQL_MEMMGR_PENDING_MEMORY_GRANTS,
PRIO_MSSQL_LOCKS_WAIT,
PRIO_MSSQL_LOCKS_DEADLOCK,
PRIO_MSSQL_SQL_ERRORS
};