mirror of https://github.com/lukechilds/node.git
Ryan Dahl
14 years ago
9 changed files with 358 additions and 2 deletions
@ -0,0 +1,64 @@ |
|||||
|
/* |
||||
|
* This is the DTrace library file for the node provider, which includes |
||||
|
* the necessary translators to get from the args[] to something useful. |
||||
|
* Be warned: the mechanics here are seriously ugly -- and one must always |
||||
|
* keep in mind that clean abstractions often require filthy systems. |
||||
|
*/ |
||||
|
#pragma D depends_on library procfs.d |
||||
|
|
||||
|
typedef struct { |
||||
|
int32_t fd; |
||||
|
int32_t port; |
||||
|
uint32_t remote; |
||||
|
} node_dtrace_connection_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
int32_t fd; |
||||
|
int32_t port; |
||||
|
uint64_t remote; |
||||
|
} node_dtrace_connection64_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
int fd; |
||||
|
string remoteAddress; |
||||
|
int remotePort; |
||||
|
} node_connection_t; |
||||
|
|
||||
|
translator node_connection_t <node_dtrace_connection_t *nc> { |
||||
|
fd = *(int32_t *)copyin((uintptr_t)&nc->fd, sizeof (int32_t)); |
||||
|
remotePort = |
||||
|
*(int32_t *)copyin((uintptr_t)&nc->port, sizeof (int32_t)); |
||||
|
remoteAddress = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? |
||||
|
copyinstr((uintptr_t)*(uint32_t *)copyin((uintptr_t)&nc->remote, |
||||
|
sizeof (int32_t))) : |
||||
|
copyinstr((uintptr_t)*(uint64_t *)copyin((uintptr_t) |
||||
|
&((node_dtrace_connection64_t *)nc)->remote, sizeof (int64_t))); |
||||
|
}; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint32_t url; |
||||
|
uint32_t method; |
||||
|
} node_dtrace_http_request_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint64_t url; |
||||
|
uint64_t method; |
||||
|
} node_dtrace_http_request64_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
string url; |
||||
|
string method; |
||||
|
} node_http_request_t; |
||||
|
|
||||
|
translator node_http_request_t <node_dtrace_http_request_t *nd> { |
||||
|
url = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? |
||||
|
copyinstr((uintptr_t)*(uint32_t *)copyin((uintptr_t)&nd->url, |
||||
|
sizeof (int32_t))) : |
||||
|
copyinstr((uintptr_t)*(uint64_t *)copyin((uintptr_t) |
||||
|
&((node_dtrace_http_request64_t *)nd)->url, sizeof (int64_t))); |
||||
|
method = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? |
||||
|
copyinstr((uintptr_t)*(uint32_t *)copyin((uintptr_t)&nd->method, |
||||
|
sizeof (int32_t))) : |
||||
|
copyinstr((uintptr_t)*(uint64_t *)copyin((uintptr_t) |
||||
|
&((node_dtrace_http_request64_t *)nd)->method, sizeof (int64_t))); |
||||
|
}; |
@ -0,0 +1,113 @@ |
|||||
|
#include <node_dtrace.h> |
||||
|
|
||||
|
#ifdef HAVE_DTRACE |
||||
|
#include "node_provider.h" |
||||
|
#else |
||||
|
#define NODE_HTTP_SERVER_REQUEST(arg0, arg1) |
||||
|
#define NODE_HTTP_SERVER_REQUEST_ENABLED() (0) |
||||
|
#define NODE_HTTP_SERVER_RESPONSE(arg0) |
||||
|
#define NODE_HTTP_SERVER_RESPONSE_ENABLED() (0) |
||||
|
#define NODE_NET_SERVER_CONNECTION(arg0) |
||||
|
#define NODE_NET_SERVER_CONNECTION_ENABLED() (0) |
||||
|
#define NODE_NET_STREAM_END(arg0) |
||||
|
#define NODE_NET_STREAM_END_ENABLED() (0) |
||||
|
#endif |
||||
|
|
||||
|
namespace node { |
||||
|
|
||||
|
using namespace v8; |
||||
|
|
||||
|
#define SLURP_STRING(obj, member, valp) \ |
||||
|
String::Utf8Value _##member(obj->Get(String::New(#member))->ToString()); \ |
||||
|
if ((*(const char **)valp = *_##member) == NULL) \ |
||||
|
*(const char **)valp = "<unknown>"; |
||||
|
|
||||
|
#define SLURP_INT(obj, member, valp) \ |
||||
|
*valp = obj->Get(String::New(#member))->ToInteger()->Value(); |
||||
|
|
||||
|
#define SLURP_CONNECTION(arg, conn) \ |
||||
|
node_dtrace_connection_t conn; \ |
||||
|
Local<Object> _##conn = Local<Object>::Cast(arg); \ |
||||
|
SLURP_INT(_##conn, fd, &conn.fd); \ |
||||
|
SLURP_STRING(_##conn, remoteAddress, &conn.remote); \ |
||||
|
SLURP_INT(_##conn, remotePort, &conn.port); |
||||
|
|
||||
|
Handle<Value> DTRACE_NET_SERVER_CONNECTION(const Arguments& args) { |
||||
|
if (!NODE_NET_SERVER_CONNECTION_ENABLED()) |
||||
|
return Undefined(); |
||||
|
|
||||
|
HandleScope scope; |
||||
|
|
||||
|
SLURP_CONNECTION(args[0], conn); |
||||
|
NODE_NET_SERVER_CONNECTION(&conn); |
||||
|
|
||||
|
return Undefined(); |
||||
|
} |
||||
|
|
||||
|
Handle<Value> DTRACE_NET_STREAM_END(const Arguments& args) { |
||||
|
if (!NODE_NET_STREAM_END_ENABLED()) |
||||
|
return Undefined(); |
||||
|
|
||||
|
HandleScope scope; |
||||
|
|
||||
|
SLURP_CONNECTION(args[0], conn); |
||||
|
NODE_NET_STREAM_END(&conn); |
||||
|
|
||||
|
return Undefined(); |
||||
|
} |
||||
|
|
||||
|
Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) { |
||||
|
node_dtrace_http_request_t req; |
||||
|
|
||||
|
if (!NODE_HTTP_SERVER_REQUEST_ENABLED()) |
||||
|
return Undefined(); |
||||
|
|
||||
|
HandleScope scope; |
||||
|
|
||||
|
Local<Object> arg0 = Local<Object>::Cast(args[0]); |
||||
|
Local<Object> arg1 = Local<Object>::Cast(args[1]); |
||||
|
|
||||
|
SLURP_STRING(arg0, url, &req.url); |
||||
|
SLURP_STRING(arg0, method, &req.method); |
||||
|
|
||||
|
SLURP_CONNECTION(args[1], conn); |
||||
|
|
||||
|
NODE_HTTP_SERVER_REQUEST(&req, &conn); |
||||
|
return Undefined(); |
||||
|
} |
||||
|
|
||||
|
Handle<Value> DTRACE_HTTP_SERVER_RESPONSE(const Arguments& args) { |
||||
|
if (!NODE_HTTP_SERVER_RESPONSE_ENABLED()) |
||||
|
return Undefined(); |
||||
|
|
||||
|
HandleScope scope; |
||||
|
|
||||
|
SLURP_CONNECTION(args[0], conn); |
||||
|
NODE_HTTP_SERVER_RESPONSE(&conn); |
||||
|
|
||||
|
return Undefined(); |
||||
|
} |
||||
|
|
||||
|
#define NODE_PROBE(name) #name, name |
||||
|
|
||||
|
void InitDTrace(Handle<Object> target) { |
||||
|
static struct { |
||||
|
const char *name; |
||||
|
Handle<Value> (*func)(const Arguments&); |
||||
|
Persistent<FunctionTemplate> templ; |
||||
|
} tab[] = { |
||||
|
{ NODE_PROBE(DTRACE_NET_SERVER_CONNECTION) }, |
||||
|
{ NODE_PROBE(DTRACE_NET_STREAM_END) }, |
||||
|
{ NODE_PROBE(DTRACE_HTTP_SERVER_REQUEST) }, |
||||
|
{ NODE_PROBE(DTRACE_HTTP_SERVER_RESPONSE) }, |
||||
|
{ NULL } |
||||
|
}; |
||||
|
|
||||
|
for (int i = 0; tab[i].name != NULL; i++) { |
||||
|
tab[i].templ = Persistent<FunctionTemplate>::New( |
||||
|
FunctionTemplate::New(tab[i].func)); |
||||
|
target->Set(String::NewSymbol(tab[i].name), tab[i].templ->GetFunction()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
#ifndef NODE_DTRACE_H_ |
||||
|
#define NODE_DTRACE_H_ |
||||
|
|
||||
|
#include <node.h> |
||||
|
#include <v8.h> |
||||
|
|
||||
|
extern "C" { |
||||
|
|
||||
|
typedef struct { |
||||
|
int32_t fd; |
||||
|
int32_t port; |
||||
|
char *remote; |
||||
|
} node_dtrace_connection_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
char *url; |
||||
|
char *method; |
||||
|
} node_dtrace_http_request_t; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
namespace node { |
||||
|
|
||||
|
void InitDTrace(v8::Handle<v8::Object> target); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endif |
@ -0,0 +1,44 @@ |
|||||
|
/* |
||||
|
* DTrace provider for node.js. |
||||
|
*/ |
||||
|
|
||||
|
/* |
||||
|
* In order to have the information we need here to create the provider, |
||||
|
* we must declare bogus definitions for our depended-upon structures. And |
||||
|
* yes, the fact that we need to do this represents a shortcoming in DTrace, |
||||
|
* one that would be resolved by that elusive El Dorado: dynamic translators. |
||||
|
*/ |
||||
|
|
||||
|
typedef struct { |
||||
|
int dummy; |
||||
|
} node_dtrace_connection_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
int dummy; |
||||
|
} node_connection_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
int dummy; |
||||
|
} node_dtrace_http_request_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
int dummy; |
||||
|
} node_http_request_t; |
||||
|
|
||||
|
provider node { |
||||
|
probe net__server__connection(node_dtrace_connection_t *c) : |
||||
|
(node_connection_t *c); |
||||
|
probe net__stream__end(node_dtrace_connection_t *c) : |
||||
|
(node_connection_t *c); |
||||
|
probe http__server__request(node_dtrace_http_request_t *h, |
||||
|
node_dtrace_connection_t *c) : |
||||
|
(node_http_request_t *h, node_connection_t *c); |
||||
|
probe http__server__response(node_dtrace_connection_t *c) : |
||||
|
(node_connection_t *c); |
||||
|
}; |
||||
|
|
||||
|
#pragma D attributes Evolving/Evolving/ISA provider node provider |
||||
|
#pragma D attributes Private/Private/Unknown provider node module |
||||
|
#pragma D attributes Private/Private/Unknown provider node function |
||||
|
#pragma D attributes Private/Private/ISA provider node name |
||||
|
#pragma D attributes Evolving/Evolving/ISA provider node args |
Loading…
Reference in new issue