diff options
Diffstat (limited to 'src/collectors/windows.plugin/perflib-memory.c')
-rw-r--r-- | src/collectors/windows.plugin/perflib-memory.c | 284 |
1 files changed, 219 insertions, 65 deletions
diff --git a/src/collectors/windows.plugin/perflib-memory.c b/src/collectors/windows.plugin/perflib-memory.c index c876fc68a..e26729cda 100644 --- a/src/collectors/windows.plugin/perflib-memory.c +++ b/src/collectors/windows.plugin/perflib-memory.c @@ -1,65 +1,219 @@ -// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "windows_plugin.h"
-#include "windows-internals.h"
-
-#define _COMMON_PLUGIN_NAME "windows.plugin"
-#define _COMMON_PLUGIN_MODULE_NAME "PerflibMemory"
-#include "../common-contexts/common-contexts.h"
-
-static void initialize(void) {
- ;
-}
-
-static bool do_memory(PERF_DATA_BLOCK *pDataBlock, int update_every) {
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, "Memory");
- if (!pObjectType)
- return false;
-
- static COUNTER_DATA pagesPerSec = { .key = "Pages/sec" };
- static COUNTER_DATA pageFaultsPerSec = { .key = "Page Faults/sec" };
-
- if(perflibGetObjectCounter(pDataBlock, pObjectType, &pageFaultsPerSec) &&
- perflibGetObjectCounter(pDataBlock, pObjectType, &pagesPerSec)) {
- ULONGLONG total = pageFaultsPerSec.current.Data;
- ULONGLONG major = pagesPerSec.current.Data;
- ULONGLONG minor = (total > major) ? total - major : 0;
- common_mem_pgfaults(minor, major, update_every);
- }
-
- static COUNTER_DATA availableBytes = { .key = "Available Bytes" };
- static COUNTER_DATA availableKBytes = { .key = "Available KBytes" };
- static COUNTER_DATA availableMBytes = { .key = "Available MBytes" };
- ULONGLONG available_bytes = 0;
-
- if(perflibGetObjectCounter(pDataBlock, pObjectType, &availableBytes))
- available_bytes = availableBytes.current.Data;
- else if(perflibGetObjectCounter(pDataBlock, pObjectType, &availableKBytes))
- available_bytes = availableKBytes.current.Data * 1024;
- else if(perflibGetObjectCounter(pDataBlock, pObjectType, &availableMBytes))
- available_bytes = availableMBytes.current.Data * 1024 * 1024;
-
- common_mem_available(available_bytes, update_every);
-
- return true;
-}
-
-int do_PerflibMemory(int update_every, usec_t dt __maybe_unused) {
- static bool initialized = false;
-
- if(unlikely(!initialized)) {
- initialize();
- initialized = true;
- }
-
- DWORD id = RegistryFindIDByName("Memory");
- if(id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
- return -1;
-
- PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
- if(!pDataBlock) return -1;
-
- do_memory(pDataBlock, update_every);
-
- return 0;
-}
+// SPDX-License-Identifier: GPL-3.0-or-later + +#include "windows_plugin.h" +#include "windows-internals.h" + +#define _COMMON_PLUGIN_NAME "windows.plugin" +#define _COMMON_PLUGIN_MODULE_NAME "PerflibMemory" +#include "../common-contexts/common-contexts.h" + +struct swap { + RRDSET *operations; + RRDDIM *rd_op_read; + RRDDIM *rd_op_write; + + RRDSET *pages; + RRDDIM *rd_page_read; + RRDDIM *rd_page_write; + + COUNTER_DATA pageReadsTotal; + COUNTER_DATA pageWritesTotal; + COUNTER_DATA pageInputTotal; + COUNTER_DATA pageOutputTotal; +}; + +struct system_pool { + RRDSET *pool; + RRDDIM *rd_paged; + RRDDIM *rd_nonpaged; + + COUNTER_DATA pagedData; + COUNTER_DATA nonPagedData; +}; + +struct swap localSwap = { 0 }; +struct system_pool localPool = { 0 }; + +void initialize_swap_keys(struct swap *p) { + // SWAP Operations + p->pageReadsTotal.key = "Page Reads/sec"; + p->pageWritesTotal.key = "Page Writes/s"; + + // Swap Pages + p->pageInputTotal.key = "Pages Input/sec"; + p->pageOutputTotal.key = "Pages Output/s"; +} + +void initialize_pool_keys(struct system_pool *p) { + p->pagedData.key = "Pool Paged Bytes"; + p->nonPagedData.key = "Pool Nonpaged Bytes"; +} + +static void initialize(void) { + initialize_swap_keys(&localSwap); + initialize_pool_keys(&localPool); +} + +static void do_memory_swap(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) +{ + perflibGetObjectCounter(pDataBlock, pObjectType, &localSwap.pageReadsTotal); + perflibGetObjectCounter(pDataBlock, pObjectType, &localSwap.pageWritesTotal); + perflibGetObjectCounter(pDataBlock, pObjectType, &localSwap.pageInputTotal); + perflibGetObjectCounter(pDataBlock, pObjectType, &localSwap.pageOutputTotal); + + if (!localSwap.operations) { + localSwap.operations = rrdset_create_localhost( + "mem" + , "swap_operations", NULL + , "swap" + , "mem.swap_iops" + + , "Swap Operations" + , "operations/s" + , PLUGIN_WINDOWS_NAME + , "PerflibMemory" + , NETDATA_CHART_PRIO_MEM_SWAPIO + , update_every + , RRDSET_TYPE_STACKED + ); + + localSwap.rd_op_read = rrddim_add(localSwap.operations, "read", NULL, + 1, 1, RRD_ALGORITHM_INCREMENTAL); + localSwap.rd_op_write = rrddim_add(localSwap.operations, "write", NULL, + 1, -1, RRD_ALGORITHM_INCREMENTAL); + } + + rrddim_set_by_pointer(localSwap.operations, + localSwap.rd_op_read, + (collected_number)localSwap.pageReadsTotal.current.Data); + + rrddim_set_by_pointer(localSwap.operations, + localSwap.rd_op_write, + (collected_number)localSwap.pageWritesTotal.current.Data); + rrdset_done(localSwap.operations); + + if (!localSwap.pages) { + localSwap.pages = rrdset_create_localhost( + "mem" + , "swap_pages", NULL + , "swap" + , "mem.swap_pages_io" + + , "Swap Pages" + , "pages/s" + , PLUGIN_WINDOWS_NAME + , "PerflibMemory" + , NETDATA_CHART_PRIO_MEM_SWAP_PAGES + , update_every + , RRDSET_TYPE_STACKED + ); + + localSwap.rd_page_read = rrddim_add(localSwap.pages, "read", NULL, + 1, 1, RRD_ALGORITHM_INCREMENTAL); + localSwap.rd_page_write = rrddim_add(localSwap.pages, "write", NULL, + 1, -1, RRD_ALGORITHM_INCREMENTAL); + } + + rrddim_set_by_pointer(localSwap.pages, + localSwap.rd_page_read, + (collected_number)localSwap.pageInputTotal.current.Data); + + rrddim_set_by_pointer(localSwap.pages, + localSwap.rd_page_write, + (collected_number)localSwap.pageOutputTotal.current.Data); + rrdset_done(localSwap.pages); +} + +static void do_memory_system_pool(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every) +{ + perflibGetObjectCounter(pDataBlock, pObjectType, &localPool.nonPagedData); + perflibGetObjectCounter(pDataBlock, pObjectType, &localPool.pagedData); + + if (!localPool.pool) { + localPool.pool = rrdset_create_localhost( + "mem" + , "system_pool", NULL + , "mem" + , "mem.system_pool_size" + + , "System Memory Pool" + , "bytes" + , PLUGIN_WINDOWS_NAME + , "PerflibMemory" + , NETDATA_CHART_PRIO_MEM_SYSTEM_POOL + , update_every + , RRDSET_TYPE_STACKED + ); + + localPool.rd_paged = rrddim_add(localPool.pool, "paged", NULL, + 1, 1, RRD_ALGORITHM_ABSOLUTE); + localPool.rd_nonpaged = rrddim_add(localPool.pool, "pool-paged", NULL, + 1, 1, RRD_ALGORITHM_ABSOLUTE); + } + + rrddim_set_by_pointer(localPool.pool, + localPool.rd_paged, + (collected_number)localPool.pagedData.current.Data); + + rrddim_set_by_pointer(localPool.pool, + localPool.rd_nonpaged, + (collected_number)localPool.nonPagedData.current.Data); + rrdset_done(localPool.pool); +} + +static bool do_memory(PERF_DATA_BLOCK *pDataBlock, int update_every) { + PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, "Memory"); + if (!pObjectType) + return false; + + static COUNTER_DATA pagesPerSec = { .key = "Pages/sec" }; + static COUNTER_DATA pageFaultsPerSec = { .key = "Page Faults/sec" }; + + if(perflibGetObjectCounter(pDataBlock, pObjectType, &pageFaultsPerSec) && + perflibGetObjectCounter(pDataBlock, pObjectType, &pagesPerSec)) { + ULONGLONG total = pageFaultsPerSec.current.Data; + ULONGLONG major = pagesPerSec.current.Data; + ULONGLONG minor = (total > major) ? total - major : 0; + common_mem_pgfaults(minor, major, update_every); + } + + static COUNTER_DATA availableBytes = { .key = "Available Bytes" }; + static COUNTER_DATA availableKBytes = { .key = "Available KBytes" }; + static COUNTER_DATA availableMBytes = { .key = "Available MBytes" }; + ULONGLONG available_bytes = 0; + + if(perflibGetObjectCounter(pDataBlock, pObjectType, &availableBytes)) + available_bytes = availableBytes.current.Data; + else if(perflibGetObjectCounter(pDataBlock, pObjectType, &availableKBytes)) + available_bytes = availableKBytes.current.Data * 1024; + else if(perflibGetObjectCounter(pDataBlock, pObjectType, &availableMBytes)) + available_bytes = availableMBytes.current.Data * 1024 * 1024; + + common_mem_available(available_bytes, update_every); + + do_memory_swap(pDataBlock, pObjectType, update_every); + + do_memory_system_pool(pDataBlock, pObjectType, update_every); + + return true; +} + +int do_PerflibMemory(int update_every, usec_t dt __maybe_unused) { + static bool initialized = false; + + if(unlikely(!initialized)) { + initialize(); + initialized = true; + } + + DWORD id = RegistryFindIDByName("Memory"); + if(id == PERFLIB_REGISTRY_NAME_NOT_FOUND) + return -1; + + PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id); + if(!pDataBlock) return -1; + + do_memory(pDataBlock, update_every); + + return 0; +} |