mirror of
https://github.com/netdata/netdata.git
synced 2025-04-28 14:42:31 +00:00
MSSQL Metrics (Part II). (#18689)
This commit is contained in:
parent
260f718cd2
commit
30b532952a
2 changed files with 753 additions and 25 deletions
src/collectors/windows.plugin
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue