Dati e analisi

LogViewer

Un visualizzatore desktop, in Go, che decodifica file diagnostici binari in una tabella interrogabile via SQL.

Strumenti
Go · Wails · SQLite
Esito
Sostituito

Contesto

Applicativo per la decodifica di file diagnostici binari. Un file CSV, detto baseline, definisce la struttura dei pacchetti per la decodifica del binario.

Sviluppato in Go, su host Linux, con target Windows.

In breve

Un decoder in Go condiviso tra una finestra desktop e una CLI headless, che produce lo stesso output byte per byte in entrambi i casi, così un tecnico può riprodurre da riga di comando esattamente ciò che la finestra ha mostrato. I record decodificati finiscono in un database SQLite, una colonna per segnale. È possibile eseguire ricerche usando SQL — velocita > 100 AND allarme = 1 — invece di una pila di menu a tendina (scelta obbligata, a causa di un elevato numero di colonne atteso).

Cosa ho costruito

Dopo essermi allontanato dallo sviluppo per Windows, avevo rifiutato diversi lavori perché il target richiesto era Windows. Non mi è costato molto: per anni, dopo l’avvento del web, le applicazioni desktop erano passate di moda, sopravvivendo solo in poche nicchie. L’arrivo delle app per smartphone ha poi in parte invertito quella tendenza: il software installato e nativo è tornato rilevante, anche se ora sui telefoni invece che sui desktop.

Da qualche anno ho iniziato a considerare Go come un buon modo per puntare a Windows sviluppando su un host Linux, grazie alle sue notevoli capacità di cross-compilazione.

La GUI, però, restava un problema: all’epoca nessun framework mi sembrava abbastanza maturo per quello che mi serviva. Fyne sembrava un toolkit meraviglioso, e negli ultimi tempi sta guadagnando terreno — è stato il mio primo tentativo di costruire l’interfaccia dell’applicazione (la versione CLI esisteva già a quel punto). Non si è però rivelato all’altezza del compito.

Non volevo buttare via il lavoro già fatto sulla CLI, così ho continuato a cercare: ho trovato Wails, ed è nato LogViewer.

Il backend in Go se la cavava bene nel decodificare i file binari strutturati bit a bit e nello scriverli in una tabella SQLite creata dinamicamente, e l’interfaccia è stata costruita senza problemi con Vue.js. Andava tutto bene… finché un giorno non è più andato bene. Mi aspettavo di avere a che fare con pacchetti diagnostici con molti campi, ma un giorno ho ricevuto una chiamata: «Non riesco ad aprire questo file». Ho lanciato LogViewer da terminale e ho visto l’errore: too many columns on binary_0?! Ho aperto la baseline che definiva la struttura dei pacchetti e ho scoperto che il numero di campi superava il massimo numero di colonne supportato da SQLite (ovvero 2000). Nel video si vede una baseline con oltre 3600 campi, ottenuta da quella reale mascherando i nomi dei campi. (Questo è un buon esempio di come una cattiva decisione sui dati, presa all’inizio, si ripercuota rapidamente se non affrontata, causando problemi più grandi in seguito.)

Ho provato a passare a DuckDB al posto di SQLite: risolveva il problema della cardinalità, ma l’inserimento massivo iniziale dei dati è passato da 7 secondi a oltre 2 minuti e mezzo — un po’ di rallentamento era prevedibile, dato che il formato colonnare di DuckDB non è pensato per gli inserimenti riga per riga, ma era decisamente troppo.

Ho quindi deciso di ricompilare la libreria SQLite per supportare più di 32.000 colonne (potenza del open source: è sufficiente definire SQLITE_MAX_COLUMN al valore desiderato in compilazione). Ed è proprio lì che l’IA può farti risparmiare ore: nel giro di pochi minuti, la ricompilazione della libreria è stata integrata nella normale build di Wails! Merito di Go e di quanto bene si integri con il C puro.

Definirei questo progetto un fallimento: il software è stato poi sostituito con quella che sembra una riscrittura in Visual Basic (probabilmente il cliente ha preferito allontanarsi da Go, tornando a qualcosa di più familiare per il proprio personale). Dovrei però limitare quel fallimento all’aspetto commerciale: su quello tecnico non ho nulla da rimpiangere. (Penso comunque che prima o poi darò un’altra possibilità a Fyne.)