Skip to content

Commit ea94d15

Browse files
committed
added app solutions
1 parent 564d992 commit ea94d15

8 files changed

Lines changed: 243 additions & 6 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: '3.8'
2+
3+
services:
4+
5+
batch:
6+
image: jaimesalas/prom-batch
7+
build:
8+
context: ./batch
9+
dockerfile: ./Dockerfile
10+
11+
web:
12+
image: jaimesalas/prom-web
13+
build:
14+
context: ./web
15+
dockerfile: ./Dockerfile
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Publish images
2+
3+
```bash
4+
cd .solutions
5+
```
6+
7+
```bash
8+
docker-compose build
9+
```
10+
11+
```bash
12+
docker push jaimesalas/prom-batch
13+
docker push jaimesalas/prom-web
14+
```
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
node_modules
2-
Dockerfile
3-
*.md
2+
*.md
3+
Dockerfile
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const promClient = require('prom-client');
2+
3+
const counter = new promClient.Counter({
4+
name: 'http_requests_received_total',
5+
help: 'Total number of requests received and response code',
6+
labelNames: ['method', 'response_code']
7+
});
8+
9+
10+
const histogram = new promClient.Histogram({
11+
name: 'http_request_duration_seconds',
12+
help: 'Shows processing requests durations',
13+
labelNames: ['code']
14+
});
15+
16+
const delaySummary = new promClient.Summary({
17+
name: 'web_delay_seconds',
18+
help: 'Custom delay added',
19+
});
20+
21+
module.exports.counter = counter;
22+
module.exports.histogram = histogram;
23+
module.exports.delaySummary = delaySummary;

06-monitoring/00-prometheus/.solutions/web/index.js

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,44 @@
11
const express = require('express');
2+
const promClient = require('prom-client');
23
const { port } = require('./config');
3-
const { getQuote } = require('./helpers');
4+
const { getQuote, delay, getRandom } = require('./helpers');
5+
const { counter, histogram, delaySummary } = require('./custom-metrics');
6+
7+
const { register, collectDefaultMetrics } = promClient;
8+
9+
collectDefaultMetrics();
410

511
const app = express();
612

7-
// curl -X GET "http://localhost:3000/quote"
8-
app.get('/quote', async (_, res) => {
13+
// curl http://localhost:3000/metrics
14+
app.get('/metrics', async (_, res) => {
915
try {
16+
res.set('Content-Type', register.contentType);
17+
res.end(await register.metrics());
18+
} catch (ex) {
19+
res.status(500).end(ex);
20+
}
21+
});
22+
23+
24+
// curl -X GET "http://localhost:3000/quote?slow=true"
25+
app.get('/quote', async (req, res) => {
26+
try {
27+
counter.labels('GET', 200).inc();
28+
const end = histogram.startTimer();
1029
const quote = getQuote();
30+
const { slow } = req.query;
31+
32+
if (slow === 'true') {
33+
const delaySeconds = getRandom(2, 10);
34+
delaySummary.observe(delaySeconds);
35+
await delay(delaySeconds);
36+
}
37+
38+
histogram.labels(200).observe(end());
1139
res.send(quote);
1240
} catch (ex) {
41+
counter.labels('GET', 500).inc();
1342
res.status(500).end(ex);
1443
}
1544
});

06-monitoring/00-prometheus/.solutions/web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
"keywords": [],
1717
"author": "",
1818
"license": "ISC"
19-
}
19+
}

06-monitoring/00-prometheus/03-summaries-histograms/01-nodejs-client-library/readme.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,146 @@ El ejemplo que vamos a crear se trata de una aplicación web que expone un endpo
1111
Creamos `custom-metrics.js`
1212

1313
```js
14+
const promClient = require('prom-client');
15+
16+
const counter = new promClient.Counter({
17+
name: 'http_requests_received_total',
18+
help: 'Total number of requests received and response code',
19+
labelNames: ['method', 'response_code']
20+
});
21+
22+
23+
const histogram = new promClient.Histogram({
24+
name: 'http_request_duration_seconds',
25+
help: 'Shows processing requests durations',
26+
labelNames: ['code']
27+
});
28+
29+
const delaySummary = new promClient.Summary({
30+
name: 'web_delay_seconds',
31+
help: 'Custom delay added',
32+
});
33+
34+
module.exports.counter = counter;
35+
module.exports.histogram = histogram;
36+
module.exports.delaySummary = delaySummary;
37+
```
38+
39+
## 2. Actualizamos index.js
40+
41+
Abrimos el fichero `index.js`
42+
43+
Primero vamos añadir las métricas que se exponen por defecto:
44+
45+
```diff
46+
const express = require('express');
47+
+const promClient = require('prom-client');
48+
const { port } = require('./config');
49+
const { getQuote } = require('./helpers');
50+
51+
+const { register, collectDefaultMetrics } = promClient;
52+
+
53+
+collectDefaultMetrics();
54+
55+
const app = express();
56+
57+
// curl -X GET "http://localhost:3000/quote"
58+
app.get('/quote', async (_, res) => {
59+
try {
60+
const quote = getQuote();
61+
res.send(quote);
62+
} catch (ex) {
63+
res.status(500).end(ex);
64+
}
65+
});
66+
67+
app.listen(port, () => {
68+
console.log(`Listenning at ${port}`);
69+
});
70+
```
71+
72+
Vamos a hacer que el endpoint se comporte de una manera distinta en función de recibir un `query param`. Además queremos resgistrar cada vez que se realiza una petición al endpoint `quote`
73+
74+
```diff
75+
const express = require('express');
76+
const promClient = require('prom-client');
77+
const { port } = require('./config');
78+
-const { getQuote } = require('./helpers');
79+
+const { getQuote, delay, getRandom } = require('./helpers');
80+
+const { counter, histogram, delaySummary } = require('./custom-metrics');
81+
# ....
82+
```
83+
84+
Y actualizamos el endpoint de la siguiente manera.
85+
86+
```js
87+
// curl -X GET "http://localhost:3000/quote?slow=true"
88+
app.get('/quote', async (req, res) => {
89+
try {
90+
counter.labels('GET', 200).inc();
91+
const end = histogram.startTimer();
92+
const quote = getQuote();
93+
const { slow } = req.query;
94+
95+
if (slow === 'true') {
96+
const delaySeconds = getRandom(2, 10);
97+
delaySummary.observe(delaySeconds);
98+
await delay(delaySeconds);
99+
}
100+
101+
histogram.labels(200).observe(end());
102+
res.send(quote);
103+
} catch (ex) {
104+
counter.labels('GET', 500).inc();
105+
res.status(500).end(ex);
106+
}
107+
});
108+
```
109+
110+
Para que esto funcione debemos exponer las métricas.
111+
112+
```js
113+
// curl http://localhost:3000/metrics
114+
app.get('/metrics', async (_, res) => {
115+
try {
116+
res.set('Content-Type', register.contentType);
117+
res.end(await register.metrics());
118+
} catch (ex) {
119+
res.status(500).end(ex);
120+
}
121+
});
122+
```
123+
124+
## 3. Comprobamos la app
125+
126+
Vamos a comprobar que la aplicación funciona como nosotros esperamos
127+
128+
```bash
129+
npm start
130+
```
131+
132+
En un terminal nuevo hagamos un par de peticiones:
133+
134+
```bash
135+
curl -X GET "http://localhost:3000/quote?slow=true"
136+
curl -X GET "http://localhost:3000/quote"
137+
```
138+
139+
Y podemos obtener las métricas llamando a su endpoint:
140+
141+
```bash
142+
curl http://localhost:3000/metrics
143+
```
144+
145+
```ini
146+
# HELP http_requests_received_total Total number of requests received and response code
147+
# TYPE http_requests_received_total counter
148+
http_requests_received_total{method="GET",response_code="200"} 2
149+
150+
# HELP http_request_duration_seconds Shows processing requests durations
151+
# TYPE http_request_duration_seconds histogram
152+
http_request_duration_seconds_bucket{le="0.005"} 0
153+
http_request_duration_seconds_bucket{le="0.01"} 0
154+
http_request_duration_seconds_bucket{le="0.025"} 0
155+
# ....
14156
```
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
$script = <<-SCRIPT
2+
echo Downloading prometheus node exporter linux
3+
4+
apt-get update
5+
apt-get -y install prometheus-node-exporter
6+
7+
SCRIPT
8+
9+
Vagrant.configure("2") do |config|
10+
config.vm.box = "bento/ubuntu-20.04"
11+
config.vm.network "private_network", ip: "10.0.0.10"
12+
config.vm.provision "docker"
13+
config.vm.provision "shell", inline: $script
14+
end

0 commit comments

Comments
 (0)