프로젝트

일반

사용자정보

통계
| 개정판:

root / HServer / 00.Server / 00.Program / node_modules / dtrace-provider / README.md

이력 | 보기 | 이력해설 | 다운로드 (8.17 KB)

1
# dtrace-provider - Native DTrace providers for Node.js apps.
2

    
3
This extension allows you to create native DTrace providers for your
4
Node.js applications. That is, to create providers and probes which
5
expose information specific to your application, rather than
6
information about the node runtime.
7

    
8
You could use this to expose high-level information about the inner
9
workings of your application, or to create a specific context in which
10
to look at information from other runtime or system-level providers. 
11

    
12
The provider is not created in the usual way, by declaring it and then
13
changing the build process to include it, but instead dynamically at
14
runtime. This is done entirely in-process, and there is no background
15
compiler or [dtrace(1M)](https://illumos.org/man/1M/dtrace) invocation.
16
The process creating the provider need not run as root.
17

    
18
## INSTALL
19

    
20
    $ npm install dtrace-provider
21

    
22
## EXAMPLE
23

    
24
Here's a simple example of creating a provider:
25

    
26
```javascript
27
var d = require('dtrace-provider');
28

    
29
var dtp = d.createDTraceProvider("nodeapp");
30
var p1 = dtp.addProbe("probe1", "int", "int");
31
var p2 = dtp.addProbe("probe2", "char *");
32
dtp.enable();
33
```
34

    
35
Probes may be fired via the provider object:
36

    
37
```javascript
38
dtp.fire("probe1", function() {
39
    return [1, 2];
40
});
41
dtp.fire("probe2", function() {
42
    return ["hello, dtrace via provider", "foo"];
43
});
44
```
45

    
46
or via the probe objects themselves:
47

    
48
```javascript
49
p1.fire(function() {
50
  return [1, 2, 3, 4, 5, 6];
51
});
52
p2.fire(function() {
53
  return ["hello, dtrace via probe", "foo"];
54
});
55
```
56

    
57
Note that `.fire()` takes a callback that returns the arguments to be
58
provided when the DTrace probe actually fires. This allows you to call
59
`.fire()` unconditionally when you want to fire the probe, but the
60
callback will be invoked only when the DTrace probe is actually
61
enabled. This allows you to create probes whose arguments might be
62
expensive to construct, and only do any work when the probe is
63
actually enabled. (Examples might include converting a large object to
64
a string representation or gathering large amounts of information.)
65

    
66
In some cases, creating a new closure to pass to `.fire()` each time
67
it's called may introduce unwanted overhead. For extremely
68
CPU-intensive or memory-conscious workloads, you can avoid this by
69
lifting the closures for your hot probes into an outer scope. You can
70
then supply arguments to that function as additional arguments to
71
`.fire()`. As an example, you can convert the following program:
72

    
73
```javascript
74
function manipulateObj(largeObj) {
75
    var count = 0;
76
    var name = null;
77
    ...
78
    p1.fire(function () {
79
        return [count, keyToValue(name), JSON.stringify(largeObj)];
80
    });
81
}
82
```
83

    
84
Into this one:
85

    
86
```javascript
87
function f(a, b, c) {
88
    return [a, keyToValue(b), JSON.stringify(c)];
89
}
90

    
91
function manipulateObj(largeObj) {
92
    var count = 0;
93
    var name = null;
94
    ...
95
    p1.fire(f, count, name, largeObj);
96
}
97
```
98

    
99
Be careful to avoid passing `.fire()` additional arguments that are
100
themselves expensive to construct, as that undermines the design goal
101
here: minimizing the effect of disabled probes.
102

    
103
This example creates a provider called "nodeapp", and adds two
104
probes. It then enables the provider, at which point the provider
105
becomes visible to DTrace.
106

    
107
The probes are then fired, which produces this output:
108

    
109
    $ sudo dtrace -Z -n 'nodeapp*:::probe1{ trace(arg0); trace(arg1) }'  \
110
                     -n 'nodeapp*:::probe2{ trace(copyinstr(arg0));  }'
111
    dtrace: description 'nodeapp*:::probe1' matched 0 probes
112
    dtrace: description 'nodeapp*:::probe2' matched 0 probes
113
    CPU     ID                    FUNCTION:NAME
114
      1 123562                      func:probe1                 1                2
115
      1 123563                      func:probe2   hello, dtrace                    
116

    
117
Arguments are captured by a callback only executed when the probe is
118
enabled. This means you can do more expensive work to gather arguments.
119

    
120
The maximum number of arguments supported is 32. 
121

    
122
Available argument types are "int", for integer numeric values,
123
"char *" for strings, and "json" for objects rendered into JSON strings.
124

    
125
Arguments typed as "json" will be created as "char *" probes in
126
DTrace, but objects passed to these probe arguments will be
127
automatically serialized to JSON before being passed to DTrace. This
128
feature is best used in conjunction with the json() D subroutine, but
129
is available whether or not the platform supports it.
130

    
131
    # create a json probe:
132

    
133
    var dtp = d.createDTraceProvider("nodeapp");
134
    var p1 = dtp.addProbe("j1", "json");
135
    dtp.enable();
136
    p1.fire(function() { return { "foo": "bar" }; });
137

    
138
    # on a platform supporting json():
139

    
140
    $ sudo dtrace -Z -n 'nodeapp*:::j1{ this->j = copyinstr(arg0); \
141
                                        trace(json(this->j, "foo")) }'
142
    dtrace: description 'nodeapp$target:::j1' matched 0 probes
143
    CPU     ID                    FUNCTION:NAME
144
      0  68712                            j1:j1   bar
145

    
146
## PLATFORM SUPPORT
147

    
148
This libusdt-based Node.JS module supports 64 and 32 bit processes on
149
Mac OS X and Solaris-like systems such as illumos or SmartOS. As more
150
platform support is added to libusdt, those platforms will be
151
supported by this module. See libusdt's status at:
152

    
153
  https://github.com/chrisa/libusdt#readme
154

    
155
When using Mac OS X, be aware that as of 10.11 (El Capitan), DTrace use
156
is restricted, and you'll probably want to
157
[disable SIP](http://internals.exposed/blog/dtrace-vs-sip.html) to
158
effectively use DTrace.
159

    
160
FreeBSD 10 and 11 are also supported, but you'll need to make sure that
161
you have the DTrace headers installed in `/usr/src` otherwise libusdt
162
won't be able to compile. You can
163
[clone them using SVN](https://www.freebsd.org/doc/handbook/svn.html),
164
or find the correct `src.txz`
165
[here](http://ftp.freebsd.org/pub/FreeBSD/releases/) and extract that.
166
Also note that FreeBSD 10 is restricted to only 4 working arguments per
167
probe.
168

    
169
Platforms not supporting DTrace (notably, Linux and Windows) may
170
install this module without building libusdt, with a stub no-op
171
implementation provided for compatibility. This allows cross-platform
172
npm modules to embed probes and include a dependency on this module.
173

    
174
GNU Make is required to build libusdt; the build scripts will look for
175
gmake in `PATH` first, and then for make.
176

    
177
### TROUBLESHOOTING BUILD ISSUES
178

    
179
If compilation fails during installation on platforms with DTrace, then
180
the library will fall back to the stub implementation that does nothing.
181
To force an installation failure when compiling fails, set the environment
182
variable `NODE_DTRACE_PROVIDER_REQUIRE` to `hard`:
183

    
184
```shell
185
$ NODE_DTRACE_PROVIDER_REQUIRE=hard npm install
186
```
187

    
188
This will then show you the output of the build process so you can see at
189
which point it's having an issue. Common issues are:
190

    
191
- Missing a C/C++ compiler toolchain for your platform.
192
- `python` is Python 3 instead of Python 2; run `npm config set python python2.7`
193
  (or similar) to set the Python binary npm uses.
194
- On OS X you may need to agree to the XCode license if that's the compiler
195
  toolchain you're using. This will usually manifest with an error like
196
  `Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.`
197
  To accept the license, you can run `sudo xcodebuild -license`.
198

    
199
Once you've found and fixed the issue, you can run `npm rebuild` to rerun
200
the lifecycle scripts.
201

    
202
## CAVEATS
203

    
204
There is some overhead to probes, even when disabled. Probes are
205
already using the "is-enabled" feature of DTrace to control execution
206
of the arguments-gathering callback, but some work still needs to be
207
done before that's checked. This overhead should not be a problem
208
unless probes are placed in particularly hot code paths.
209

    
210
## CONTRIBUTING
211

    
212
To clone the project's source code:
213

    
214
    $ git clone --recursive https://github.com/chrisa/node-dtrace-provider.git
215

    
216
For issues, please use the [GitHub issue tracker](https://github.com/chrisa/node-dtrace-provider/issues)
217
linked to the repository. GitHub pull requests are very welcome.
218

    
219
## RUNNING THE TESTS
220

    
221
```shell
222
$ npm install
223
$ sudo ./node_modules/.bin/tap --tap test/*.test.js
224
```
225

    
226
## OTHER IMPLEMENTATIONS
227

    
228
This node extension is derived from the ruby-dtrace gem, via the Perl
229
module Devel::DTrace::Provider, both of which provide the same
230
functionality to those languages.