Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added heap used and total heap statistics. #35

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ Here is the list of data the module reports periodically:
utcstart: <when the process was started>,
events: <number of new reports being processed since last stats reporting>,,
cpu: <cpu usage>,
mem: <memory usage>,
mem: <ratio of used to total heap memory used>,
usedheap: <v8 heap memory used>,
totalheap: <v8 total heap size>,
cpuperreq: <cpu usage per request>,
oreqs: <current open requests count>,
sys_cpu: <system cpu load>,
Expand Down Expand Up @@ -83,6 +85,24 @@ monitor.setIpcMonitorPath('/tmp/my-process-stats.mon');
```
Sets the datagram socket name to write the stats. Defaults to /tmp/nodejs.mon

## setReportInterval(ms)
```js
monitor.setReportInterval(1000);
```
Sets the report interval. Defaults to 1000ms. Integer.

## setCustomName(name)
```js
monitor.setCustomName("processname");
```
Sets the custom process name. This will be sent as custom_name inside the JSON payload. String.

## setCustomId(id)
```js
monitor.setCustomName("process-id");
```
Sets the custom process id. This will be sent as custom_id inside the JSON payload. String.

# Health Status
Monitr supports custom health functionality whereby the app can report its own health.
The following methods are added to process.monitor to set and get the health information.
Expand Down
74 changes: 72 additions & 2 deletions src/monitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@ using namespace v8;
// This is the default IPC path where the stats are written to
// Could use the setter method to change this
static string _ipcMonitorPath = "/tmp/nodejs.mon";
static string _customName = "";
static string _customId = "";

static bool _show_backtrace = false; //< default to false for performance

// Normally reports will be sent every REPORT_INTERVAL_MS
// However, if there is no receiver on the other end (i.e. sendmsg()
// returns -1), then the reporting thread will wait MAX_INACTIVITY_RETRIES
// before trying again.
static const int REPORT_INTERVAL_MS = 1000;
static int REPORT_INTERVAL_MS = 1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this static const int?

static const int MAX_INACTIVITY_RETRIES = 5;

/* globals used for signal catching, etc */
Expand Down Expand Up @@ -403,7 +406,9 @@ void NodeMonitor::setStatistics() {
v8::HeapStatistics v8stats;
Nan::GetHeapStatistics(&v8stats);

stats_.pmem_ = (v8stats.used_heap_size() / (double) v8stats.total_heap_size());
stats_.usedheap_ = v8stats.used_heap_size();
stats_.totalheap_ = v8stats.total_heap_size();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How expensive are these calls? Should we try to make them only once each?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes. that's probably a much better idea. I've updated the code to not do the extra call.

stats_.pmem_ = (stats_.usedheap_ / (double) stats_.totalheap_);
}

{ // Obtains the CPU usage
Expand Down Expand Up @@ -786,6 +791,18 @@ bool NodeMonitor::sendReport() {
data.append(buffer);
}

snprintf(buffer, sizeof(buffer), "\"custom_name\":\"%s\",", _customName.c_str());
data.append(buffer);

snprintf(buffer, sizeof(buffer), "\"custom_id\":\"%s\",", _customId.c_str());
data.append(buffer);

snprintf(buffer, sizeof(buffer), "\"usedheap\":%d,", stats.usedheap_);
data.append(buffer);

snprintf(buffer, sizeof(buffer), "\"totalheap\":%d,", stats.totalheap_);
data.append(buffer);

// requests served since beginning
snprintf(buffer, sizeof(buffer), "\"reqstotal\":%d,", stats.lastRequests_);
data.append(buffer);
Expand Down Expand Up @@ -1027,6 +1044,18 @@ static NAN_GETTER(GetterIPCMonitorPath) {
info.GetReturnValue().Set(Nan::New<String>(_ipcMonitorPath.c_str()).ToLocalChecked());
}

static NAN_GETTER(GetterCustomName) {
info.GetReturnValue().Set(Nan::New<String>(_customName.c_str()).ToLocalChecked());
}

static NAN_GETTER(GetterReportInterval) {
info.GetReturnValue().Set(Nan::New<Number>(REPORT_INTERVAL_MS));
}

static NAN_GETTER(GetterCustomId) {
info.GetReturnValue().Set(Nan::New<String>(_customId.c_str()).ToLocalChecked());
}

static NAN_GETTER(GetterShowBackTrace) {
info.GetReturnValue().Set(_show_backtrace);
}
Expand All @@ -1050,6 +1079,35 @@ static NAN_METHOD(SetterIPCMonitorPath) {
info.GetReturnValue().SetUndefined();
}

static NAN_METHOD(SetterReportInterval) {
if (info.Length() < 1 ||
(!info[0]->IsNumber() && !info[0]->IsUndefined() && !info[0]->IsNull())) {
THROW_BAD_ARGS();
}
REPORT_INTERVAL_MS = info[0]->Uint32Value();
info.GetReturnValue().SetUndefined();
}

static NAN_METHOD(SetterCustomName) {
if (info.Length() < 1 ||
(!info[0]->IsString() && !info[0]->IsUndefined() && !info[0]->IsNull())) {
THROW_BAD_ARGS();
}
String::Utf8Value customName(info[0]);
_customName = *customName;
info.GetReturnValue().SetUndefined();
}

static NAN_METHOD(SetterCustomId) {
if (info.Length() < 1 ||
(!info[0]->IsString() && !info[0]->IsUndefined() && !info[0]->IsNull())) {
THROW_BAD_ARGS();
}
String::Utf8Value customId(info[0]);
_customId = *customId;
info.GetReturnValue().SetUndefined();
}

static NAN_METHOD(StartMonitor) {
NodeMonitor::getInstance().Start();
info.GetReturnValue().SetUndefined();
Expand All @@ -1076,9 +1134,21 @@ NAN_MODULE_INIT(init) {
Nan::SetAccessor( exports, Nan::New("ipcMonitorPath").ToLocalChecked(),
GetterIPCMonitorPath, 0, v8::Local<v8::Value>(),
v8::PROHIBITS_OVERWRITING, v8::DontDelete );
Nan::SetAccessor( exports, Nan::New("customName").ToLocalChecked(),
GetterCustomName, 0, v8::Local<v8::Value>(),
v8::PROHIBITS_OVERWRITING, v8::DontDelete );
Nan::SetAccessor( exports, Nan::New("customId").ToLocalChecked(),
GetterCustomId, 0, v8::Local<v8::Value>(),
v8::PROHIBITS_OVERWRITING, v8::DontDelete );
Nan::SetAccessor( exports, Nan::New("reportInterval").ToLocalChecked(),
GetterReportInterval, 0, v8::Local<v8::Value>(),
v8::PROHIBITS_OVERWRITING, v8::DontDelete );
Nan::SetAccessor( exports, Nan::New("showBacktrace").ToLocalChecked(),
GetterShowBackTrace, SetterShowBackTrace );
Nan::Export( exports, "setIpcMonitorPath", SetterIPCMonitorPath);
Nan::Export( exports, "setReportInterval", SetterReportInterval);
Nan::Export( exports, "setCustomName", SetterCustomName);
Nan::Export( exports, "setCustomId", SetterCustomId);
Nan::Export( exports, "start", StartMonitor);
Nan::Export( exports, "stop", StopMonitor);

Expand Down
4 changes: 4 additions & 0 deletions src/monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ typedef struct {
volatile time_t healthStatusTimestamp_;

volatile double pmem_;

volatile int usedheap_;

volatile int totalheap_;
} Statistics;


Expand Down