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.

image0

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

image1

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

image2

Esempio LD (PTP136A000, LD_SysLogReport)

image3

StringToLogFile_v1, salva una stringa in un file di log

image4

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
image5

Esempio LD (PTP136A100, LD_StringToLogFile)

image6

FIFOFile_v1, gestisce registro FIFO su file

image7

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.

image8

FileMemoryDump, dump memoria su file

image9

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
image10

Esempio LD (PTP136A310, FBD_FileMemoryDump)

image11