blob: 903150ed61b3c1cac70f460b8520c296df40ee5b [file] [log] [blame]
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "node_counters.h"
#include <perflib.h>
#include "node_win32_perfctr_provider.h"
#define __INIT_node_perfctr_provider_IMP
#include <node_perfctr_provider.h>
typedef ULONG (WINAPI *PerfStartProviderExFunc)(
__in LPGUID ProviderGuid,
__in_opt PPERF_PROVIDER_CONTEXT ProviderContext,
__out PHANDLE Provider
);
typedef ULONG (WINAPI *PerfStopProviderFunc)(
__in HANDLE ProviderHandle
);
typedef ULONG (WINAPI *PerfSetCounterSetInfoFunc)(
__in HANDLE ProviderHandle,
__inout_bcount(TemplateSize) PPERF_COUNTERSET_INFO Template,
__in ULONG TemplateSize
);
typedef PPERF_COUNTERSET_INSTANCE (WINAPI *PerfCreateInstanceFunc)(
__in HANDLE ProviderHandle,
__in LPCGUID CounterSetGuid,
__in PCWSTR Name,
__in ULONG Id
);
typedef ULONG (WINAPI *PerfDeleteInstanceFunc)(
__in HANDLE Provider,
__in PPERF_COUNTERSET_INSTANCE InstanceBlock
);
typedef ULONG (WINAPI *PerfSetULongCounterValueFunc)(
__in HANDLE Provider,
__inout PPERF_COUNTERSET_INSTANCE Instance,
__in ULONG CounterId,
__in ULONG Value
);
typedef ULONG (WINAPI *PerfSetULongLongCounterValueFunc)(
__in HANDLE Provider,
__inout PPERF_COUNTERSET_INSTANCE Instance,
__in ULONG CounterId,
__in ULONGLONG Value
);
typedef ULONG (WINAPI *PerfIncrementULongCounterValueFunc)(
__in HANDLE Provider,
__inout PPERF_COUNTERSET_INSTANCE Instance,
__in ULONG CounterId,
__in ULONG Value
);
typedef ULONG (WINAPI *PerfIncrementULongLongCounterValueFunc)(
__in HANDLE Provider,
__inout PPERF_COUNTERSET_INSTANCE Instance,
__in ULONG CounterId,
__in ULONGLONG Value
);
typedef ULONG (WINAPI *PerfDecrementULongCounterValueFunc)(
__in HANDLE Provider,
__inout PPERF_COUNTERSET_INSTANCE Instance,
__in ULONG CounterId,
__in ULONG Value
);
typedef ULONG (WINAPI *PerfDecrementULongLongCounterValueFunc)(
__in HANDLE Provider,
__inout PPERF_COUNTERSET_INSTANCE Instance,
__in ULONG CounterId,
__in ULONGLONG Value
);
HMODULE advapimod;
PerfStartProviderExFunc perfctr_startProvider;
PerfStopProviderFunc perfctr_stopProvider;
PerfSetCounterSetInfoFunc perfctr_setCounterSetInfo;
PerfCreateInstanceFunc perfctr_createInstance;
PerfDeleteInstanceFunc perfctr_deleteInstance;
PerfSetULongCounterValueFunc perfctr_setULongValue;
PerfSetULongLongCounterValueFunc perfctr_setULongLongValue;
PerfIncrementULongCounterValueFunc perfctr_incrementULongValue;
PerfIncrementULongLongCounterValueFunc perfctr_incrementULongLongValue;
PerfDecrementULongCounterValueFunc perfctr_decrementULongValue;
PerfDecrementULongLongCounterValueFunc perfctr_decrementULongLongValue;
PPERF_COUNTERSET_INSTANCE perfctr_instance;
#define NODE_COUNTER_HTTP_SERVER_REQUEST 1
#define NODE_COUNTER_HTTP_SERVER_RESPONSE 2
#define NODE_COUNTER_HTTP_CLIENT_REQUEST 3
#define NODE_COUNTER_HTTP_CLIENT_RESPONSE 4
#define NODE_COUNTER_SERVER_CONNS 5
#define NODE_COUNTER_NET_BYTES_SENT 6
#define NODE_COUNTER_NET_BYTES_RECV 7
#define NODE_COUNTER_GC_PERCENTTIME 8
#define NODE_COUNTER_PIPE_BYTES_SENT 9
#define NODE_COUNTER_PIPE_BYTES_RECV 10
namespace node {
EXTERN_C DECLSPEC_SELECTANY HANDLE NodeCounterProvider = NULL;
void InitPerfCountersWin32() {
ULONG status;
PERF_PROVIDER_CONTEXT providerContext;
// create instance name using pid
#define INST_MAX_LEN 32
#define INST_PREFIX_LEN 5
#define INST_PREFIX L"node_"
wchar_t Inst[INST_MAX_LEN];
DWORD pid = GetCurrentProcessId();
wcscpy_s(Inst, INST_MAX_LEN, INST_PREFIX);
_itow_s(pid, Inst + INST_PREFIX_LEN, INST_MAX_LEN - INST_PREFIX_LEN, 10);
advapimod = LoadLibrary("advapi32.dll");
if (advapimod) {
perfctr_startProvider = (PerfStartProviderExFunc)
GetProcAddress(advapimod, "PerfStartProviderEx");
perfctr_stopProvider = (PerfStopProviderFunc)
GetProcAddress(advapimod, "PerfStopProvider");
perfctr_setCounterSetInfo = (PerfSetCounterSetInfoFunc)
GetProcAddress(advapimod, "PerfSetCounterSetInfo");
perfctr_createInstance = (PerfCreateInstanceFunc)
GetProcAddress(advapimod, "PerfCreateInstance");
perfctr_deleteInstance = (PerfDeleteInstanceFunc)
GetProcAddress(advapimod, "PerfDeleteInstance");
perfctr_setULongValue = (PerfSetULongCounterValueFunc)
GetProcAddress(advapimod, "PerfSetULongCounterValue");
perfctr_setULongLongValue = (PerfSetULongLongCounterValueFunc)
GetProcAddress(advapimod, "PerfSetULongLongCounterValue");
perfctr_incrementULongValue = (PerfIncrementULongCounterValueFunc)
GetProcAddress(advapimod, "PerfIncrementULongCounterValue");
perfctr_incrementULongLongValue = (PerfIncrementULongLongCounterValueFunc)
GetProcAddress(advapimod, "PerfIncrementULongLongCounterValue");
perfctr_decrementULongValue = (PerfDecrementULongCounterValueFunc)
GetProcAddress(advapimod, "PerfDecrementULongCounterValue");
perfctr_decrementULongLongValue = (PerfDecrementULongLongCounterValueFunc)
GetProcAddress(advapimod, "PerfDecrementULongLongCounterValue");
ZeroMemory(&providerContext, sizeof(providerContext));
providerContext.ContextSize = sizeof(providerContext);
if (!perfctr_startProvider ||
!perfctr_setCounterSetInfo ||
!perfctr_createInstance) {
NodeCounterProvider = NULL;
return;
}
status = perfctr_startProvider(&NodeCounterSetGuid,
&providerContext,
&NodeCounterProvider);
if (status != ERROR_SUCCESS) {
NodeCounterProvider = NULL;
return;
}
status = perfctr_setCounterSetInfo(NodeCounterProvider,
&NodeCounterSetInfo.CounterSet,
sizeof(NodeCounterSetInfo));
if (status != ERROR_SUCCESS) {
perfctr_stopProvider(NodeCounterProvider);
NodeCounterProvider = NULL;
return;
}
perfctr_instance = perfctr_createInstance(NodeCounterProvider,
&NodeCounterSetGuid,
Inst,
1);
if (perfctr_instance == NULL) {
perfctr_stopProvider(NodeCounterProvider);
NodeCounterProvider = NULL;
}
}
}
void TermPerfCountersWin32() {
if (NodeCounterProvider != NULL &&
perfctr_stopProvider != NULL) {
perfctr_stopProvider(NodeCounterProvider);
NodeCounterProvider = NULL;
}
if (advapimod) {
FreeLibrary(advapimod);
advapimod = NULL;
}
}
void NODE_COUNT_HTTP_SERVER_REQUEST() {
if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
perfctr_incrementULongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_HTTP_SERVER_REQUEST,
1);
}
}
void NODE_COUNT_HTTP_SERVER_RESPONSE() {
if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
perfctr_incrementULongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_HTTP_SERVER_RESPONSE,
1);
}
}
void NODE_COUNT_HTTP_CLIENT_REQUEST() {
if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
perfctr_incrementULongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_HTTP_CLIENT_REQUEST,
1);
}
}
void NODE_COUNT_HTTP_CLIENT_RESPONSE() {
if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
perfctr_incrementULongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_HTTP_CLIENT_RESPONSE,
1);
}
}
void NODE_COUNT_SERVER_CONN_OPEN() {
if (NodeCounterProvider != NULL && perfctr_incrementULongValue != NULL) {
perfctr_incrementULongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_SERVER_CONNS,
1);
}
}
void NODE_COUNT_SERVER_CONN_CLOSE() {
if (NodeCounterProvider != NULL && perfctr_decrementULongValue != NULL) {
perfctr_decrementULongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_SERVER_CONNS,
1);
}
}
void NODE_COUNT_NET_BYTES_SENT(int bytes) {
if (NodeCounterProvider != NULL && perfctr_incrementULongLongValue != NULL) {
perfctr_incrementULongLongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_NET_BYTES_SENT,
static_cast<ULONGLONG>(bytes));
}
}
void NODE_COUNT_NET_BYTES_RECV(int bytes) {
if (NodeCounterProvider != NULL && perfctr_incrementULongLongValue != NULL) {
perfctr_incrementULongLongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_NET_BYTES_RECV,
static_cast<ULONGLONG>(bytes));
}
}
uint64_t NODE_COUNT_GET_GC_RAWTIME() {
LARGE_INTEGER timegc;
if (QueryPerformanceCounter(&timegc)) {
return timegc.QuadPart;
} else {
return static_cast<uint64_t>(GetTickCount());
}
}
void NODE_COUNT_GC_PERCENTTIME(unsigned int percent) {
if (NodeCounterProvider != NULL && perfctr_setULongValue != NULL) {
perfctr_setULongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_GC_PERCENTTIME,
percent);
}
}
void NODE_COUNT_PIPE_BYTES_SENT(int bytes) {
if (NodeCounterProvider != NULL && perfctr_incrementULongLongValue != NULL) {
perfctr_incrementULongLongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_PIPE_BYTES_SENT,
static_cast<ULONGLONG>(bytes));
}
}
void NODE_COUNT_PIPE_BYTES_RECV(int bytes) {
if (NodeCounterProvider != NULL && perfctr_incrementULongLongValue != NULL) {
perfctr_incrementULongLongValue(NodeCounterProvider,
perfctr_instance,
NODE_COUNTER_PIPE_BYTES_RECV,
static_cast<ULONGLONG>(bytes));
}
}
}