Skip to content

Commit d00a744

Browse files
committed
feat(monitoring): Add metrics endpoint for Prometheus
1 parent 31cbfc5 commit d00a744

13 files changed

Lines changed: 169 additions & 139 deletions

File tree

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ deploy_production:
2929
- ssh-add <(echo "$SSH_PRIVATE_KEY")
3030
- mkdir -p ~/.ssh
3131
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
32-
- ssh linkvalue@62.4.5.247 "rm -rf lvconnect && git clone git@gitlab.com:LinkValue/Lab/LvConnect.git lvconnect && cd lvconnect && yarn install"
32+
- ssh linkvalue@62.4.5.247 "rm -rf lvconnect && git clone git@gitlab.com:LinkValue/Lab/LvConnect.git lvconnect && cd lvconnect && yarn install && pm2 restart all"
3333
only:
3434
- tags
3535
when: manual

config/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ module.exports = {
99
},
1010
},
1111
mongodb: {
12-
host: 'mongo',
12+
host: 'localhost',
1313
port: 27017,
1414
database: 'lvconnect_test',
1515
},
1616
kue: {
1717
redis: {
18-
host: 'redis',
18+
host: 'localhost',
1919
port: 6379,
2020
db: 0,
2121
},

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"node-trello": "^1.1.2",
5252
"ovh": "2.0.1",
5353
"pmx": "^1.2.0",
54+
"prom-client": "^9.0.0",
5455
"request": "^2.79.0",
5556
"request-promise": "^4.1.1",
5657
"uuid": "^3.0.1",

server/create-server.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
const Glue = require('glue');
2+
const config = require('config');
3+
4+
const globalRoutes = require('./global-routes');
5+
6+
const manifest = {
7+
server: {
8+
cache: config.server.cache,
9+
},
10+
registrations: [{
11+
plugin: {
12+
register: 'good',
13+
options: config.logs,
14+
},
15+
}, {
16+
plugin: 'hapi-auth-cookie',
17+
}, {
18+
plugin: 'hapi-auth-basic',
19+
}, {
20+
plugin: 'hapi-auth-bearer-token',
21+
}, {
22+
plugin: {
23+
register: 'crumb',
24+
options: config.csrf,
25+
},
26+
}, {
27+
plugin: 'vision',
28+
}, {
29+
plugin: 'inert',
30+
}, {
31+
plugin: {
32+
register: './mongodb',
33+
options: config.mongodb,
34+
},
35+
}, {
36+
plugin: {
37+
register: './mailjet',
38+
options: config.mailjet,
39+
},
40+
}, {
41+
plugin: './monitoring',
42+
}, {
43+
plugin: './users',
44+
}, {
45+
plugin: {
46+
register: './login',
47+
options: config.login,
48+
},
49+
}, {
50+
plugin: {
51+
register: './oauth',
52+
options: config.oauth,
53+
},
54+
}, {
55+
plugin: './dashboard',
56+
}, {
57+
plugin: {
58+
register: './tasks',
59+
options: config.kue,
60+
},
61+
}],
62+
connections: [{
63+
host: config.host.hostname,
64+
port: config.host.port,
65+
routes: {
66+
cors: {
67+
origin: ['*'],
68+
},
69+
},
70+
}],
71+
};
72+
73+
function createServer() {
74+
return Glue.compose(manifest, {
75+
relativeTo: __dirname,
76+
});
77+
}
78+
79+
function createAndInitServer() {
80+
createServer()
81+
.then(server => server.start().then(() => server))
82+
.then((server) => {
83+
server.log('info', `Server started on port ${server.connections[0].info.uri}`);
84+
85+
server.route(globalRoutes);
86+
87+
// Handle uncaught promise rejections
88+
process.on('unhandledRejection', (reason) => {
89+
server.log('error', `Unhandled rejection: ${reason.stack}`);
90+
});
91+
})
92+
.catch((err) => {
93+
console.error(err.stack); // eslint-disable-line no-console
94+
process.exit(1);
95+
});
96+
}
97+
98+
module.exports = {
99+
createServer,
100+
createAndInitServer,
101+
};

server/dashboard/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
const Boom = require('boom');
2-
const uuid = require('uuid');
32
const handlebars = require('handlebars');
43
const routes = require('./routes');
54

server/dashboard/layouts/default.hbs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1">
66

77
<!-- Material Design Lite -->
8-
<link rel="stylesheet" href="/mdl/material-icons.css">
9-
<link rel="stylesheet" href="/mdl/material.blue-light_blue.min.css">
8+
<link rel="stylesheet" href="/assets/material-icons.css">
9+
<link rel="stylesheet" href="/assets/material.blue-light_blue.min.css">
10+
<script defer async src="/assets/material.min.js"></script>
1011

1112
<!-- LvConnect -->
1213
<link rel="stylesheet" href="/dashboard/assets/css/dashboard.css">
@@ -45,6 +46,5 @@
4546
{{{content}}}
4647
</main>
4748
</div>
48-
<script defer async src="/mdl/material.min.js"></script>
4949
</body>
5050
</html>

server/global-routes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const path = require('path');
22

33
module.exports = [{
44
method: 'GET',
5-
path: '/mdl/{param*}',
5+
path: '/assets/{param*}',
66
config: {
77
auth: false,
88
},

server/index.js

Lines changed: 2 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,3 @@
1-
const pmx = require('pmx');
1+
const { createAndInitServer } = require('./create-server');
22

3-
let pmxProbe;
4-
if (require.main === module && process.env.NODE_ENV === 'production') {
5-
pmxProbe = pmx.init({
6-
http: true,
7-
errors: true,
8-
custom_probes: true, // Auto expose JS Loop Latency and HTTP req/s as custom metrics
9-
network: true, // Network monitoring at the application level
10-
ports: true, // Shows which ports your app is listening on (default: false)
11-
});
12-
}
13-
14-
const Glue = require('glue');
15-
const config = require('config');
16-
17-
const globalRoutes = require('./global-routes');
18-
19-
const manifest = {
20-
server: {
21-
cache: config.server.cache,
22-
},
23-
registrations: [{
24-
plugin: {
25-
register: 'good',
26-
options: config.logs,
27-
},
28-
}, {
29-
plugin: 'hapi-auth-cookie',
30-
}, {
31-
plugin: 'hapi-auth-basic',
32-
}, {
33-
plugin: 'hapi-auth-bearer-token',
34-
}, {
35-
plugin: {
36-
register: 'crumb',
37-
options: config.csrf,
38-
},
39-
}, {
40-
plugin: 'vision',
41-
}, {
42-
plugin: 'inert',
43-
}, {
44-
plugin: {
45-
register: './mongodb',
46-
options: config.mongodb,
47-
},
48-
}, {
49-
plugin: {
50-
register: './mailjet',
51-
options: config.mailjet,
52-
},
53-
}, {
54-
plugin: './users',
55-
}, {
56-
plugin: {
57-
register: './login',
58-
options: config.login,
59-
},
60-
}, {
61-
plugin: {
62-
register: './oauth',
63-
options: config.oauth,
64-
},
65-
}, {
66-
plugin: './dashboard',
67-
}, {
68-
plugin: {
69-
register: './tasks',
70-
options: config.kue,
71-
},
72-
}],
73-
connections: [{
74-
host: config.host.hostname,
75-
port: config.host.port,
76-
routes: {
77-
cors: {
78-
origin: ['*'],
79-
},
80-
},
81-
}],
82-
};
83-
84-
function createServer() {
85-
return Glue.compose(manifest, {
86-
relativeTo: __dirname,
87-
});
88-
}
89-
90-
module.exports = createServer;
91-
92-
if (require.main === module) {
93-
createServer()
94-
.then(server => server.start().then(() => server))
95-
.then((server) => {
96-
server.log('info', `Server started on port ${server.connections[0].info.uri}`);
97-
98-
server.route(globalRoutes);
99-
100-
// Handle uncaught promise rejections
101-
process.on('unhandledRejection', (reason) => {
102-
server.log('error', `Unhandled rejection: ${reason.stack}`);
103-
});
104-
105-
// Error probing
106-
if (pmxProbe) {
107-
server.on('log', (event, { error }) => {
108-
if (error) {
109-
pmxProbe.notify(event.data);
110-
}
111-
});
112-
}
113-
})
114-
.catch((err) => {
115-
console.error(err.stack); // eslint-disable-line no-console
116-
process.exit(1);
117-
});
118-
}
3+
createAndInitServer();

server/mailjet/index.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,6 @@ exports.register = (server, { apiKey, apiToken }, next) => {
3434
.catch(err => server.log('error', err));
3535
});
3636

37-
server.route({
38-
method: 'GET',
39-
path: '/test',
40-
config: { auth: false },
41-
handler(req, res) {
42-
req.server.plugins.mailjet.sendAccountCreationMail();
43-
res('Hello');
44-
},
45-
});
46-
4737
next();
4838
};
4939

server/monitoring/index.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const client = require('prom-client');
2+
3+
const requestCounter = new client.Counter({
4+
name: 'http_requests_total',
5+
help: 'HTTP Requests per seconds',
6+
labelNames: ['method', 'path'],
7+
});
8+
const collectDefaultMetrics = client.collectDefaultMetrics;
9+
collectDefaultMetrics(5000);
10+
11+
exports.register = (server, config, next) => {
12+
server.route({
13+
method: 'GET',
14+
path: '/metrics',
15+
handler(req, res) {
16+
res(client.register.metrics())
17+
.type(client.register.contentType);
18+
},
19+
});
20+
21+
server.on({ name: 'request-internal', filter: 'received' }, (req) => {
22+
if (!/\/assets\//.test(req.path)) {
23+
requestCounter.labels(req.method, req.path).inc();
24+
}
25+
});
26+
27+
next();
28+
};
29+
30+
exports.register.attributes = {
31+
name: 'monitoring',
32+
version: '0.0.1',
33+
};

0 commit comments

Comments
 (0)