Introduzione
JuliuS espone un server HTTP locale basato su Indy TIdHTTPServer che consente il controllo remoto del motore di scripting e del browser embedded (Chromium CEF). Tutti gli endpoint usano una singola rotta con parametri in query string.
Gli endpoint sono divisi in tre macro-aree: Browser CEF (operazioni dentro il browser embedded), Ispezione pagina / DevTools (lettura del DOM, frame, network), OS (mouse e tastiera a livello sistema operativo, per finestre native fuori dal browser).
Base URL & Autenticazione
Carica script da file
Settings.Data.scriptPath e lo apre nell'editor grafico di JuliuS. Usare questo endpoint quando lo script da eseguire risiede già sul disco della macchina che ospita JuliuS. L'estensione .js viene aggiunta automaticamente se il file non viene trovato senza di essa, rendendo opzionale specificarla nella chiamata. Il caricamento è asincrono: la risposta arriva immediatamente, ma l'apertura dell'editor avviene nel thread principale poco dopo.OKErrore, file non trovato [...]Carica script da stream
OKErrore nello scritp — body assente o errore letturaLeggi script corrente
frmScript. La lettura avviene direttamente da SynSynaScript.Text via TThread.Synchronize, quindi include anche le eventuali modifiche fatte manualmente dall'utente nell'editor dopo il caricamento iniziale, e non solo l'ultimo valore impostato via loadscript o readscritpfromstream. È un endpoint di pura lettura: non modifica lo stato dell'editor né l'esecuzione in corso. Utile per verificare cosa sta per essere eseguito prima di un start, per fare un backup veloce dell'editor remoto o per confrontare lo script in memoria con il file su disco.| Parametro | Obbligatorio | Descrizione |
|---|---|---|
| operation | ✓ | Deve essere getscript |
| Header risposta | Valore |
|---|---|
| Content-Type | text/plain; charset=utf-8 |
frmScript o errore durante la letturaLeggi linea corrente
SynSynaScript in frmScript. Questa è esattamente la riga che verrebbe usata come punto di partenza dal prossimo ?operation=start: l'esecuzione dello script inizia infatti dalla posizione corrente del caret nell'editor. Utile per monitorare a che punto è arrivata l'esecuzione di uno script, sincronizzare interfacce esterne con il puntatore di esecuzione, o verificare la riga di partenza prima di lanciare uno start. Endpoint puramente di lettura: non altera lo stato dell'editor.| Parametro | Obbligatorio | Descrizione |
|---|---|---|
| operation | ✓ | Deve essere getcurrentline |
| Header risposta | Valore |
|---|---|
| Content-Type | text/plain; charset=utf-8 |
42)0 — frmScript non inizializzato o errore di letturaImposta linea di partenza
SynSynaScript alla riga indicata (1-based), che diventerà la riga di partenza usata dal prossimo ?operation=start. La colonna del caret viene riportata a 1. Se il valore richiesto supera il numero di righe presenti nello script, viene applicato un clamp sull'ultima riga disponibile. L'operazione è protetta: se uno script è già in esecuzione la chiamata viene rifiutata per evitare di alterare il puntatore di esecuzione corrente. Più flessibile rispetto a reset cursore, che riporta sempre il caret alla riga 1.| Parametro | Obbligatorio | Descrizione |
|---|---|---|
| operation | ✓ | Deve essere setcurrentline |
| line | ✓ | Numero di riga (intero ≥ 1, 1-based). Valori oltre il numero massimo di righe vengono limitati all'ultima riga disponibile. |
| Header risposta | Valore |
|---|---|
| Content-Type | text/plain; charset=utf-8 |
line_set_N — conferma con il numero di riga effettivamente impostato (può differire da quello richiesto se è stato applicato il clamp)ERROR: parametro line mancante o non numericoERROR: line deve essere >= 1ERROR: script in esecuzione, impossibile cambiare la linea correnteERROR: frmScript non inizializzato?operation=setcurrentline&line=N, poi ?operation=start per avviare l'esecuzione dalla riga scelta.Avvia esecuzione
currentLine. Prima di chiamare questo endpoint è buona pratica verificare lo stato con ?operation=status: se un processo è già in esecuzione la chiamata viene rifiutata con un messaggio esplicito, evitando esecuzioni concorrenti. I parametri excelLine e remoteVirtualPath impostano il contesto di logging e upload degli screenshot, usati dallo script durante l'esecuzione.| Parametro | Obbligatorio | Descrizione |
|---|---|---|
| operation | ✓ | Deve essere start |
| currentLine | Riga di partenza dell'esecuzione | |
| excelLine | Nome base della riga nel log Excel, usato per nominare i file di screenshot | |
| remoteVirtualPath | Path virtuale remoto per l'upload degli screenshot (_ viene sostituito con /). Il trailing / viene aggiunto automaticamente. |
startedAlready Running, check status before try to start another processScript is not already initiated — nessun form di script apertoFerma esecuzione
frmScript.stopExecution nel thread principale. L'operazione gestisce correttamente sia lo stato running che lo stato paused, rimuovendo entrambi i flag di stato. Viene inoltre chiusa ogni finestra popup figlia aperta durante l'esecuzione. Se non è in corso alcuna esecuzione la chiamata è un no-op silenzioso.Reset cursore
IsRunning = true) la chiamata viene ignorata silenziosamente senza restituire errori, evitando interferenze con il processo in corso.IsRunning = true).Status
start per evitare avvii multipli, e durante l'esecuzione per rilevare quando uno script è terminato. Lo stato tiene conto sia dell'esecuzione attiva dello script che del caricamento della pagina nel browser (MainBrowserFrm.FPageLoading): se la pagina è ancora in caricamento il sistema risulta occupato anche se lo script è tecnicamente in pausa.on working — script in esecuzione o pagina in caricamentono operation progress — sistema idle, pronto per un nuovo startGet Result (funzione fissa)
preventivo() — la funzione di estrazione del risultato per convenzione negli script JuliuS — e restituisce il suo valore serializzato come JSON di TOperationResult. Il JSON include il risultato grezzo, l'ID operazione, la data di avvio e la lista degli screenshot catturati. Da usare al termine di uno script di preventivazione per recuperare il valore calcolato. Per funzioni con nome diverso usare l'endpoint Get Result variabile.Get Result (funzione variabile)
getresult: esegue nel browser la funzione JavaScript il cui nome viene passato come parametro, aggiungendo automaticamente le parentesi (). Restituisce il valore in formato JSON TOperationResult, esattamente come l'endpoint fisso. Usare questo endpoint quando lo script espone funzioni di estrazione con nomi personalizzati (es. getOrderTotal, calcolaPremio) invece della funzione standard preventivo(). La funzione deve essere già definita nel contesto JS del browser al momento della chiamata.| Parametro | Descrizione |
|---|---|
| getresult | Nome della funzione JS da eseguire, senza parentesi. Le () vengono aggiunte automaticamente. |
Click (CEF)
SCREEN_SIZE. Per click su finestre native Windows o dialog di sistema usare invece gli endpoint OS Mouse, che agiscono a livello sistema operativo.| Parametro | Descrizione |
|---|---|
| X | Coordinata X in pixel relativa al pannello CEF |
| Y | Coordinata Y in pixel relativa al pannello CEF |
Snapshot (CEF)
scalefactor indica il fattore di scala DPI del monitor e va usato dal client per interpretare correttamente le dimensioni dell'immagine in ambienti con display ad alta densità (HiDPI). Questo endpoint cattura solo il pannello del browser, non l'intera finestra di JuliuS né il desktop. Per screenshot dell'intero desktop usare osscreenshotjpg.| Header risposta | Valore |
|---|---|
| Content-Type | image/jpg |
| scalefactor | Fattore DPI del monitor (es. 1.25 per display 125%) |
Restart Chromium
Azzera la sessione Chromium embedded senza riavviare l'applicazione.
Tramite DevTools Protocol cancella cache HTTP, cookie, localStorage,
sessionStorage e IndexedDB, poi naviga su about:blank.
Risponde solo quando il reset è completato.
Risposta
chromium_restarted — reset completatoERROR: ... — messaggio di erroreEsempio
Delete Chromium Cache
Esegue un reset completo della cache Chromium: svuota cache HTTP,
cookie e storage tramite DevTools Protocol, poi cancella fisicamente
la directory GlobalCEFApp.RootCache su disco.
Più lenta di restartchromium — usare per cache corrotta
o per garantire una sessione indistinguibile da un avvio a freddo.
Confronto con restartchromium
| Azione | restartchromium | deletechromiumcache |
|---|---|---|
| Cache HTTP in memoria | ✅ | ✅ |
| Cookie in memoria | ✅ | ✅ |
| LocalStorage / IndexedDB | ✅ | ✅ |
| File cache su disco | ❌ | ✅ |
| Tempo medio | ~3 s | ~5 s |
Risposta
chromium_cache_deleted — pulizia completataERROR: ... — messaggio di erroreEsempio
Get DOM
document.documentElement.outerHTML. È utile per analisi offline del DOM, debug di pagine con rendering dinamico o per verificare lo stato attuale della pagina prima di eseguire interazioni. Poiché restituisce il DOM live (post JavaScript, non il sorgente originale del server), riflette lo stato effettivo della pagina incluse le modifiche apportate dagli script già eseguiti.text/html; charset=utf-8ERROR: ... — eccezione internaGet Form Fields
input, select, textarea e button. Per ogni elemento vengono incluse proprietà come id, name, type, value e visible. Particolarmente utile in fase di sviluppo di uno script, per identificare gli ID degli elementi da usare nei comandi WRITETO senza dover ispezionare manualmente il sorgente della pagina.application/json; charset=utf-8ERROR: ... — eccezione internaGet Page Info
readyState e lista degli iframe presenti con i relativi URL. È l'endpoint ideale per verificare rapidamente su quale pagina si trova il browser, controllare che il caricamento sia completo (readyState === "complete") e identificare la struttura dei frame prima di usare TARGET_FRAME negli script.url, title, readyState, lista iframes — application/json; charset=utf-8ERROR: ... — eccezione internaGet Console Log
console.log, console.warn ed console.error accumulati fino a quel momento. Indispensabile per il debug dei blocchi SNIPPET negli script, che tipicamente usano console.log() per tracciare l'esecuzione. I messaggi vengono accumulati in memoria e restituiti ad ogni chiamata senza essere svuotati, salvo reset esplicito.application/json; charset=utf-8ERROR: ... — eccezione internaEvalJS (via API)
?operation=getresult, il risultato non viene registrato nel TOperationResult corrente ma restituito direttamente nella risposta HTTP. L'espressione deve essere URL-encoded. Utile per interrogazioni rapide del DOM o per verificare lo stato di variabili JS senza dover definire una funzione dedicata nello script.text/plain; charset=utf-8ERROR: ... — eccezione interna o errore JSFind Element
id, tagName, value, visible e boundingRect. Utile per implementare logica condizionale nei flussi di automazione: verificare che un pulsante sia presente prima di cliccare, attendere la comparsa di un elemento di risultato o rilevare messaggi di errore nella pagina. Il selettore deve essere URL-encoded.application/json; charset=utf-8ERROR: ... — eccezione internaGet Frame List
name, id, url, il flag isMain e il flag isFocused. È l'endpoint di riferimento da consultare prima di usare la direttiva TARGET_FRAME=POPUP negli script, per identificare esattamente il nome o l'URL del frame target. Particolarmente utile con pagine che aprono popup o usano frame annidati.name, id, url, isMain, isFocused{"error":"..."}Get Frame Source
frame viene omesso, viene restituito il sorgente del frame principale. Utile per ispezionare il contenuto di iframe di terze parti, form caricati in frame separati o popup figlio aperti durante la navigazione.| Parametro | Obbligatorio | Descrizione |
|---|---|---|
| frame | Nome del frame target. Se omesso → frame principale. |
text/html; charset=utf-8ERROR: ... — frame non trovato o errore internoWait Page Load
WAIT fissi negli script, questo endpoint si adatta ai tempi reali del server: restituisce la risposta non appena la pagina è pronta, riducendo i tempi di attesa inutili. La richiesta gira nel thread HTTP senza bloccare il main thread dell'applicazione. Il timeout predefinito è 15 secondi e può essere aumentato per pagine particolarmente lente.| Parametro | Default | Descrizione |
|---|---|---|
| timeout | 15000 | Timeout massimo di attesa in millisecondi |
loaded — pagina caricata correttamente entro il timeouttimeout — il timeout è scaduto prima del completamento del caricamentoDevTools Protocol
params accetta un oggetto JSON URL-encoded con i parametri specifici del comando CDP. Consultare la documentazione CDP ufficiale per la lista completa dei metodi disponibili.| Parametro | Obbligatorio | Descrizione |
|---|---|---|
| devtools | ✓ | Metodo CDP da eseguire (es. Network.enable, DOM.getDocument) |
| params | Parametri del comando come JSON URL-encoded |
{"error":"..."} — metodo non valido o errore CDPStart Network Log
Network.enable tramite il Chrome DevTools Protocol per intercettare tutte le richieste HTTP/HTTPS effettuate dal browser: XHR, fetch, caricamento di risorse. Va chiamato prima di navigare verso la pagina da monitorare, in modo da non perdere le prime richieste. I dati raccolti sono poi recuperabili con ?operation=getnetworklog. Utile per analizzare le API chiamate da una pagina web o per identificare endpoint da replicare.network log startedERROR: ... — eccezione internaGet Network Log
startnetworklog. Il log è un array JSON in cui ogni entry contiene il metodo HTTP (method), l'URL completo (url) e il tipo di risorsa (type, es. XHR, Fetch, Document). Chiamare questo endpoint più volte non azzera il log: il buffer cresce fino al prossimo startnetworklog. Ideale per reverse engineering delle API di una pagina web o per verificare le chiamate effettuate durante l'esecuzione di uno script.method, url, type per ogni richiesta — application/json; charset=utf-8{"error":"..."}OS Mouse — Move
TCrossSO.SetMousePos). A differenza dell'endpoint click CEF che agisce dentro il browser embedded, questo endpoint controlla il cursore a livello SO ed è in grado di interagire con qualsiasi finestra visibile sul desktop: dialog nativi Windows, popup di sistema, finestre di altre applicazioni o la stessa interfaccia di JuliuS. Usare in combinazione con osmouseclick per eseguire click precisi su elementi nativi.movedERROR: ...OS Mouse — Click sinistro
TCrossSO.MouseLClick. Deve essere preceduto da una chiamata a osmousemove per posizionare correttamente il cursore. Agisce a livello sistema operativo, quindi funziona su qualsiasi finestra attiva sul desktop, non solo sul browser CEF. Per spostamento e click in un'unica operazione atomica usare osmousemoveclick.clickedOS Mouse — Move + Click
moved_and_clickedOS Mouse — Click destro
TCrossSO.MouseRClick. Utile per aprire menu contestuali nativi del sistema operativo o di applicazioni Windows che non espongono i propri elementi tramite interfaccia web. Come gli altri endpoint OS mouse, agisce a livello di sistema operativo e non è vincolato al browser CEF.right_clickedOS Mouse — Get posizione
{"x": N, "y": N}. Utile durante lo sviluppo e il debug di automazioni per calibrare le coordinate da usare negli endpoint osmousemove e osmousemoveclick, o per verificare che il cursore si trovi nella posizione attesa prima di eseguire un click.{"x":320,"y":240} — application/json; charset=utf-8{"error":"..."}OS Tastiera — Key Press
WRITETO che scrive nel browser CEF, questo endpoint agisce a livello SO e può controllare qualsiasi finestra attiva: dialog nativi Windows, form non web, applicazioni desktop. Per tasti comuni (ENTER, ESC, TAB) sono disponibili gli shortcut dedicati più leggibili; usare questo endpoint quando si ha bisogno di un tasto specifico non coperto dagli shortcut.| Keycode | Tasto | Keycode | Tasto |
|---|---|---|---|
| 13 | ENTER | 27 | ESC |
| 9 | TAB | 32 | SPAZIO |
| 8 | BACKSPACE | 46 | DELETE |
| 37 | ← LEFT | 38 | ↑ UP |
| 39 | → RIGHT | 40 | ↓ DOWN |
| 112–123 | F1–F12 | 65–90 | A–Z |
key_pressedOS Tastiera — Shortcut tasti comuni
oskeypress. Ogni endpoint esegue esattamente la stessa operazione del corrispondente keycode numerico, ma rende i log e le sequenze di automazione immediatamente comprensibili. Usare questi shortcut ogni volta che è possibile; ricorrere a oskeypress con keycode numerico solo per tasti non coperti da questi alias.| Operation | Tasto | Risposta |
|---|---|---|
| oskeyenter | ENTER (↵) | enter |
| oskeyesc | ESC | esc |
| oskeytab | TAB (⇥) | tab |
| oskeybackspace | BACKSPACE (⌫) | backspace |
OS Tastiera — Arrow Keys
dir accetta i valori up, down, left, right in minuscolo; valori non riconosciuti vengono ignorati silenziosamente.| dir | Tasto |
|---|---|
| up | ↑ Freccia su |
| down | ↓ Freccia giù |
| left | ← Freccia sinistra |
| right | → Freccia destra |
arrow_down / arrow_up / ecc.OS Tastiera — Key Combo
keybd_event delle API Windows. Il parametro combo accetta la sintassi modificatore+tasto in minuscolo, URL-encoded se necessario. Il modificatore può essere ctrl, shift o alt; il tasto può essere una lettera singola (a–z) oppure un tasto speciale per nome. Disponibile solo su piattaforma Windows: su altre piattaforme l'endpoint risponde con un messaggio di errore esplicito senza generare eccezioni.| Campo combo | Valori accettati |
|---|---|
| modifier | ctrl, shift, alt |
| key | Lettera singola (a–z), oppure: f4–f6, f10–f12, tab, enter, esc, del, home, end, pageup, pagedown |
combo_ctrl+c — conferma della combinazione eseguitaERROR: formato combo non valido, usare modifier+keyERROR: tasto non riconosciuto [...]ERROR: oskeycombо not implemented on this platformOS Screenshot (PNG)
scalefactor indica il fattore DPI del monitor. Usare la variante osscreenshotjpg quando la dimensione del file è prioritaria rispetto alla qualità.| Header risposta | Valore |
|---|---|
| Content-Type | image/png |
| scalefactor | Fattore DPI del monitor |
ERROR: screenshot failedOS Screenshot (JPG)
| Header risposta | Valore |
|---|---|
| Content-Type | image/jpg |
| scalefactor | Fattore DPI del monitor |
ERROR: screenshot failedGet Browser Window Info
mainForm) che del pannello browser CEF (browser), compresi i valori assoluti di schermo (screenLeft, screenTop). Il campo scaleFactor indica il fattore DPI del monitor. Questo endpoint è fondamentale per convertire coordinate relative al browser in coordinate assolute di schermo da usare con gli endpoint OS mouse, in modo che le automazioni funzionino correttamente indipendentemente da dove è posizionata la finestra di JuliuS sul desktop.Struttura risposta JSON
mainForm, browser e scaleFactor — application/json; charset=utf-8{"error":"..."}browser.screenLeft e browser.screenTop, poi sommarli alle coordinate relative del browser per ottenere le coordinate assolute di schermo da passare a osmousemoveclick.Browser Move Click
snapshot e MOUSE_CLICK), delegando internamente a ClickOnBrowserRelative la conversione in coordinate assolute di schermo. È più affidabile di osmousemoveclick con coordinate assolute perché funziona correttamente indipendentemente dalla posizione della finestra JuliuS sul desktop e dal fattore di scala DPI, senza che il chiamante debba calcolare la conversione manualmente.| Parametro | Descrizione |
|---|---|
| x | Coordinata X in pixel CSS relativa all'angolo superiore sinistro del pannello browser |
| y | Coordinata Y in pixel CSS relativa all'angolo superiore sinistro del pannello browser |
clicked_at_browser_320_240 — conferma con le coordinate usateERROR: ...?operation=click invia un evento sintetico CEF interno. osmousemoveclick usa coordinate assolute di schermo. browsermoveclick usa coordinate relative al browser ma agisce a livello SO — è il punto di equilibrio tra semplicità d'uso e affidabilità cross-posizione.Rewrite Variabili Globali
GLOBALV dello script attualmente caricato, sovrascrivendo i valori precedenti. Il contenuto viene caricato in frmScript.GlobalV tramite LoadFromStream e poi updateGlobalV aggiorna fisicamente le righe del blocco GLOBALV=BEGIN/END nell'editor. Utile nei sistemi di orchestrazione per parametrizzare uno script già caricato con dati diversi (es. cliente diverso, pratica diversa) senza ricaricare l'intero file. Il body deve contenere coppie var nome="valore"; nel formato del blocco GLOBALV.API Logging — Panoramica
Ogni richiesta HTTP ricevuta dal server JuliuS viene registrata automaticamente come una riga JSON Lines nel file di log dell'applicazione. Il logging si appoggia all'unit synaLog (singleton globale thLog, scrittura asincrona con thread writer dedicato, rotazione automatica a 100 MB, archiviazione zip dei vecchi log con retention di 7 giorni). Il file di log è lo stesso usato dal motore di scripting (wLog), quindi richieste API e log di esecuzione script appaiono nella stessa sequenza temporale.
Formato di una riga di log
Campi presenti in ogni entry
| Campo | Descrizione |
|---|---|
| ts | Timestamp locale ISO 8601 con millisecondi |
| tag | Sempre "API" — distingue le righe API dagli altri log di sistema |
| reqId | ID a 8 caratteri (primi 8 hex di un GUID) per correlare entry/exit della stessa request |
| client | IP del chiamante (AContext.Binding.PeerIP) |
| method | Metodo HTTP (GET, POST) |
| uri | URI richiesto (sempre / per JuliuS, parametri in query string) |
| op | Operazione identificata: valore di ?operation= se presente, altrimenti dedotta da loadscript, globalv, navigate, evaljs, getresult, findelement, devtools |
| durMs | Durata della request in millisecondi (dal ricevimento alla composizione della risposta) |
| params | Oggetto con tutti i parametri query string e form |
| bodyBytes | (solo se logBodies=true e c'è body POST) — dimensione in byte del body |
| bodyPreview | (solo se logBodies=true) — anteprima testuale del body fino a maxBodyPreview caratteri, oppure <REDACTED> per operazioni sensibili |
| response | Anteprima della risposta troncata a maxBodyPreview caratteri, oppure <binary> se il content-type è image/* |
Operazioni sensibili (mascherate se maskSensitive=true)
Il body delle seguenti operazioni viene sostituito con <REDACTED> per evitare di scrivere su disco credenziali o dati personali contenuti nelle variabili globali, e per non far esplodere il log con script di grandi dimensioni:
POST /?operation=readscritpfromstream— body con sorgente script (potenzialmente MB)POST /?globalv=rewrite— body con variabili globali (potenzialmente credenziali)
Configurazione
I quattro toggle sono in Settings.Data.ApiLog e modificabili a caldo tramite setapilog senza riavviare il server:
| Parametro | Tipo | Default | Descrizione |
|---|---|---|---|
| Enabled | boolean | true | Master switch: se false, nessuna richiesta viene loggata |
| LogBodies | boolean | false | Se true, include bodyPreview e bodyBytes nelle entry |
| MaskSensitive | boolean | true | Se true, redact dei body di operazioni sensibili anche con LogBodies=true |
| MaxBodyPreview | integer | 500 | Caratteri massimi per bodyPreview e response |
jq, grep, importazione in Splunk/ELK. Esempio rapido per filtrare gli errori:grep '"response":"ERROR' app.log | jq -r '[.ts,.op,.response] | @tsv'Status del log
| Header risposta | Valore |
|---|---|
| Content-Type | application/json; charset=utf-8 |
Struttura risposta
Toggle a caldo
| Parametro | Valori | Descrizione |
|---|---|---|
| enabled | true / false / 1 / 0 | Master switch del log |
| logbodies | true / false | Logga body POST e response |
| masksensitive | true / false | Redact dei body di operazioni sensibili |
| maxpreview | intero > 0 | Caratteri massimi nelle anteprime |
Esempi
uSettings.pas → TApiLogSettings.Initialize.Leggi ultime righe
thLog, poi legge il file di log e restituisce le ultime N righe nel body della risposta come testo plain UTF-8. Il default è 200 righe, il limite massimo è 5000. Utile per debug remoto senza dover accedere al filesystem della macchina JuliuS, o per integrazione con cruscotti di monitoring.| Parametro | Default | Descrizione |
|---|---|---|
| lines | 200 | Numero di righe finali da restituire. Valori < 1 → 1, valori > 5000 → 5000. |
| Header risposta | Valore |
|---|---|
| Content-Type | text/plain; charset=utf-8 |
ERROR: thLog non attivo — il logger globale non è inizializzatoERROR: ... — file in uso esclusivo dal writer o I/O errorFlush a disco
thLog.FlushLog per scaricare immediatamente su disco tutte le righe ancora bufferizzate nel thread writer di synaLog. In condizioni normali il writer fa il flush automaticamente ogni 200 righe (se FdoFlush=true) o all'arresto del thread; questo endpoint serve quando si vuole garantire che il file su disco contenga tutto fino a quel momento, ad esempio prima di copiarlo via per analisi.flushedERROR: thLog non attivoERROR: ... — eccezione durante il flushForza rotazione
thLog.RequestRotate per innescare la rotazione manuale del file: thLog chiude il file corrente, lo rinomina con un nome unico e lo zippa in background tramite txtUtils.ZipAndDeleteAsync, poi apre un file nuovo e pulito. L'operazione è asincrona: il flag di rotazione viene impostato e processato dal thread Execute di thLog alla prossima iterazione, tipicamente entro un secondo. Indipendentemente da questa chiamata, la rotazione automatica per dimensione (default 100 MB, check ogni 30 secondi) resta sempre attiva.rotate_requested — flag impostato, il thread writer effettuerà la rotazioneERROR: thLog non attivorotateapilog per partire con un file fresco, eseguire i test, poi flushapilog e raccogliere il file di log "pulito" che contiene solo quella sessione.