docs: update ClickHouse schema with TTL, MV and users
- README.md: add complete DDL with mabase_prod database - Add TTL (1 day) on http_logs_raw table - Add materialized view mv_http_logs for automatic data transfer - Document users (data_writer, analyst) and grants - Add migration script for existing data - architecture.yml: add database, TTL settings, MV, users sections Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
82
README.md
82
README.md
@ -194,34 +194,31 @@ Tous les champs des sources A et B sont fusionnés au même niveau. Les champs d
|
|||||||
|
|
||||||
## Schema ClickHouse
|
## Schema ClickHouse
|
||||||
|
|
||||||
Le service utilise deux tables ClickHouse :
|
Le service utilise deux tables ClickHouse dans la base `mabase_prod` :
|
||||||
|
|
||||||
### Table brute (`http_logs_raw`)
|
### Setup complet
|
||||||
|
|
||||||
Table d'ingestion qui stocke le log corrélé brut au format JSON :
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
CREATE TABLE http_logs_raw
|
-- 1. Créer la base de données
|
||||||
|
CREATE DATABASE IF NOT EXISTS mabase_prod;
|
||||||
|
|
||||||
|
-- 2. Table brute avec TTL (1 jour de rétention)
|
||||||
|
DROP TABLE IF EXISTS mabase_prod.http_logs_raw;
|
||||||
|
|
||||||
|
CREATE TABLE mabase_prod.http_logs_raw
|
||||||
(
|
(
|
||||||
raw_json String
|
raw_json String,
|
||||||
|
ingest_time DateTime DEFAULT now()
|
||||||
)
|
)
|
||||||
ENGINE = MergeTree
|
ENGINE = MergeTree
|
||||||
ORDER BY tuple();
|
ORDER BY tuple()
|
||||||
```
|
TTL ingest_time + INTERVAL 1 DAY
|
||||||
|
SETTINGS ttl_only_drop_parts = 1;
|
||||||
|
|
||||||
**Format d'insertion :** Le service envoie chaque log corrélé sérialisé en JSON dans la colonne `raw_json` :
|
-- 3. Table parsée
|
||||||
|
DROP TABLE IF EXISTS mabase_prod.http_logs;
|
||||||
|
|
||||||
```sql
|
CREATE TABLE mabase_prod.http_logs
|
||||||
INSERT INTO http_logs_raw (raw_json) FORMAT JSONEachRow
|
|
||||||
{"raw_json":"{\"timestamp\":\"2024-01-01T12:00:00Z\",\"src_ip\":\"192.168.1.1\",\"correlated\":true,...}"}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Table enrichie (`http_logs`)
|
|
||||||
|
|
||||||
Vue matérialisée qui extrait les champs du JSON pour l'analyse :
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE http_logs
|
|
||||||
(
|
(
|
||||||
raw_json String,
|
raw_json String,
|
||||||
|
|
||||||
@ -246,7 +243,6 @@ CREATE TABLE http_logs
|
|||||||
http_version LowCardinality(String) DEFAULT JSONExtractString(raw_json, 'http_version'),
|
http_version LowCardinality(String) DEFAULT JSONExtractString(raw_json, 'http_version'),
|
||||||
orphan_side LowCardinality(String) DEFAULT JSONExtractString(raw_json, 'orphan_side'),
|
orphan_side LowCardinality(String) DEFAULT JSONExtractString(raw_json, 'orphan_side'),
|
||||||
|
|
||||||
-- champs « presque toujours là »
|
|
||||||
a_timestamp UInt64 DEFAULT JSONExtractUInt(raw_json, 'a_timestamp'),
|
a_timestamp UInt64 DEFAULT JSONExtractUInt(raw_json, 'a_timestamp'),
|
||||||
b_timestamp UInt64 DEFAULT JSONExtractUInt(raw_json, 'b_timestamp'),
|
b_timestamp UInt64 DEFAULT JSONExtractUInt(raw_json, 'b_timestamp'),
|
||||||
conn_id String DEFAULT JSONExtractString(raw_json, 'conn_id'),
|
conn_id String DEFAULT JSONExtractString(raw_json, 'conn_id'),
|
||||||
@ -263,12 +259,54 @@ CREATE TABLE http_logs
|
|||||||
ja3_hash String DEFAULT JSONExtractString(raw_json, 'ja3_hash'),
|
ja3_hash String DEFAULT JSONExtractString(raw_json, 'ja3_hash'),
|
||||||
ja4 String DEFAULT JSONExtractString(raw_json, 'ja4'),
|
ja4 String DEFAULT JSONExtractString(raw_json, 'ja4'),
|
||||||
|
|
||||||
-- tous les autres champs JSON (headers dynamiques etc.)
|
|
||||||
extra JSON DEFAULT raw_json
|
extra JSON DEFAULT raw_json
|
||||||
)
|
)
|
||||||
ENGINE = MergeTree
|
ENGINE = MergeTree
|
||||||
PARTITION BY toYYYYMM(log_date)
|
PARTITION BY toYYYYMM(log_date)
|
||||||
ORDER BY (log_date, dst_ip, src_ip, time);
|
ORDER BY (log_date, dst_ip, src_ip, time);
|
||||||
|
|
||||||
|
-- 4. Vue matérialisée (RAW → logs)
|
||||||
|
DROP VIEW IF EXISTS mabase_prod.mv_http_logs;
|
||||||
|
|
||||||
|
CREATE MATERIALIZED VIEW mabase_prod.mv_http_logs
|
||||||
|
TO mabase_prod.http_logs
|
||||||
|
AS
|
||||||
|
SELECT raw_json
|
||||||
|
FROM mabase_prod.http_logs_raw;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Utilisateurs et permissions
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Créer les utilisateurs
|
||||||
|
CREATE USER IF NOT EXISTS data_writer IDENTIFIED WITH TonMotDePasseInsert;
|
||||||
|
CREATE USER IF NOT EXISTS analyst IDENTIFIED WITH TonMotDePasseAnalyst;
|
||||||
|
|
||||||
|
-- Droits pour data_writer (INSERT + SELECT pour la MV)
|
||||||
|
GRANT INSERT(raw_json) ON mabase_prod.http_logs_raw TO data_writer;
|
||||||
|
GRANT SELECT(raw_json) ON mabase_prod.http_logs_raw TO data_writer;
|
||||||
|
|
||||||
|
-- Droits pour analyst (lecture seule sur les logs parsés)
|
||||||
|
GRANT SELECT ON mabase_prod.http_logs TO analyst;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Format d'insertion
|
||||||
|
|
||||||
|
Le service envoie chaque log corrélé sérialisé en JSON dans la colonne `raw_json` :
|
||||||
|
|
||||||
|
```sql
|
||||||
|
INSERT INTO mabase_prod.http_logs_raw (raw_json) FORMAT JSONEachRow
|
||||||
|
{"raw_json":"{\"timestamp\":\"2024-01-01T12:00:00Z\",\"src_ip\":\"192.168.1.1\",\"correlated\":true,...}"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Migration des données existantes
|
||||||
|
|
||||||
|
Si vous avez déjà des données dans l'ancienne table `http_logs_raw` :
|
||||||
|
|
||||||
|
```sql
|
||||||
|
INSERT INTO mabase_prod.http_logs (raw_json)
|
||||||
|
SELECT raw_json
|
||||||
|
FROM mabase_prod.http_logs_raw;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|||||||
@ -401,22 +401,30 @@ schema:
|
|||||||
|
|
||||||
clickhouse_schema:
|
clickhouse_schema:
|
||||||
strategy: external_ddls
|
strategy: external_ddls
|
||||||
|
database: mabase_prod
|
||||||
description: >
|
description: >
|
||||||
La table ClickHouse est gérée en dehors du service. Deux tables sont utilisées :
|
La table ClickHouse est gérée en dehors du service. Deux tables sont utilisées :
|
||||||
http_logs_raw (table d'ingestion avec le JSON brut) et http_logs (table enrichie
|
http_logs_raw (table d'ingestion avec TTL 1 jour) et http_logs (table enrichie
|
||||||
avec extraction des champs via des colonnes matérialisées).
|
avec extraction des champs via des colonnes matérialisées). Une vue matérialisée
|
||||||
|
transfère automatiquement les données de RAW vers parsée.
|
||||||
tables:
|
tables:
|
||||||
- name: http_logs_raw
|
- name: http_logs_raw
|
||||||
description: >
|
description: >
|
||||||
Table d'ingestion brute. Une seule colonne raw_json contient le log corrélé
|
Table d'ingestion brute avec TTL. Une seule colonne raw_json contient le log
|
||||||
complet sérialisé en JSON. Le service insère via INSERT INTO http_logs_raw (raw_json).
|
corrélé complet sérialisé en JSON. TTL de 1 jour pour limiter le stockage.
|
||||||
engine: MergeTree
|
engine: MergeTree
|
||||||
order_by: tuple()
|
order_by: tuple()
|
||||||
|
ttl: ingest_time + INTERVAL 1 DAY
|
||||||
|
settings:
|
||||||
|
ttl_only_drop_parts: 1
|
||||||
columns:
|
columns:
|
||||||
- name: raw_json
|
- name: raw_json
|
||||||
type: String
|
type: String
|
||||||
insert_format: >
|
- name: ingest_time
|
||||||
INSERT INTO http_logs_raw (raw_json) FORMAT JSONEachRow
|
type: DateTime
|
||||||
|
default: now()
|
||||||
|
insert_format: |
|
||||||
|
INSERT INTO mabase_prod.http_logs_raw (raw_json) FORMAT JSONEachRow
|
||||||
{"raw_json":"{...log corrélé sérialisé en JSON...}"}
|
{"raw_json":"{...log corrélé sérialisé en JSON...}"}
|
||||||
|
|
||||||
- name: http_logs
|
- name: http_logs
|
||||||
@ -529,6 +537,36 @@ clickhouse_schema:
|
|||||||
type: JSON
|
type: JSON
|
||||||
default: raw_json
|
default: raw_json
|
||||||
|
|
||||||
|
- name: mv_http_logs
|
||||||
|
type: materialized_view
|
||||||
|
description: >
|
||||||
|
Vue matérialisée qui transfère automatiquement les données de http_logs_raw
|
||||||
|
vers http_logs lors de chaque INSERT.
|
||||||
|
target: mabase_prod.http_logs
|
||||||
|
query: |
|
||||||
|
SELECT raw_json FROM mabase_prod.http_logs_raw
|
||||||
|
|
||||||
|
users:
|
||||||
|
- name: data_writer
|
||||||
|
description: Utilisateur pour l'insertion des logs (utilisé par logcorrelator)
|
||||||
|
grants:
|
||||||
|
- INSERT(raw_json) ON mabase_prod.http_logs_raw
|
||||||
|
- SELECT(raw_json) ON mabase_prod.http_logs_raw
|
||||||
|
|
||||||
|
- name: analyst
|
||||||
|
description: Utilisateur pour la lecture des logs parsés (BI, requêtes)
|
||||||
|
grants:
|
||||||
|
- SELECT ON mabase_prod.http_logs
|
||||||
|
|
||||||
|
migration:
|
||||||
|
description: >
|
||||||
|
Script de migration pour transférer les données existantes de l'ancienne
|
||||||
|
table http_logs_raw vers la nouvelle structure avec vue matérialisée.
|
||||||
|
sql: |
|
||||||
|
INSERT INTO mabase_prod.http_logs (raw_json)
|
||||||
|
SELECT raw_json
|
||||||
|
FROM mabase_prod.http_logs_raw;
|
||||||
|
|
||||||
architecture:
|
architecture:
|
||||||
description: >
|
description: >
|
||||||
Architecture hexagonale : domaine de corrélation indépendant, ports abstraits
|
Architecture hexagonale : domaine de corrélation indépendant, ports abstraits
|
||||||
|
|||||||
Reference in New Issue
Block a user