hping 0.0.5 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +21 -0
- package/README.md +74 -74
- package/bin/hping +4 -383
- package/config/hping.yaml +3 -2
- package/lib/cli.js +671 -0
- package/lib/logger.js +25 -30
- package/logs/.gitignore +4 -0
- package/package.json +13 -8
- package/test/cli.integration.test.js +446 -0
- package/test/cli.unit.test.js +72 -0
- package/.npmignore +0 -3
- package/lib/helpers.js +0 -48
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
strategy:
|
|
11
|
+
fail-fast: false
|
|
12
|
+
matrix:
|
|
13
|
+
node-version: [20.x, 22.x, 24.x]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: ${{ matrix.node-version }}
|
|
19
|
+
cache: npm
|
|
20
|
+
- run: npm ci
|
|
21
|
+
- run: npm test
|
package/README.md
CHANGED
|
@@ -1,54 +1,71 @@
|
|
|
1
1
|
hPING (HTTP ping)
|
|
2
2
|
=====
|
|
3
3
|
|
|
4
|
-
Node.js CLI that sends HTTP HEAD
|
|
4
|
+
Node.js CLI that sends HTTP `HEAD`, `GET`, or `POST` requests to web/api servers.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
<img src="http://www.anothervision.com/img/github/hping.gif" width="1126"/>
|
|
7
|
+
hPING is a quick way to check and monitor HTTP server availability.
|
|
8
|
+
|
|
9
|
+
## Node.js Support
|
|
10
|
+
|
|
11
|
+
- Supported: `Node.js 20+` (validated against current major runtimes, including Node `22+`).
|
|
7
12
|
|
|
8
13
|
## Installation
|
|
9
|
-
|
|
14
|
+
|
|
15
|
+
hPING is installable via npm:
|
|
16
|
+
|
|
10
17
|
```bash
|
|
11
18
|
$ npm install hping -g
|
|
12
19
|
```
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
$ npm install git://github.com/kurdin/hping#master -g
|
|
16
|
-
```
|
|
17
|
-
or
|
|
18
|
-
```bash
|
|
19
|
-
$ git clone https://github.com/kurdin/hping
|
|
20
|
-
$ cd hping
|
|
21
|
-
$ npm install
|
|
22
|
-
$ npm link
|
|
23
|
-
```
|
|
20
|
+
|
|
24
21
|
## Usage
|
|
25
22
|
|
|
26
|
-
hPING single server
|
|
23
|
+
hPING single server `www.google.com`:
|
|
24
|
+
|
|
27
25
|
```bash
|
|
28
|
-
$ hping www.google.com
|
|
26
|
+
$ hping www.google.com
|
|
29
27
|
```
|
|
30
|
-
|
|
28
|
+
|
|
29
|
+
hPING server `www.google.com` with a 10-second interval:
|
|
30
|
+
|
|
31
31
|
```bash
|
|
32
|
-
$ hping www.google.com -i 10
|
|
32
|
+
$ hping www.google.com -i 10
|
|
33
33
|
```
|
|
34
|
-
|
|
34
|
+
|
|
35
|
+
hPING single server with `GET` method:
|
|
36
|
+
|
|
35
37
|
```bash
|
|
36
38
|
$ hping get www.google.com
|
|
37
39
|
```
|
|
38
|
-
|
|
40
|
+
|
|
41
|
+
hPING multiple servers:
|
|
42
|
+
|
|
39
43
|
```bash
|
|
40
44
|
$ hping www.google.com www.apple.com www.microsoft.com
|
|
41
45
|
```
|
|
42
|
-
|
|
46
|
+
|
|
47
|
+
hPING group of servers from config file (default config: `~/.hping/hping.conf.yaml`):
|
|
48
|
+
|
|
43
49
|
```bash
|
|
44
50
|
$ hping "apple production"
|
|
45
51
|
```
|
|
52
|
+
|
|
46
53
|
hPING can mix group of servers and separate hosts with single command:
|
|
54
|
+
|
|
47
55
|
```bash
|
|
48
56
|
$ hping "apple production" www.github.com
|
|
49
57
|
```
|
|
58
|
+
|
|
59
|
+
Explicit `ping` command (modern style):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
$ hping ping www.google.com
|
|
63
|
+
```
|
|
64
|
+
|
|
50
65
|
## Settings
|
|
51
|
-
|
|
66
|
+
|
|
67
|
+
hPING default settings (`~/.hping/hping.conf.yaml`):
|
|
68
|
+
|
|
52
69
|
```bash
|
|
53
70
|
interval: 1 # (seconds) interval between hPING requests
|
|
54
71
|
type: HEAD # (type or requests): HEAD, GET, POST, PUT
|
|
@@ -68,80 +85,63 @@ display_in_output: # use true || fasle to turn on/off log output sections
|
|
|
68
85
|
type: false
|
|
69
86
|
status_code: true
|
|
70
87
|
status_info: true
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
88
|
+
server: true
|
|
89
|
+
content_length: false
|
|
90
|
+
response_time: true
|
|
74
91
|
```
|
|
75
|
-
|
|
92
|
+
|
|
93
|
+
Show hPING server groups:
|
|
94
|
+
|
|
76
95
|
```bash
|
|
77
96
|
$ hping servers
|
|
78
|
-
"microsoft live":
|
|
79
|
-
"http://www.live.com"
|
|
80
|
-
"http://www.live.fr"
|
|
81
|
-
"http://www.live.de"
|
|
82
|
-
"http://www.live.ru"
|
|
83
|
-
"http://www.live.com/api"
|
|
84
|
-
|
|
85
|
-
"apple production":
|
|
86
|
-
"http://www.apple.com"
|
|
87
|
-
"http://www.icloud.com"
|
|
88
|
-
"https://itunes.apple.com"
|
|
89
|
-
|
|
90
|
-
"eurohosting":
|
|
91
|
-
"http://www.leaseweb.eu"
|
|
92
|
-
"http://www.hetzner.de"
|
|
93
|
-
"http://www.1and1.co.uk"
|
|
94
97
|
```
|
|
98
|
+
|
|
95
99
|
Display hPING current settings:
|
|
100
|
+
|
|
96
101
|
```bash
|
|
97
102
|
$ hping settings
|
|
98
103
|
```
|
|
99
|
-
|
|
104
|
+
|
|
105
|
+
hPING server `www.google.com` with custom config:
|
|
106
|
+
|
|
100
107
|
```bash
|
|
101
|
-
$ hping www.google.com -c /etc/hping.conf.yaml
|
|
108
|
+
$ hping www.google.com -c /etc/hping.conf.yaml
|
|
102
109
|
```
|
|
110
|
+
|
|
103
111
|
## Help
|
|
112
|
+
|
|
104
113
|
hPING quick usage help:
|
|
114
|
+
|
|
105
115
|
```bash
|
|
106
116
|
$ hping
|
|
107
|
-
usage: hping [head|get|post] [http(s)://]www.webserver.com[:port] [another host] [server group]
|
|
117
|
+
usage: hping [ping|head|get|post] [http(s)://]www.webserver.com[:port] [another host] [server group]
|
|
108
118
|
```
|
|
119
|
+
|
|
109
120
|
hPING full help:
|
|
121
|
+
|
|
110
122
|
```bash
|
|
111
123
|
$ hping -h
|
|
112
|
-
Usage: hping [head|get|post] [http(s)://]www.webserver.com[:port] [another host] [server group]
|
|
113
|
-
|
|
114
|
-
Commands:
|
|
115
|
-
|
|
116
|
-
servers
|
|
117
|
-
Show server groups information from config file
|
|
118
|
-
|
|
119
|
-
settings
|
|
120
|
-
Show hPING settings from config file
|
|
121
|
-
|
|
122
|
-
get
|
|
123
|
-
Sends HTTP GET requests to web or api server (set default in ~/.hping/hping.conf.yaml)
|
|
124
|
-
|
|
125
|
-
post
|
|
126
|
-
Sends HTTP POST requests to web or api server (set default in ~/.hping/hping.conf.yaml)
|
|
127
|
-
|
|
128
|
-
head
|
|
129
|
-
Sends HTTP HEAD requests to web or api server (set default in ~/.hping/hping.conf.yaml)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Options:
|
|
133
|
-
|
|
134
|
-
-h, --help output usage information
|
|
135
|
-
-V, --version output the version number
|
|
136
|
-
-c, --config [~/.hping/hping.conf.yaml] hping config file in YAML format
|
|
137
|
-
-i, --interval [1]
|
|
138
124
|
```
|
|
125
|
+
|
|
139
126
|
## Log to file
|
|
140
|
-
You can setup hPING to log status change to separate log file. Default log file located in ``~/.hping/logs`` folder, you can change it with ``log_file`` option.
|
|
141
127
|
|
|
142
|
-
|
|
128
|
+
Enable status-change logging with `log_status_change: true`.
|
|
129
|
+
|
|
130
|
+
Default log file location: `~/.hping/logs/hping.log` (override with `log_file`).
|
|
131
|
+
|
|
132
|
+
## Development
|
|
133
|
+
|
|
134
|
+
Install deps:
|
|
143
135
|
|
|
144
|
-
|
|
136
|
+
```bash
|
|
137
|
+
$ npm install
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Run tests:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
$ npm test
|
|
144
|
+
```
|
|
145
145
|
|
|
146
146
|
##License
|
|
147
147
|
The MIT License (MIT)
|
package/bin/hping
CHANGED
|
@@ -2,388 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
util = require('util'),
|
|
7
|
-
pkg = require('../package.json'),
|
|
8
|
-
fs = require('fs'),
|
|
9
|
-
log4js = require('log4js'),
|
|
10
|
-
dns = require('dns'),
|
|
11
|
-
path = require('path'),
|
|
12
|
-
color = require('cli-color'),
|
|
13
|
-
request = require('request'),
|
|
14
|
-
status_codes = require('../lib/status'),
|
|
15
|
-
config = require('yaml-config'),
|
|
16
|
-
helpers = require('../lib/helpers'),
|
|
17
|
-
info = 'hPING sends HEAD or GET or POST requests to web or api servers to check if they alive',
|
|
18
|
-
usage = '[head|get|post] [http(s)://]www.webserver.com[:port] [another host] [server group]',
|
|
19
|
-
hping_home_dir = getHPINGHome(),
|
|
20
|
-
defconfile = path.resolve(__dirname, '../config/hping.yaml'),
|
|
21
|
-
confile = path.resolve(hping_home_dir, 'hping.conf.yaml'),
|
|
22
|
-
colors = {
|
|
23
|
-
r: 'red',
|
|
24
|
-
g: 'green',
|
|
25
|
-
bb: 'blackBright',
|
|
26
|
-
u: 'underline',
|
|
27
|
-
m: 'magenta',
|
|
28
|
-
y: 'yellow'
|
|
29
|
-
},
|
|
30
|
-
defaults = {
|
|
31
|
-
confile: confile,
|
|
32
|
-
interval: 1
|
|
33
|
-
};
|
|
5
|
+
const { runCli } = require('../lib/cli');
|
|
34
6
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
program
|
|
39
|
-
.version(pkg.version)
|
|
40
|
-
.usage(usage)
|
|
41
|
-
.option('-c, --config [' + confile + ']', 'hping config file in YAML format', defaults.confile)
|
|
42
|
-
.option('-i, --interval [1]', 'hping interval in seconds (set default in ' + confile + ')', defaults.interval);
|
|
43
|
-
|
|
44
|
-
program
|
|
45
|
-
.command('servers')
|
|
46
|
-
.description('Show server groups information from config file')
|
|
47
|
-
.action(function() {
|
|
48
|
-
hping('servers');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
program
|
|
52
|
-
.command('settings')
|
|
53
|
-
.description('Show hPING settings from config file')
|
|
54
|
-
.action(function() {
|
|
55
|
-
hping('settings');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
program
|
|
59
|
-
.command('get')
|
|
60
|
-
.description('Sends HTTP GET requests to web or api server (set default in ' + confile + ')')
|
|
61
|
-
.action(function() {
|
|
62
|
-
if (program.args.length > 1) {
|
|
63
|
-
hping(program.args, 'GET');
|
|
64
|
-
} else {
|
|
65
|
-
console.log(usage);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
program
|
|
70
|
-
.command('post')
|
|
71
|
-
.description('Sends HTTP POST requests to web or api server (set default in ' + confile + ')')
|
|
72
|
-
.action(function() {
|
|
73
|
-
if (program.args.length > 1) {
|
|
74
|
-
hping(program.args, 'POST');
|
|
75
|
-
} else {
|
|
76
|
-
console.log(usage);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
program
|
|
81
|
-
.command('head')
|
|
82
|
-
.description('Sends HTTP HEAD requests to web or api server (set default in ' + confile + ')')
|
|
83
|
-
.action(function() {
|
|
84
|
-
if (program.args.length > 1) {
|
|
85
|
-
hping(program.args, 'HEAD');
|
|
86
|
-
} else {
|
|
87
|
-
console.log(usage);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
program
|
|
92
|
-
.on('*', function(e) {
|
|
93
|
-
hping(e);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
program.parse(process.argv);
|
|
97
|
-
|
|
98
|
-
if (program.args.length < 1) {
|
|
99
|
-
console.log('usage: hping ' + usage);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function hping(args, type) {
|
|
103
|
-
fs.exists(confile, function(exists) {
|
|
104
|
-
if (exists) {
|
|
105
|
-
hping_run(args, type);
|
|
106
|
-
} else {
|
|
107
|
-
fs.mkdir(path.resolve(hping_home_dir), function(e) {
|
|
108
|
-
if (!e || (e && e.code === 'EEXIST')) {
|
|
109
|
-
fs.mkdir(path.resolve(hping_home_dir + '/logs'), function(e) {
|
|
110
|
-
fs.createReadStream(defconfile).pipe(fs.createWriteStream(confile)).on('error', function(err) {
|
|
111
|
-
console.log(err);
|
|
112
|
-
}).on('close', function() {
|
|
113
|
-
hping_run(args, type);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
} else {
|
|
117
|
-
console.log(e);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function hping_run(args, type) {
|
|
125
|
-
var cnf = (program.config !== defaults.confile) ? program.config : defaults.confile;
|
|
126
|
-
settings = config.readConfig(cnf);
|
|
127
|
-
if (!settings.interval) {
|
|
128
|
-
console.error('Specified config file: %s could not be used, see error above. Using default config: %s', cnf, defaults.confile);
|
|
129
|
-
settings = config.readConfig(defaults.confile);
|
|
130
|
-
cnf = defaults.confile;
|
|
131
|
-
}
|
|
132
|
-
if (settings.log_status_change) logger_file = require('../lib/logger')(settings.log_file);
|
|
133
|
-
settings.interval = (program.interval === 1) ? settings.interval : program.interval;
|
|
134
|
-
if (args == 'servers') {
|
|
135
|
-
showServers();
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
if (args == 'settings') {
|
|
139
|
-
showSettings(cnf);
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
args.forEach(function(url) {
|
|
143
|
-
if (typeof url == 'string' || url instanceof String) {
|
|
144
|
-
if (settings.servers && settings.servers[url]) {
|
|
145
|
-
settings.servers[url].forEach(function(url) {
|
|
146
|
-
prerequest(url, type);
|
|
147
|
-
});
|
|
148
|
-
} else {
|
|
149
|
-
prerequest(url, type);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function prerequest(url, t) {
|
|
156
|
-
if (!/^(https?):\/\//i.test(url)) url = 'http://' + url;
|
|
157
|
-
|
|
158
|
-
var type = t || settings.type.toUpperCase(),
|
|
159
|
-
run_time = 0,
|
|
160
|
-
interval = ints(settings.interval),
|
|
161
|
-
max_run_time = ints(settings.max_run_time),
|
|
162
|
-
options = {
|
|
163
|
-
url: url,
|
|
164
|
-
timeout: ints(settings.timeout) || 5000,
|
|
165
|
-
method: type,
|
|
166
|
-
headers: {
|
|
167
|
-
'User-Agent': 'hPING [git.io/hping]'
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
dns.resolve4(require('url').parse(url).hostname, function(err, ip) {
|
|
172
|
-
if (err) ip = [''];
|
|
173
|
-
stats[url] = [];
|
|
174
|
-
(function dorequest() {
|
|
175
|
-
var start = new Date();
|
|
176
|
-
request(options, function(e, r) {
|
|
177
|
-
var res_time = new Date() - start;
|
|
178
|
-
var line = predisplay(e, r, url, type, ip[0], res_time);
|
|
179
|
-
display(line);
|
|
180
|
-
});
|
|
181
|
-
if (max_run_time === 0 || max_run_time > (interval * run_time)) {
|
|
182
|
-
setTimeout(dorequest, interval * 1000);
|
|
183
|
-
run_time++;
|
|
184
|
-
} else {
|
|
185
|
-
console.log('hPING: Maximum running time has been reached (set in config), exiting.');
|
|
186
|
-
gracefulExit();
|
|
187
|
-
}
|
|
188
|
-
})();
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function predisplay(err, res, url_org, type, ip, ms) {
|
|
193
|
-
var hcode, hlength, hserver, hinfo, hip, htime, code, status_color, empty,
|
|
194
|
-
sdo = settings.display_in_output,
|
|
195
|
-
status = '[UP]',
|
|
196
|
-
down = '[DOWN]',
|
|
197
|
-
hstatus = status,
|
|
198
|
-
htype = cc('type', type.toLowerCase()),
|
|
199
|
-
hurl = url_org,
|
|
200
|
-
line = [],
|
|
201
|
-
url_p = require('url').parse(url_org);
|
|
202
|
-
|
|
203
|
-
if (ip && hurl.indexOf(ip) == -1) hip = '(' + ip + ')';
|
|
204
|
-
if (err && err.code) {
|
|
205
|
-
code = 'error';
|
|
206
|
-
status_color = colors.r;
|
|
207
|
-
status = down;
|
|
208
|
-
hcode = cc('error', err.code.toLowerCase(), colors.r);
|
|
209
|
-
ms = 0;
|
|
210
|
-
switch (err.code) {
|
|
211
|
-
case 'ETIMEDOUT':
|
|
212
|
-
hinfo = cc('info', 'connection_timeout', colors.r);
|
|
213
|
-
break;
|
|
214
|
-
case 'ENOTFOUND':
|
|
215
|
-
hinfo = cc('info', 'server_not_found', colors.r);
|
|
216
|
-
break;
|
|
217
|
-
case 'ECONNRESET':
|
|
218
|
-
hinfo = cc('info', 'connection_closed', colors.r);
|
|
219
|
-
break;
|
|
220
|
-
case 'ECONNREFUSED':
|
|
221
|
-
hinfo = cc('info', 'connection_refused', colors.r);
|
|
222
|
-
break;
|
|
223
|
-
}
|
|
224
|
-
} else if (res && res.headers) {
|
|
225
|
-
htime = cc('time', ms, colors.u, 'ms');
|
|
226
|
-
code = res.statusCode;
|
|
227
|
-
status_color = statusColor(code);
|
|
228
|
-
if (code >= 500) status = down;
|
|
229
|
-
hcode = cc('code', code, (status_color !== colors.g) ? status_color : '');
|
|
230
|
-
if (status_codes[code]) hinfo = cc('info', status_codes[code].replace(/\s+/g, '_'), (status_color !== colors.g) ? status_color : '');
|
|
231
|
-
if (res.headers['content-length'] && res.headers['content-length'] > 0) hlength = 'content-length=' + res.headers['content-length'];
|
|
232
|
-
if (res.headers.server) hserver = 'server=' + res.headers.server;
|
|
233
|
-
} else {
|
|
234
|
-
status = hstatus = 'unknown_error';
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
hurl = hurl.replace(url_p.hostname, colr('bold', colr(status_color, url_p.hostname))).replace(url_p.port, colr('bold', colr(status_color, url_p.port)));
|
|
238
|
-
if (url_p.path && url_p.path != '/' && code !== 'error') hurl = hurl.replace(url_p.path, colr(status_color, url_p.path));
|
|
239
|
-
hstatus = colr('bold', colr(status_color, status));
|
|
240
|
-
hip = colr(colors.bb, hip);
|
|
241
|
-
|
|
242
|
-
line = [
|
|
243
|
-
'hPING:', (sdo.status) ? hstatus : empty, (sdo.url) ? hurl : empty, (sdo.ip) ? hip : empty, (sdo.type) ? htype : empty, (sdo.status_code) ? hcode : empty, (sdo.status_info) ? hinfo : empty, (sdo.server) ? hserver : empty, (sdo.content_length) ? hlength : empty, (sdo.response_time) ? htime : empty
|
|
244
|
-
];
|
|
245
|
-
|
|
246
|
-
if (stats[url_org].length >= ints(settings.stats_for_last)) stats[url_org].shift();
|
|
247
|
-
if (settings.log_status_change) {
|
|
248
|
-
if (stats[url_org][stats[url_org].length - 1] === undefined || (stats[url_org][stats[url_org].length - 1] !== undefined && stats[url_org][stats[url_org].length - 1].status !== status)) {
|
|
249
|
-
log(line);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
stats[url_org].push({
|
|
253
|
-
status: status,
|
|
254
|
-
code: code,
|
|
255
|
-
time: ms
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
return line;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function showServers() {
|
|
262
|
-
console.log(info, (settings.servers) ? '\nServer groups (set in config):' + pp(settings.servers) : '', 'usage: hping ' + usage);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
function showSettings(cnf) {
|
|
266
|
-
console.log('Settings from config file: %s %s', cnf, pp(settings));
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function display(line) {
|
|
270
|
-
console.log(pline(line));
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
function log(line) {
|
|
274
|
-
if (settings.log_status_change) logger_file.info(pline(line));
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function gracefulExit() {
|
|
278
|
-
var updateNotifier = require('update-notifier');
|
|
279
|
-
|
|
280
|
-
if (ints(settings.show_stats_for_last) > 0) {
|
|
281
|
-
for (var url in stats) {
|
|
282
|
-
if (url) {
|
|
283
|
-
display(displayStat(url));
|
|
284
|
-
if (settings.log_stats_on_exit) log(displayStat(url));
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
log4js.shutdown(function() {
|
|
289
|
-
updateNotifier({packageName: pkg.name, packageVersion: pkg.version}).notify();
|
|
290
|
-
process.exit(1);
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
function statusColor(code) {
|
|
295
|
-
var status_color = colors.g;
|
|
296
|
-
|
|
297
|
-
if (code >= 500 || code == 'error') {
|
|
298
|
-
status_color = colors.r;
|
|
299
|
-
} else if (code >= 400) {
|
|
300
|
-
status_color = colors.y;
|
|
301
|
-
}
|
|
302
|
-
return status_color;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
function displayStat(url) {
|
|
306
|
-
if (stats[url].length === 0) return;
|
|
307
|
-
|
|
308
|
-
var codes = [],
|
|
309
|
-
out = [],
|
|
310
|
-
total = {
|
|
311
|
-
requests: stats[url].length,
|
|
312
|
-
codes: {},
|
|
313
|
-
time: [],
|
|
314
|
-
up: 0,
|
|
315
|
-
down: 0
|
|
316
|
-
},
|
|
317
|
-
timesrange,
|
|
318
|
-
requests = '[' + ((total.requests > settings.show_stats_for_last) ? 'last ' : '') + total.requests + ' requests] ',
|
|
319
|
-
stat_line = '\n--- ' + url + ' hPING statistics ' + requests + '---\n';
|
|
320
|
-
|
|
321
|
-
stats[url].forEach(function(stat) {
|
|
322
|
-
|
|
323
|
-
if (!total.codes[stat.code]) total.codes[stat.code] = 1;
|
|
324
|
-
else total.codes[stat.code]++;
|
|
325
|
-
|
|
326
|
-
if (stat.status == '[UP]') total.up++;
|
|
327
|
-
else total.down++;
|
|
328
|
-
|
|
329
|
-
if (stat.time > 0) total.time.push(stat.time);
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
for (var code in total.codes) {
|
|
333
|
-
if (code) codes.push(statProcess(code, total.codes[code], total.requests, statusColor(code), ''));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
timesrange = total.time.range();
|
|
337
|
-
|
|
338
|
-
out = [
|
|
339
|
-
stat_line,
|
|
340
|
-
statProcess('UP', total.up, total.requests, colors.g, 'bold'),
|
|
341
|
-
statProcess('DOWN', total.down, total.requests, colors.r, 'bold'),
|
|
342
|
-
codes.join(' '), (timesrange.min) ? 'time(min=' + timesrange.min + ' avg=' + timesrange.avg + ' max=' + timesrange.max + ')ms' : ''
|
|
343
|
-
];
|
|
344
|
-
|
|
345
|
-
function statProcess(lb, tv, tr, tc, tb) {
|
|
346
|
-
if (lb === 'error') lb += 's';
|
|
347
|
-
var st = lb + '=' + Math.floor10((tv / tr) * 100) + '%';
|
|
348
|
-
return (tv > 0) ? colr(tb, colr(tc, st)) : '';
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return out;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
process.on('SIGTERM', function() {
|
|
355
|
-
gracefulExit();
|
|
356
|
-
}).on('SIGINT', function() {
|
|
357
|
-
gracefulExit();
|
|
7
|
+
runCli(process.argv.slice(2)).catch((error) => {
|
|
8
|
+
console.error(error.message || error);
|
|
9
|
+
process.exitCode = 1;
|
|
358
10
|
});
|
|
359
|
-
|
|
360
|
-
function cc(s1, s2, c, s3) {
|
|
361
|
-
if (!s3) s3 = '';
|
|
362
|
-
return (c && settings.use_colors) ? s1 + '=' + (color[c](s2)) + s3 : s1 + '=' + s2 + s3;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
function colr(c, s) {
|
|
366
|
-
return (!settings.use_colors || !c) ? s : color[c](s);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
function ints(s) {
|
|
370
|
-
return parseInt(s, 10);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function pp(s) {
|
|
374
|
-
return JSON.stringify(s, null, ' ').replace(/[{}]|\,|[\[\]]|/g, '').replace(/\n\s*\n\s*\n/g, '\n');
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function pline(l) {
|
|
378
|
-
if (util.isArray(l)) {
|
|
379
|
-
l = l.filter(function(e) {
|
|
380
|
-
return e;
|
|
381
|
-
});
|
|
382
|
-
return l.join(' ').replace(/\n\s/g, '\n');
|
|
383
|
-
}
|
|
384
|
-
return '';
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
function getHPINGHome() {
|
|
388
|
-
return path.resolve(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, '.hping/');
|
|
389
|
-
}
|
package/config/hping.yaml
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
default:
|
|
2
2
|
|
|
3
3
|
interval: 1 # (seconds) interval between hPING requests
|
|
4
|
-
type: HEAD # (type
|
|
4
|
+
type: HEAD # (request type): HEAD, GET, POST
|
|
5
5
|
timeout: 5000 # (milliseconds) request connection timeout
|
|
6
6
|
use_colors: true # (true || false), use colors for hPING output
|
|
7
7
|
show_stats_for_last: 100 # (number of requests) show hPING statistics for last X number of requests, set 0 to disable
|
|
8
|
+
stats_for_last: 100 # (number of requests) keep stats for last X requests per target
|
|
8
9
|
max_run_time: 600 # (seconds) hPING maximum running time, set 0 to disable
|
|
9
10
|
|
|
10
11
|
log_status_change: false # (true || false) if true, hPING will log status changes to log file
|
|
11
12
|
log_file: logs/hping.log # (path) to hPING log file, default path in users home .hping folder
|
|
12
13
|
log_stats_on_exit: true # (true || false) if true, hPING will log statistics to file on exit
|
|
13
14
|
|
|
14
|
-
display_in_output: # use true ||
|
|
15
|
+
display_in_output: # use true || false to turn on/off log output sections
|
|
15
16
|
status: true
|
|
16
17
|
url: true
|
|
17
18
|
ip: true
|