feat: Keep-Alive correlation, TTL management, SIGHUP handling, logrotate support
Major features: - One-to-many correlation mode (Keep-Alive) for HTTP connections - Dynamic TTL for network events with reset on each correlation - Separate configurable buffer sizes for HTTP and network events - SIGHUP signal handling for log rotation without service restart - FileSink.Reopen() method for log file rotation - logrotate configuration included in RPM - ExecReload added to systemd service Configuration changes: - New YAML structure with nested sections (time_window, orphan_policy, matching, buffers, ttl) - Backward compatibility maintained for deprecated fields Packaging: - RPM version 1.1.0 with logrotate config - Updated spec file and changelog - All distributions: el8, el9, el10 Tests: - New tests for Keep-Alive mode and TTL reset - Updated mocks with Reopen() interface method Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
440
architecture.yml
440
architecture.yml
@ -9,12 +9,13 @@ service:
|
||||
événements HTTP applicatifs (source A, typiquement Apache ou reverse proxy)
|
||||
avec des événements réseau (source B, métadonnées IP/TCP, JA3/JA4, etc.)
|
||||
sur la base de la combinaison strictement définie src_ip + src_port, avec
|
||||
une fenêtre temporelle configurable. Le service produit un log corrélé
|
||||
unique pour chaque paire correspondante, émet toujours les événements A
|
||||
même lorsqu’aucun événement B corrélé n’est disponible, n’émet jamais de
|
||||
logs B seuls, et pousse les logs agrégés en temps quasi réel vers
|
||||
ClickHouse et/ou un fichier local, en minimisant la rétention en mémoire
|
||||
et sur disque.
|
||||
une fenêtre temporelle configurable. Le service supporte les connexions
|
||||
HTTP Keep-Alive : un log réseau peut être corrélé à plusieurs logs HTTP
|
||||
successifs (stratégie 1‑à‑N). La rétention en mémoire est bornée par des
|
||||
tailles de caches configurables et un TTL dynamique pour la source B. Le
|
||||
service émet toujours les événements A même lorsqu’aucun événement B n’est
|
||||
disponible, n’émet jamais de logs B seuls, et pousse les résultats vers
|
||||
ClickHouse et/ou un fichier local.
|
||||
|
||||
runtime:
|
||||
deployment:
|
||||
@ -23,7 +24,7 @@ runtime:
|
||||
logcorrelator est livré sous forme de binaire autonome, exécuté comme un
|
||||
service systemd. L'unité systemd assure le démarrage automatique au boot,
|
||||
le redémarrage en cas de crash, et une intégration standard dans l'écosystème
|
||||
Linux (notamment sur CentOS 7 et Rocky Linux 8+).
|
||||
Linux.
|
||||
binary_path: /usr/bin/logcorrelator
|
||||
config_path: /etc/logcorrelator/logcorrelator.yml
|
||||
user: logcorrelator
|
||||
@ -41,6 +42,7 @@ runtime:
|
||||
User=logcorrelator
|
||||
Group=logcorrelator
|
||||
ExecStart=/usr/bin/logcorrelator -config /etc/logcorrelator/logcorrelator.yml
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
@ -63,98 +65,186 @@ runtime:
|
||||
graceful_shutdown:
|
||||
- SIGINT
|
||||
- SIGTERM
|
||||
reload:
|
||||
- SIGHUP
|
||||
description: >
|
||||
En réception de SIGINT ou SIGTERM, le service arrête proprement la lecture
|
||||
des sockets Unix, vide les buffers d’envoi (dans les limites de la politique
|
||||
de drop), ferme les connexions ClickHouse puis s’arrête.
|
||||
SIGINT/SIGTERM : arrêt propre (arrêt des sockets, vidage des buffers, fermeture
|
||||
des sinks). SIGHUP : réouverture des fichiers de sortie (utile pour la
|
||||
rotation des logs via logrotate) sans arrêter le service.
|
||||
|
||||
packaging:
|
||||
description: >
|
||||
logcorrelator est distribué sous forme de packages .rpm (Rocky Linux, AlmaLinux,
|
||||
RHEL), construits intégralement dans des conteneurs. Le changelog RPM est mis
|
||||
à jour à chaque changement de version.
|
||||
formats:
|
||||
- rpm
|
||||
target_distros:
|
||||
- rocky-linux-8
|
||||
- rocky-linux-9
|
||||
- almalinux-10
|
||||
- rhel-8
|
||||
- rhel-9
|
||||
- rhel-10
|
||||
rpm:
|
||||
tool: fpm
|
||||
changelog:
|
||||
source: git # ou CHANGELOG.md
|
||||
description: >
|
||||
À chaque build, un script génère un fichier de changelog RPM à partir de
|
||||
l’historique (tags/commits) et le passe à fpm (option --rpm-changelog).
|
||||
contents:
|
||||
- path: /usr/bin/logcorrelator
|
||||
type: binary
|
||||
- path: /etc/logcorrelator/logcorrelator.yml
|
||||
type: config
|
||||
directives: "%config(noreplace)"
|
||||
- path: /etc/logcorrelator/logcorrelator.yml.example
|
||||
type: doc
|
||||
description: Fichier d'exemple toujours mis à jour par le RPM.
|
||||
- path: /etc/systemd/system/logcorrelator.service
|
||||
type: systemd_unit
|
||||
- path: /etc/logrotate.d/logcorrelator
|
||||
type: logrotate_script
|
||||
logrotate_example: |
|
||||
/var/log/logcorrelator/*.log {
|
||||
daily
|
||||
rotate 7
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 logcorrelator logcorrelator
|
||||
postrotate
|
||||
systemctl reload logcorrelator > /dev/null 2>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
|
||||
config:
|
||||
format: yaml
|
||||
location: /etc/logcorrelator/logcorrelator.yml
|
||||
reload_strategy: signal_sighup_for_files
|
||||
description: >
|
||||
Toute la configuration est centralisée dans un fichier YAML lisible,
|
||||
stocké dans /etc/logcorrelator.
|
||||
reload_strategy: restart_service
|
||||
Toute la configuration est centralisée dans un fichier YAML lisible. Le RPM
|
||||
fournit aussi un fichier d’exemple mis à jour à chaque version.
|
||||
example: |
|
||||
# Logging configuration
|
||||
# /etc/logcorrelator/logcorrelator.yml
|
||||
|
||||
log:
|
||||
level: INFO # DEBUG, INFO, WARN, ERROR
|
||||
|
||||
# Inputs - at least 2 unix sockets required
|
||||
inputs:
|
||||
unix_sockets:
|
||||
# Source HTTP (A) : logs applicatifs en JSON, 1 datagramme = 1 log.
|
||||
- name: http
|
||||
path: /var/run/logcorrelator/http.socket
|
||||
socket_permissions: "0660"
|
||||
- name: network
|
||||
path: /var/run/logcorrelator/network.socket
|
||||
path: /var/run/logcorrelator/http.sock
|
||||
socket_permissions: "0666"
|
||||
socket_type: dgram
|
||||
max_datagram_bytes: 65535
|
||||
|
||||
# Source réseau (B) : logs IP/TCP/JA3... en JSON, 1 datagramme = 1 log.
|
||||
- name: network
|
||||
path: /var/run/logcorrelator/network.sock
|
||||
socket_permissions: "0666"
|
||||
socket_type: dgram
|
||||
max_datagram_bytes: 65535
|
||||
|
||||
# Outputs
|
||||
outputs:
|
||||
file:
|
||||
enabled: true
|
||||
path: /var/log/logcorrelator/correlated.log
|
||||
clickhouse:
|
||||
dsn: clickhouse://user:pass@localhost:9000/db
|
||||
table: correlated_logs
|
||||
stdout: false
|
||||
format: json_lines
|
||||
|
||||
clickhouse:
|
||||
enabled: true
|
||||
dsn: clickhouse://user:pass@localhost:9000/db
|
||||
table: correlated_logs_http_network
|
||||
batch_size: 500
|
||||
flush_interval_ms: 200
|
||||
max_buffer_size: 5000
|
||||
drop_on_overflow: true
|
||||
async_insert: true
|
||||
timeout_ms: 1000
|
||||
|
||||
stdout:
|
||||
enabled: false
|
||||
|
||||
# Correlation (optional)
|
||||
correlation:
|
||||
time_window_s: 1
|
||||
emit_orphans: true
|
||||
# Fenêtre de corrélation : si le log HTTP arrive avant le réseau, il attend
|
||||
# au plus cette durée (sauf éviction du cache HTTP).
|
||||
time_window:
|
||||
value: 1
|
||||
unit: s
|
||||
|
||||
orphan_policy:
|
||||
apache_always_emit: true
|
||||
network_emit: false
|
||||
|
||||
matching:
|
||||
mode: one_to_many # Keep‑Alive : un B peut corréler plusieurs A.
|
||||
|
||||
buffers:
|
||||
# Tailles max des caches en mémoire (en nombre de logs).
|
||||
max_http_items: 10000
|
||||
max_network_items: 20000
|
||||
|
||||
ttl:
|
||||
# Durée de vie standard d’un log réseau (B) en mémoire. Chaque corrélation
|
||||
# réussie avec un A réinitialise ce TTL.
|
||||
network_ttl_s: 30
|
||||
|
||||
inputs:
|
||||
description: >
|
||||
Le service consomme deux flux de logs JSON via des sockets Unix. Le schéma
|
||||
exact des logs pour chaque source est flexible et peut évoluer. Seuls
|
||||
quelques champs sont nécessaires pour la corrélation.
|
||||
Deux flux de logs JSON via sockets Unix datagram (SOCK_DGRAM). Chaque datagramme
|
||||
contient un JSON complet.
|
||||
unix_sockets:
|
||||
- name: apache_source
|
||||
id: A
|
||||
description: >
|
||||
Source A, destinée aux logs HTTP applicatifs (Apache, reverse proxy, etc.).
|
||||
Le schéma JSON est variable, avec un champ timestamp numérique obligatoire
|
||||
et des champs header_* dynamiques.
|
||||
Source A, logs HTTP applicatifs (Apache, reverse proxy, etc.). Schéma JSON
|
||||
variable, champ timestamp obligatoire, headers dynamiques (header_*).
|
||||
path: /var/run/logcorrelator/apache.sock
|
||||
permissions: "0666"
|
||||
protocol: unix
|
||||
mode: stream
|
||||
socket_type: dgram
|
||||
mode: datagram
|
||||
format: json
|
||||
framing: line
|
||||
framing: message
|
||||
max_datagram_bytes: 65535
|
||||
retry_on_error: true
|
||||
|
||||
- name: network_source
|
||||
id: B
|
||||
description: >
|
||||
Source B, destinée aux logs réseau (métadonnées IP/TCP, JA3/JA4, etc.).
|
||||
Le schéma JSON est variable ; seuls src_ip et src_port sont requis.
|
||||
Source B, logs réseau (métadonnées IP/TCP, JA3/JA4, etc.). Seuls src_ip
|
||||
et src_port sont requis pour la corrélation.
|
||||
path: /var/run/logcorrelator/network.sock
|
||||
permissions: "0666"
|
||||
protocol: unix
|
||||
mode: stream
|
||||
socket_type: dgram
|
||||
mode: datagram
|
||||
format: json
|
||||
framing: line
|
||||
framing: message
|
||||
max_datagram_bytes: 65535
|
||||
retry_on_error: true
|
||||
|
||||
outputs:
|
||||
description: >
|
||||
Les logs corrélés sont envoyés vers un ou plusieurs sinks. MultiSink permet
|
||||
de diffuser chaque log corrélé vers plusieurs destinations (fichier,
|
||||
ClickHouse, stdout…).
|
||||
Les logs corrélés sont envoyés vers un ou plusieurs sinks (MultiSink).
|
||||
sinks:
|
||||
file:
|
||||
enabled: true
|
||||
description: >
|
||||
Sink vers fichier local, utile pour debug ou archivage local. Écrit un
|
||||
JSON par ligne dans le chemin configuré. Rotation gérée par logrotate
|
||||
ou équivalent.
|
||||
Sink fichier local. Un JSON par ligne. Rotation gérée par logrotate,
|
||||
réouverture du fichier sur SIGHUP.
|
||||
path: /var/log/logcorrelator/correlated.log
|
||||
format: json_lines
|
||||
rotate_managed_by: external
|
||||
rotate_managed_by: external_logrotate
|
||||
clickhouse:
|
||||
enabled: true
|
||||
description: >
|
||||
Sink principal pour l’archivage et l’analyse en temps quasi réel. Les
|
||||
logs corrélés sont insérés en batch dans ClickHouse avec un small buffer
|
||||
et des inserts asynchrones. En cas de saturation ou d’indisponibilité
|
||||
ClickHouse, les logs sont drop pour éviter de saturer la machine locale.
|
||||
Sink principal pour l’archivage et l’analyse quasi temps réel. Inserts
|
||||
batch asynchrones, drop en cas de saturation.
|
||||
dsn: clickhouse://user:pass@host:9000/db
|
||||
table: correlated_logs_http_network
|
||||
batch_size: 500
|
||||
@ -166,13 +256,12 @@ outputs:
|
||||
stdout:
|
||||
enabled: false
|
||||
description: >
|
||||
Sink optionnel vers stdout pour les tests et le développement.
|
||||
Sink optionnel pour les tests/développement.
|
||||
|
||||
correlation:
|
||||
description: >
|
||||
Corrélation strictement basée sur src_ip + src_port et une fenêtre temporelle
|
||||
configurable. Aucun autre champ (dst_ip, dst_port, JA3/JA4, headers HTTP...)
|
||||
n’est utilisé pour la décision de corrélation.
|
||||
Corrélation stricte basée sur src_ip + src_port et une fenêtre temporelle
|
||||
configurable. Aucun autre champ n’est utilisé pour la décision de corrélation.
|
||||
key:
|
||||
- src_ip
|
||||
- src_port
|
||||
@ -180,53 +269,50 @@ correlation:
|
||||
value: 1
|
||||
unit: s
|
||||
description: >
|
||||
Fenêtre de temps symétrique appliquée aux timestamps de A et B. Deux
|
||||
événements sont corrélés si |tA - tB| <= time_window. La valeur et l'unité
|
||||
sont définies dans le YAML.
|
||||
Fenêtre de temps appliquée aux timestamps de A et B. Si B n’arrive pas dans
|
||||
ce délai, A est émis comme orphelin.
|
||||
retention_limits:
|
||||
max_http_items: 10000
|
||||
max_network_items: 20000
|
||||
description: >
|
||||
Limites des caches. Si max_http_items est atteint, le plus ancien A est
|
||||
évincé et émis orphelin. Si max_network_items est atteint, le plus ancien B
|
||||
est supprimé silencieusement.
|
||||
ttl_management:
|
||||
network_ttl_s: 30
|
||||
description: >
|
||||
TTL des logs réseau. Chaque fois qu’un B est corrélé à un A (Keep‑Alive),
|
||||
son TTL est remis à cette valeur.
|
||||
timestamp_source:
|
||||
apache: field_timestamp
|
||||
network: reception_time
|
||||
description: >
|
||||
Pour A, utilisation du champ numérique "timestamp" (epoch ns). Pour B,
|
||||
utilisation du temps de réception local.
|
||||
orphan_policy:
|
||||
apache_always_emit: true
|
||||
network_emit: false
|
||||
description: >
|
||||
A est toujours émis (même sans B) avec correlated=false et orphan_side="A".
|
||||
B n’est jamais émis seul.
|
||||
matching:
|
||||
mode: one_to_one_first_match
|
||||
mode: one_to_many
|
||||
description: >
|
||||
Stratégie 1‑à‑1, premier match : lors de l’arrivée d’un événement, on
|
||||
cherche le premier événement compatible dans le buffer de l’autre source.
|
||||
Les autres restent en attente ou expirent.
|
||||
Stratégie 1‑à‑N : un log réseau peut être utilisé pour plusieurs logs HTTP
|
||||
successifs tant qu’il n’a pas expiré ni été évincé.
|
||||
|
||||
schema:
|
||||
description: >
|
||||
Les schémas des sources A et B sont variables. Le service impose seulement
|
||||
quelques champs obligatoires nécessaires à la corrélation et accepte des
|
||||
champs supplémentaires sans modification de code.
|
||||
Schémas variables pour A et B. Quelques champs seulement sont obligatoires
|
||||
pour la corrélation, les autres sont acceptés sans modification de code.
|
||||
source_A:
|
||||
description: >
|
||||
Logs HTTP applicatifs (Apache/reverse proxy) au format JSON. Schéma
|
||||
variable, avec champs obligatoires pour corrélation (src_ip, src_port,
|
||||
timestamp) et collecte des autres champs dans des maps.
|
||||
Logs HTTP applicatifs au format JSON.
|
||||
required_fields:
|
||||
- name: src_ip
|
||||
type: string
|
||||
description: Adresse IP source client.
|
||||
- name: src_port
|
||||
type: int
|
||||
description: Port source client.
|
||||
- name: timestamp
|
||||
type: int64
|
||||
unit: ns
|
||||
description: Timestamp de référence pour la corrélation.
|
||||
optional_fields:
|
||||
- name: time
|
||||
type: string
|
||||
format: rfc3339
|
||||
- name: dst_ip
|
||||
type: string
|
||||
- name: dst_port
|
||||
@ -242,16 +328,10 @@ schema:
|
||||
dynamic_fields:
|
||||
- pattern: header_*
|
||||
target_map: headers
|
||||
description: >
|
||||
Tous les champs header_* sont collectés dans headers[clé] = valeur.
|
||||
- pattern: "*"
|
||||
target_map: extra
|
||||
description: >
|
||||
Tous les champs non reconnus explicitement vont dans extra.
|
||||
source_B:
|
||||
description: >
|
||||
Logs réseau JSON (IP/TCP, JA3/JA4...). Schéma variable. src_ip et src_port
|
||||
sont obligatoires pour la corrélation, le reste est libre.
|
||||
description: Logs réseau JSON (IP/TCP, JA3/JA4...).
|
||||
required_fields:
|
||||
- name: src_ip
|
||||
type: string
|
||||
@ -265,14 +345,10 @@ schema:
|
||||
dynamic_fields:
|
||||
- pattern: "*"
|
||||
target_map: extra
|
||||
description: >
|
||||
Tous les autres champs (ip_meta_*, tcp_meta_*, ja3, ja4, etc.) sont
|
||||
rangés dans extra.
|
||||
|
||||
normalized_event:
|
||||
description: >
|
||||
Représentation interne unifiée des événements A/B sur laquelle opère la
|
||||
logique de corrélation.
|
||||
Représentation interne unifiée des événements A/B.
|
||||
fields:
|
||||
- name: source
|
||||
type: enum("A","B")
|
||||
@ -293,13 +369,10 @@ schema:
|
||||
optional: true
|
||||
- name: extra
|
||||
type: map[string]any
|
||||
description: Champs additionnels provenant de A ou B.
|
||||
|
||||
correlated_log:
|
||||
description: >
|
||||
Structure du log corrélé émis vers les sinks (fichier, ClickHouse). Contient
|
||||
les informations de corrélation et tous les champs des sources A et B fusionnés
|
||||
dans une structure JSON plate (flat).
|
||||
Structure du log corrélé émis vers les sinks.
|
||||
fields:
|
||||
- name: timestamp
|
||||
type: time.Time
|
||||
@ -319,18 +392,13 @@ schema:
|
||||
type: string
|
||||
- name: "*"
|
||||
type: map[string]any
|
||||
description: >
|
||||
Tous les champs additionnels provenant de A et B sont fusionnés
|
||||
directement à la racine du JSON (structure plate, sans subdivisions).
|
||||
|
||||
clickhouse_schema:
|
||||
strategy: external_ddls
|
||||
description: >
|
||||
logcorrelator ne gère pas les ALTER TABLE. La table ClickHouse doit être
|
||||
créée/modifiée en dehors du service. logcorrelator remplit les colonnes
|
||||
existantes qu'il connaît et met NULL si un champ manque.
|
||||
Depuis la version 1.0.3, les champs apache et network sont remplacés par
|
||||
une colonne unique fields JSON contenant tous les champs fusionnés.
|
||||
La table ClickHouse est gérée en dehors du service. logcorrelator remplit
|
||||
les colonnes connues et met NULL si un champ manque. Tous les champs fusionnés
|
||||
sont exposés dans une colonne JSON (fields).
|
||||
base_columns:
|
||||
- name: timestamp
|
||||
type: DateTime64(9)
|
||||
@ -350,31 +418,26 @@ clickhouse_schema:
|
||||
type: JSON
|
||||
dynamic_fields:
|
||||
mode: map_or_additional_columns
|
||||
description: >
|
||||
Les champs dynamiques peuvent être exposés via colonnes dédiées créées par
|
||||
migration, ou via Map/JSON.
|
||||
|
||||
architecture:
|
||||
description: >
|
||||
Architecture hexagonale : domaine de corrélation indépendant, ports
|
||||
abstraits pour les sources/sinks, adaptateurs pour sockets Unix, fichier et
|
||||
ClickHouse, couche application d’orchestration, et modules infra pour
|
||||
config/observabilité.
|
||||
Architecture hexagonale : domaine de corrélation indépendant, ports abstraits
|
||||
pour les sources/sinks, adaptateurs pour sockets Unix, fichier et ClickHouse,
|
||||
couche application d’orchestration, et modules infra (config, observabilité).
|
||||
modules:
|
||||
- name: cmd/logcorrelator
|
||||
type: entrypoint
|
||||
responsibilities:
|
||||
- Chargement configuration YAML.
|
||||
- Chargement de la configuration YAML.
|
||||
- Initialisation des adaptateurs d'entrée/sortie.
|
||||
- Création du CorrelationService.
|
||||
- Démarrage de l'orchestrateur.
|
||||
- Gestion du cycle de vie (signaux systemd).
|
||||
- Démarrage de l’orchestrateur.
|
||||
- Gestion des signaux (SIGINT, SIGTERM, SIGHUP).
|
||||
- name: internal/domain
|
||||
type: domain
|
||||
responsibilities:
|
||||
- Modèles NormalizedEvent et CorrelatedLog.
|
||||
- Implémentation de CorrelationService (buffers, fenêtre,
|
||||
orphelins).
|
||||
- CorrelationService (fenêtre, TTL, buffers bornés, 1‑à‑N, orphelins).
|
||||
- name: internal/ports
|
||||
type: ports
|
||||
responsibilities:
|
||||
@ -382,163 +445,70 @@ architecture:
|
||||
- name: internal/app
|
||||
type: application
|
||||
responsibilities:
|
||||
- Orchestrator : relier EventSource → CorrelationService → MultiSink.
|
||||
- Orchestrator : EventSource → CorrelationService → MultiSink.
|
||||
- name: internal/adapters/inbound/unixsocket
|
||||
type: adapter_inbound
|
||||
responsibilities:
|
||||
- Lecture sockets Unix + parsing JSON → NormalizedEvent.
|
||||
- Lecture Unix datagram (SOCK_DGRAM) et parsing JSON → NormalizedEvent.
|
||||
- name: internal/adapters/outbound/file
|
||||
type: adapter_outbound
|
||||
responsibilities:
|
||||
- Écriture fichier JSON lines.
|
||||
- Écriture JSON lines.
|
||||
- Réouverture du fichier sur SIGHUP.
|
||||
- name: internal/adapters/outbound/clickhouse
|
||||
type: adapter_outbound
|
||||
responsibilities:
|
||||
- Bufferisation + inserts batch vers ClickHouse.
|
||||
- Application de drop_on_overflow.
|
||||
- Bufferisation + inserts batch, gestion du drop_on_overflow.
|
||||
- name: internal/adapters/outbound/multi
|
||||
type: adapter_outbound
|
||||
responsibilities:
|
||||
- Fan-out vers plusieurs sinks.
|
||||
- Fan‑out vers plusieurs sinks.
|
||||
- name: internal/config
|
||||
type: infrastructure
|
||||
responsibilities:
|
||||
- Chargement/validation config YAML.
|
||||
- Chargement/validation de la configuration YAML.
|
||||
- name: internal/observability
|
||||
type: infrastructure
|
||||
responsibilities:
|
||||
- Logging et métriques internes.
|
||||
- Logging interne, métriques (tailles des caches, évictions, erreurs datagram).
|
||||
|
||||
testing:
|
||||
unit:
|
||||
description: >
|
||||
Tests unitaires table-driven avec couverture cible ≥ 80 %. Focalisés sur
|
||||
la logique de corrélation, parsing et sink ClickHouse.[web:94][web:98][web:102]
|
||||
Tests unitaires table‑driven, couverture cible ≥ 80 %, focale sur la logique
|
||||
de corrélation, les caches et les sinks.
|
||||
coverage_minimum: 0.8
|
||||
focus:
|
||||
- CorrelationService
|
||||
- Parsing A/B → NormalizedEvent
|
||||
- CorrelationService (fenêtre, TTL, évictions, 1‑à‑N)
|
||||
- Parsing A/B → NormalizedEvent (datagrammes)
|
||||
- ClickHouseSink (batching, overflow)
|
||||
- FileSink (réouverture sur SIGHUP)
|
||||
- MultiSink
|
||||
integration:
|
||||
description: >
|
||||
Tests d’intégration validant le flux complet A+B → corrélation → sinks,
|
||||
avec sockets simulés et ClickHouse mocké.
|
||||
avec sockets Unix datagram simulées, ClickHouse mocké et scénarios Keep‑Alive.
|
||||
|
||||
docker:
|
||||
description: >
|
||||
Build et tests entièrement encapsulés dans Docker, avec multi‑stage build :
|
||||
un stage builder pour compiler et tester, un stage runtime minimal pour
|
||||
exécuter le service.[web:95][web:103]
|
||||
images:
|
||||
builder:
|
||||
base: golang:latest
|
||||
purpose: build_and_test
|
||||
runtime:
|
||||
base: scratch
|
||||
purpose: run_binary_only
|
||||
build:
|
||||
multi_stage: true
|
||||
steps:
|
||||
- name: unit_tests
|
||||
description: >
|
||||
go test ./... avec génération de couverture. Le build échoue si la
|
||||
couverture est < 80 %.
|
||||
- name: compile_binary
|
||||
description: >
|
||||
Compilation CGO_ENABLED=0, GOOS=linux, GOARCH=amd64 pour un binaire
|
||||
statique /usr/bin/logcorrelator.
|
||||
- name: assemble_runtime_image
|
||||
description: >
|
||||
Copie du binaire dans l’image runtime et définition de l’ENTRYPOINT.
|
||||
|
||||
packaging:
|
||||
description: >
|
||||
logcorrelator est distribué sous forme de packages .rpm (Rocky Linux 8, 9 et AlmaLinux 10),
|
||||
construits intégralement dans Docker avec fpm.
|
||||
formats:
|
||||
- rpm
|
||||
target_distros:
|
||||
rpm:
|
||||
- rocky-linux-8
|
||||
- rocky-linux-9
|
||||
- almalinux-10
|
||||
- rhel-8+
|
||||
- rhel-9+
|
||||
- rhel-10+
|
||||
tool: fpm
|
||||
Build, tests et packaging RPM sont exécutés intégralement dans des conteneurs
|
||||
via un multi‑stage build.
|
||||
build_pipeline:
|
||||
dockerfile: Dockerfile.package
|
||||
multi_stage: true
|
||||
stages:
|
||||
- name: builder
|
||||
- name: test_and_compile
|
||||
base: golang:latest
|
||||
description: >
|
||||
Compilation du binaire Go avec CGO_ENABLED=0 pour un binaire statique.
|
||||
GOOS=linux GOARCH=amd64.
|
||||
- name: rpm_rocky8_builder
|
||||
go test ./... (échec si couverture < 80 %), puis compilation d’un binaire
|
||||
statique (CGO_ENABLED=0, GOOS=linux, GOARCH=amd64).
|
||||
- name: rpm_builder
|
||||
base: ruby:alpine
|
||||
description: >
|
||||
Construction du package RPM pour Rocky Linux 8 (el8) avec fpm.
|
||||
- name: rpm_rocky9_builder
|
||||
Installation de fpm, git et outils RPM. Génération du changelog RPM à
|
||||
partir de l’historique. Construction des .rpm pour les différentes
|
||||
distributions.
|
||||
- name: output_export
|
||||
base: scratch
|
||||
description: >
|
||||
Construction du package RPM pour Rocky Linux 9 (el9) avec fpm.
|
||||
- name: rpm_almalinux10_builder
|
||||
description: >
|
||||
Construction du package RPM pour AlmaLinux 10 (el10) avec fpm.
|
||||
- name: output
|
||||
description: >
|
||||
Image Alpine minimale contenant les packages dans
|
||||
/packages/rpm/{rocky8,rocky9,almalinux10}.
|
||||
files:
|
||||
binary:
|
||||
source: dist/logcorrelator
|
||||
dest: /usr/bin/logcorrelator
|
||||
mode: "0755"
|
||||
config:
|
||||
- source: config.example.yml
|
||||
dest: /etc/logcorrelator/logcorrelator.yml
|
||||
mode: "0640"
|
||||
config_file: true
|
||||
- source: config.example.yml
|
||||
dest: /usr/share/logcorrelator/logcorrelator.yml.example
|
||||
mode: "0640"
|
||||
directories:
|
||||
- path: /var/log/logcorrelator
|
||||
mode: "0755"
|
||||
- path: /var/run/logcorrelator
|
||||
mode: "0755"
|
||||
- path: /etc/logcorrelator
|
||||
mode: "0750"
|
||||
maintainer_scripts:
|
||||
rpm:
|
||||
post: packaging/rpm/post
|
||||
preun: packaging/rpm/preun
|
||||
postun: packaging/rpm/postun
|
||||
dependencies:
|
||||
rpm:
|
||||
- systemd
|
||||
verify:
|
||||
rpm:
|
||||
rocky8:
|
||||
command: docker run --rm -v $(pwd)/dist/rpm/rocky8:/packages rockylinux:8 sh -c "dnf install -y /packages/*.rpm"
|
||||
rocky9:
|
||||
command: docker run --rm -v $(pwd)/dist/rpm/rocky9:/packages rockylinux:9 sh -c "dnf install -y /packages/*.rpm"
|
||||
almalinux10:
|
||||
command: docker run --rm -v $(pwd)/dist/rpm/almalinux10:/packages almalinux:10 sh -c "dnf install -y /packages/*.rpm"
|
||||
|
||||
non_functional:
|
||||
performance:
|
||||
target_latency_ms: 1000
|
||||
description: >
|
||||
Latence visée < 1 s entre réception et insertion ClickHouse, avec
|
||||
batching léger.
|
||||
reliability:
|
||||
drop_on_clickhouse_failure: true
|
||||
description: >
|
||||
En cas de ClickHouse lent/HS, les logs sont drop au‑delà du buffer pour
|
||||
protéger la machine.
|
||||
security:
|
||||
user_separation: true
|
||||
privileges: least
|
||||
description: >
|
||||
Service sous utilisateur dédié, pas de secrets en clair dans les logs,
|
||||
principe de moindre privilège.
|
||||
Étape minimale pour exposer les paquets RPM produits (docker build --output).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user