what log system to use ?

 

Hello all,

new to this world (trading, development on MQL5,...), I would like to know which LOG system you guys are using

  • no logging at all
  • the default "Print()" or "PrintFormat()" method
  • homemade simple function file (what did you put inside?) 
  • a more complete library
    • I have tried Log4MQL and I got debugging issues (after loading the library, the mt5 debugger jumped from one line to another, one file to another, obviously causing fatal errors) ; code here:  https://www.mql5.com/en/code/31452
    • I downloaded ProF's logger at https://www.mql5.com/en/articles/150
    • I tried to start to code my own following orchard forex videos here: ***

I may be wrong (and i hope), but I have the feeling many things have to be coded by oneself (?)

Thank you all for your kind replies and clues.

BTW I am using MT5 build 3280 of 29/04/2022

Log4mql (MT5)
Log4mql (MT5)
  • www.mql5.com
A logging library similar to Log4j but for MQL.
 
Logging can turn into quite some hazel and scatter across the whole code, giving you a hard time managing all your code and logic.

I personally switched to use error codes for permanent logging.

For development I use a different approach, so that this type of logging stands out from the "production code".

I developed my own solutions for both approaches and also shared them with the community to be used and contributed freely.

If you are interested, both are available in Cloud Storage and on Code Base (outdated). Search for "MQL plus" to find them, if you are interested.

It serves me very well in terms of issue resolution and versatility of usage. Main focus for me is, easy and simple integration.

Especially distinguishing between permanent and development logging is essential to me, as I don't want all the check and debug output in my production environment.

 
Dominik Christian Egert #:
Logging can turn into quite some hazel and scatter across the whole code, giving you a hard time managing all your code and logic.

I personally switched to use error codes for permanent logging.

For development I use a different approach, so that this type of logging stands out from the "production code".

I developed my own solutions for both approaches and also shared them with the community to be used and contributed freely.

If you are interested, both are available in Cloud Storage and on Code Base (outdated). Search for "MQL plus" to find them, if you are interested.

It serves me very well in terms of issue resolution and versatility of usage. Main focus for me is, easy and simple integration.

Especially distinguishing between permanent and development logging is essential to me, as I don't want all the check and debug output in my production environment.

Great ! thank you for your reply. 

I will test it right now ! :) 

@folks , some other clues ?

 

@Dominik Christian Egert, Is there somewhere a sample code I could use to write into a file ? (maybe CSV?)

Thank you

 
How computer resources are sold
 

My solutions do not provide such feature (jet).


In general I would say this depends to which part you are referring, if you are asking for the lib_error project, focusing on custom and mql error-codes, this could be added very easily to the library by yourself.

If you have downloaded both the required project "MQLplus Include LIbrary Collection" and the optional "LibError" sample project, you would need to take a look at the file lib_error.mqh from the "Include Collection". 

You will find a function in there, called "UserOnError" which you can edit to your personal extend as you like. in the lower part of that function, you can add output to file.

/////////////////////////////////////////////////////////
//
//  OnError() Function
//
//  Generic error handling function.
//  Some return codes are not of interest, so
//  they get sorted out here and are
//  surpressed of being journaled.
//
const bool UserOnError(int& err, const string prefix = NULL)
{
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  Adjust your error handling behaviour here as you need.
    //  Do not forget to enbale the user supplied error handler macro. (LIB_ERR_USER_ERROR_HANDLER)
    //



    ///////////////////////////////////////            
    //
    // Treat certain environments 
    //  differently than others.
    //
    const static bool non_reporting_exec_env =   ( MQLInfoInteger(MQL_PROFILER)             // Is in profiler mode
                                                    || MQLInfoInteger(MQL_FORWARD)          // Is forward strategy tester
                                                    || MQLInfoInteger(MQL_OPTIMIZATION)     // Is running in optimization environment
                                                    || MQLInfoInteger(MQL_FRAME_MODE))      // Is running as optimization result receiver
                                              && ( !MQLInfoInteger(MQL_VISUAL_MODE)         // And is not strategy tester visual mode
                                                    || !MQLInfoInteger(MQL_DEBUG));         // Or not in debug mode

    
    
    ///////////////////////////////////////            
    //
    // Get and return current error code
    // 
    err = GetLastError();



    ///////////////////////////////////////            
    //
    // Use a bitmask to filter error 
    //  codes for their severity.
    //
    // You may design this as you like.
    //  It all depends on how you set up 
    //  your error codes and what they mean.
    //
    //  Keep in mind, error code 0xxxxxxx00 
    //  is always a success code.
    //
    const int err_mask = 0x000000FF | (0x0000FF00 * (((err & 0xFFFF0000) == NULL) & 0x01));



    ///////////////////////////////////////            
    //
    // Success code, treat warnings 
    //  as success.
    //
    if( ((err & err_mask) == ERR_SUCCESS)
     || ((err_mask == 0xFF) && ((err & LIB_ERR_LEVEL_WARNING) == LIB_ERR_LEVEL_WARNING)) )
    {
                ResetUserErrorCode();
                return(false); 
    }



    ///////////////////////////////////////            
    //
    // Handled error codes return as 
    //  non error. Governed by the flag
    //  LIB_ERR_LEVEL_WARNING_AS_ERROR
    //
    else if((err_mask == 0xFF) && ((err & LIB_ERR_LEVEL_HANDLED_ERROR) == LIB_ERR_LEVEL_HANDLED_ERROR))
    #ifndef LIB_ERR_LEVEL_WARNING_AS_ERROR
    { return(false); }
        #else
    { return(true); }
        #endif



    ///////////////////////////////////////            
    //
    // Skip output for certain runtime 
    //  environments. 
    //
    if(non_reporting_exec_env)
    { return(true); }



    ///////////////////////////////////////
    //
    // Default action to perform on error
    //
    //  This is not very compatible with
    //  mql4, as printf does not respect
    //  new lines. 
    //
    // Calling ResolveLastErrorCode with 
    // an error code of -1 will read last
    // occured error from API.
    //
    #ifndef __MQL4_COMPATIBILITY_CODE__
        printf("%s", ResolveLastErrorCode(-1, prefix));

    #else 
        // MQL4 compatible multi line output
        string out = ResolveLastErrorCode(-1, prefix);
        string multipart[];
        StringReplace(out, "\r", "");
        const int lines = StringSplit(out, 0x0A, multipart);

        // Multiline journal output support
        for(int cnt = lines - 1; (cnt >= NULL) && !_StopFlag; cnt--)
        { printf("%s", multipart[cnt]); };
    
    #endif


    // Return error state
    return(true);

    //
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
//
/////////////////////////////////////////////////////////



To be clear, this function will returnyou the string of the current/last error occured.

ResolveLastErrorCode(-1, prefix)


See the example howto project from LibError to get an understanding of how to use the library.



Concerning the lib_debug.mqh, this project does not support output to a file as it is inteded for development use. The Log-Facility of the Terminal provides enough tools to handle the logs as required for myself, therefore I have never had the need to have debug output to a file, to be honest.

I cannot think of any reasonable scenario in where I would need such, beyond of what is provided by the terminal. - After all it has a log viewer which gives me the ability to filter the output as I need it, since the output of the lib_debug.mqh library is well structured and therefore has lots of possibilities to filter exactly for what I am looking for. 


It is quite easy to trace the changes of a variable over time as well as see what causes these changes with very few lines of code inserted into the source code of my project. Once I have narrowed down and resolved the issue, I usually remove the debugging lines again. 

 

Here a short example of how you would change the above code, especially the last section of the function, so that you get a copy of the error message.


    ///////////////////////////////////////
    //
    // Default action to perform on error
    //
    //  This is not very compatible with
    //  mql4, as printf does not respect
    //  new lines. 
    //
    // Calling ResolveLastErrorCode with 
    // an error code of -1 will read last
    // occured error from API.
    //


    // Get error text from API
    const string last_err_msg = ResolveLastErrorCode(-1, prefix);




    // Write string and error number to a file

        // Add your code here
        // [...]
        // last_err_msg -> contains message
        // err -> contains error number


    // Skip output to terminal journal by returning here
	
	// Return true to indicate an error
	return(true); 




    // Default message processing
    #ifndef __MQL4_COMPATIBILITY_CODE__
        printf("%s", last_err_msg);

    #else 
        // MQL4 compatible multi line output
        string multipart[];
        StringReplace(last_err_msg, "\r", "");
        const int lines = StringSplit(last_err_msg, 0x0A, multipart);

        // Multiline journal output support
        for(int cnt = lines - 1; (cnt >= NULL) && !_StopFlag; cnt--)
        { printf("%s", multipart[cnt]); };
    
    #endif


 

Wow you're so fast!

Thank you so much I really appreciate it. 

I will have a look on how to use all that :) 

Reason: