# Dashboard Activity & Tasks su Elasticsearch **Autore:** Matteo Benedetto **Email:** matteo.benedetto@e-geos.it **Data:** 03/12/2025 --- ## 1. Struttura dei dati in Elasticsearch ### 1.1 Indice Tutti i dati sono indicizzati in Elasticsearch nell'indice: - **Nome indice:** `geodata` L'indice viene creato automaticamente dal servizio `data_loader` (contenitore Docker) oppure tramite lo script di inizializzazione usato nella fase di sviluppo. ### 1.2 Mapping principale Il mapping dell’indice `geodata` è stato definito in modo esplicito per evitare problemi con i tipi dinamici e per supportare aggregazioni e visualizzazioni in Grafana. Campi principali: - `location` (`geo_point`) - Coordinate geografiche del punto (latitudine/longitudine). - `timestamp` (`date`) - Data/ora dell’evento. - `status` (`keyword`) - Stato del ticket/attività. Valori possibili: `OPEN`, `CLOSED`, `IN_PROGRESS`, `ON_HOLD`. - `timing_status` (`keyword`) - Stato di puntualità, definito solo quando `status = CLOSED`. - Valori possibili: `CLOSED_ON_TIME`, `CLOSED_LATE`. - `lead_time` (`integer`) - Tempo di lavorazione (in minuti) per le attività chiuse, usato per le medie nella dashboard. - `operator` (`keyword`) - Operatore responsabile (es. `Operator A`, `Operator B`, …). - `duration` (`integer`) - Durata generica dell’evento (valore grezzo usato solo come informativo). - `task_type` (`keyword`) - Tipo di task, usato nella dashboard **Tasks**. Valori esemplificativi: - `Create Activity` - `Close Activity` - `Create WF` - `Close WF` - `Select DTO` - `Report Generation` - `Report QC` - `min_duration` (`integer`) - Durata minima simulata per il tipo di task (in secondi). - `max_duration` (`integer`) - Durata massima simulata per il tipo di task (in secondi). - `avg_duration` (`integer`) - Durata media simulata per il tipo di task (in secondi). - `task_duration` (`integer`) - Durata effettiva del singolo evento (in secondi). - `id` (`integer`) - Identificativo numerico univoco del record nella generazione mock. ### 1.3 Generazione e caricamento dati - **Generazione dati**: file `generate_mock_data.py` - Genera un file GeoJSON `data/sample.geojson` con 1000 feature. - Popola per ogni feature: - coordinate casuali in Europa, - campi di stato (`status`, `timing_status`, `lead_time`), - informazioni di task (`task_type`, durate, operatore, timestamp). - **Caricamento in Elasticsearch**: file `loader/load_data.py` - Attende che Elasticsearch sia disponibile. - Crea l’indice `geodata` con il mapping descritto sopra. - Legge `sample.geojson` e per ogni feature crea un documento con: - `location.lat` / `location.lon` - tutti i campi in `properties` (timestamp, status, operator, ecc.). --- ## 2. Dashboard "Activity" La prima dashboard si chiama **"Activity"** ed è salvata in `grafana/dashboards/dashboard.json`. ### 2.1 Pannelli principali 1. **Activity Status** (table) - **Datasource:** `Elasticsearch` - **Query:** aggregazione `terms` sul campo `status` + metrica `count`. - **Trasformazioni:** - `organize` per rinominare i campi in `Status`, `Count`, `Avg Lead Time`. - `calculateField` per calcolare il totale e la colonna `Proportion` (percentuale sul totale). - **Colori:** override sul campo `Status` con testo colorato (OPEN giallo, CLOSED blu, IN_PROGRESS azzurro, ON_HOLD viola). - **Uso:** fornisce il riepilogo delle attività per stato con la proporzione e il tempo medio di lavorazione. 2. **Activity Distribution** (geomap heatmap) - **Datasource:** `Elasticsearch` - **Query:** metrica `raw_data` con `query: "*"` e `timeField: "timestamp"`. - **Layer:** tipo `heatmap` con: - `location.mode = "coords"` - `latitude = "location.lat"`, `longitude = "location.lon"` - **Uso:** visualizza la distribuzione geografica degli eventi come heatmap sull’Europa. 3. **Timing Status** (table) - **Datasource:** `Elasticsearch` - **Query:** aggregazione `terms` su `timing_status` + metrica `count`. - **Colori:** - `CLOSED_ON_TIME` con background verde. - `CLOSED_LATE` con background arancione. - **Uso:** mostra il numero di attività chiuse in tempo vs in ritardo. 4. **On-Time vs Late** (pie chart) - **Datasource:** `Elasticsearch` - **Query:** identica a `Timing Status` (terms su `timing_status`). - **Trasformazioni:** - trasformazione per convertire i risultati dell’aggregazione in valori per il pie chart. - **Uso:** rappresentazione grafica (torta) della ripartizione CLOSED_ON_TIME vs CLOSED_LATE. 5. **Activity Over Time** (time series) - **Datasource:** `Elasticsearch` - **Query:** `date_histogram` su `timestamp` + metrica `count`. - **Uso:** andamento temporale del numero di eventi. --- ## 3. Dashboard "Tasks" La seconda dashboard si chiama **"Tasks"** ed è salvata in `grafana/dashboards/tasks_dashboard.json`. ### 3.1 Tasks (tabella in alto a sinistra) - **Datasource:** `Elasticsearch` - **Query:** - `terms` su `task_type` (raggruppamento per tipo di task). - Metriche: - `count` (Total) - `min` su `task_duration` (Min Duration) - `max` su `task_duration` (Max Duration) - **Trasformazioni:** - `organize` per rinominare i campi: - `task_type → Task` - `Count → Total` - `Min task_duration → Min Duration` - `Max task_duration → Max Duration` - **Colori:** testo del campo `Task` colorato in azzurro. - **Uso:** riepilogo per tipo di task con numero totale e range di durata. ### 3.2 Tasks by Operator (grafico a barre orizzontali) - **Datasource:** `Elasticsearch` - **Query:** - Primo livello: `terms` su `operator` (asse Y del grafico). - Secondo livello: `terms` su `task_type` (serie colorate). - Metrica: `count`. - **Trasformazioni:** - `groupingToMatrix` (o equivalente) per trasformare l’output dell’aggregazione in una matrice con: - `rowField = operator` - `columnField = task_type` - `valueField = Count` - **Opzioni grafiche:** - `orientation = horizontal`. - `stacking = normal` per avere barre impilate per operatore. - Legenda a destra con un colore per ogni tipo di task (`Create Activity`, `Close Activity`, `Create WF`, `Close WF`, `Select DTO`, `Report Generation`, `Report QC`). - **Uso:** mostra per ogni operatore il numero di task, suddivisi per tipologia come barre orizzontali impilate. ### 3.3 Tasks (tabella in basso) - **Datasource:** `Elasticsearch` - **Query:** - `terms` su `task_type` e `operator` (raggruppamento per Task + Operator). - Metriche: - `count` (Total) - `min`/`max`/`avg` su `task_duration`. - **Trasformazioni:** - `organize` per ordinare le colonne e rinominare i campi in: - `Task`, `Operator`, `Total`, `Min`, `Max`, `Average`. - **Unità di misura:** - Durate espresse in secondi, visualizzate in Grafana come secondi/minuti (in base al formato scelto nella colonna). - **Uso:** tabella dettagliata per tipo di task e operatore, con statistiche di durata. --- ## 4. Note operative - **Provisioning Grafana** - I file delle dashboard sono montati nel container Grafana tramite Docker Compose. - Ogni modifica ai file JSON (`dashboard.json`, `tasks_dashboard.json`) richiede un **riavvio del container Grafana** (`docker compose restart grafana`). - **Datasource Elasticsearch** - È definito tramite provisioning (file `datasource.yml`) usando: - `jsonData.index = "geodata"` - `jsonData.timeField = "timestamp"` - Non viene usata la `uid` del datasource nelle dashboard: i pannelli si riferiscono al datasource tramite `"datasource": "Elasticsearch"` per evitare problemi di provisioning. - **Rigenerazione dati** - Per rigenerare i dati mock: 1. Eseguire `python3 generate_mock_data.py` nella root del progetto. 2. Cancellare l’indice `geodata` in Elasticsearch. 3. Riavviare il container `data_loader` in modo che ricrei l’indice con il mapping corretto e ricarichi `sample.geojson`. Questo documento descrive lo stato corrente della soluzione (stack Docker Elasticsearch + Grafana + loader Python) usata per visualizzare dati geospaziali e metriche di attività/task nelle dashboard **Activity** e **Tasks**.