RouterLogger è una semplice applicazione per la registrazione dello stato della connessione ADSL, che include implementazioni specifiche per i seguenti router:
- TP-Link TD-W8970 V1
- ASUS DSL-N12E
- ASUS DSL-N14U
- D-Link DSL-2750B
Il funzionamento è basato sull'interfaccia Telnet esposta dalla maggior parte dei modem router ADSL odierni, pertanto è possibile estendere l'applicazione in modo da farla lavorare con qualsiasi modem router disponga di una tale interfaccia che permetta di recuperare informazioni sullo stato della connessione.
Molti dispositivi hanno l'interfaccia Telnet disabilitata per impostazione predefinita, occorre pertanto abilitarla tramite configurazione web prima di poter utilizzare l'applicazione.
- scaricare la release adatta alla propria piattaforma, possibilmente la più recente;
- per Raspberry Pi scaricare la release
gtk-linux-armhf
;
- per Raspberry Pi scaricare la release
- installare (o scompattare, a seconda dei casi) il programma in una cartella a piacimento.
Per avviare l'applicazione è richiesto Java Runtime Environment (JRE) versione 6 (1.6) o successiva.
Al primo avvio sarà necessario accedere alla configurazione, scheda Router, per specificare il modello di router (Dispositivo/Classe Reader) e pochi altri parametri di connessione:
- Nome utente: username per accedere al router (normalmente è lo stesso usato per accedere all'interfaccia grafica tramite browser);
- Password: password per accedere al router (normalmente è la stessa usata per accedere all'interfaccia grafica tramite browser);
- Indirizzo: indirizzo IP del router (solitamente
192.168.0.1
oppure192.168.1.1
che è il valore predefinito); - Porta Telnet: porta Telnet del router (predefinita:
23
).
Una volta configurato, il programma si connetterà al router e inizierà a interrogarlo ciclicamente, memorizzando di volta in volta le informazioni sullo stato della connessione in una mappa chiave-valore, dove le chiavi sono i nomi (o etichette) dei parametri di funzionamento del modem router/linea ADSL. A ogni interrogazione, questa mappa viene rigenerata e il suo contenuto viene di norma aggiunto ad un file in formato CSV, ma è anche possibile configurare il salvataggio in una tabella di un database.
L'applicazione crea un file per ogni giornata, e a ogni iterazione corrisponde una riga nel file. Per attivare questo tipo di salvataggio non occorre configurare nulla: questa è la modalità predefinita.
Di norma i file generati vengono salvati in una sottocartella RouterLogger
all'interno della cartella Documenti
; per specificare una cartella diversa occorre accedere alla configurazione (menù Strumenti) e modificare la relativa opzione presente nella scheda Salvataggio > CSV.
L'applicazione crea una tabella per memorizzare i dati (se non presente), e a ogni iterazione corrisponde una riga nella tabella.
Per attivare il salvataggio su database, occorre innanzi tutto aggiungere la libreria JDBC del proprio database (ad es. ojdbc6.jar
nel caso di Oracle) all'interno della directory dropins
dell'applicazione, quindi accedere alla configurazione (menù Strumenti) e compilare le seguenti opzioni nella scheda Salvataggio > Database:
- Nome classe driver: nome completo della classe del driver JDBC (ad es.:
oracle.jdbc.OracleDriver
). - URL di connessione JDBC: URL per il collegamento al database (ad es.:
jdbc:oracle:thin:@localhost:1521:XE
). - Nome utente: nome utente per accedere al database.
- Password: password per accedere al database.
Infine, impostare la seguente opzione nella scheda Salvataggio:
- Destinazione/Classe Writer: Database
È disponibile un'opzione che consente di avviare l'applicazione in modalità riga di comando (senza interfaccia grafica):
- Windows:
routerlogger.bat -c
- Linux:
routerlogger.sh -c
- OS X:
routerlogger.command -c
In questo caso, prima del primo avvio, occorre modificare manualmente il file di configurazione routerlogger.cfg
con un editor di testo per attivare (rimuovendo il #
a inizio riga) e impostare le seguenti proprietà:
reader.class.name
= Uno traTpLink8970Reader
,AsusDslN12EReader
,AsusDslN14UReader
eDLinkDsl2750Reader
, a seconda del modello di dispositivo da monitorare;router.address
= indirizzo IP del router (solitamente192.168.0.1
oppure192.168.1.1
che è il valore predefinito);router.port
= porta Telnet del router (predefinita:23
);router.username
= nome utente per accedere al router (normalmente è lo stesso usato per accedere all'interfaccia grafica tramite browser);router.password
= password per accedere al router (normalmente è la stessa usata per accedere all'interfaccia grafica tramite browser).
Se si utilizza l'interfaccia grafica, è possibile accedere alla configurazione dal menù Strumenti > Configurazione. Utilizzando l'interfaccia a riga di comando, invece, occorre modificare manualmente il file routerlogger.cfg
con un editor di testo come Blocco note.
Il file routerlogger.cfg
fornito contiene già tutte le impostazioni dell'applicazione, e quasi tutte sono disabilitate per impostazione predefinita (chiave preceduta dal carattere #
). Il principio è il cosiddetto Convention Over Configuration (noto anche come Configuration by Exception), secondo il quale non occorre preoccuparsi di configurare nulla esplicitamente, fatta eccezione per pochi parametri per i quali non può esistere un valore predefinito; nel nostro caso si tratta esclusivamente delle credenziali di accesso del router e degli eventuali parametri di connessione al database.
Tutte le proprietà che non vengono configurate esplicitamente assumono un certo valore predefinito (default) che sarà specificato nei paragrafi seguenti. In caso di necessità, è possibile abilitare una o più impostazioni rimuovendo il carattere di commento #
presente all'inizio della relativa chiave e sostituendo il valore predefinito con quello desiderato. È altresì possibile ripulire il file routerlogger.cfg
rimuovendo completamente le righe ritenute inutili.
Segue una disamina di tutte le impostazioni disponibili, in aggiunta a quelle già viste per la configurazione di base. Le seguenti impostazioni sono tutte facoltative, salvo diversa indicazione.
logger.iterations
= numero di iterazioni da effettuare. Normalmente l'applicazione registra l'attività del modem per un tempo indefinito, ossia finché non viene chiusa dall'utente, ma è possibile indicare un numero di iterazioni massimo dopo il quale l'applicazione si chiuderà automaticamente. Valori minori o uguali a zero equivalgono a infinito (default:0
).logger.close.when.finished
= specifica se l'applicazione debba chiudersi automaticamente dopo l'ultima iterazione. Ininfluente se il numero di iterazioni è infinito (default:false
).
logger.interval.normal.ms
= intervallo tra le richieste di informazioni al modem in condizioni normali, in millisecondi (default:5000
ms). Valori inferiori a1000
potrebbero creare problemi di funzionamento del dispositivo o blocco dell'applicazione a causa dell'elevato numero di richieste.logger.interval.fast.ms
= intervallo tra le richieste di informazioni al modem in caso di raggiungimento di una o più soglie (cfr. par. soglie), in millisecondi (default:1000
ms). Valori inferiori a1000
potrebbero creare problemi di funzionamento del dispositivo o blocco dell'applicazione a causa dell'elevato numero di richieste.logger.hysteresis.ms
= intervallo di tempo durante il quale l'applicazione continua a registrare a frequenza accelerata (logger.interval.fast.ms
) anche dopo che un valore, che precedentemente aveva raggiunto una soglia, è rientrato nella norma, in millisecondi (default:10000
ms).logger.retry.count
= numero di tentativi di riavvio del ciclo da effettuare in caso di errore durante l'esecuzione (default:3
). Il contatore si azzera se il ciclo riparte con successo. Utile, ad esempio, in caso di riavvio del modem.logger.retry.interval.ms
= intervallo tra i tentativi di riavvio, in millisecondi (default:30000
ms).logger.error.log.destination.path
= percorso in cui saranno salvati eventuali file registro (.log
) contenenti i dettagli degli errori occorsi durante l'esecuzione del programma (default: stessa cartella del programma).language
= codice nazione (en
,it
, ...) che determina la lingua dell'interfaccia (default: lingua di sistema; se non disponibile:en
).
socket.timeout.ms
= timeout del socket in millisecondi, ossia il tempo di inattività massimo durante la comunicazione con il server, trascorso il quale si assume che la comunicazione si sia interrotta (default:30000
ms). Questo valore deve essere sempre maggiore dell'intervallo tra le richieste (logger.interval.normal.ms
).connection.timeout.ms
= timeout della connessione in millisecondi, ossia il tempo di attesa massimo in fase di connessione, trascorso il quale si assume che il server non sia raggiungibile (default:20000
ms).telnet.newline.characters
= specifica come inviare il comando di ritorno a capo al server; può assumere uno tra i seguenti valori:CRLF
(default): invia la coppia di caratteri di controlloCR
(0x0D
) eLF
(0x0A
) (\r\n
, stile DOS/Windows).LF
: invia il solo carattereLF
(0x0A
) (\n
, stile Linux/OS X).CR
: invia il solo carattereCR
(0x0D
) (\r
).
reader.log.connected
= specifica se registrare l'avvenuta connessione al router su file e via email (default:false
).reader.wait.disconnected
= specifica se disconnettersi dal router dopo ogni interrogazione. Normalmente l'applicazione resta sempre connessa al dispositivo, ma in caso di intervallo tra le richieste maggiore di alcuni secondi può essere opportuno abilitare questa opzione che forza una disconnessione e riconnessione ad ogni iterazione (default:false
).reader.wait.disconnected.interval.threshold
= disconnette solo se l'intervallo è superiore ad una certa soglia configurabile con la proprietàreader.wait.disconnected.interval.threshold.ms
(default:true
).reader.wait.disconnected.interval.threshold.ms
= l'intervallo minimo al di sotto del quale non viene effettuata la disconnessione, in millisecondi (default:1000
ms).
gui.table.items.max
= numero massimo di righe contenute nella tabella a video; al raggiungimento del limite, le righe più vecchie vengono cancellate. Questa impostazione non influisce in alcun modo sul salvataggio delle informazioni ma ha effetto unicamente sull'interfaccia grafica dell'applicazione (default:2000
, valori maggiori comportano una maggiore occupazione di memoria).gui.table.columns.pack
= riduce al minimo la larghezza delle colonne della tabella a video adattandola ai valori e ignorando la larghezza dei nomi delle chiavi in intestazione (default:false
).gui.table.columns.padding.right
= aggiunge un margine destro alle colonne della tabella a video; utile con alcuni ambienti grafici Linux. Il valore determina le dimensioni del margine (default:0
, ossia nessun margine).gui.minimize.tray
= specifica se l'applicazione deve essere ridotta a icona nell'area di notifica invece che nella barra delle applicazioni (default:true
).gui.start.minimized
= specifica se l'applicazione deve essere avviata già ridotta a icona (default:false
).gui.tray.tooltip
= specifica se deve essere mostrato un avviso nell'area di notifica in caso di raggiungimento di una soglia (default:true
).gui.confirm.close
= specifica se deve essere mostrato un messaggio di conferma quando si tenta di chiudere l'applicazione (default:false
).gui.console.max.chars
= dimensione massima della console, in caratteri; la console viene automaticamente ripulita al raggiungimento della soglia per limitare l'utilizzo di memoria (default:50000
caratteri).gui.important.keys
= elenco, separato da delimitatore, dei nomi delle chiavi i cui valori saranno evidenziati nella tabella (default: vuoto). Gli stessi valori saranno mostrati anche nel suggerimento che compare soffermandosi con il mouse sull'eventuale icona di RouterLogger nell'area di notifica.gui.important.keys.separator
= delimitatore (o espressione regolare) usato per separare i nomi delle chiavi specificate nella proprietàgui.important.keys
(default:,
). Scegliere un delimitatore che non contenga sequenze di caratteri presenti anche nei nomi delle chiavi.gui.clipboard.max.chars
= dimensione massima degli appunti, in caratteri. (default:100000
caratteri). In ambiente Linux/GTK, non impostare mai valori superiori a131072
(128 KiB), in caso contrario potrebbero verificarsi problemi dovuti all'esaurimento della memoria.gui.important.keys.color
= codice RGB del colore di evidenziazione delle colonne della tabella (default:255,255,0
, ossia giallo).gui.thresholds.reached.color
= codice RGB del colore dei valori oltre soglia in tabella (default:255,0,0
ossia rosso).
console.animation
= specifica se si desidera visualizzare una piccola animazione in console che segnala il funzionamento dell'applicazione (default:true
).console.show.configuration
= specifica se si desidera visualizzare l'elenco delle proprietà attive delrouterlogger.cfg
all'avvio dell'applicazione (default:false
).console.show.keys
= elenco, separato da delimitatore, dei nomi delle chiavi i cui valori devono essere visualizzati in console a ogni iterazione (default: vuoto). Un eccessivo numero di chiavi da visualizzare provocherà lo scorrimento verticale della console, un effetto collaterale probabilmente indesiderato.console.show.keys.separator
= delimitatore (o espressione regolare) usato per separare i nomi delle chiavi specificate nella proprietàconsole.show.keys
(default:,
). Scegliere un delimitatore che non contenga sequenze di caratteri presenti anche nei nomi delle chiavi.console.debug
= in caso di errore, stampa messaggi dettagliati (default:false
).
La selezione del modello di modem router da interrogare si effettua configurando nel routerlogger.cfg
la seguente proprietà:
reader.class.name
= identifica la classe che si occupa di ricavare dallo specifico modello di modem router le informazioni sullo stato della connessione tramite Telnet, e può assumere i valori seguenti:TpLink8970Reader
: lettura informazioni dal router TP-Link TD-W8970 V1.AsusDslN12EReader
: lettura informazioni dal router ASUS DSL-N12E.AsusDslN14UReader
: lettura informazioni dal router ASUS DSL-N14U.DLinkDsl2750Reader
: lettura informazioni dal router D-Link DSL-2750B.DummyReader
: generazione di dati casuali (nessuna connessione né lettura da alcun dispositivo), da usarsi solo a scopo di test.- nome completo (inclusi tutti i package separati da
.
) di una classe concreta che estendaReader
. Per maggiori informazioni, vedere il paragrafo Supporto di altri modelli di router.
tplink.8970.command.info.adsl
: comando da inviare al router per ottenere informazioni sullo stato della portante ADSL (default:adsl show info
).tplink.8970.command.info.wan
: comando da inviare al router per ottenere informazioni sullo stato della connessione ad Internet (default: non valorizzato, di conseguenza non vengono estratte queste informazioni).
asus.dsln12e.command.info.adsl
: comando da inviare al router per ottenere informazioni sullo stato della portante ADSL (default:show wan adsl
).asus.dsln12e.command.info.wan
: comando da inviare al router per ottenere informazioni sullo stato della connessione ad Internet (default:show wan interface
).
asus.dsln14u.command.info.adsl
: comando da inviare al router per ottenere informazioni sullo stato della portante ADSL (default:tcapi show Info_Adsl
).asus.dsln14u.command.info.wan
: comando da inviare al router per ottenere informazioni sullo stato della connessione ad Internet (default: non valorizzato, di conseguenza non vengono estratte queste informazioni).
dlink.2750.command.info.adsl.status
: comando da inviare al router per ottenere informazioni sullo stato della portante ADSL (Up/Down) (default:adsl status
).dlink.2750.command.info.adsl.snr
: comando da inviare al router per ottenere informazioni sul rapporto segnale/rumore della linea ADSL (default:adsl snr
).
La selezione della modalità di salvataggio delle informazioni si effettua configurando la seguente proprietà:
writer.class.name
: identifica la classe che si occupa del salvataggio delle informazioni, e può assumere i valori seguenti:CsvWriter
: scrittura su file CSV (default).DatabaseWriter
: scrittura su database.DummyWriter
: nessuna scrittura (utile a scopo di test).- nome completo (inclusi tutti i package separati da
.
) di una classe concreta che estendaWriter
. Per maggiori informazioni, vedere il paragrafo Modalità di salvataggio alternative.
csv.destination.path
= percorso in cui saranno salvati i file CSV generati (default: directory dell'applicazione).csv.newline.characters
= specifica come deve essere rappresentato il ritorno a capo nei file CSV generati. Se questa proprietà non è presente (o è commentata), viene utilizzata la rappresentazione specifica della piattaforma su cui si esegue l'applicazione. La proprietà può assumere uno tra i seguenti valori:CRLF
: scrive la coppia di caratteri di controlloCR
(0x0D
) eLF
(0x0A
) (\r\n
, stile DOS/Windows).LF
: scrive il solo carattereLF
(0x0A
) (\n
, stile Linux/OS X).CR
: scrive il solo carattereCR
(0x0D
) (\r
).
csv.field.separator
= separatore dei campi utilizzato nei file CSV generati (default:;
, compatibile con Microsoft Excel).csv.field.separator.replacement
= poiché il testo da scrivere nei file CSV non deve mai contenere il separatore, tutte le eventuali occorrenze del separatore saranno sostituite da questa stringa (default:,
).
database.driver.class.name
= nome completo della classe del driver JDBC (ad es.:oracle.jdbc.OracleDriver
).database.url
= URL per il collegamento al database (ad es.:jdbc:oracle:thin:@localhost:1521:XE
).database.username
= nome utente per accedere al database.database.password
= password per accedere al database.database.table.name
= nome della tabella in cui saranno inseriti i dati (default:router_log
).database.connection.validation.timeout.ms
= tempo di attesa massimo su richiesta di verifica della validità della connessione al database, in millisecondi (default:2000
ms).database.timestamp.column.type
= tipo di dato utilizzato per la colonna del timestamp in fase di creazione della tabella (default:TIMESTAMP
).database.response.column.type
= tipo di dato utilizzato per la colonna del response_time_ms in fase di creazione della tabella (default:INTEGER
).database.info.column.type
= tipo di dato utilizzato per tutte le altre colonne in fase di creazione della tabella (default:VARCHAR(250)
).database.column.name.prefix
= prefisso per i nomi delle colonne della tabella (default:rl_
).database.column.name.max.length
= lunghezza massima dei nomi delle colonne, superata la quale il nome viene troncato (default:30
).
Le soglie permettono di specificare dei valori limite per uno o più parametri di funzionamento del dispositivo; lo scopo è di poter incrementare la frequenza di interrogazione nelle situazioni critiche, in modo da aggiungere informazioni che potrebbero essere utili per la diagnosi di eventuali problemi della linea.
Nel caso delle linee ADSL, ad esempio, un parametro che determina la stabilità della connessione e che può essere soggetto ad ampie e talvolta repentine variazioni, è il rapporto segnale-rumore (SNR). Utilizzando le soglie è possibile fare in modo che la frequenza di registrazione dei dati venga incrementata quando il valore del SNR scende al di sotto di una certa soglia.
Quando una soglia viene raggiunta, il periodo di registrazione passa da quello normale, definito dalla proprietà logger.interval.normal.ms
(default 5 secondi), a quello definito dalla proprietà logger.interval.fast.ms
(default un secondo).
Ogni soglia è costituita da una proprietà nel file routerlogger.cfg
definita come segue:
threshold.identificativo.univoco.soglia
= chiave operatore valore
dove:
- chiave: chiave del parametro di interesse; deve corrispondere ad una chiave presente nella mappa delle informazioni estratte.
- operatore: operatore relazionale (di confronto) che determina la condizione di raggiungimento:
lt
(oppure<
): minore di...le
(oppure<=
): minore o uguale a...eq
(oppure=
,==
): uguale a...ge
(oppure>=
): maggiore o uguale a...gt
(oppure>
): maggiore di...ne
(oppure<>
,!=
,^=
): diverso da...
- valore: valore di soglia.
Il prefisso threshold.
è obbligatorio perché segnala all'applicazione che la proprietà riguarda una soglia.
L'identificativo univoco soglia può essere un qualsiasi testo senza spazi né carattere =
.
Aggiungendo la riga seguente al file routerlogger.cfg
, si imposterà una soglia di 10.0 dB per il SNR; qualora il valore del SNR dovesse scendere al di sotto di 10.0 dB, la frequenza (o, più precisamente, il periodo) di logging passerebbe da 5000 a 1000 millisecondi.
threshold.snr.down=downstreamNoiseMargin lt 100
Può capitare che, al raggiungimento di una o più soglie specifiche, non si desideri incrementare la frequenza di registrazione né ricevere eventuali segnalazioni via email; il caso tipico è quello della velocità di downstream agganciata, che in alcuni casi potrebbe essere inferiore al normale. In questi casi può comunque risultare utile un avviso nell'area di notifica e una particolare evidenziazione nella tabella a video (solo versione con interfaccia grafica), come normalmente avviene quando una soglia viene raggiunta. Per ottenere questo comportamento, valorizzare opportunamente le seguenti proprietà nel file routerlogger.cfg
:
thresholds.excluded
= elenco, separato da delimitatore, degli identificativi univoci delle soglie per le quali, al raggiungimento, non si desidera né l'incremento della frequenza di registrazione, né l'invio di segnalazioni via email.thresholds.excluded.separator
= delimitatore (o espressione regolare) usato per separare gli identificativi univoci delle soglie specificati nella proprietàthresholds.excluded
(default:,
). Scegliere un delimitatore che non contenga sequenze di caratteri presenti anche negli identificativi delle soglie.
È possibile configurare RouterLogger in modo che invii comunicazioni via email. Questa funzionalità è particolarmente utile se si esegue il programma in un dispositivo dedicato o comunque non presidiato, come un Raspberry Pi.
In particolare si possono configurare i seguenti invii:
log.email
= invia una segnalazione per ogni errore che si verifica durante l'esecuzione del programma. Se la connessione non fosse disponibile al momento, ritenta periodicamente l'invio (default:false
).log.email.ignore.duplicates
= evita l'invio di messaggi duplicati causati da eccezione persistente, ad esempio quando il programma non riesce a connettersi al router perché spento (default:true
).
csv.email
= invia i file CSV delle giornate precedenti, compressi in formato ZIP, uno per messaggio. Funziona solo se si imposta il salvataggio in formato CSV (default:false
). A regime viene inviata un'email al giorno, ma alla prima attivazione vengono inviati tutti i file CSV presenti nella cartella di destinazione dei CSV, può quindi essere il caso di spostarli altrove o comprimerli prima di attivare questa opzione. I file inviati con successo vengono mantenuti in formato ZIP nella cartella di destinazione dei CSV (i relativi CSV non compressi vengono invece cancellati dopo l'invio per risparmiare spazio di archiviazione).thresholds.email
= invia una segnalazione quando vengono raggiunte una o più soglie (default:false
). Per evitare l'invio di un numero eccessivo di messaggi, è disponibile la seguente proprietà:thresholds.email.send.interval.secs
= intervallo, in secondi, tra gli invii delle email relative al raggiungimento delle soglie. Le email conterranno tutti i dettagli sulle soglie raggiunte nell'intervallo (default:3600
secondi).thresholds.email.max.items
= numero massimo di segnalazioni che possono essere incluse in un singolo messaggio (default:50
). Valori eccessivi possono causare l'invio di email voluminose e un'elevata occupazione di memoria.
Per consentire l'invio delle email occorre avere un account di posta elettronica e configurare i parametri presenti nella sezione Email della configurazione, identificati dalle seguenti chiavi di configurazione:
email.host
= indirizzo del server SMTP da utilizzare per l'invio delle email.email.username
= nome utente per l'autenticazione al server SMTP.email.password
= password per l'autenticazione al server SMTP.email.from.name
= nome da utilizzare come mittente.email.from.address
= indirizzo email da utilizzare come mittente.email.to.addresses
= indirizzi email dei destinatari "A" (separati da virgola).email.cc.addresses
= indirizzi email dei destinatari "Cc" (separati da virgola).email.bcc.addresses
= indirizzi email dei destinatari "Ccn" (separati da virgola).email.ssl.connect
= specifica se utilizzare la connessione sicura SSL (default:false
).email.port
= porta SMTP del server (default:25
).email.ssl.port
= porta SMTP SSL del server (default:465
).email.ssl.identity
= specifica se effettuare il controllo di identità del server secondo l'RFC 2595 (default:false
).email.starttls.enabled
= abilita l'uso del comando STARTTLS (default:false
).email.starttls.required
= richiede l'uso del comando STARTTLS (default:false
).email.send.interval.secs
= intervallo, in secondi, tra i tentativi di invio dei messaggi in caso di problemi (default:60
secondi).email.connection.timeout
= timeout in fase di connessione al server SMTP (default:60000
ms).email.socket.timeout
= timeout della connessione al server SMTP, una volta stabilita (default:60000
ms).email.max.sendings.per.cycle
= numero massimo di email che possono essere inviate contemporaneamente (default:3
). Un valore eccessivo potrebbe far scattare il blocco dell'account utilizzato per l'invio per sospetto spamming. I messaggi non inviati saranno comunque man mano inviati ai successivi tentativi, intervallati come da proprietàemail.send.interval.secs
.email.max.queue.size
= dimensione massima della coda delle email (default:10
messaggi). Quando un messaggio non può essere inviato per assenza di rete o per superamento del numero massimo di email che possono essere inviate contemporaneamente, esso viene messo in una coda. Valori eccessivi possono causare un'elevata occupazione di memoria.
L'invio funziona senza problemi con Gmail, a patto di consentire l'accesso alle applicazioni "meno sicure"; per questo motivo è consigliabile creare un account dedicato a RouterLogger.
RouterLogger può esporre una semplice interfaccia web che consente di:
- visualizzare lo stato della connessione ad Internet;
- riavviare l'applicazione;
- connettere l'applicazione al server Telnet del router;
- disconnettere l'applicazione dal server Telnet del router;
- chiudere l'applicazione.
Per attivare e configurare il server web sono disponibili le seguenti opzioni:
server.enabled
= abilita il server web (default:false
).server.authentication
= richiede autenticazione con nome utente e password per l'accesso all'interfaccia web. Per motivi di sicurezza, questa opzione dovrebbe essere mantenuta sempre attiva (default:true
).server.username
= nome utente per l'accesso all'interfaccia web.server.password
= password per l'accesso all'interfaccia web.
server.port
= porta del server web (default:8080
).server.compress.response
= abilita la compressione dati, quando possibile (default:false
).server.handler.root.enabled
= abilita la pagina Home (default:true
).server.handler.close.enabled
= abilita la funzione Chiudi (default:false
).server.handler.connect.enabled
= abilita la funzione Connetti (default:false
).server.handler.disconnect.enabled
= abilita la funzione Disconnetti (default:false
).server.handler.restart.enabled
= abilita la funzione Riavvia (default:false
).server.handler.status.enabled
= abilita la funzione Stato (default:true
).server.handler.status.refresh
= aggiorna automaticamente la pagina Stato inserendo l'header HTTP Refresh (default:false
).server.handler.status.refresh.secs
= intervallo di aggiornamento della pagina Stato, in secondi (default:5
).server.handler.json.enabled
= abilita le risorse JSON (default:true
).server.handler.json.refresh
= aggiorna automaticamente le risorse JSON inserendo l'header HTTP Refresh (default:true
).server.handler.json.refresh.secs
= ntervallo di aggiornamento delle risorse JSON, in secondi (default:0
, ossia autodetermina).server.log.request
= regola il livello di registrazione delle richieste HTTP ricevute dall'applicazione. La proprietà può assumere uno tra i seguenti valori:0
: nessuna registrazione.1
: registrazione nel registro a video (default).2
: registrazione su file.3
: registrazione nel registro a video e su file.
server.threads
= numero di thread dedicati alla gestione delle richieste HTTP. Benché valori inferiori o uguali al numero di thread del processore possano garantire una risposta più pronta da parte del server, valori eccessivi possono provocare grave degrado prestazionale (default:1
).
Per aumentare il livello di sicurezza della comunicazione con RouterLogger, è possibile abilitare il protocollo di comunicazione sicura HTTPS. Questa funzione richiede la presenza di un certificato SSL sul sistema che esegue l'applicazione. Per creare un certificato SSL in modo semplice e veloce, è possibile utilizzare il comando keytool, che prevede una sintassi del seguente tipo:
keytool -genkey -alias "myalias" -keyalg "RSA" -keypass "mykeypass" -keystore "mykeystore.jks" -storepass "mystorepass" -validity 365
Volendo invece utilizzare OpenSSL, una possibile sequenza di comandi è la seguente:
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
openssl pkcs12 -export -out mykeystore.pfx -inkey server.key -in server.crt
È caldamente consigliato mantenere sempre aggiornata l'installazione di Java per garantire i più elevati livelli di sicurezza disponibili. Molti browser bloccano le connessioni con i server che non rispettano dei criteri minimi di sicurezza, e questi criteri vengono periodicamente rivisti.
La configurazione del protocollo HTTPS si effettua mediante le seguenti proprietà:
server.ssl.enabled
= Abilita il protocollo di comunicazione sicura HTTPS (default:false
).server.ssl.keystore.file
= Puntamento al file keystore (prodotto da keytool o OpenSSL).server.ssl.storepass
= Password keystore (storepass
).server.ssl.keypass
= Password chiave privata (keypass
).
Le seguenti proprietà consentono di personalizzare ulteriormente la configurazione della connessione sicura:
server.ssl.keystore.type
= Tipo diKeyStore
(default:JKS
).server.ssl.kmf.algorithm
= Algoritmo utilizzato daKeyManagerFactory
(default: dipendente dalla piattaforma).server.ssl.tmf.algorithm
= Algoritmo utilizzato daTrustManagerFactory
(default: dipendente dalla piattaforma).server.ssl.protocol
= Protocollo SSL utilizzato (default:TLS
).
RouterLogger può collegarsi ad un server (broker) MQTT per inviare messaggi JSON sullo stato della connessione e del programma stesso. Per attivare e configurare il client MQTT sono disponibili le seguenti opzioni:
mqtt.enabled
= abilita il client MQTT (default:false
).mqtt.server.uri
= elenco, separato da|
, delle URI di collegamento al server MQTT. Tipicamente è sufficiente inserire un unico valore (es.tcp://192.168.1.100:1883
).mqtt.username
= nome utente per la connessione al server MQTT (se richiesto dal server).mqtt.password
= password per la connessione al server MQTT (se richiesta dal server).mqtt.clean.session
= se attiva, questa opzione disabilita la persistenza della sessione del client. Questa opzione dovrebbe essere mantenuta sempre attiva, in quanto RouterLogger si limita a pubblicare messaggi (default:true
).mqtt.automatic.reconnect
= specifica se tentare automaticamente la riconnessione in caso di disconnessione dovuta a problemi di rete (default:true
).mqtt.connect.retry
= specifica se ritentare automaticamente la connessione in caso di problemi di comunicazione (default:true
).mqtt.client.id
= identificativo univoco del client (default:RouterLogger
).mqtt.connection.timeout
= timeout della connessione in secondi, ossia il tempo di attesa massimo in fase di connessione, trascorso il quale si assume che il server non sia raggiungibile (default:30
secondi).mqtt.keep.alive.interval
= tempo di inattività massimo durante la comunicazione con il server, in secondi, trascorso il quale si assume che la comunicazione si sia interrotta (default:60
secondi).mqtt.max.inflight
= numero massimo di messaggi in transito (default:10
).mqtt.version
= versione del protocollo MQTT. La proprietà può assumere uno tra i seguenti valori:0
: se possibile 3.1.1, in caso contrario 3.1 (default).3
: 3.1.4
: 3.1.1.
mqtt.persistence.file.enabled
= abilita la persistenza su file dei messaggi in transito con QoS 1 o 2. Se questa opzione è disattivata, i messaggi vengono mantenuti in memoria e quindi vengono persi in caso di arresto dell'applicazione (default:false
).mqtt.persistence.file.custom
= abilita la selezione di un percorso specifico per la persistenza dei messaggi in transito (default:false
).mqtt.persistence.file.path
= directory di base per la persistenza dei messaggi in transito (default: directory da cui è stato avviato il programma).mqtt.data.enabled
= abilita la pubblicazione dei messaggi contenenti le informazioni sulla connessione (default:true
).mqtt.data.topic
= topic (argomento) dei messaggi contenenti le informazioni sulla connessione (default:router/logger/data
).mqtt.data.qos
= Livello QoS dei messaggi contenenti le informazioni sulla connessione (default:0
).mqtt.data.retained
= specifica se l'ultimo messaggio contenente le informazioni sulla connessione deve essere mantenuto sul server (default:true
).mqtt.data.throttling.ms
= intervallo minimo tra l'invio dei messaggi contenenti le informazioni sulla connessione. Di norma viene inviato un messaggio per ogni iterazione, ma può essere utile impostare questo valore per evitare un sovraccarico dei client riceventi o del broker (default0
, ossia nessun intervallo minimo).mqtt.status.enabled
= abilita la pubblicazione dei messaggi contenenti lo stato dell'applicazione (default:true
).mqtt.status.topic
= topic (argomento) dei messaggi contenenti lo stato dell'applicazione (default:router/logger/status
).mqtt.status.qos
= Livello QoS dei messaggi contenenti lo stato dell'applicazione (default:2
).mqtt.status.retained
= specifica se l'ultimo messaggio contenente lo stato dell'applicazione deve essere mantenuto sul server (default:true
).mqtt.thresholds.enabled
= abilita la pubblicazione dei messaggi contenenti le soglie raggiunte (default:true
).mqtt.thresholds.topic
= topic (argomento) dei messaggi contenenti le soglie raggiunte (default:router/logger/data
).mqtt.thresholds.qos
= Livello QoS dei messaggi contenenti le soglie raggiunte (default:0
).mqtt.thresholds.retained
= specifica se l'ultimo messaggio contenente le soglie raggiunte deve essere mantenuto sul server (default:true
).mqtt.thresholds.throttling.ms
= intervallo minimo tra l'invio dei messaggi contenenti le raggiunte. Di norma viene inviato un messaggio per ogni iterazione in cui risulta raggiunta almeno una soglia non esclusa, ma può essere utile impostare questo valore per evitare un sovraccarico dei client riceventi o del broker, anche in ragione del fatto che quando viene raggiunta una soglia, tipicamente la frequenza di interrogazione aumenta (default0
, ossia nessun intervallo minimo).
È possibile estendere l'applicazione in modo da farla lavorare con qualsiasi modem router disponga di un'interfaccia Telnet che permetta di recuperare informazioni sullo stato della connessione. Per farlo, è sufficiente implementare una classe personalizzata che estenda la classe astratta Reader
.
I metodi da implementare tassativamente sono i seguenti:
login
: effettua l'autenticazione al server Telnet comunicando le credenziali di accesso che, per semplicità, vengono preventivamente lette dal filerouterlogger.cfg
e rese disponibili direttamente nel metodo sotto forma di parametriusername
epassword
.readInfo
: interagisce con il server in modo da ottenere le informazioni sulla connessione ADSL e le restituisce sotto forma di mappa chiave-valore.
All'occorrenza può essere opportuno sovrascrivere anche i seguenti metodi, che non sono dichiarati abstract
in Reader
:
logout
: invia il comando di logout al server; l'implementazione predefinita inviaexit
, ma alcuni router possono richiedere un comando diverso, ad esempiologout
, pertanto in questi casi il metodo deve essere opportunamente sovrascritto.getDeviceModel
: restituisce una stringa contenente marca e modello del router (utile solo in visualizzazione); l'implementazione predefinita restituisce il nome della classe in esecuzione (senza package).release
: libera risorse eventualmente allocate dalReader
, ad esempio file o connessioni a database. Normalmente non necessario.
La classe astratta
Reader
dispone di alcuni metodi di utilità che permettono di interagire agevolmente con il server Telnet e che possono essere quindi utilizzati, oltre che sovrascritti, in caso di necessità; in particolare:
readFromTelnet(...)
: legge l'output del server Telnet e lo restituisce come stringa.writeToTelnet(...)
: invia comandi al server Telnet.
È inoltre possibile accedere alle proprietà di configurazione (
routerlogger.cfg
) tramite la variabileconfiguration
dichiarataprotected
nella classeReader
.
Per maggiori informazioni è possibile consultare la documentazione Javadoc inclusa nel codice sorgente.
Occorrerà quindi configurare l'applicazione in modo che faccia uso della classe realizzata modificando il file routerlogger.cfg
e specificando come proprietà reader.class.name
il nome completo della classe (inclusi tutti i package separati da .
). Sarà inoltre necessario copiare nella directory dropins
dell'applicazione il JAR aggiuntivo contenente la classe esterna, in modo che sia aggiunta automaticamente al classpath.
Nel caso in cui si volessero salvare le informazioni in formato diverso da CSV o database SQL, si può estendere la classe astratta Writer
e sarà ovviamente necessario implementare i due metodi seguenti:
saveInfo
: effettua il salvataggio delle informazioni ottenute, con le modalità desiderate.release
: libera risorse eventualmente allocate dalWriter
, ad esempio file o connessioni a database.
È possibile accedere alle proprietà di configurazione (
routerlogger.cfg
) tramite la variabileconfiguration
dichiarataprotected
nella classeWriter
.
Occorrerà quindi configurare l'applicazione in modo che faccia uso della classe realizzata modificando il file routerlogger.cfg
e specificando come proprietà writer.class.name
il nome completo della classe (inclusi tutti i package separati da .
). Sarà inoltre necessario copiare nella directory dropins
dell'applicazione il JAR aggiuntivo contenente la classe esterna, in modo che quest'ultima sia aggiunta automaticamente al classpath.
Quest'applicazione include componenti realizzati da Apache Software Foundation e da Eclipse Foundation.
L'icona dell'applicazione è stata realizzata da Pedram Pourang (licenza GPL) e prelevata da DeviantArt.