Skip to content

Commit

Permalink
feat(influxdb-grafana): ajout de l'écriture des données dans une base (
Browse files Browse the repository at this point in the history
…#43)

* feat(influx): écriture dans une base influx

* add tag for test name

* Mise au prope du code

* Ajout d'un docker-compose avec une stack influxdb

* Ajout d'une explication sur l'utilisation d'influxdb

* Fait d'influxdb un format de rapport à part entière
  • Loading branch information
Damien-Ar authored Jul 3, 2022
1 parent 6f1fa87 commit 072987f
Show file tree
Hide file tree
Showing 12 changed files with 1,705 additions and 4 deletions.
23 changes: 23 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# InfluxDB
# Ne pas modifier les deux variables suivante
INFLUXDB_HOST=greenit-cli-influxdb
INFLUXDB_PORT=8086

INFLUXDB_ORG_NAME=default
INFLUXDB_USERNAME=default
INFLUXDB_PASSWORD=defaultinfluxdb
INFLUXDB_BUCKET_NAME=db0
INFLUXDB_RETENTION=24w

# Renseigner ces variables une fois influxdb démarré pour la première fois
INFLUXDB_TOKEN=token
INFLUXDB_ORG_ID=orgId

# Grafana
GRAFANA_USERNAME=admin
GRAFANA_PASSWORD=admin

# Image Version
# Attention lors des changements de versions
INFLUXDB_IMAGE_VERSION=influxdb:2.1.1
GRAFANA_IMAGE_VERSION=grafana/grafana:8.4.3
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ dist/
results/
results_test/
*.xlsx
*.yaml
*.yaml
!docker-compose.yaml
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ Paramètres optionnels :
Choix :
- xlsx
- html
- influxdb

- `--headers , -h` : Chemin vers le fichier YAML contenant les headers HTTP configurés pour accéder aux URL à analyser.

Expand All @@ -338,6 +339,12 @@ Choix :
accept-language: 'en-US,en;q=0.9,en;q=0.8'
```

- `--influxdb` : Active l'écriture des données dans une base influxdb
- `--influxdb_hostname` : URL de la base influxdb
- `--influxdb_org` : Nom de l'organisation influxdb
- `--influxdb_token` : Token de connexion pour influxdb
- `--influxdb_bucket` : Bucket infludb sur lequel envoyer les données

### Usage avec Docker
1. Déposer le fichier `<url_input_file>` dans le dossier `/<path>/input`.
2. Lancer l'analyse :
Expand Down Expand Up @@ -450,6 +457,27 @@ Exemple d'un rapport :

![Page d'une URL analysée dans le rapport HTML](./docs/rapport-html-detail-page.png)

#### InfluxDB
Prérequis :
- Le paramètre suivant est définit : `--format=influxdb` ou `-f=influxdb`

Les données seront envoyés sur influxdb.

Un docker-compose avec un exemple de configuration d'influxdb et de grafana est présent dans le projet. Lors de la première utilisation, quelques étapes de mise en place sont nécessaires :
- Changer les couples nom d'utilisateur/mot de passe dans le fichier .env (optionel) ;
- Démarrer le conteneur influxdb : `docker-compose up greenit-cli-influxdb` ;
- Se connecter à influxdb (`http://localhost:8086` par défault) pour récupérer l'id de l'organisation (dans l'url après la connexion `http://localhost:8086/orgs/<org id>`) et le token de connection (data -> API Token), et renseigner les variables d'environnement correspondantes ;
- Il est ensuite possible de démarrer le conteneur grafana et d'envoyer les données sur influxdb.

Ces étapes ne seront pas nécessaire à nouveau. Il faudra toutefois redémarrer au moins le conteneur influxdb avant un test.

Exemple d'usage :
```shell
greenit analyse exampleUrl.yaml --format=influxdb --influxdb_hostname http://localhost:8086 --influxdb_org organisation --influxdb_token token --influxdb_bucket db0
```
Exemple de dashboard grafana (l'url testée est celle du site d'[ecoindex](http://ecoindex.fr/))
![Page d'une URL analysée dans le rapport HTML](./docs/grafana-dashboard.png)

## ParseSiteMap

```
Expand Down
91 changes: 91 additions & 0 deletions cli-core/influxdb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
const {InfluxDB, Point, HttpError} = require('@influxdata/influxdb-client');
const fs = require('fs');
const ProgressBar = require('progress');

async function write(reports, options) {

if (!options.influxdb_hostname) {
throw `You must define an InfluxDB hostname.`;
}
if (!options.influxdb_token) {
throw `You must define an InfluxDB token.`;
}
if (!options.influxdb_bucket) {
throw `You must define an InfluxDB bucket name.`;
}
if (!options.influxdb_org) {
throw `You must define an InfluxDB organisation.`;
}

const url = options.influxdb_hostname;

//initialise progress bar
let progressBar;
if (!options.ci){
progressBar = new ProgressBar(' Push to InfluxDB [:bar] :percent Remaining: :etas Time: :elapseds', {
complete: '=',
incomplete: ' ',
width: 40,
total: reports.length+2
});
progressBar.tick();
} else {
console.log('Push report to InfluxDB ...');
}

// initialise client
const client = new InfluxDB({url: options.influxdb_hostname, token: options.influxdb_token});
const writeApi = client.getWriteApi(options.influxdb_org, options.influxdb_bucket);

// create points from reports
const points = reports.map((file) => {
let obj = JSON.parse(fs.readFileSync(file.path).toString());
let hostname = obj.url.split('/')[2];
let point = new Point("eco_index")
.tag("pageName", obj.pageInformations.name)
.tag("hostname", hostname)
.stringField("url", obj.url)
.stringField("hostname", hostname)
.stringField("grade", obj.grade)
.intField("ecoindex", obj.ecoIndex)
.floatField("water", obj.waterConsumption)
.floatField("ges", obj.greenhouseGasesEmission)
.floatField("domSize", obj.domSize)
.stringField("pageSize", `${Math.round(obj.responsesSize / 1000)} (${Math.round(obj.responsesSizeUncompress / 1000)})`)
.floatField("nbRequest", obj.nbRequest)
.floatField("nbPlugins", obj.pluginsNumber)
.floatField("cssFilesNumber", obj.printStyleSheetsNumber)
.floatField("cssInlineNumber", obj.inlineStyleSheetsNumber)
.floatField("emptySrcTagNumber", obj.emptySrcTagNumber)
.floatField("inlineJsScriptsNumber", obj.inlineJsScriptsNumber)
.floatField("responsesSize", Math.round(obj.responsesSize / 1000))
.floatField("responsesSizeUncompress", Math.round(obj.responsesSizeUncompress / 1000));

Object.keys(obj.bestPractices)
.map(key => point.stringField(key, obj.bestPractices[key].complianceLevel || 'A'));

if (progressBar) progressBar.tick()

return point
});

//upload points and close connexion
writeApi.writePoints(points);

writeApi
.close()
.then(() => {
if (progressBar) progressBar.tick();
})
.catch(e => {
console.log('Writing to influx failed\n');
console.error(e);
if (e instanceof HttpError && e.statusCode === 401) {
console.log(`The InfluxDB database: ${bucket} doesn't exist.`);
}
});
}

module.exports = {
write
}
9 changes: 7 additions & 2 deletions commands/analyse.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const login = require('../cli-core/analysis.js').login;
const create_global_report = require('../cli-core/reportGlobal.js').create_global_report;
const create_XLSX_report = require('../cli-core/reportExcel.js').create_XLSX_report;
const create_html_report = require('../cli-core/reportHtml.js').create_html_report;
const writeToInflux = require("../cli-core/influxdb").write;

//launch core
async function analyse_core(options) {
Expand Down Expand Up @@ -76,9 +77,13 @@ async function analyse_core(options) {
let reportObj = await create_global_report(reports, options);
if (reportFormat === 'html') {
await create_html_report(reportObj, options);
} else {
} else if (reportFormat === 'influxdb') {
await writeToInflux(reports, options);
}
else {
await create_XLSX_report(reportObj, options);
}

}

function readProxy(proxyFile) {
Expand Down Expand Up @@ -109,7 +114,7 @@ function readHeaders(headersFile) {

function getReportFormat(format, filename) {
// Check if format is defined
const formats = ['xlsx', 'html'];
const formats = ['xlsx', 'html', 'influxdb'];
if (format && formats.includes(format.toLowerCase())) {
return format.toLowerCase();
}
Expand Down
44 changes: 44 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
services:
greenit-cli-influxdb:
image: ${INFLUXDB_IMAGE_VERSION}
container_name: ${INFLUXDB_HOST}
ports:
- '8086:8086'
volumes:
- greenit-cli-influxdb-storage:/var/lib/influxdb2
- ./influxdb/queries:/home/queries:rw
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=${INFLUXDB_USERNAME}
- DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUXDB_PASSWORD}
- DOCKER_INFLUXDB_INIT_ORG=${INFLUXDB_ORG_NAME}
- DOCKER_INFLUXDB_INIT_BUCKET=${INFLUXDB_BUCKET_NAME}
- DOCKER_INFLUXDB_INIT_RETENTION=${INFLUXDB_RETENTION}

greenit-cli-grafana:
container_name: greenit-cli-grafana
image: ${GRAFANA_IMAGE_VERSION}
ports:
- '3000:3000'
volumes:
- greenit-cli-grafana-storage:/var/lib/grafana
- ./grafana-provisioning/:/etc/grafana/provisioning
depends_on:
- greenit-cli-influxdb
environment:
- GF_SECURITY_ADMIN_USER=${GRAFANA_USERNAME}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_USERS_ALLOW_SIGN_UP=false
- GF_USERS_ALLOW_ORG_CREATE=false
- INFLUXDB_ORG_ID=${INFLUXDB_ORG_ID}
- INFLUXDB_TOKEN=${INFLUXDB_TOKEN}
- INFLUXDB_BUCKET_NAME=${INFLUXDB_BUCKET_NAME}
- INFLUXDB_HOST=${INFLUXDB_HOST}
- INFLUXDB_PORT=${INFLUXDB_PORT}

volumes:
greenit-cli-influxdb-storage:
driver: local
greenit-cli-grafana-storage:
driver: local
Binary file added docs/grafana-dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions grafana-provisioning/dashboards/dashboard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: 1
providers:
- name: InfluxDB
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /etc/grafana/provisioning/dashboards

Loading

0 comments on commit 072987f

Please sign in to comment.