Librerie: Logging Class for both MQL4 and MQL5

 

Logging Class for both MQL4 and MQL5:

La classe CDebugLogger è un'utility di log flessibile e completa, progettata per l'uso in ambienti MQL4/5. Consente agli sviluppatori di registrare i messaggi a vari livelli di importanza (INFO, WARNING, ERROR, DEBUG) con la possibilità di includere timestamp, firme di funzioni, nomi di file e numeri di riga nelle voci di log. La classe supporta la registrazione sia nella console che nei file, con la possibilità di salvare i log in una cartella comune e in formato CSV. Inoltre, offre la funzionalità di silenziare i log in base a parole chiave specifiche, garantendo che le informazioni sensibili non vengano registrate. Questa classe è ideale per gli sviluppatori che desiderano implementare solidi meccanismi di registrazione nelle loro applicazioni MQL4/5, con caratteristiche personalizzabili che soddisfano un'ampia gamma di esigenze di debug e monitoraggio.

Author: VitalDefender Inc.

 

Ho letto il nome "Best Logging Class", che ha attirato la mia attenzione. "Migliore" è un livello piuttosto alto, quindi ero curioso di verificarlo. Eviterò di parlare dei dettagli, poiché si tratta di un codice distribuito liberamente che richiede di essere indulgenti.

Utilizzo e caratteristiche:

  • L'idea delle parole chiave nascoste è buona. L'implementazione è però debole (vedere sotto). Inoltre, silenzia troppi messaggi, per esempio se sto usando logging. AddSilentKeyword("start"), filtrerà un log usando "started" o "starting", che non è proprio quello che mi aspetterei da un filtraggio per "parole chiave".
  • Il resto sono funzioni molto basilari. Ad esempio, poiché il nucleo di MQL è guidato dagli eventi, è necessario che un sistema di log eviti di inondare il log con le stesse voci ripetute, cosa che può accadere facilmente con un Log() inserito in un OnTick(), OnTimer() o OnChartEvent().

Dal punto di vista della codifica:

  • Il vostro costruttore e la vostra Initialize() sono codici duplicati per le parti essenziali.
  • IsMessageSilent() utilizza un ciclo di controllo per ogni parola di m_silent_keywords[] e all'interno di questo ciclo converte le 'parole chiave' in minuscole. Su ogni log! È davvero inefficiente.
  • La classe è difficilmente personalizzabile, per esempio se voglio personalizzare il log per ""Nome file: " + __FILE__ + "\n", dovrò modificare il vostro codice, o derivare una classe e riscrivere interamente il metodo Log(). Lo stesso problema si presenta per qualsiasi modifica personalizzata, ad esempio utilizzando un file BIN.
  • Si definisce una macro Print() che sovrascrive quella integrata in MQL. È una pessima idea costringere l'utente della propria libreria a stampare() nel proprio log.

Conclusione :

La vostra libreria è una corretta libreria di log di base. Può essere comoda per alcuni principianti o codificatori che non hanno il tempo di costruirsela da soli, fornendo loro alcune funzioni di log facili da usare.

L'uso del qualificatore "migliore" non è assolutamente giustificato. Le funzionalità sono corrette ma basilari e l'implementazione è di livello amatoriale.

 
Alain Verleyen __FILE__ + "\n", dovrò modificare il vostro codice, o derivare una classe e riscrivere interamente il metodo Log(). Lo stesso problema si presenta per qualsiasi modifica personalizzata, ad esempio utilizzando un file BIN.
  • Si definisce una macro Print() che sovrascrive quella integrata in MQL. È una pessima idea costringere l'utente della propria libreria a stampare() nel proprio log.
  • Conclusione :

    La vostra libreria è una corretta libreria di log di base. Può essere comoda per alcuni principianti o codificatori che non hanno il tempo di costruirsela da soli, fornendo loro alcune funzioni di log facili da usare.

    L'uso del qualificatore "migliore" non è assolutamente giustificato. Le funzionalità sono corrette ma basilari e l'implementazione è di livello amatoriale.

    Grazie per il tuo commento.
    Mi rendo conto che "migliore" potrebbe essere un'esagerazione rispetto alle tue aspettative. La mia intenzione era quella di condividere un codice che potesse essere facilmente modificato e compreso da chiunque. Spero comunque di aver dato un piccolo contributo alla comunità e che la classe sia disponibile per tutti. Procederò presto a ottimizzare il codice come da te suggerito.
    Grazie ancora per il feedback.
     
    Non c'è di che.
     
    2024.09.01 14:51:25.011 Logging (EURUSD,M30)    File Name: Logging.mqh Function: string CDebugLogger::FormatLogEntry(LogLevel,string) 2024.09.01 14:51 Line: 276 [INFO] Script started successfully.
    

    Penso che si debba usare MACROS invece di un metodo di classe per poter emettere il nome del file, la firma della funzione e il numero di riga in cui si verifica la chiamata di log.

     
    amrali __FILE__ + "n", dovrò modificare il vostro codice o derivare una classe e riscrivere interamente il metodo Log(). Lo stesso problema si presenta per qualsiasi modifica personalizzata, ad esempio utilizzando un file BIN.
  • Si definisce una macro Print() che sovrascrive quella integrata in MQL. È una pessima idea costringere l'utente della propria libreria a stampare() nel proprio log.
  • Conclusione :

    La vostra libreria è una corretta libreria di log di base. Può essere comoda per alcuni principianti o codificatori che non hanno il tempo di costruirsela da soli, fornendo loro alcune funzioni di log facili da usare.

    L'uso del qualificatore "migliore" non è assolutamente giustificato. Le funzionalità sono corrette ma basilari e l'implementazione è di livello amatoriale.

    Per quanto riguarda la possibilità di silenziare singole parole, credo che un modo efficiente sia semplicemente quello di scrivere 'start', includendo uno spazio o un altro carattere. In definitiva, come per altri linguaggi, la configurazione dei log ha senso se fatta nell'Init . Come già detto, deve essere semplice in modo che sia facilmente adottabile da tutti. Se pensate che sia necessario aggiungere qualcos'altro, scrivetelo pure e cercherò di aggiungere il codice quando avrò tempo. Per quanto riguarda la funzione "Stampa", ognuno è libero di commentarla se lo desidera.

    Sono a disposizione per qualsiasi ulteriore modifica!

     
    Alain Verleyen #:
    Il resto sono caratteristiche molto basilari. Ad esempio, poiché il nucleo di MQL è guidato dagli eventi, è necessario un sistema di log per evitare di inondare il log con le stesse voci ripetute, cosa che può accadere facilmente con una Log() inserita in una OnTick(), OnTimer() o OnChartEvent().

    Come risolvere questo problema?

     
    hini #:

    Come risolvere questo problema?

    In realtà è semplice, ma probabilmente non facile.

    Pensate al vostro diario di uscita come a un elenco o a un array. Ogni elemento rappresenta una posizione specifica nel codice. Quindi, per ogni chiamata "print to journal", si ha un elemento separato.

    Ogni elemento ha il proprio elenco di voci e finché si ripetono (il messaggio è uguale al precedente), vengono registrati un contatore e un timestamp. Una volta che non sono uguali, si stampa l'ultimo messaggio, compresi il timestamp e il contatore del primo e dell'ultimo.


    In questo modo si ottiene una sorta di filtro per evitare di riempire il registro degli esperti del terminale.

    Una volta terminato il programma, si scaricano tutti i messaggi non ancora stampati.
     
    Dominik Egert #:
    In realtà è semplice, ma probabilmente non facile.

    Pensate al vostro diario di uscita come a un elenco o a un array. Ogni elemento rappresenta una posizione specifica nel codice. Quindi, per ogni chiamata "print to journal", si ha un elemento separato.

    Ogni elemento ha il proprio elenco di voci e finché si ripetono (il messaggio è uguale al precedente), vengono registrati un contatore e un timestamp. Una volta che non sono uguali, si stampa l'ultimo messaggio, compresi il primo e l'ultimo timestamp e il contatore.


    In questo modo si ottiene una sorta di filtro per evitare di riempire il log degli esperti dei terminali.

    Una volta terminato il programma, si scaricano tutti i messaggi non ancora stampati.

    Grazie per la risposta. Attualmente sto utilizzando la libreria MQL Plus Enhanced Debugging Support per stampare i log. Tuttavia, a volte stampa una grande quantità di log ripetitivi e al momento non ho un metodo per risolvere questo problema. La soluzione da lei suggerita è un approccio che proverò quando avrò tempo. Richiede un'attenta progettazione del sistema di registrazione.

     
    Dominik Egert #:
    In realtà è semplice, ma probabilmente non facile.

    Pensate al vostro diario di uscita come a un elenco o a un array. Ogni elemento rappresenta una posizione specifica nel codice. Quindi, per ogni chiamata "print to journal", si ha un elemento separato.

    Ogni elemento ha il proprio elenco di voci e finché si ripetono (il messaggio è uguale al precedente), vengono registrati un contatore e un timestamp. Una volta che non sono uguali, si stampa l'ultimo messaggio, compresi il primo e l'ultimo timestamp e il contatore.


    In questo modo si ottiene una sorta di filtro per evitare di riempire il log degli esperti dei terminali.

    Una volta terminato il programma, si scaricano tutti i messaggi non ancora stampati.
    È semplice e facile.
     
    hini #:

    Grazie per la risposta. Attualmente sto utilizzando la libreria MQL Plus Enhanced Debugging Support per stampare i log. Tuttavia, a volte stampa una grande quantità di log ripetitivi e al momento non ho un metodo per risolvere questo problema. La soluzione da lei suggerita è un approccio che proverò quando avrò tempo. Richiede un'attenta progettazione del sistema di registrazione.


    Potrebbe essere integrato con lib debug.

    Lib Debug, tuttavia, non è pensato per essere un sistema di log, ma un log di debug, che fornisce una traccia completa del codice.