CérénIT

Le blog tech de Nicolas Steinmetz (Time Series, IoT, Web, Ops, Data)

Web, Ops & Data - Septembre 2020

podman timezone grafana dashboard terraform sécurité terrascan terracost nvidia arm cni csi network storage cilium calico longhorn portworx openebs rancher python gke warp10 influxdb data-engineer date-scientist sql

Cloud

  • terrascan : terrascan va scanner vos fichiers terraform et les valider contre 500+ règles de sécurité (au format Open Policy Agent) afin d’identifier les éventuels problèmes de sécurité. L’outil supporte AWS, GCP et Azure.
  • infracost : estimez le coût de vos projets terraform à l’heure ou au mois. Il est même possible de faire apparaitre les évolutions de vos coûts d’infra lors d’une MR/PR. A défaut d’être forcément précis, cela pourra au moins donner une idée et permettra peut être de sensibiliser les développeurs et/ou les clients aux évolutions de couts de leurs projets.

Code

  • All Python versions before 3.6 are now totally unsupported : Python 2 n’est plus supporté depuis le début de l’année - c’est au tour de Python 3.5 de ne plus l’être depuis le 13 sept. Pour Python 3.6, ce sera décembre 2021.
  • nackjicholson/aiosql : juste milieu (?) entre du SQL brut et un ORM, aiosql semble permettre d’associer une requête SQL à une fonction pour une manipulation assez simple ensuite dans le code par la suite.

Container et orchestration

(Big) data

  • #19. Lucien Fregosi - Hugo Larcher - Erika Gelinard - Dessine moi un data engineer : Pour cette saison 2 de DataBuzzWord, des réflexions intéressantes autour du Data Engineer / Data Scientists, le Data Engineer qui fait du Build/Run, les pipelines & job as a service et de l’importance de simplifier / déporter le run pour que le Data Engineer et a fortiori le Data Scientist se concentrent sur leurs pipelines ou leur exploitation et gérer moins d’infrastructure.

Hardware

Time Series

  • InfluxDB OSS 2.0 General Availability Roadmap : un bon résumé sur les avancées d’Influx 2.0 OSS et la transition 1.x vers 2.x ; Début septembre, j’étais sceptique quand même avec le retour du stockage et du requêtage da la V1 dans la branche v2 (cf la PR “Port TSM1 storage engine”) et ce à un mois de la date de release prévue annoncés aux Influxdays de Londres (ie fin septembre). Au final, la version 2.0 OSS et Entreprise auront les feautres “frontend” de la V2 (Tasks, Dashobards, etc) mais uniquement le moteur de stockage de la V1. Si je comprends le besoin pour ne pas perdre leurs clients dans la migration, c’est un écart de plus entre les version OSS/Entreprise et la version Cloud. Les couches hautes (API, UI, fonctionnalités type Task/Dashboards/…) seront commmunes mais sous le capot (stockage, ingestion), cela diffère. On peut raisonnablement se demander si c’est une phase intermédiaire avant une migration ultérieure sur le moteur de stockage de la 2.0 quand InfluxData aura plus de recul sur le sujet ou bien si les projets Cloud et OSS/Entreprise ne vont pas diverger significativement à moyen terme. Ceux qui ont commencé à alimenter leur base InfluxDB 2.0 sur la base des versions beta devront repartir de zéro du fait de cette incompatibilité de version de moteur de stockage.
  • Popular community plugins that can improve your Grafana dashboards : une collection de plugins Grafana pour améliorer vos dashboards.
  • September 2020: Warp 10 release 2.7.0, ready for FLoWS : la version 2.7 de Warp 10 est disponible et est la première version qui va supporter FLoWS, la syntaxe fonctionnelle alternative à WarpScript. Pour en savoir plus sur FLoWS, je vous renvoie à l’édition 5 du Paris Time Series Meetup avec la présentation de FLoWS. D’autres améliorations font partie de cette release, tant d’un point de vue fonctionnalités que performances.

Git: hook commit-msg pour adopter les conventional commits

git commit conventional commit

Les “conventional commits” apportent une formalisation des messages de commit git. Ils sont de la forme :

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Pour reprendre quelques exemples :

# Commit message with no body
feat: allow provided config object to extend other configs

# Commit message with scope
feat(lang): add polish language

# Commit message with ! to draw attention to breaking change
refactor!: drop support for Node 6

# Commit message with both ! and BREAKING CHANGE footer
refactor!: drop support for Node 6

BREAKING CHANGE: refactor to use JavaScript features not available in Node 6.

En forçant ce formalisme, le développeur est un peu moins tenté d’avoir un historique de commit du style :

fix  button
typo
add some tests
add some tests
...

Au lieu de faire un commit à chaque sauvegarde du fichier ou presque, il va commencer à “raconter une histoire” :

fix: button on home page does not work on IE6
docs: typo in the README file
feat: add some tests for module XXX

Cela a le mérite aussi de générer un changelog plus agréable à lire. Si en plus, on rajoute par ex un identifiant de ticket, on peut alors facilement retracer l’historique d’un changement et sa raison d’être :

fix(123): button on home page does not work on IE6
docs(211): typo in the README file
feat(175): add some tests for module XXX

Un peu à la manière de “Properly managing your .gitignore file”, on peut vouloir que le hook git s’applique à tous nos dépôts présents et à venir et ne pas avoir à contribuer le hook à chaque dépôt git.

# Create ~/.git-templates/hooks
mkdir -p ~/.git-templates/hooks
# Create commit-msg file and make it executable
touch ~/.git-templates/hooks/commit-msg
chmod +x ~/.git-templates/hooks/commit-msg

Ajoutons ensuite notre hooks dans ~/.git-templates/hooks/commit-msg :

#!/usr/bin/env python3
# Original source: https://github.com/prahladyeri/enforce-git-message/
# Extended with BREAKING CHANGE, exclamation mark support (!) and space before " : " for French people

import re, sys, os

examples = """+ 61c8ca9 fix: navbar not responsive on mobile
+ 479c48b test: prepared test cases for user authentication
+ a992020 chore: moved to semantic versioning
+ b818120 fix: button click even handler firing twice
+ c6e9a97 fix: login page css
+ dfdc715 feat(auth): added social login using twitter
+ b235677 BREAKING CHANGE: remove support for XXX
+ a234556 revert!: back to version X.Y.Z for component ZZZ
+ b123456 feat : we support space before : for French people :-)
"""

def main():
    pattern = r'(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|BREAKING CHANGE)(\([\w\-\s]+\))?!?\s?:\s.*'
    filename = sys.argv[1]
    ss = open(filename, 'r').read()
    m = re.match(pattern, ss)
    if m == None:
        print("\nCOMMIT FAILED!")
        print("\nPlease enter commit message in the conventional format and try to commit again. Examples:")
        print("\n" + examples)
        sys.exit(1)

if __name__ == "__main__":
    main()

Il faut ensuite indiquer à git que vos templates sont dans ce dossier :

git config --global init.templatedir '~/.git-templates'

Pour les dépots git existants, il faut réinitialiser votre dépôt git :

cd /path/to/git/repo
git init
Dépôt Git existant réinitialisé dans /path/to/git/repo/.git/

Vous pouvez alors commencer à travailler dans votre repo et valider le bon fonctionnement du hook.

Premiers pas avec Warp 10 : comptabilité et prévisions de fin d'année

warp10 timeseries forecast dashboard warpstudio arima

Suite de notre épopée :

Cherchant à me familiariser avec la base de données orientée série temporelles Warp 10 d’une part et à améliorer mes tableaux de bord comptables pour me faire des projections à fin d’année (parce que bon, faire juste la moyenne des mois précédents comme valeur pour les mois à venir, c’est un peu trop facile), je me suis dit que c’était un exercice qui pouvait répondre aux deux besoins après avoir lu Time series forecasts in WarpScript.

Pour ceux qui ne connaissent pas encore Warp 10 , c’est une solution de geo-timeseries (séries spatio temporelles) open source, éditée par SenX, société française basée à Brest. Pour en savoir plus sur Warp 10 , vous pouvez regarder l’éditions 1 et l’édition 5 du Paris Time Series Meetup.

Pour prendre en main Warp 10 et appréhender le langage de programmation Warpscript, je vous invite à suivre le tutoriel sur les cyclones en utilisant la Sandbox Warp10 mise à disposition par Senx.

Le jeu de données

Pour le jeu de données, j’ai donc récupéré de mes tableaux de bords mon chiffre d’affaires et mes dépenses mensuels sur la période Janvier 2017 à Mai 2020.

Nous allons donc créer 2 séries (appelées aussi GTS)

Soit crnt-revenue.gts:

# 2017
1483225200000000// revenue{company=cerenit} 0
1485903600000000// revenue{company=cerenit} 13800
1488322800000000// revenue{company=cerenit} 11325
1490997600000000// revenue{company=cerenit} 300
1493589600000000// revenue{company=cerenit} 6825
1496268000000000// revenue{company=cerenit} 8450
1498860000000000// revenue{company=cerenit} 5425
1501538400000000// revenue{company=cerenit} 10650
1504216800000000// revenue{company=cerenit} 13650
1506808800000000// revenue{company=cerenit} 0
1509490800000000// revenue{company=cerenit} 11200
1512082800000000// revenue{company=cerenit} 19225
# 2018
1514761200000000// revenue{company=cerenit} 8300
1517439600000000// revenue{company=cerenit} 8850
1519858800000000// revenue{company=cerenit} 10285
1522533600000000// revenue{company=cerenit} 8850
1525125600000000// revenue{company=cerenit} 8850
1527804000000000// revenue{company=cerenit} 9450
1530396000000000// revenue{company=cerenit} 12000
1533074400000000// revenue{company=cerenit} 11250
1535752800000000// revenue{company=cerenit} 15013
1538344800000000// revenue{company=cerenit} 15750
1541026800000000// revenue{company=cerenit} 13750
1543618800000000// revenue{company=cerenit} 10125
# 2019
1546297200000000// revenue{company=cerenit} 15375
1548975600000000// revenue{company=cerenit} 14750
1551394800000000// revenue{company=cerenit} 11600
1554069600000000// revenue{company=cerenit} 20622
1556661600000000// revenue{company=cerenit} 6376
1559340000000000// revenue{company=cerenit} 13350
1561932000000000// revenue{company=cerenit} 11250
1564610400000000// revenue{company=cerenit} 7050
1567288800000000// revenue{company=cerenit} 14750
1569880800000000// revenue{company=cerenit} 12326
1572562800000000// revenue{company=cerenit} 12513
1575154800000000// revenue{company=cerenit} 9082
# 2020
1577833200000000// revenue{company=cerenit} 13000
1580511600000000// revenue{company=cerenit} 12375
1583017200000000// revenue{company=cerenit} 15500
1585692000000000// revenue{company=cerenit} 5525
1588284000000000// revenue{company=cerenit} 15750

et crnt-expenses.gts:

# 2017
1483225200000000// expense{company=cerenit} 219
1485903600000000// expense{company=cerenit} 5471
1488322800000000// expense{company=cerenit} 7441
1490997600000000// expense{company=cerenit} 6217
1493589600000000// expense{company=cerenit} 5676
1496268000000000// expense{company=cerenit} 5719
1498860000000000// expense{company=cerenit} 5617
1501538400000000// expense{company=cerenit} 5690
1504216800000000// expense{company=cerenit} 5831
1506808800000000// expense{company=cerenit} 9015
1509490800000000// expense{company=cerenit} 8903
1512082800000000// expense{company=cerenit} 11181
# 2018
1514761200000000// expense{company=cerenit} 9352
1517439600000000// expense{company=cerenit} 9297
1519858800000000// expense{company=cerenit} 8506
1522533600000000// expense{company=cerenit} 8677
1525125600000000// expense{company=cerenit} 10136
1527804000000000// expense{company=cerenit} 10949
1530396000000000// expense{company=cerenit} 8971
1533074400000000// expense{company=cerenit} 9062
1535752800000000// expense{company=cerenit} 9910
1538344800000000// expense{company=cerenit} 10190
1541026800000000// expense{company=cerenit} 10913
1543618800000000// expense{company=cerenit} 13569
# 2019
1546297200000000// expense{company=cerenit} 11553
1548975600000000// expense{company=cerenit} 11401
1551394800000000// expense{company=cerenit} 10072
1554069600000000// expense{company=cerenit} 10904
1556661600000000// expense{company=cerenit} 9983
1559340000000000// expense{company=cerenit} 11541
1561932000000000// expense{company=cerenit} 11065
1564610400000000// expense{company=cerenit} 10359
1567288800000000// expense{company=cerenit} 10450
1569880800000000// expense{company=cerenit} 9893
1572562800000000// expense{company=cerenit} 10014
1575154800000000// expense{company=cerenit} 15354
# 2020
1577833200000000// expense{company=cerenit} 9673
1580511600000000// expense{company=cerenit} 9933
1583017200000000// expense{company=cerenit} 9815
1585692000000000// expense{company=cerenit} 9400
1588284000000000// expense{company=cerenit} 9381

Pour chaque fichier:

  • le premier champ est un timestamp correspondant au 1er jour de chaque mois à 00h00.
  • la partie // indique qu’il n’y a pas de position spatiale (longitude, lattitude, élévation)
  • expense et revenue sont les noms des classes qui vont stocker mes informations
  • company est un label que je positionne sur mes données avec le nom de mon entreprise
  • le dernier champ est la valeur de mon chiffre d’affaires ou de mes dépenses mensuels.

Pour plus d’information sur la modélisation, cf GTS Input Format.

Insertion des données

Lorsque vous utilisez la Sandbox, 3 tokens vous sont donnés :

  • un token pour lire les données ; j’y ferai référence via <readToken> par la suite
  • un token pour écrire les données ; j’y ferai référence via <writeToken> par la suite
  • un token pour supprimer les données ; j’y ferai référence via <deleteToken> par la suite
#!/usr/bin/env bash

for file in crnt-expenses crnt-revenue ; do
	curl -v -H 'Transfer-Encoding: chunked' -H 'X-Warp10-Token: <writeToken>' -T ${file}.gts 'https://sandbox.senx.io/api/v0/update'
done

Premières requêtes

Pour ce faire, nous allons utiliser le Warp Studio ; pour la datasource, il conviendra de veiller à ce que la SenX Sandbox soit bien sélectionnée.

L’équivalent de “SELECT * FROM *” peut se faire de la façon suivante :

# Authentification auprès de l'instance en lecture
'<readToken> 'readToken' STORE
# FETCH permet de récupérer une liste de GTS, ici on demande toutes les classes via ~.* et tous les labels en prenanr les 1000 dernières valeurs ; on récupère donc toutes les séries.
[ $readToken '~.*' {} NOW -1000 ] FETCH

Si vous cliquez sur l’onglet “Dataviz”, vous avez alors immédiatement une représentation graphique de vos points.

warp10 - fetch

Maintenant que nos données sont bien présentes, on va vouloir aller un peu plus loin dans nos manipulations.

Premières manipulations

Ce que nous voulons faire :

  • Sélectionner chaque série et la stocker dans une variable,
  • Calculer le résultat mensuel et le persister dans une troisième série temporelle
  • Afficher les trois séries.

Pour sélectionner chaque série et la stocker dans une variable:

# Authentification auprès de l'instance en lecture
'<readToken>' 'readToken' STORE

# FETCH : permet de récupérer une liste de série, ici on filtre sur la classe expense, sur le label company = cerenit et sur les dates du 01/12/2016 au 01/06/2020.
# 0 GET : on sait que l'on a qu'une seule série qui correspond à la requête. Donc on ne retient que le 1er élément pour passer d'une liste de GTS à une seule et unique GTS.
# STORE : stocke le résultat dans une variable exp.
[ $readToken 'expense' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'exp' STORE

# Idem pour la classe revenue, stockée dans une variable revenue.
[ $readToken 'revenue' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'revenue' STORE

# Affiche les 2 séries
$exp
$revenue

A ce stade, vous avez la même représentation graphique que précédemment si vous cliquez sur Dataviz.

warp10 - fetch

Calculons maintenant le résultat mensuel (chiffre d’affaires - dépenses) :

# Authentification auprès de l'instance en lecture
'<readToken>' 'readToken' STORE

# Le même bloc que précédemment
[ $readToken 'expense' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'exp' STORE

[ $readToken 'revenue' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'revenue' STORE

# Calcul: il suffit se soustraire les deux éléments pour avoir le résultat
$revenue $exp -
# on affiche également les deux autres variables pour la dataviz
$exp
$revenue

warp10 - result

A ce stade :

  • Au niveau de la dataviz, la légende ne fournit aucune information sur la nature de la série
  • Cette donnée n’est pas encore persistée

Jusqu’à présent, nous avons utilisé que le <readToken> pour lire les données. Pour la persistence, nous allons utilier le <writeToken>.

# Authentification auprès de l'instance en lecture
'<readToken>' 'readToken' STORE
# Authentification auprès de l'instance en écriture
'<writeToken>' 'writeToken' STORE

[ $readToken 'expense' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'exp' STORE

[ $readToken 'revenue' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'revenue' STORE

# La première ligne est inchangée, elle calcule le résultat mensuel et la donnée est de type GTS
# Du coup, comme nous sommes dans une pile et que l'on hérite de ce qu'il s'est passé avant, on peut lui assigner un nom via RENAME
# Puis lui ajouter le label company avec pour valeur cerenit
# Et utiliser la fonction UPDATE pour stocker en base la GTS ainsi obtenue.
$revenue $exp -
"result" RENAME
{ "company" "cerenit" } RELABEL
$writeToken UPDATE

# Comme pour revenue et expense, on récupère les données sous la forme d'une GTS que l'on stocke dans une variable
[ $readToken 'result' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'result' STORE

# On vide la pile
CLEAR
# On affiche les variables créées
$revenue
$exp
$result

warp10 - result store

Et voilà !

Prévoyons le futur

Warp10 dispose d’une extension propriétaire et payante permettant d’appliquer des algorithmes de prévisions sur des séries temporelles : warp10-ext-forecasting. Il est possible d’utiliser cette extension sur la Sandbox Warp10 mise à disposition par SenX.

Il existe une fonction AUTO et SAUTO (version saisonnière) qui applique automatiquement des algorythmes d’AutoML sur vos données.

# Authentification auprès de l'instance en lecture
'<readToken>' 'readToken' STORE

# Récupération des trois séries
[ $readToken 'expense' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'exp' STORE

[ $readToken 'revenue' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'revenue' STORE

[ $readToken 'result' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'result' STORE

CLEAR
$revenue
$exp
$result
# MAP: la fonction `AUTO` s'attend à manipuler des nombres au format `DOUBLE` et non des entiers. Il faut donc faire la conversion.
# FORECAST: sur les données obtenues du MAP, on applique la fonction AUTO et on demande les 8 prochaines occurents (pour aller jusqu'à la fin d'année)
# Le .ADDVALUES permet de "fusionner" les prévisions avec la série parente (sans les persister en base à ce stade)
# Commes les 3 projections sont disponibles dans la pile, elles sont également affichées
[ $result mapper.todouble 0 0 0 ] MAP
AUTO 8 FORECAST.ADDVALUES
[ $revenue mapper.todouble 0 0 0 ] MAP
AUTO 8 FORECAST.ADDVALUES
[ $exp mapper.todouble 0 0 0 ] MAP
AUTO 8 FORECAST.ADDVALUES

warp10 - forecast auto

Du fait du FORECAST.ADDVALUES, on pourrait se passer d’afficher les trois premières séries. Mais vistuellement, cela permet de voir la différence entre la série originale et la projection.

Une fois l’effet Whaou passé, on peut se demander quel modèle a été appliqué. Pour cela il y a la fonction MODELINFO

# Authentification auprès de l'instance en lecture
'<readToken>' 'readToken' STORE

# Récupération des trois séries
[ $readToken 'expense' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'exp' STORE

[ $readToken 'revenue' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'revenue' STORE

[ $readToken 'result' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'result' STORE

CLEAR
[ $result mapper.todouble 0 0 0 ] MAP
AUTO MODELINFO
[ $revenue mapper.todouble 0 0 0 ] MAP
AUTO MODELINFO
[ $exp mapper.todouble 0 0 0 ] MAP
AUTO MODELINFO

Dans l’onglet des résultats, on voit l’information: "model": "ARIMA".

warp10 - forecast modelinfo

Si on veut alors faire la même chose en utilisant le modèle ARIMA :

# Authentification auprès de l'instance en lecture
'<readToken>' 'readToken' STORE

# Récupération des trois séries
[ $readToken 'expense' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'exp' STORE

[ $readToken 'revenue' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'revenue' STORE

[ $readToken 'result' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'result' STORE

CLEAR

# SEARCH.ARIMA: applique un modèle ARIMA (ARMA ou ARIMA) sur la GTS passée en paramètre
# FORECAST.ADDVALUES: fait une précision sur les 7 prochaines occurences et les fusionne avec la série sur laquelle la projection est faite.
# Les 3 projections restant dans la pile, elles sont affichées
[ $revenue mapper.todouble 0 0 0 ] MAP
SEARCH.ARIMA
7 FORECAST.ADDVALUES

[ $exp mapper.todouble 0 0 0 ] MAP
SEARCH.ARIMA
7 FORECAST.ADDVALUES

[ $result mapper.todouble 0 0 0 ] MAP
SEARCH.ARIMA
7 FORECAST.ADDVALUES

warp10 - forecast arima

Et nous obtenons bien le même résultat.

On peut se poser alors la question de voir si la projection sur le résultat est la même que la soustraction entre la projection de chiffres d’affaires et de dépenses et mesurer l’éventuel écart.

# Authentification auprès de l'instance en lecture
'<readToken>' 'readToken' STORE

[[ $readToken 'expense' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'exp' STORE

[ $readToken 'revenue' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'revenue' STORE

[ $readToken 'result' { 'company' '=cerenit' } '2016-12-01T00:00:00Z' '2020-06-01T00:00:00Z' ] FETCH
0 GET
'result' STORE

CLEAR
# La différence sur les 3 projections est que l'on stocke chaque résultat dans une variable
[ $result mapper.todouble 0 0 0 ] MAP
AUTO 8 FORECAST.ADDVALUES
'fresult' STORE

[ $revenue mapper.todouble 0 0 0 ] MAP
AUTO 8 FORECAST.ADDVALUES
'frevenue' STORE

[ $exp mapper.todouble 0 0 0 ] MAP
AUTO 8 FORECAST.ADDVALUES
'fexp' STORE

$frevenue
$fexp
$fresult
# ici on calcule la projection du résultat sur la base des projections de chiffres d'affaires et de dépenses
$frevenue $fexp -

On constate bien un écart entre la courbe orange (la soustraction des projections) et la courbe bleu (la projection du résultat).

warp10 - forecast arima

Nous voilà à la fin de ce billet, j’espère que ce tour du propriétaire vous aura permis d’apprécier Warp10 et ses capacités.

Il ne reste plus qu’à voir en fin d’année dans quelles mesures ces projections seront valides ou pas !

Mon bilan sur Warp10 à ce stade :

  • Il faut absolument suivre le tutoriel sur les cyclones, cela permet de se mettre progressivement à Warpscript et de comprendre les mécanismes de fonctionnement du langage et de la pile (stack).
  • la notation de Warpscript est particulière au début mais on s’y fait petit à petit et sinon FLoWS devrait lever les dernières réticences.
  • Comme on a une pile, il ne faut pas hésiter à utiliser STOP et TYPOEOF notamment pour savoir ce que l’on manipule comme donnée à un instant T ; cf Debugging WarpScript
  • Le WarpStudio ou l’extension VSCode permettent d’avoir un contexte de développement agréable avec l’autocomplétion, la documentation des fonctions, etc.
  • Contrairement à InfluxDB où tout s’articule autour du measurement (équivalent de la classe ici), le fait d’avoir un langage de manipulation (et pas principalement de requêtage avec quelques transformations) de données permet d’avoir une modélisation plus souple et de réconcilier les données ensuite. Le même exercice dans InfluxDB supposerait d’avoir un seul measurement et d’avoir les différentes valeurs en son sein. Du coup, cela empêcherait le calcul et le stockage du résultat par ex. Il aurait fallu le calculer au préalable et l’insérer dans la base en même temps que les données de chiffre d’affaires et de dépenses pour que les données soient ensemble. Certes Flux et InfluxDB 2.0 vont lever quelques contraintes de modélisation et de manipulation de données, mais le prisme de la modélisation autour du measurement reste primordial dans le produit.
  • Avoir un langage de manipulation de données et non uniquement de requêtage et quelques transformation évite aussi de devoir sortir les données pour les analyser puis les renvoyer vers la base de données le cas échéant. Non seulement on reste au plus près de la donnée (éxécution coté serveur) mais on évite aussi les problématiques de drivers, conversion dans les structures de données du langage cible, etc.
  • Les classes de warpscript sont certes mono valeurs (même si le multivalue existe) mais je présume que cela sert surtout pour des données de même nature plutôt que pour des données hétérogènes. En effet, il s’agit d’une liste et non d’un tableau de données. (NDLR: Mathias me précise qu’une multivalue est une GTS et non une simple liste - cela est précisé si on lit bien la totalité de la doc de multivalue)

Une expérience au final positive qui pousse à aller creuser plus loin les fonctionnalités de cette plateforme. Ce sera l’opportunité de rédiger d’autres billets à l’avenir.

Web, Ops & Data - Août 2020

python vscode cassandra nosql mariadb s3 cdk terraform ptyhon setuptools git gitignore rook ceph

Cloud

  • CDK for Terraform: Enabling Python & TypeScript Support : cdk est le Cloud Development Kit édité par AWS, Hashicorp annonce donc son support dans terraform. Si la démo semble fonctionner (faut aimer typescript…), à voir ce que cela peut donner sur des projets de plus grande ampleur et ce que donne l’empilement d’abstractions (Code > CDK > Terraform > Provider) lors des erreurs et bugs.

Code

Container et orchestration

(No)SQL

  • Introducing Apache Cassandra 4.0 Beta: Battle Tested From Day One : Première beta pour la tant attendue Cassandra 4.0 - version GA espérée pour la fin d’année. On notera le passage à Java 11 et le nouveau ZGC, des gains de performance sur les tâches d’opération, un audit logging, et bien d’autres choses encore. A noter que l’écosystème semble prêt déjà à supporter la 4.0 comme avec Repair, Medusa, etc.
  • MariaDB S3 Engine: Implementation and Benchmarking : MariaDB dispose d’un plugin S3 en version alpha. Il permet de déporter des tables dans S3 et de les requêter. Pour des cas en lecture et suivant vos requêtes cela peut avoir du sens apparemment. D’autres billets sur le sujet devraient suivre prochainement.

OS

Web, Ops & Data - Juillet 2020

terraform acme letsencrypt influxdb influxdays questdb timeseries rancher suse stash kubedb maesh warp10 warpscript flows ptsm rgpd safe-harbor données personnelles grafana flux

Cloud

Container et orchestration

  • Announcing Maesh 1.3 : Maesh continue son chemin et ajoute la capacité de surveiller des namespace particuliées (en plus de pouvoir en ignorer), le support du lookup des ports (http -> 80), le support de CoreDNS chez AKS et d’autres améliorations encore.
  • Electro Mpnkeys #9 – Traefik et Maesh : de l’ingress au service mesh avec Michael Matur : si vous voulez en savoir plus sur Traefik et Maesh, je vous conseille cet épisode (et les autres) du podcast Electro Monkeys.
  • Introducing Traefik Pilot: a First Look at Our New SaaS Control Platform for Traefik : Containous, la société derrière Traefik, Maesh et Yaegi sort son offre SaaS pour piloter et monitorer ses instances traefik. Un système de plugins pour les middleware fait également son apparaition. Il faut une version 2.3+ (actuellement en RC) de Traefik pour bénéficier de cette intégration.
  • Relicensing Stash & KubeDB : KubeDB, l’operateur de bases de données et Stash, l’outil de sauvegarde se cherchent un modèle économique et changent de licence. La version gratuite, avec code source disponible, reste disponible pour des usages non commerciaux (voir les détails de la licence pour une slite exacte). Pour un usage commercial, il faudra passer par la version Entreprise qui apporte aussi des fonctionnalités supplémentaires.
  • Suse to acquire Rancher : Suse était sorti de mon radar; c’est donc pour moi l’entrée (ou le retour ?) de Suse dans le monde de kubernetes et de son orchestration. Est-ce une volonté d’aller prendre des parts de marchés à Redhat/Openshift ou de faire face à des rumeurs telles que Google en discussion pour acquérir D2IQ (ex Mesoshphère) ? A voir si cette acquisition va être un tremplin pour Rancher et ses différents projets (rke, rio, k3s, longhorn, etc) comme l’indique son CTO ou pas.

Time Series

Vie privée & données personnelles

Le Privacy Shield, l’accord entre l’Europe et les USA sur le transfert des données des Européens vers les USA (ou les sociétés américaines) vient d’être invalidé par la cour de justice européene. Les flux “absolument nécessaires” peuvent continuer à se faire pour le moment et la cour a validé “les clauses contractuelles types” définies par la Commission Européenne pourront être utilisées par les entreprises. Néanmoins, pour s’y référer, il semble qu’il faut vérifier que l’entreprise protège effectivement les données. Je vous invite à contacter votre juriste ou avocat pour mieux appréhender les impacts de cette invalidation si vous utilisez les plateformes cloud et des services dont les entreprises sont basées aux USA. En tant qu’individu, il peut être intéressant de se poser des questions également. N’étant pas juriste, je vais donc limiter mon interprétation ici et vous laisse lire les liens ci-dessous.

8 9 10 11 12