Funzioni ed FB supporto log (eLLabLogLib)¶
Questa libreria rende disponibili una serie di funzioni e di blocchi funzione per la gestione di logs.
Gestione invio notifiche a server Syslog¶
SYSLOG (System Log) è un protocollo appartenente alla Suite di protocolli Internet utilizzato per trasmettere attraverso una rete semplici informazioni di log. Il protocollo è stato standardizzato dall’ IETF.
Generalmente viene utilizzato via UDP attraverso la porta 514; in particolari applicazioni dove il monitoraggio è fondamentale oppure certi eventi possono innescare azioni da parte del server SYSLOG, si ricorre ad implementazioni TCP e/o a crittografia.
Il client invia un certo messaggio di testo, al massimo 1024 caratteri, al server, comunemente definito come «syslogd», «syslog daemon» o «syslog server». La semplicità del protocollo fa sì che il server possa gestire messaggi provenienti da una variegata tipologia di macchine, da computer, stampanti, dispositivi di rete, macchinari, ecc. Il server può limitarsi a registrare l’evento, per avere un archivio centrale degli avvenimenti, oppure reagire a particolari livelli di severità chiamando programmi, inviando e-mail, ecc. ecc.
Un messaggio di notifica inviato al server Syslog inizia con un indicatore di impianto Facility e di gravità Severity. Di seguito tabelle con indicazione dei codici assegnati.
Facility codes | |
0 | Kernel messages |
1 | User-level messages |
2 | Mail system |
3 | System daemons |
4 | Security/authorization messages |
5 | Messages generated internally by syslogd |
6 | Line printer subsystem |
7 | Network news subsystem |
8 | UUCP subsystem |
9 | Clock daemon |
10 | Security/authorization messages |
11 | FTP daemon |
12 | NTP subsystem |
Severity codes | |
0 | Emergencies Sistema inutilizzabile |
1 | Alerts Richiede intervento immediato |
2 | Critical Condizioni critiche |
3 | Errors Condizione d’errore |
4 | Warnings Condizioni di warning |
5 | Notifications Condizioni di anomalia non critici (bugs) |
6 | Informational Messaggi informativi |
7 | Debugging Messaggi di debug |
Il messaggio prosegue poi con l’indicazione di data e ora, del nome del dispositivo che ha inviato il messaggio Hostname ed il testo del messaggio Message.
Server Syslog
Un server SYSLOG è un punto centrale dove far arrivare tutti i messaggi di errore dei vari apparati hardware e software di una rete quali router, switch, server, stampanti ecc… per avere un controllo centralizzato degli errori degli apparati.
SYSLOG è particolarmente diffuso in unix e conseguentemente sotto linux, in ambiente windows esistono programmi freeware e/o a pagamento per la gestione del server. Il server può selezionare (filtrare) i messaggi in arrivo in base a diversi criteri, ad ogni selezione corrisponde almeno una azione.
In pratica si tratta di stabilire dei criteri di selezione e l’azione da intraprendere in funzione della provenienza e tipo di messaggio
Il criterio di selezione può essere ad esempio:
Priorità, Indirizzo IP del mittente del messaggio, Nome del Host, Testo (o parte di esso) del messaggio, Intervallo di tempo di uno o più giorni della settimana.
Le azioni possono essere ad esempio:
Nessuna (ignorare il messaggio), Visualizzarlo nel programma di monitoraggio, Inviarlo ad un altro Syslog server, Emettere un suono di allarme, Eseguire un programma, Inviare un E-mail, Memorizzare il messaggio in un Database (esempio MySQL), Memorizzare il messaggio in un logfile, Eseguire uno script, ecc…
Per le mie necessità ho utilizzato Syslog Watcher (Sito http://www.snmpsoft.com), un ottimo programma gratuito, di seguito uno screenshot con la visualizzazione di notifiche inviate da un sistema SlimLine.
Come si vede le varie notifiche sono suddivise con colori in base alla loro importanza e nel testo del messaggio è possibile riportare qualsiasi informazione ad esempio il codice operatore che ha avuto accesso all’ingresso rilevato da un lettore RFID.
SysLogReport, send a report to Syslog server¶
Type | Library |
---|---|
FB | eLLabLogLib_B000 |
Questo blocco funzione esegue l’invio di messaggi di notifica ad un server Syslog il cui indirizzo IP è definito in SyslogIP e la porta in SyslogPort. Questo è un blocco funzione protetto per utilizzarlo occorre richiedere il codice di protezione, vedi protezione funzioni e blocchi funzione. E” comunque possibile utilizzarlo liberamente in modo test per 30 Min.
E” possibile impostare sia il codice di impianto Facility che di gravità Severity oltre al nome del sistema host Hostname.
Attivando l’ingresso Send viene inviata la notifica al server Syslog, eseguito l’invio viene attivata per un loop l’uscita Done, in caso di errore esecuzione viene attivata per un loop l’uscita Fault.
Enable (BOOL) | Comando di abilitazione blocco funzione. |
Send (BOOL) | Comando di invio notifica. |
Mode (USINT) | Modo operativo, 0:UDP. |
SyslogIP (STRING[16]) | Indirizzo IP server Syslog |
SyslogPort (UINT) | Porta utilizzata dal server Syslog. |
Facility (USINT) | Codice impianto. |
Severity (USINT) | Codice gravità. |
HostName (STRING[32]) | Nome sistema che invia il messaggio di notifica. |
Message (STRING[160]) | Testo descrittivo del messaggio di notifica. |
Enabled (BOOL) | Attivo su abilitazione blocco funzione. |
Done (BOOL) | Attivo per un loop al termine dell’invio del messaggio di notifica. |
Fault (BOOL) | Attivo per un loop su errore esecuzione del comando. |
Codici di errore
In caso di errore si attiva l’uscita Fault, con SysGetLastError è possibile rilevare il codice di errore.
10034020 | FB protetta, terminato tempo funzionamento in modo demo. |
10034080 | FB usata in task diversa da Back. |
10034100 | Server Syslog non raggiungibile, il server non risponde al ping. |
Esempi¶
Nel seguente esempio, utilizzando i due ingressi del modulo CPU è possibile eseguire l’invio di un messaggio di notifica al server Syslog con IP 192.168.0.81 sulla porta 514 in UDP.
Definizione variabili
Esempio LD (PTP136A000, LD_SysLogReport)
StringToLogFile_v1, salva una stringa in un file di log¶
Type | Library |
---|---|
FB | eLLabLogLib_B100 |
Questo blocco funzione (Può essere utilizzato come una funzione, ha esecuzione atomica) effettua il log della stringa StringToLog nel file su disco di nome Filename. Ogni riga viene terminata con CR-LF. Al raggiungimento di MaxRowsInFile righe nel file, se Circular è settato, si riprende a salvare dall’inizio del file sovrascrivendo le righe già presenti. Se Circular non è settato non viene più effettuato il log segnalando errore. La variabile MaxRowsLen permette di limitare la lunghezza massima di ciascuna riga presente nel file di log.
Se Circular è settato se la lunghezza di StringToLog è inferiore a MaxRowsLen, vengono aggiunti degli spazi sino ad avere lunghezza definita. In RowIndexPtr occorre inserire l’indirizzo della variabile usata come indice della successiva riga in cui fare log. Normalmente deve essere una variabile tamponata per permettere di scrivere nel punto giusto anche dopo uno spegnimento-accensione del sistema. Se invece non si usa una variabile tamponata, ad ogni spegnimento-accensione, si ripartirà a scrivere dall’inizio del file. Quindi si può scegliere il comportamento voluto.
Questo è un blocco funzione protetto. Per utilizzarlo occorre richiedere il codice di protezione, vedi protezione funzioni e blocchi funzione. E” comunque possibile utilizzarlo liberamente in modo test per 30 Min.
Attivando l’ingresso Write viene salvata su disco la stringa StringToLog. Eseguito il salvataggio, viene attivata per un loop l’uscita Done. In caso di errore esecuzione viene attivata per un loop l’uscita Fault.
Enable (BOOL) | Comando di abilitazione blocco funzione. |
Write (BOOL) | Comando di scrittura di StringToLog nel file. |
StringToLog (@USINT) | Puntatore a stringa di cui fare log. |
Filename (STRING[32]) | Percorso e nome del file in cui fare log (es.: “SDCard/MyFile.txt”). |
Circular (BOOL) | Indica se effettuare il riporto circolare delle righe di log. |
MaxRowLen (USINT) | Numero massimo di caratteri riga file di log. Se stringa più lunga viene troncata. |
MaxRowsInFile (UDINT) | Numero massimo di righe nel file. |
RowIndexPtr (@UDINT) | Pointer alla variabile usata come indice della successiva riga di log. |
Enabled (BOOL) | Attivo su abilitazione blocco funzione. |
Done (BOOL) | Attivo per un loop se la scrittura nel file è riuscita. |
Fault (BOOL) | Attivo per un loop su errore esecuzione del comando. |
Codici di errore
In caso di errore si attiva l’uscita Fault e con SysGetLastError è possibile rilevare il codice di errore.
10035020 | FB protetta. Terminato il tempo di funzionamento in modo demo. |
10035080 | FB usata in task diversa da Back. |
10035100 | Stringa in log troppo lunga (Maggiore di MaxRowLen) stringa è stata troncata. |
10035110 | Raggiunto il massimo numero di righe di log. |
10035120 | Errore apertura file. |
10035130 | Errore posizionamento nel file. |
10035140 | Errore scrittura nel file. |
10035150 | Errore chiusura file. |
Esempi¶
Nel seguente esempio ad ogni attivazione dell’input Di00M00, viene salvata la stringa presente in Str nel file di nome Storage/MyLog.txt. Avendo impostato Circular uguale TRUE, al raggiungimento di 100 log viene sovrascritto il primo. La variabile LogIndex è una variabile mappata nell’area delle variabili tamponate (Vedi definizione nel riquadro rosso).
Definizione variabili |
![]() |
Esempio LD (PTP136A100, LD_StringToLogFile)
FIFOFile_v1, gestisce registro FIFO su file¶
Type | Library |
---|---|
FB | eLLabLogLib_B100 |
Questo blocco funzione effettua la gestione di un registro FIFO su di un file (Può essere eseguito in un solo loop di programma come una funzione).
Attivando In i dati nel buffer puntato da Dp per la dimensione indicata in Dls sono inseriti nel registro FIFO. In UTCTime è ritornato il valore di Data/Ora UTC di inserimento nel registro FIFO.
Attivando l’ingresso Out il primo record inserito nel FIFO viene trasferito nel buffer di uscita puntato da Dp la cui dimensione è definita in Dls. In UTCTime è ritornato il valore di Data/Ora UTC di inserimento nel registro FIFO del record letto. In Dl è ritornata la lunghezza del record FIFO.
In FIFOIDx occorre fornire l’indirizzo di un array di 2 UDINT che devono essere allocati dal programma. Se si desidera che la situazione dei dati nel FIFO sia mantenuta allo spegnimento del sistema occorre allocare questo array in una memoria tampone.
L’uscita DataOn se attiva indica la presenza di almeno un record nel registro FIFO. In FIFOSpace viene ritornato lo spazio disponibile, dati di dimensione inferiore o uguale possono essere inseriti nel registro. L’uscita Ok si attiva per un loop di programma ad ogni esecuzione di un comando se l’esecuzione ha esito positivo. In caso di errore esecuzione viene attivata per un loop l’uscita Fault.
In (BOOL) | Comando di inserimento record nel registro FIFO. |
Out (BOOL) | Comando di lettura record dal registro FIFO. |
Delete (BOOL) | Comando di cancellazione record dal registro FIFO. |
FIFOIDx (@UDINT) | Pointer alla variabile indice di gestione FIFO (Deve essere un array di 2 UDINT). |
FIFOFilename (@STRING) | Percorso e nome del file in cui fare log (es.: “SDCard/FIFO.bin”). |
FIFOSize (UDINT) | Lunghezza massima del file FIFO. |
Dp (@BYTE) | Pointer al buffer dati sia In che in Out dal FIFO. |
Dls (UDINT) | Lunghezza record dati in In al FIFO. Dimensione buffer dati in Out dal FIFO. |
Ok (BOOL) | Attivo per un loop se comando riuscito. |
Fault (BOOL) | Attivo per un loop su errore esecuzione comando. |
DataOn (BOOL) | Attivo se almeno un record dati è presente nel FIFO. |
FIFOSpace (UDINT) | Spazio disponibile nel file FIFO. |
UTCTime (UDINT) | Data/Ora in UTC di inserimento nel FIFO se In. Record letto se Out. |
Dl (UDINT) | Lunghezza record letto da FIFO. |
Codici di errore
In caso di errore si attiva l’uscita Fault e con SysGetLastError è possibile rilevare il codice di errore.
10056050 | Non è indicato il valore di FIFOIDx. |
10056060 | FB usata in task diversa da Back. |
10056070 | Nome file FIFO non corretto. |
10056100 | Lunghezza record da inserire in FIFO errata (Comando In). |
10056101 | Non c’è spazio in FIFO per contenere record (Comando In). |
10056110 | Errore apertura file di appoggio (Comando In). |
10056200 | Non ci sono dati nel registro FIFO (Comando Out). |
10056210 | Errore apertura file di appoggio (Comando Out). |
10056220 | Errore CRC record registro FIFO (Comando Out). Registro FIFO viene inizializzato. |
10056221 | Lunghezza record registro FIFO maggiore di buffer appoggio (Comando Out). |
10056300 | Non ci sono dati nel registro FIFO (Comando Delete). |
10056310 | Errore apertura file di appoggio (Comando Delete). |
10056320 | Errore CRC record registro FIFO (Comando Delete). Registro FIFO viene inizializzato. |
1005650 (0~4) | Errori lettura dati in file di appoggio. Registro FIFO viene inizializzato. |
1005660 (0~4) | Errori scrittura dati da file di appoggio. Registro FIFO viene inizializzato. |
Esempi¶
Nel seguente esempio sul fronte di variazione dell’input Di00CPU sono inseriti più records nel registro FIFO. Ad ogni attivazione dell’ingresso Di01CPU viene letto ed eliminato dal registro FIFO il record inserito più datato.
Definizione variabili |
VAR FIFO : FIFOFile_v1; (* FIFO file FB instance *) FIFOData : STRING[ 32 ]; (* FIFO data Input/Output *) Pulse : ARRAY[ 0..1 ] OF BOOL; (* Pulse flag *) Counter : UDINT; (* Counter *) i : INT; (* Auxiliary variable *) FIFOIDx : ARRAY[ 0..1 ] OF UDINT; (* FIFO indexes *) FIFOFilename : STRING[ 32 ] := “Storage/FIFO.bin”; (* FIFO file *) END_VAR |
Esempio ST (PTP136A310, ST_FIFOFile)
(\* INITIALIZATION \*)
(\* Execute the program initialization. \*)
IF (SysFirstLoop) THEN
(\* FIFO on file init. \*)
FIFO.**FIFOFilename**:=ADR(**FIFOFilename**); (\* Path and name of FIFO file \*)
FIFO.FIFOIDx:=ADR(FIFOIDx); (\* FIFO indexes \*)
FIFO.FIFOSize:=1000; (\* FIFO file size \*)
(\* This is optional. \*)
(\* Wear leveling, if the two indexes have the same value delete the \*)
(\* FIFO file. I'll be created by the FB in a new disk position. \*)
IF (Sysfilelength(**FIFOFilename**) <> -1) THEN
IF (FIFOIDx[0] = FIFOIDx[1]) THEN i:=Sysremove(\ **FIFOFilename**);
FIFOIDx[0]:=0; FIFOIDx[1]:=0; END_IF;
END_IF;
END_IF;
(\* INSERT DATA ON FIFO REGISTER \*)
(\* Manage the data record and insert it on FIFO register. \*)
IF (Di00CPU <> Pulse[0]) THEN
Pulse[0]:=Di00CPU; (\* Pulse flag \*)
IF NOT(Pulse[0]) THEN
FIFO(In:=TRUE, Dp:=ADR('Di00CPU is reset'), Dls:=Sysstrlen(FIFO.Dp)); (\* Write record on FIFO \*)
ELSE
FIFO(In:=TRUE, Dp:=ADR('Di00CPU is set'), Dls:=Sysstrlen(FIFO.Dp)); (\* Write record on FIFO \*)
(\* Increase the counter and add value to FIFO. \*)
Counter:=Counter+1; (\* Counter \*)
i:=SysVarsnprintf(ADR(FIFOData), SIZEOF(FIFOData), 'Counter=%d', UDINT_TYPE, ADR(Counter));
FIFO(In:=TRUE, Dp:=ADR(FIFOData), Dls:=LEN(FIFOData)); (\* Write record on FIFO \*)
END_IF;
END_IF;
(\* EXTRACT DATA FROM FIFO REGISTER \*)
(\* Extract and delete record from FIFO register. \*)
IF (Di01CPU <> Pulse[1]) THEN
Pulse[1]:=Di01CPU; (\* Pulse flag \*)
IF (Pulse[1]) THEN
FIFO(Out:=TRUE, Dp:=ADR(FIFOData), Dls:=SIZEOF(FIFOData)); (\* Read record from FIFO \*)
FIFO(Delete:=TRUE); (\* Delete record from FIFO \*)
END_IF;
END_IF;
(\* [End of file] \*)
Ecco lo screenshot del programma di esempio in esecuzione. Come si vede le due variabili FIFOIDx assumono lo stesso valore quando il registro FIFO è vuoto. Se i due indici hanno lo stesso valore, opzionalmente è possibile al primo loop di programma oppure a tempo eseguire la cancellazione del file di appoggio. In questo modo il file viene rilocato sul disco creando un effetto di wear leveling.
Se FIFOIDx è dichiarato RETAIN è possibile mantenere i dati registrati nel FIFO anche a sistema spento.
FileMemoryDump, dump memoria su file¶
Type | Library |
FB | eLLabLogLib_B000 |
Questo blocco funzione effettua il dump di una zona di memoria memoria a partire da indirizzo definito in MBufferPtr per il numero di bytes definito in MBufferSize su di un file su disco di nome Filename. A partire dalla eLLabLogLib_B310 può essere eseguito il dump anche di un buffer allocato con RMalloc.
Sul fronte di attivazione dell’ingresso Write viene creato il file ed il contenuto della memoria viene scritto nel file. Sul fronte di attivazione dell’ingresso Read viene letto il file ed il suo contenuto trasferito in memoria.
Terminato il comando viene attivata per un loop l’uscita Done, in caso di errore esecuzione viene attivata per un loop l’uscita Fault.
Il file di dump su disco è un file ascii quindi è possibile editarlo con un qualsiasi text editor, ecco un esempio di file.
`` 00000000: 00 AB 12 34 00 00 00 00 | 00 00 00 12 00 0F 0A CC ``
`` 00000010: 02 00 00 00 00 00 00 00 | EF C0 DD 00 00 00 01 00 ``
Enable (BOOL) | Comando di abilitazione blocco funzione. |
Read (BOOL) | Comando di lettura da dump file in memoria. |
Write (BOOL) | Comando di scrittura memoria su dump file. |
Filename (STRING[32]) | Percorso e nome del file in cui fare log (es.: “Storage/Dump.txt”). |
MBufferPtr (@USINT) | Pointer a buffer di memoria su cui opera il dump. |
MBufferSize (UDINT) | Dimensione in bytes del buffer di memoria. |
Enabled (BOOL) | Attivo su abilitazione blocco funzione. |
Done (BOOL) | Attivo per un loop se comando eseguito. |
Fault (BOOL) | Attivo per un loop su errore esecuzione del comando. |
Codici di errore
In caso di errore si attiva l’uscita Fault e con SysGetLastError è possibile rilevare il codice di errore.
10036070 | Errore case gestione. |
10036100 | FB eseguita in task diversa da Back. |
10036200 | Errore apertura file su comando di lettura. |
10036210 | Errore posizionamento file su comando di lettura. |
10036220 | Errore lettura da file su comando di lettura. |
10036230 | Errore chiusura file su comando di lettura. |
10036240~4 | Errore dati presenti su file di dump su comando di lettura. |
10036400 | Errore apertura file su comando di scrittura. |
10036410 | Errore posizionamento file su comando di scrittura. |
10036420 | Errore scrittura su file su comando di scrittura. |
10036430 | Errore chiusura file su comando di scrittura. |
Esempi¶
Nel seguente esempio sul fronte di attivazione dell’input Di01CPU viene eseguito il dump del buffer di memoria DumpBuffer nel file Storage/Dump.txt. Dopo aver eseguito il dump attivando l’input Di00CPU è possibile rileggere i dati dal file di dump e ritrasferirli nel buffer di memoria.
Definizione variabili |
![]() |
Esempio LD (PTP136A310, FBD_FileMemoryDump)