This repository was archived by the owner on Oct 20, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathsyscall2.js
More file actions
145 lines (96 loc) · 4.17 KB
/
syscall2.js
File metadata and controls
145 lines (96 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright 2016 Circonus, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
'use strict';
/*
This plugin requires node v4.4+ (if the version of node installed is v0.10, use the io.js plugin).
To use this module the user NAD runs as needs privileges to run DTrace.
By default NAD runs as the unprivileged user 'nobody'. The 'nobody' user, by default,
cannot run dtrace.
Adding a line such as the following to /etc/user_attr will add the two privileges
required (dtrace_kernel and file_dac_read) in a default OmniOS install. Different
OSes and/or local security modfications may require different privileges:
nobody::::type=normal;defaultpriv=basic,dtrace_kernel,file_dac_read
Note: if there is already a line for nobody, modify it by adding the additional privileges.
### Configuration ###
To track the syscalls for a specific process. Create a configuration file
/opt/circonus/etc/syscall2.json, for example:
{
"execname": "node"
}
Will collect syscall metrics only for process(es) where the execname is 'node'.
### enabling the plugin ###
1. Disable NAD:
svcadm disable nad
2. Enable the plugin:
cd /opt/circonus/etc/node-agent.d
ln -s illumous/syscall2.js syscall.js
3. Add additional privileges for nobody if not already done. (see above)
4. Enable NAD:
svcadm enable nad
### disabling the plugin ###
1. Disable NAD:
svcadm disable nad
2. Remove the symlink for the plugin:
cd /opt/circonus/etc/node-agent.d
rm syscall.js
3. Remove the additional privileges for nobody that were added to /etc/user_attr.
If a line was added, remove it. If an existing line was modified, remove the modifications.
4. Enable NAD:
svcadm enable nad
*/
const path = require('path');
const Dtrace = require('dtrace_aggr2');
const DEFAULT_SAMPLES = 60;
const MILLISECOND = 1000;
let singleton = null;
module.exports = class Syscall {
/**
* creates new instance
*/
constructor() {
if (singleton !== null) {
return singleton;
}
const cfgName = `${path.basename(__filename, '.js')}.json`; // e.g. syscall2.json
const cfgFile = path.resolve(path.join(__dirname, '..', '..', cfgName));
let execName = null;
try {
const cfg = require(cfgFile); // eslint-disable-line global-require
if ({}.hasOwnProperty.call(cfg, 'execname')) {
execName = cfg.execname;
}
} catch (err) {
console.error(err);
}
let script = '';
if (execName === null) {
script = 'syscall:::entry{self->start=timestamp;}syscall:::return/self->start/{@l[strjoin(probefunc,"`latency_us")] = llquantize((timestamp-self->start)/1000, 10, 0, 6, 100); self->start = 0;}'; // eslint-disable-line max-len
} else {
script = `syscall:::entry/execname=="${execName}"/{self->start=timestamp;}syscall:::return/self->start/{@l[strjoin(strjoin(execname,"\`"),strjoin(probefunc,"\`latency_us"))] = llquantize((timestamp-self->start)/1000, 10, 0, 6, 100); self->start = 0;}`; // eslint-disable-line max-len
}
script += 'tick-1sec{printf(">START\\n");printa("=%s%@d\\n", @l);printf(">END\\n");trunc(@l);}';
this.dtrace = new Dtrace(script);
this.dtrace.start();
singleton = this; // eslint-disable-line consistent-this
return singleton;
}
/**
* called by nad to run the plugin
* @arg {Object} plugin definition
* @arg {Function} cb callback
* @arg {Object} req http request object
* @arg {Object} args instance arguments
* @arg {String} instance id
* @returns {Undefined} nothing
*/
run(plugin, cb, req, args, instance) { // eslint-disable-line max-params, no-unused-vars
let samples = DEFAULT_SAMPLES;
if (req && {}.hasOwnProperty.call(req, 'headers') && {}.hasOwnProperty.call(req.headers, 'x-reconnoiter-period')) {
samples = Math.floor(req.headers['x-reconnoiter-period'] / MILLISECOND);
}
const metrics = this.dtrace.flush(samples);
plugin.running = false; // eslint-disable-line no-param-reassign
cb(plugin, metrics, instance);
}
};