Logging V2 for both MQL4 and MQL5 – library MetaTrader 5

CDebugLogger Class V2: A Comprehensive Logging Utility for MQL4/5

The CDebugLogger class is a powerful and flexible logging utility specifically designed for MQL4/5 environments. It is an essential tool for developers who need to monitor, debug, and track the behavior of their applications with precision.

In this new version of the CDebugLogger class, I have introduced several improvements to enhance its functionality and versatility. These improvements include a debounce mechanism to prevent excessive logging in event-driven systems like OnTick, OnTimer, and OnChartEvent, as well as new filtering and silencing options to help developers focus on the most relevant log entries.

I’ve decided to release this updated version as a separate codebase to give users the freedom to choose the implementation that best fits their needs. Whether you prefer the original version or this enhanced one, you now have the option to select the logging tool that suits your workflow and project requirements.

Below, we explore the key features and capabilities of this enhanced class.

Key Features

  • Multiple Log Levels: The CDebugLogger class supports logging at different levels of importance, including INFO, WARNING, ERRORand DEBUG. This allows developers to filter and focus on messages of particular significance.
  • Timestamp Inclusion: Developers can choose to include timestamps in their log messages, with customizable formats. This feature is crucial for tracking the exact time of events and debugging time-sensitive issues.
  • File Logging: The class provides robust support for logging to files. Developers can enable or disable file logging, specify the log file’s path, and choose whether to save logs in a common folder. Additionally, logs can be saved in a CSV format, making them easy to parse and analyze.
  • Contextual Information: To enhance the clarity of log messages, the CDebugLogger class allows the inclusion of function signatures, file names, and line numbers. This contextual information helps in pinpointing the exact location of issues within the code.
  • Silent Keywords: A unique feature of this class is the ability to silence logs that contain specific keywords. This is particularly useful for preventing sensitive information, such as passwords or confidential data, from being logged.
  • Filter Keywords: Another unique feature of this class is the ability to filter logs that contain specific keywords. This is particularly useful for debugging by focusing only on logs that are relevant to specific issues. Developers can narrow down the log output to include only messages containing certain terms, making it easier to identify and address problems related to those terms without being overwhelmed by unrelated log entries.
  • Debounce Logging for Events: To prevent log spamming and excessive logging in event-driven systems (such as OnTick, OnTimer, and OnChartEvent), the CDebugLogger class includes a debouncing mechanism. This feature ensures that repeated log entries from the same event are temporarily suppressed, allowing only unique or significant changes to be logged. This is particularly useful for reducing noise in the logs and preventing performance degradation in high-frequency event environments.

Example Usage

Below is an example of how to initialize and use the CDebugLogger class:

// Initialize the logger with INFO level logging to a file
CDebugLogger logger(INFO, true, "log.txt", true, TIME_DATE | TIME_MINUTES, false, true, true, true);

// Log a simple message
logger.Log(INFO, "This is an info message");

// Silence a keyword
logger.AddSilentKeyword("password");

// Log a message that will be silenced
logger.Log(INFO, "User entered password: 1234");

// Enable file logging
logger.EnableFileLogging(true, "debug.log", false);

// Remove a silenced keyword
logger.RemoveSilentKeyword("password");

// Log a message after removing the keyword from the silence list
logger.Log(INFO, "User entered password: 1234");

// Add a keyword to filter logs
logger.AddFilterKeyword("success");

// Log a message that will be filtered out
logger.Log(INFO, "Operation failed");

// Log a message that will pass the filter
logger.Log(INFO, "Operation successful");

// Remove a keyword from the filter
logger.RemoveFilterKeyword("success");

// Initialize using the generic Log function
logging.Initialize(WARNING, true, "warnings.log", true, TIME_SECONDS, true, false, true, true);

// Log a warning using the generic Log function
Log(WARNING, "This is a warning message");

Script Example

To utilize the CDebugLogger class in a script, simply include the necessary library at the beginning of your file, as shown below:

Alternative:  RSI adaptive EMA - indicator MetaTrader 5
//--- It is important to include this header file before all others
#include <Logging.mqh>  


//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
 FUNCSIG, true);
   Log(INFO, "This log includes line number, file name, and function signature in a custom order.");

   //--- Add a keyword to filter logs containing 'important'
   logging.AddFilterKeyword("important");

   //--- Log some messages to demonstrate the filter
   Log(INFO, "This is an important message."); // This message will be visible
   Log(INFO, "This is a regular message.");    // This message will not be visible

   //--- Remove the filter keyword to show all logs
   logging.RemoveFilterKeyword("important");

   //--- Log a final message indicating the end of the script
   Log(INFO, "Script execution completed.");

Output CSV example:

Timestamp,Level,Message
"2024.09.01 18:31:44","INFO","Script started successfully."
"2024.09.01 18:31:44","WARNING","This is a warning message."
"2024.09.01 18:31:44","ERROR","This is an error message."
"2024.09.01 18:31:44","DEBUG","This is a debug message for debugging purposes."
"2024.09.01 18:31:44","INFO","User entered password: 1234"
"2024.09.01 18:31:44","INFO","This message is logged using the generic Log function."
"2024.09.01 18:31:44","INFO","This message is logged using the Print macro."
Timestamp,Level,Message,Filename,Line
"2024.09.01 18:31","INFO","This log includes only the file name and line number.","Logging.mq5","135"
Timestamp,Level,Message,Funcsig
"2024.09.01 18:31:44","INFO","This log includes only the function signature.","void OnStart()"
Timestamp,Level,Message,Filename,Line,Funcsig
"18:31","INFO","This log includes line number, file name, and function signature in a custom order.","Logging.mq5","141","void OnStart()"
"18:31","INFO","This is an important message.","Logging.mq5","147","void OnStart()"
"18:31","INFO","Script execution completed.","Logging.mq5","154","void OnStart()"


Exper Advisor Example

#include <Logging.mqh>

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  int log_options = LINE 
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)

//--- destroy timer
   EventKillTimer(); 

int counter = 0;
datetime last_time = 0; //--- Stores the last time the counter was updated
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  logging.BeginEvent(); //--- Start a new event
   Log(INFO, "Sample message");
   Log(INFO, "Another message");
   Log(INFO, "Sample message"); 
//--- Get the current time
   datetime current_time = TimeLocal();
//--- Check if at least 2 seconds have passed since the counter was last updated
   if (current_time - last_time >= 2)
     //--- Update the counter
      counter++;
      //--- Update the last time
      last_time = current_time;
      //--- Log the message with the new counter value
      Log(INFO, "Counter value: " + IntegerToString(counter));
      //--- You can also log another message
      Log(INFO, "Updated after 2 seconds"); 
   else
     //--- Log a message indicating that the timer is active but the counter hasn't changed
      Log(INFO, "Timer active but counter unchanged");  

Output MT5 terminal example:

2024.09.22 13:00:29.589 test_logging (EURUSD,H1)        2024.09.22 13:00:29 Line: 43 Function: void OnTimer() [INFO] Sample message
2024.09.22 13:00:29.589 test_logging (EURUSD,H1)        2024.09.22 13:00:29 Line: 44 Function: void OnTimer() [INFO] Another message
2024.09.22 13:00:29.589 test_logging (EURUSD,H1)        2024.09.22 13:00:29 Line: 45 Function: void OnTimer() [INFO] Sample message
2024.09.22 13:00:29.589 test_logging (EURUSD,H1)        2024.09.22 13:00:29 Line: 55 Function: void OnTimer() [INFO] Counter value: 1
2024.09.22 13:00:29.589 test_logging (EURUSD,H1)        2024.09.22 13:00:29 Line: 57 Function: void OnTimer() [INFO] Updated after 2 seconds
2024.09.22 13:00:29.605 test_logging (EURUSD,H1)        2024.09.22 13:00:29 Line: 60 Function: void OnTimer() [INFO] Timer active but counter unchanged
2024.09.22 13:00:31.001 test_logging (EURUSD,H1)        2024.09.22 13:00:31 Line: 55 Function: void OnTimer() [INFO] Counter value: 2
2024.09.22 13:00:31.001 test_logging (EURUSD,H1)        2024.09.22 13:00:31 Line: 57 Function: void OnTimer() [INFO] Updated after 2 seconds
2024.09.22 13:00:31.017 test_logging (EURUSD,H1)        2024.09.22 13:00:31 Line: 60 Function: void OnTimer() [INFO] Timer active but counter unchanged
2024.09.22 13:00:33.001 test_logging (EURUSD,H1)        2024.09.22 13:00:33 Line: 55 Function: void OnTimer() [INFO] Counter value: 3
2024.09.22 13:00:33.001 test_logging (EURUSD,H1)        2024.09.22 13:00:33 Line: 57 Function: void OnTimer() [INFO] Updated after 2 seconds
2024.09.22 13:00:33.016 test_logging (EURUSD,H1)        2024.09.22 13:00:33 Line: 60 Function: void OnTimer() [INFO] Timer active but counter unchanged


Conclusion

The CDebugLogger class is an invaluable tool for any MQL4/5 developer. With its wide range of customizable features, it enables precise logging and monitoring of applications, facilitating easier debugging and better application performance tracking. Whether you need simple message logging or detailed contextual information, the CDebugLogger class provides a reliable and efficient solution tailored to your development needs.

Alternative:  XEnvelopes2 - indicator MetaTrader 5

For more information about the CDebugLogger class or to explore other advanced tools and solutions, visit StormWave Technologies.

📈 ROBOTFX MetaTrader Expert Advisors and Indicators to maximize profits and minimize the risks