from chatgpt
This commit is contained in:
commit
3deb05dc7d
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"editor.fontSize": 13,
|
||||
"terminal.integrated.fontSize": 13,
|
||||
"window.zoomLevel": 1.4,
|
||||
}
|
||||
7
Dockerfile
Normal file
7
Dockerfile
Normal file
@ -0,0 +1,7 @@
|
||||
FROM bash:5.2
|
||||
|
||||
WORKDIR /app
|
||||
COPY fake_logs.sh .
|
||||
RUN chmod +x fake_logs.sh
|
||||
|
||||
CMD ["./fake_logs.sh", "100", "json"]
|
||||
770
README.md
Normal file
770
README.md
Normal file
@ -0,0 +1,770 @@
|
||||
# 🧪 Fake Log Generator for Loki
|
||||
|
||||
Ce projet génère de faux logs réalistes dans plusieurs formats (`apache`, `json`, `ltsv`, `custom`) et les envoie à Grafana Loki via Promtail.
|
||||
|
||||
## 🔧 Démarrage rapide
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
./fake_logs.sh 0 json --loop >> logs/access.log
|
||||
```
|
||||
|
||||
## 🔗 Accès
|
||||
|
||||
- Grafana : http://localhost:3000 (admin / admin)
|
||||
- Loki : http://localhost:3100
|
||||
|
||||
## 🔍 Requête exemple (Grafana Explore)
|
||||
|
||||
```logql
|
||||
{job="fake_logs"}
|
||||
```
|
||||
|
||||
## 📦 Contenu
|
||||
|
||||
- `fake_logs.sh` : générateur de logs
|
||||
- `promtail-config.yml` : config pour envoyer vers Loki
|
||||
- `docker-compose.yml` : stack Loki + Promtail + Grafana
|
||||
|
||||
|
||||
|
||||
FROM AI
|
||||
Exemple de script Bash : fake_logs.sh
|
||||
#!/bin/bash
|
||||
|
||||
# Nombre de lignes de log à générer (par défaut : 100)
|
||||
LINES=${1:-100}
|
||||
|
||||
# Listes de données factices
|
||||
METHODS=("GET" "POST" "PUT" "DELETE" "PATCH")
|
||||
PATHS=("/" "/login" "/dashboard" "/api/data" "/settings" "/products" "/checkout")
|
||||
CODES=(200 201 204 301 302 400 401 403 404 500 503)
|
||||
AGENTS=(
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
|
||||
"curl/7.68.0"
|
||||
"PostmanRuntime/7.29.0"
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X)"
|
||||
)
|
||||
|
||||
# Fonction pour générer une IP aléatoire
|
||||
random_ip() {
|
||||
echo "$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256))"
|
||||
}
|
||||
|
||||
# Fonction pour générer une date au format Apache
|
||||
random_date() {
|
||||
date -d "$((RANDOM % 30 + 1)) days ago" "+%d/%b/%Y:%H:%M:%S %z"
|
||||
}
|
||||
|
||||
# Boucle de génération de log
|
||||
for ((i=0; i<LINES; i++)); do
|
||||
IP=$(random_ip)
|
||||
DATE=$(random_date)
|
||||
METHOD=${METHODS[$RANDOM % ${#METHODS[@]}]}
|
||||
PATH=${PATHS[$RANDOM % ${#PATHS[@]}]}
|
||||
CODE=${CODES[$RANDOM % ${#CODES[@]}]}
|
||||
SIZE=$((RANDOM % 5000 + 200))
|
||||
AGENT=${AGENTS[$RANDOM % ${#AGENTS[@]}]}
|
||||
|
||||
echo "$IP - - [$DATE] \"$METHOD $PATH HTTP/1.1\" $CODE $SIZE \"$AGENT\""
|
||||
done
|
||||
🔧 Utilisation
|
||||
Rends le script exécutable :
|
||||
chmod +x fake_logs.sh
|
||||
Exécute-le :
|
||||
./fake_logs.sh 500 > access.log
|
||||
(Cela générera 500 lignes de logs dans un fichier access.log)
|
||||
🔄 Exemple de sortie :
|
||||
92.123.44.222 - - [15/May/2025:14:23:01 +0000] "GET /api/data HTTP/1.1" 200 3412 "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||
14.56.222.1 - - [10/May/2025:18:43:51 +0000] "POST /login HTTP/1.1" 401 834 "curl/7.68.0"
|
||||
Souhaites-tu qu’on ajoute la prise en charge de plusieurs formats de log (JSON, Apache, LTSV, etc.) comme le fait flog ?
|
||||
|
||||
|
||||
Vous avez dit :
|
||||
oui
|
||||
ChatGPT a dit :
|
||||
Parfait ! Voici une version étendue du script Bash fake_logs.sh qui permet de générer des logs en plusieurs formats comme le fait mingrammer/flog : apache, json, ltsv, ou custom.
|
||||
|
||||
✅ Script Bash : fake_logs.sh (multi-formats)
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# Nombre de lignes à générer
|
||||
LINES=${1:-100}
|
||||
FORMAT=${2:-apache} # apache | json | ltsv | custom
|
||||
|
||||
METHODS=("GET" "POST" "PUT" "DELETE" "PATCH")
|
||||
PATHS=("/" "/login" "/dashboard" "/api/data" "/settings" "/products" "/checkout")
|
||||
CODES=(200 201 204 301 302 400 401 403 404 500 503)
|
||||
AGENTS=(
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
|
||||
"curl/7.68.0"
|
||||
"PostmanRuntime/7.29.0"
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X)"
|
||||
)
|
||||
|
||||
random_ip() {
|
||||
echo "$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256))"
|
||||
}
|
||||
|
||||
random_date() {
|
||||
date -d "$((RANDOM % 30 + 1)) days ago" "+%d/%b/%Y:%H:%M:%S %z"
|
||||
}
|
||||
|
||||
iso_date() {
|
||||
date -d "$((RANDOM % 30 + 1)) days ago" --iso-8601=seconds
|
||||
}
|
||||
|
||||
# Fonction principale de génération de logs
|
||||
generate_log() {
|
||||
IP=$(random_ip)
|
||||
DATE=$(random_date)
|
||||
ISO_DATE=$(iso_date)
|
||||
METHOD=${METHODS[$RANDOM % ${#METHODS[@]}]}
|
||||
PATH=${PATHS[$RANDOM % ${#PATHS[@]}]}
|
||||
CODE=${CODES[$RANDOM % ${#CODES[@]}]}
|
||||
SIZE=$((RANDOM % 5000 + 200))
|
||||
AGENT=${AGENTS[$RANDOM % ${#AGENTS[@]}]}
|
||||
|
||||
case "$FORMAT" in
|
||||
apache)
|
||||
echo "$IP - - [$DATE] \"$METHOD $PATH HTTP/1.1\" $CODE $SIZE \"$AGENT\""
|
||||
;;
|
||||
json)
|
||||
echo "{\"ip\":\"$IP\",\"timestamp\":\"$ISO_DATE\",\"method\":\"$METHOD\",\"path\":\"$PATH\",\"code\":$CODE,\"size\":$SIZE,\"agent\":\"$AGENT\"}"
|
||||
;;
|
||||
ltsv)
|
||||
echo "host:$IP\ttime:$ISO_DATE\tmethod:$METHOD\tpath:$PATH\tstatus:$CODE\tsize:$SIZE\tagent:$AGENT"
|
||||
;;
|
||||
custom)
|
||||
echo "[$ISO_DATE] $IP | $METHOD $PATH => $CODE ($SIZE bytes)"
|
||||
;;
|
||||
*)
|
||||
echo "Format inconnu : $FORMAT" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Boucle de génération
|
||||
for ((i=0; i<LINES; i++)); do
|
||||
generate_log
|
||||
done
|
||||
🔧 Utilisation
|
||||
|
||||
Rends-le exécutable :
|
||||
chmod +x fake_logs.sh
|
||||
Utilisation de base :
|
||||
./fake_logs.sh 100 apache # format apache (par défaut)
|
||||
./fake_logs.sh 50 json # format JSON
|
||||
./fake_logs.sh 20 ltsv # format LTSV
|
||||
./fake_logs.sh 10 custom # format personnalisé
|
||||
Rediriger vers un fichier :
|
||||
./fake_logs.sh 100 json > logs.json
|
||||
🧪 Exemples
|
||||
|
||||
Format apache
|
||||
173.29.44.102 - - [17/May/2025:12:04:10 +0000] "GET /dashboard HTTP/1.1" 200 2641 "curl/7.68.0"
|
||||
Format json
|
||||
{"ip":"244.51.138.41","timestamp":"2025-05-06T13:32:01+00:00","method":"POST","path":"/login","code":403,"size":876,"agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X)"}
|
||||
Format ltsv
|
||||
host:201.34.118.72 time:2025-05-22T08:17:14+00:00 method:GET path:/api/data status:200 size:2123 agent:PostmanRuntime/7.29.0
|
||||
Format custom
|
||||
[2025-05-14T07:10:33+00:00] 102.144.33.111 | PUT /checkout => 201 (4321 bytes)
|
||||
Souhaites-tu que j'ajoute aussi :
|
||||
|
||||
la génération en continu (mode --loop)
|
||||
des logs dans des fichiers séparés (erreur/access)
|
||||
une version Dockerisée ?
|
||||
Je peux aussi écrire une version Python plus puissante si tu veux aller plus loin.
|
||||
|
||||
Vous avez dit :
|
||||
Souhaites-tu que j'ajoute aussi :
|
||||
|
||||
la génération en continu (mode --loop)
|
||||
des logs dans des fichiers séparés (erreur/access)
|
||||
une version Dockerisée ? oui
|
||||
ChatGPT a dit :
|
||||
Parfait ! Voici une version complète de fake_logs.sh avec génération continue (--loop), fichiers séparés (access.log / error.log), et image Docker.
|
||||
|
||||
📜 Script Bash complet : fake_logs.sh
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# Nombre de lignes par défaut
|
||||
LINES=${1:-100}
|
||||
FORMAT=${2:-apache}
|
||||
MODE=$3
|
||||
|
||||
METHODS=("GET" "POST" "PUT" "DELETE" "PATCH")
|
||||
PATHS=("/" "/login" "/dashboard" "/api/data" "/settings" "/products" "/checkout")
|
||||
CODES_OK=(200 201 204 301 302)
|
||||
CODES_ERR=(400 401 403 404 500 503)
|
||||
AGENTS=(
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
|
||||
"curl/7.68.0"
|
||||
"PostmanRuntime/7.29.0"
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X)"
|
||||
)
|
||||
|
||||
random_ip() {
|
||||
echo "$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256))"
|
||||
}
|
||||
|
||||
random_date() {
|
||||
date "+%d/%b/%Y:%H:%M:%S %z"
|
||||
}
|
||||
|
||||
iso_date() {
|
||||
date --iso-8601=seconds
|
||||
}
|
||||
|
||||
generate_log() {
|
||||
IP=$(random_ip)
|
||||
DATE=$(random_date)
|
||||
ISO_DATE=$(iso_date)
|
||||
METHOD=${METHODS[$RANDOM % ${#METHODS[@]}]}
|
||||
PATH=${PATHS[$RANDOM % ${#PATHS[@]}]}
|
||||
AGENT=${AGENTS[$RANDOM % ${#AGENTS[@]}]}
|
||||
SIZE=$((RANDOM % 5000 + 200))
|
||||
|
||||
# Choix entre code OK ou erreur (20% erreurs)
|
||||
if (( RANDOM % 10 < 2 )); then
|
||||
CODE=${CODES_ERR[$RANDOM % ${#CODES_ERR[@]}]}
|
||||
FILE="error.log"
|
||||
else
|
||||
CODE=${CODES_OK[$RANDOM % ${#CODES_OK[@]}]}
|
||||
FILE="access.log"
|
||||
fi
|
||||
|
||||
case "$FORMAT" in
|
||||
apache)
|
||||
LOG="$IP - - [$DATE] \"$METHOD $PATH HTTP/1.1\" $CODE $SIZE \"$AGENT\""
|
||||
;;
|
||||
json)
|
||||
LOG="{\"ip\":\"$IP\",\"timestamp\":\"$ISO_DATE\",\"method\":\"$METHOD\",\"path\":\"$PATH\",\"code\":$CODE,\"size\":$SIZE,\"agent\":\"$AGENT\"}"
|
||||
;;
|
||||
ltsv)
|
||||
LOG="host:$IP time:$ISO_DATE method:$METHOD path:$PATH status:$CODE size:$SIZE agent:$AGENT"
|
||||
;;
|
||||
custom)
|
||||
LOG="[$ISO_DATE] $IP | $METHOD $PATH => $CODE ($SIZE bytes)"
|
||||
;;
|
||||
*)
|
||||
echo "Format inconnu : $FORMAT" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$LOG" >> "$FILE"
|
||||
echo "$LOG"
|
||||
}
|
||||
|
||||
# Fonction de génération continue
|
||||
generate_loop() {
|
||||
while true; do
|
||||
generate_log
|
||||
sleep 0.5
|
||||
done
|
||||
}
|
||||
|
||||
# Exécution
|
||||
if [[ "$MODE" == "--loop" ]]; then
|
||||
generate_loop
|
||||
else
|
||||
for ((i=0; i<LINES; i++)); do
|
||||
generate_log
|
||||
done
|
||||
fi
|
||||
🐳 Dockerfile
|
||||
|
||||
Voici un Dockerfile pour exécuter ton générateur de logs dans un conteneur :
|
||||
|
||||
FROM bash:5.2
|
||||
|
||||
WORKDIR /app
|
||||
COPY fake_logs.sh .
|
||||
RUN chmod +x fake_logs.sh
|
||||
|
||||
CMD ["./fake_logs.sh", "100", "apache"]
|
||||
🔧 Construction et Exécution avec Docker
|
||||
|
||||
1. Construire l'image :
|
||||
docker build -t fake-logs .
|
||||
2. Lancer une génération simple :
|
||||
docker run --rm fake-logs
|
||||
3. Lancer en boucle continue (utile pour tests de pipelines, ELK, etc.) :
|
||||
docker run --rm fake-logs ./fake_logs.sh 0 apache --loop
|
||||
4. Monter un volume pour récupérer les fichiers :
|
||||
docker run --rm -v $(pwd)/logs:/app/logs -w /app fake-logs ./fake_logs.sh 100 json
|
||||
📁 Résultat
|
||||
|
||||
access.log : requêtes réussies (200, 201, etc.)
|
||||
error.log : requêtes échouées (404, 500, etc.)
|
||||
Supporte :
|
||||
4 formats : apache, json, ltsv, custom
|
||||
Mode boucle avec --loop
|
||||
Séparation access/error
|
||||
Souhaites-tu aussi :
|
||||
|
||||
Un script pour envoyer ces logs vers un serveur (syslog, fluentd, etc.) ?
|
||||
Un service systemd pour générer des logs sur une VM ?
|
||||
Une interface Web pour déclencher/paramétrer la génération ?
|
||||
Je peux aussi t’aider à l’intégrer à une stack ELK, Loki, etc.
|
||||
|
||||
Vous avez dit :
|
||||
loki
|
||||
ChatGPT a dit :
|
||||
Parfait ! Intégrer tes faux logs générés en Bash à Grafana Loki est une excellente idée pour tester une stack d’observabilité.
|
||||
|
||||
Voici un guide complet pour envoyer tes logs générés par fake_logs.sh vers Loki, avec ou sans Docker, et visualiser dans Grafana.
|
||||
|
||||
🧱 Architecture cible
|
||||
|
||||
[fake_logs.sh] --> [Promtail] --> [Loki] --> [Grafana]
|
||||
✅ Étapes
|
||||
|
||||
1. ⚙️ Lancer une stack Loki + Grafana + Promtail via Docker Compose
|
||||
Crée un fichier docker-compose.yml :
|
||||
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
loki:
|
||||
image: grafana/loki:2.9.4
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
|
||||
promtail:
|
||||
image: grafana/promtail:2.9.4
|
||||
volumes:
|
||||
- ./logs:/var/log/fake
|
||||
- ./promtail-config.yml:/etc/promtail/promtail.yml
|
||||
command: -config.file=/etc/promtail/promtail.yml
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana:10.2.0
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||
volumes:
|
||||
- grafana-storage:/var/lib/grafana
|
||||
|
||||
volumes:
|
||||
grafana-storage:
|
||||
2. 📝 Fichier promtail-config.yml
|
||||
server:
|
||||
http_listen_port: 9080
|
||||
grpc_listen_port: 0
|
||||
|
||||
positions:
|
||||
filename: /tmp/positions.yaml
|
||||
|
||||
clients:
|
||||
- url: http://loki:3100/loki/api/v1/push
|
||||
|
||||
scrape_configs:
|
||||
- job_name: fake_logs
|
||||
static_configs:
|
||||
- targets:
|
||||
- localhost
|
||||
labels:
|
||||
job: fake_logs
|
||||
__path__: /var/log/fake/*.log
|
||||
Ce fichier dit à Promtail de lire les fichiers dans ./logs/*.log et de les pousser vers Loki.
|
||||
|
||||
3. 🚀 Lancer la stack
|
||||
docker compose up -d
|
||||
Grafana sera sur http://localhost:3000 (login: admin / admin)
|
||||
Loki sur port 3100
|
||||
Promtail lit les fichiers dans ./logs
|
||||
4. 🛠 Lancer ton script fake_logs.sh
|
||||
Assure-toi que les logs sont bien écrits dans ./logs/ :
|
||||
mkdir -p logs
|
||||
./fake_logs.sh 100 json > logs/access.log
|
||||
./fake_logs.sh 50 json > logs/error.log
|
||||
Ou en continu :
|
||||
./fake_logs.sh 0 json --loop >> logs/access.log
|
||||
Tu peux aussi Dockeriser la génération de logs :
|
||||
Monte ./logs comme volume dans le conteneur du générateur.
|
||||
5. 📊 Visualiser dans Grafana
|
||||
Va dans Grafana : http://localhost:3000
|
||||
Ajoute Loki comme source de données :
|
||||
URL : http://loki:3100
|
||||
Va dans Explore
|
||||
Exécute une requête comme :
|
||||
{job="fake_logs"}
|
||||
Tu verras tous les logs poussés par Promtail !
|
||||
|
||||
🔁 Automatiser tout ça (bonus)
|
||||
|
||||
Tu peux créer un Dockerfile pour fake_logs.sh comme générateur, et l’exécuter dans le même réseau que Promtail/Loki, pour simuler une vraie application.
|
||||
|
||||
✅ Résumé
|
||||
|
||||
Composant Rôle
|
||||
fake_logs.sh Génère des logs réalistes
|
||||
Promtail Lit les fichiers .log et les envoie à Loki
|
||||
Loki Stocke et indexe les logs
|
||||
Grafana Visualise et interroge les logs
|
||||
Souhaites-tu un repo GitHub prêt à cloner avec tout ça dedans ? Je peux te générer une structure complète immédiatement.
|
||||
|
||||
Vous avez dit :
|
||||
oui mais sur https://gitweb.dyndns.org
|
||||
ChatGPT a dit :
|
||||
Merci pour la précision !
|
||||
|
||||
🚧 Contexte
|
||||
https://gitweb.dyndns.org semble être un serveur Git auto-hébergé utilisant GitWeb. Ce type d'interface web ne permet pas directement de pousser des dépôts, comme le fait GitHub ou GitLab. Au lieu de cela, tu dois :
|
||||
|
||||
Créer un dépôt Git sur ton serveur
|
||||
Pousser ton projet localement ou via SSH
|
||||
Ensuite, GitWeb affichera le contenu automatiquement
|
||||
🛠 Étapes pour déployer ton projet sur gitweb.dyndns.org
|
||||
|
||||
✅ 1. Prépare le projet en local
|
||||
Structure du projet :
|
||||
|
||||
fake-log-generator/
|
||||
├── fake_logs.sh
|
||||
├── logs/ # (vides, ignorés)
|
||||
├── Dockerfile
|
||||
├── promtail-config.yml
|
||||
├── docker-compose.yml
|
||||
└── .gitignore
|
||||
.gitignore
|
||||
|
||||
logs/
|
||||
*.log
|
||||
Initialise Git :
|
||||
|
||||
cd fake-log-generator
|
||||
git init
|
||||
git add .
|
||||
git commit -m "Initial commit of fake log generator for Loki"
|
||||
✅ 2. Connecte-toi à ton serveur Git
|
||||
Si ton serveur GitWeb est bien configuré en tant que serveur Git SSH, il te faut une ligne comme :
|
||||
|
||||
git remote add origin ssh://user@gitweb.dyndns.org:/srv/git/fake-log-generator.git
|
||||
Ou si tu utilises git-shell :
|
||||
|
||||
git remote add origin user@gitweb.dyndns.org:fake-log-generator.git
|
||||
✅ 3. Pousse ton projet
|
||||
git push -u origin master
|
||||
⚠️ Vérifie que tu as bien les droits en écriture sur le répertoire Git distant (/srv/git/…).
|
||||
✅ 4. Configure GitWeb (si pas déjà fait)
|
||||
Assure-toi que :
|
||||
|
||||
Ton dépôt est bien placé dans le répertoire lu par GitWeb (souvent /srv/git/)
|
||||
Le fichier description existe :
|
||||
echo "Fake log generator for Loki" > /srv/git/fake-log-generator.git/description
|
||||
Le dépôt est en mode bare :
|
||||
git init --bare /srv/git/fake-log-generator.git
|
||||
✅ Bonus : contenu complet prêt à copier
|
||||
|
||||
Souhaites-tu que je te génère un .zip de ce projet prêt à envoyer, ou que je t’affiche le contenu de chaque fichier ici pour que tu le copies facilement ?
|
||||
|
||||
Je peux aussi t’aider à :
|
||||
|
||||
Automatiser les tests via GitHub Actions ou autre
|
||||
Générer un tag/version
|
||||
Ajouter un README.md avec les instructions
|
||||
Souhaites-tu tout ça ?
|
||||
|
||||
Vous avez dit :
|
||||
oui
|
||||
ChatGPT a dit :
|
||||
Parfait ! Voici le projet complet du générateur de logs pour Loki, prêt à être copié et poussé sur ton dépôt GitWeb (gitweb.dyndns.org).
|
||||
|
||||
📁 Structure du projet : fake-log-generator
|
||||
|
||||
fake-log-generator/
|
||||
├── fake_logs.sh
|
||||
├── docker-compose.yml
|
||||
├── Dockerfile
|
||||
├── promtail-config.yml
|
||||
├── .gitignore
|
||||
└── README.md
|
||||
📜 1. fake_logs.sh
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
LINES=${1:-100}
|
||||
FORMAT=${2:-apache}
|
||||
MODE=$3
|
||||
|
||||
METHODS=("GET" "POST" "PUT" "DELETE" "PATCH")
|
||||
PATHS=("/" "/login" "/dashboard" "/api/data" "/settings" "/products" "/checkout")
|
||||
CODES_OK=(200 201 204 301 302)
|
||||
CODES_ERR=(400 401 403 404 500 503)
|
||||
AGENTS=(
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
|
||||
"curl/7.68.0"
|
||||
"PostmanRuntime/7.29.0"
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X)"
|
||||
)
|
||||
|
||||
mkdir -p logs
|
||||
|
||||
random_ip() {
|
||||
echo "$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256))"
|
||||
}
|
||||
|
||||
random_date() {
|
||||
date "+%d/%b/%Y:%H:%M:%S %z"
|
||||
}
|
||||
|
||||
iso_date() {
|
||||
date --iso-8601=seconds
|
||||
}
|
||||
|
||||
generate_log() {
|
||||
IP=$(random_ip)
|
||||
DATE=$(random_date)
|
||||
ISO_DATE=$(iso_date)
|
||||
METHOD=${METHODS[$RANDOM % ${#METHODS[@]}]}
|
||||
PATH=${PATHS[$RANDOM % ${#PATHS[@]}]}
|
||||
AGENT=${AGENTS[$RANDOM % ${#AGENTS[@]}]}
|
||||
SIZE=$((RANDOM % 5000 + 200))
|
||||
|
||||
if (( RANDOM % 10 < 2 )); then
|
||||
CODE=${CODES_ERR[$RANDOM % ${#CODES_ERR[@]}]}
|
||||
FILE="logs/error.log"
|
||||
else
|
||||
CODE=${CODES_OK[$RANDOM % ${#CODES_OK[@]}]}
|
||||
FILE="logs/access.log"
|
||||
fi
|
||||
|
||||
case "$FORMAT" in
|
||||
apache)
|
||||
LOG="$IP - - [$DATE] \"$METHOD $PATH HTTP/1.1\" $CODE $SIZE \"$AGENT\""
|
||||
;;
|
||||
json)
|
||||
LOG="{\"ip\":\"$IP\",\"timestamp\":\"$ISO_DATE\",\"method\":\"$METHOD\",\"path\":\"$PATH\",\"code\":$CODE,\"size\":$SIZE,\"agent\":\"$AGENT\"}"
|
||||
;;
|
||||
ltsv)
|
||||
LOG="host:$IP time:$ISO_DATE method:$METHOD path:$PATH status:$CODE size:$SIZE agent:$AGENT"
|
||||
;;
|
||||
custom)
|
||||
LOG="[$ISO_DATE] $IP | $METHOD $PATH => $CODE ($SIZE bytes)"
|
||||
;;
|
||||
*)
|
||||
echo "Format inconnu : $FORMAT" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$LOG" >> "$FILE"
|
||||
echo "$LOG"
|
||||
}
|
||||
|
||||
if [[ "$MODE" == "--loop" ]]; then
|
||||
while true; do
|
||||
generate_log
|
||||
sleep 0.5
|
||||
done
|
||||
else
|
||||
for ((i=0; i<LINES; i++)); do
|
||||
generate_log
|
||||
done
|
||||
fi
|
||||
🐳 2. Dockerfile
|
||||
|
||||
FROM bash:5.2
|
||||
|
||||
WORKDIR /app
|
||||
COPY fake_logs.sh .
|
||||
RUN chmod +x fake_logs.sh
|
||||
|
||||
CMD ["./fake_logs.sh", "100", "json"]
|
||||
🧱 3. docker-compose.yml
|
||||
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
loki:
|
||||
image: grafana/loki:2.9.4
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
|
||||
promtail:
|
||||
image: grafana/promtail:2.9.4
|
||||
volumes:
|
||||
- ./logs:/var/log/fake
|
||||
- ./promtail-config.yml:/etc/promtail/promtail.yml
|
||||
command: -config.file=/etc/promtail/promtail.yml
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana:10.2.0
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||
volumes:
|
||||
- grafana-storage:/var/lib/grafana
|
||||
|
||||
volumes:
|
||||
grafana-storage:
|
||||
📦 4. promtail-config.yml
|
||||
|
||||
server:
|
||||
http_listen_port: 9080
|
||||
grpc_listen_port: 0
|
||||
|
||||
positions:
|
||||
filename: /tmp/positions.yaml
|
||||
|
||||
clients:
|
||||
- url: http://loki:3100/loki/api/v1/push
|
||||
|
||||
scrape_configs:
|
||||
- job_name: fake_logs
|
||||
static_configs:
|
||||
- targets:
|
||||
- localhost
|
||||
labels:
|
||||
job: fake_logs
|
||||
__path__: /var/log/fake/*.log
|
||||
📁 5. .gitignore
|
||||
|
||||
logs/
|
||||
*.log
|
||||
📘 6. README.md
|
||||
|
||||
# 🧪 Fake Log Generator for Loki
|
||||
|
||||
Ce projet génère de faux logs réalistes dans plusieurs formats (`apache`, `json`, `ltsv`, `custom`) et les envoie à Grafana Loki via Promtail.
|
||||
|
||||
## 🔧 Démarrage rapide
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
./fake_logs.sh 0 json --loop >> logs/access.log
|
||||
🔗 Accès
|
||||
|
||||
Grafana : http://localhost:3000 (admin / admin)
|
||||
Loki : http://localhost:3100
|
||||
🔍 Requête exemple (Grafana Explore)
|
||||
|
||||
{job="fake_logs"}
|
||||
📦 Contenu
|
||||
|
||||
fake_logs.sh : générateur de logs
|
||||
promtail-config.yml : config pour envoyer vers Loki
|
||||
docker-compose.yml : stack Loki + Promtail + Grafana
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Étapes suivantes pour GitWeb
|
||||
|
||||
1. Initialise Git dans le dossier :
|
||||
```bash
|
||||
git init
|
||||
git remote add origin ssh://user@gitweb.dyndns.org:/srv/git/fake-log-generator.git
|
||||
git add .
|
||||
git commit -m "Initial fake log project for Loki"
|
||||
git push -u origin master
|
||||
Vérifie que description, HEAD, etc. sont bien en place sur le serveur (mode bare repo).
|
||||
Souhaites-tu que je te prépare une archive .zip contenant tout ce projet ? Je peux aussi générer les fichiers individuellement si tu le souhaites.
|
||||
|
||||
Vous avez dit :
|
||||
oui
|
||||
ChatGPT a dit :
|
||||
📦 Ton projet est prêt !
|
||||
|
||||
Tu peux télécharger l’archive contenant le générateur de faux logs pour Loki ici :
|
||||
|
||||
👉 fake-log-generator.zip
|
||||
|
||||
Cette archive contient :
|
||||
|
||||
fake_logs.sh (le générateur de logs)
|
||||
Dockerfile + docker-compose.yml
|
||||
promtail-config.yml
|
||||
.gitignore
|
||||
README.md
|
||||
Tu peux maintenant le décompresser, le tester localement ou le pousser directement sur ton dépôt GitWeb.
|
||||
|
||||
Souhaites-tu aussi un exemple de configuration pour intégrer ça dans un dashboard Grafana ?
|
||||
|
||||
Vous avez dit :
|
||||
oui
|
||||
ChatGPT a dit :
|
||||
Parfait ! Voici un exemple complet de tableau de bord Grafana pour visualiser les logs générés par ton script fake_logs.sh via Loki.
|
||||
|
||||
📊 Dashboard Grafana pour les logs fake_logs
|
||||
|
||||
📌 Méthode 1 : Import manuel via JSON
|
||||
Tu peux importer le JSON suivant dans Grafana :
|
||||
|
||||
📝 JSON de Dashboard (extrait)
|
||||
Voici un extrait (je peux te fournir le .json complet si tu préfères en fichier) :
|
||||
|
||||
{
|
||||
"dashboard": {
|
||||
"title": "Fake Log Generator Dashboard",
|
||||
"panels": [
|
||||
{
|
||||
"type": "logs",
|
||||
"title": "Logs récents (Loki)",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "{job=\"fake_logs\"}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"dedupStrategy": "none",
|
||||
"showTime": true,
|
||||
"showLabels": true
|
||||
},
|
||||
"gridPos": { "x": 0, "y": 0, "w": 24, "h": 10 }
|
||||
},
|
||||
{
|
||||
"type": "stat",
|
||||
"title": "Nombre total de logs",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "count_over_time({job=\"fake_logs\"}[1m])",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"gridPos": { "x": 0, "y": 10, "w": 6, "h": 6 }
|
||||
},
|
||||
{
|
||||
"type": "piechart",
|
||||
"title": "Répartition par code HTTP",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "count_over_time({job=\"fake_logs\"} |= \"HTTP\" | regexp \"\\\" ([0-9]{3}) \" | unwrap code [1m]) by (code)",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"gridPos": { "x": 6, "y": 10, "w": 9, "h": 6 }
|
||||
}
|
||||
],
|
||||
"schemaVersion": 36,
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
📥 Importer dans Grafana
|
||||
|
||||
Ouvre Grafana : http://localhost:3000
|
||||
Va dans Dashboards > New > Import
|
||||
Colle le JSON ci-dessus ou charge un fichier .json
|
||||
Sélectionne ta source Loki comme "data source"
|
||||
🔍 Astuces LogQL utiles pour Grafana Explore
|
||||
|
||||
Tous les logs :
|
||||
{job="fake_logs"}
|
||||
Logs d'erreurs :
|
||||
{job="fake_logs"} |= " 5" or |= " 4"
|
||||
Filtrer par méthode HTTP :
|
||||
{job="fake_logs"} |= "POST"
|
||||
27
docker-compose.yml
Normal file
27
docker-compose.yml
Normal file
@ -0,0 +1,27 @@
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
loki:
|
||||
image: grafana/loki:2.9.4
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
|
||||
promtail:
|
||||
image: grafana/promtail:2.9.4
|
||||
volumes:
|
||||
- ./logs:/var/log/fake
|
||||
- ./promtail-config.yml:/etc/promtail/promtail.yml
|
||||
command: -config.file=/etc/promtail/promtail.yml
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana:10.2.0
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||
volumes:
|
||||
- grafana-storage:/var/lib/grafana
|
||||
|
||||
volumes:
|
||||
grafana-storage:
|
||||
82
fake-log-generator.sh
Normal file
82
fake-log-generator.sh
Normal file
@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
|
||||
LINES=${1:-100}
|
||||
FORMAT=${2:-apache}
|
||||
MODE=$3
|
||||
|
||||
METHODS=("GET" "POST" "PUT" "DELETE" "PATCH")
|
||||
PATHS=("/" "/login" "/dashboard" "/api/data" "/settings" "/products" "/checkout")
|
||||
CODES_OK=(200 201 204 301 302)
|
||||
CODES_ERR=(400 401 403 404 500 503)
|
||||
AGENTS=(
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
|
||||
"curl/7.68.0"
|
||||
"PostmanRuntime/7.29.0"
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X)"
|
||||
)
|
||||
|
||||
mkdir -p logs
|
||||
|
||||
random_ip() {
|
||||
echo "$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256))"
|
||||
}
|
||||
|
||||
random_date() {
|
||||
date "+%d/%b/%Y:%H:%M:%S %z"
|
||||
}
|
||||
|
||||
iso_date() {
|
||||
date --iso-8601=seconds
|
||||
}
|
||||
|
||||
generate_log() {
|
||||
IP=$(random_ip)
|
||||
DATE=$(random_date)
|
||||
ISO_DATE=$(iso_date)
|
||||
METHOD=${METHODS[$RANDOM % ${#METHODS[@]}]}
|
||||
PATH=${PATHS[$RANDOM % ${#PATHS[@]}]}
|
||||
AGENT=${AGENTS[$RANDOM % ${#AGENTS[@]}]}
|
||||
SIZE=$((RANDOM % 5000 + 200))
|
||||
|
||||
if (( RANDOM % 10 < 2 )); then
|
||||
CODE=${CODES_ERR[$RANDOM % ${#CODES_ERR[@]}]}
|
||||
FILE="logs/error.log"
|
||||
else
|
||||
CODE=${CODES_OK[$RANDOM % ${#CODES_OK[@]}]}
|
||||
FILE="logs/access.log"
|
||||
fi
|
||||
|
||||
case "$FORMAT" in
|
||||
apache)
|
||||
LOG="$IP - - [$DATE] \"$METHOD $PATH HTTP/1.1\" $CODE $SIZE \"$AGENT\""
|
||||
;;
|
||||
json)
|
||||
LOG="{\"ip\":\"$IP\",\"timestamp\":\"$ISO_DATE\",\"method\":\"$METHOD\",\"path\":\"$PATH\",\"code\":$CODE,\"size\":$SIZE,\"agent\":\"$AGENT\"}"
|
||||
;;
|
||||
ltsv)
|
||||
LOG="host:$IP time:$ISO_DATE method:$METHOD path:$PATH status:$CODE size:$SIZE agent:$AGENT"
|
||||
;;
|
||||
custom)
|
||||
LOG="[$ISO_DATE] $IP | $METHOD $PATH => $CODE ($SIZE bytes)"
|
||||
;;
|
||||
*)
|
||||
echo "Format inconnu : $FORMAT" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$LOG" >> "$FILE"
|
||||
echo "$LOG"
|
||||
}
|
||||
|
||||
if [[ "$MODE" == "--loop" ]]; then
|
||||
while true; do
|
||||
generate_log
|
||||
sleep 0.5
|
||||
done
|
||||
else
|
||||
for ((i=0; i<LINES; i++)); do
|
||||
generate_log
|
||||
done
|
||||
fi
|
||||
65
fake-logs-dashboard.json
Normal file
65
fake-logs-dashboard.json
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
"dashboard": {
|
||||
"id": null,
|
||||
"title": "Fake Log Generator Dashboard",
|
||||
"timezone": "browser",
|
||||
"schemaVersion": 36,
|
||||
"version": 1,
|
||||
"refresh": "10s",
|
||||
"panels": [
|
||||
{
|
||||
"type": "logs",
|
||||
"title": "Logs r\u00e9cents (Loki)",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "{job=\"fake_logs\"}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"dedupStrategy": "none",
|
||||
"showTime": true,
|
||||
"showLabels": true
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 24,
|
||||
"h": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "stat",
|
||||
"title": "Nombre total de logs",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "count_over_time({job=\"fake_logs\"}[1m])",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"gridPos": {
|
||||
"x": 0,
|
||||
"y": 10,
|
||||
"w": 6,
|
||||
"h": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "piechart",
|
||||
"title": "R\u00e9partition par code HTTP",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "count_over_time({job=\"fake_logs\"} |= \"HTTP\" | regexp \"\\\" ([0-9]{3}) \" | unwrap code [1m]) by (code)",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"gridPos": {
|
||||
"x": 6,
|
||||
"y": 10,
|
||||
"w": 9,
|
||||
"h": 6
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
18
promtail-config.yml
Normal file
18
promtail-config.yml
Normal file
@ -0,0 +1,18 @@
|
||||
server:
|
||||
http_listen_port: 9080
|
||||
grpc_listen_port: 0
|
||||
|
||||
positions:
|
||||
filename: /tmp/positions.yaml
|
||||
|
||||
clients:
|
||||
- url: http://loki:3100/loki/api/v1/push
|
||||
|
||||
scrape_configs:
|
||||
- job_name: fake_logs
|
||||
static_configs:
|
||||
- targets:
|
||||
- localhost
|
||||
labels:
|
||||
job: fake_logs
|
||||
__path__: /var/log/fake/*.log
|
||||
Loading…
x
Reference in New Issue
Block a user