| #include "node_counters.h" |
| #include "uv.h" |
| #include "env.h" |
| #include "env-inl.h" |
| |
| #include <string.h> |
| |
| |
| namespace node { |
| |
| using v8::FunctionCallbackInfo; |
| using v8::FunctionTemplate; |
| using v8::GCCallbackFlags; |
| using v8::GCEpilogueCallback; |
| using v8::GCPrologueCallback; |
| using v8::GCType; |
| using v8::Handle; |
| using v8::HandleScope; |
| using v8::Isolate; |
| using v8::Local; |
| using v8::Object; |
| using v8::String; |
| using v8::Value; |
| |
| static uint64_t counter_gc_start_time; |
| static uint64_t counter_gc_end_time; |
| |
| |
| void COUNTER_NET_SERVER_CONNECTION(const FunctionCallbackInfo<Value>&) { |
| NODE_COUNT_SERVER_CONN_OPEN(); |
| } |
| |
| |
| void COUNTER_NET_SERVER_CONNECTION_CLOSE(const FunctionCallbackInfo<Value>&) { |
| NODE_COUNT_SERVER_CONN_CLOSE(); |
| } |
| |
| |
| void COUNTER_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>&) { |
| NODE_COUNT_HTTP_SERVER_REQUEST(); |
| } |
| |
| |
| void COUNTER_HTTP_SERVER_RESPONSE(const FunctionCallbackInfo<Value>&) { |
| NODE_COUNT_HTTP_SERVER_RESPONSE(); |
| } |
| |
| |
| void COUNTER_HTTP_CLIENT_REQUEST(const FunctionCallbackInfo<Value>&) { |
| NODE_COUNT_HTTP_CLIENT_REQUEST(); |
| } |
| |
| |
| void COUNTER_HTTP_CLIENT_RESPONSE(const FunctionCallbackInfo<Value>&) { |
| NODE_COUNT_HTTP_CLIENT_RESPONSE(); |
| } |
| |
| |
| static void counter_gc_start(Isolate* isolate, |
| GCType type, |
| GCCallbackFlags flags) { |
| counter_gc_start_time = NODE_COUNT_GET_GC_RAWTIME(); |
| } |
| |
| |
| static void counter_gc_done(Isolate* isolate, |
| GCType type, |
| GCCallbackFlags flags) { |
| uint64_t endgc = NODE_COUNT_GET_GC_RAWTIME(); |
| if (endgc != 0) { |
| uint64_t totalperiod = endgc - counter_gc_end_time; |
| uint64_t gcperiod = endgc - counter_gc_start_time; |
| |
| if (totalperiod > 0) { |
| unsigned int percent = static_cast<unsigned int>( |
| (gcperiod * 100) / totalperiod); |
| |
| NODE_COUNT_GC_PERCENTTIME(percent); |
| counter_gc_end_time = endgc; |
| } |
| } |
| } |
| |
| |
| void InitPerfCounters(Environment* env, Handle<Object> target) { |
| HandleScope scope(env->isolate()); |
| |
| static struct { |
| const char* name; |
| void (*func)(const FunctionCallbackInfo<Value>&); |
| } tab[] = { |
| #define NODE_PROBE(name) #name, name |
| { NODE_PROBE(COUNTER_NET_SERVER_CONNECTION) }, |
| { NODE_PROBE(COUNTER_NET_SERVER_CONNECTION_CLOSE) }, |
| { NODE_PROBE(COUNTER_HTTP_SERVER_REQUEST) }, |
| { NODE_PROBE(COUNTER_HTTP_SERVER_RESPONSE) }, |
| { NODE_PROBE(COUNTER_HTTP_CLIENT_REQUEST) }, |
| { NODE_PROBE(COUNTER_HTTP_CLIENT_RESPONSE) } |
| #undef NODE_PROBE |
| }; |
| |
| for (int i = 0; i < ARRAY_SIZE(tab); i++) { |
| Local<String> key = OneByteString(env->isolate(), tab[i].name); |
| Local<Value> val = env->NewFunctionTemplate(tab[i].func)->GetFunction(); |
| target->Set(key, val); |
| } |
| |
| // Only Windows performance counters supported |
| // To enable other OS, use conditional compilation here |
| InitPerfCountersWin32(); |
| |
| // init times for GC percent calculation and hook callbacks |
| counter_gc_start_time = NODE_COUNT_GET_GC_RAWTIME(); |
| counter_gc_end_time = counter_gc_start_time; |
| |
| env->isolate()->AddGCPrologueCallback(counter_gc_start); |
| env->isolate()->AddGCEpilogueCallback(counter_gc_done); |
| } |
| |
| |
| void TermPerfCounters(Handle<Object> target) { |
| // Only Windows performance counters supported |
| // To enable other OS, use conditional compilation here |
| TermPerfCountersWin32(); |
| } |
| |
| } // namespace node |