1

I have a debugger class which implements a printf() c style method. It looks like this:

#define NO_DEBUG 0
#define NO_PREFIX 1
#define DEBUG_INFO 2
#define DEBUG_SUCCESS 3
#define DEBUG_WARN 4
#define DEBUG_ERROR 5
#define MAX_DEBUG_LEVEL 5


#define DEBUG_INFO_PREFIX "[INFO] "
#define DEBUG_SUCCESS_PREFIX "[SUCCESS] "
#define DEBUG_WARN_PREFIX "[WARN] "
#define DEBUG_ERROR_PREFIX "[ERROR] "

/*
*   Printing debug information to Serial in c printf style
*   If the level is higher then the global debug level or
*   the level is NO_DEBUG ( see debug.h ) then the message is not printed.
*/
void DebugSystem::print(byte level, const char *message, ...){
    if( level > debugLevel || level == NO_DEBUG ){ return; }
    char buffer[PRINT_BUFFER_SIZE];
    printPrefix(level);
    va_list  args;
    va_start (args, message);
        vsprintf (buffer, message, args);
        Serial.print(buffer);
    va_end (args);
}

It is used like this:

int count = 0;
debug.print(DEBUG_INFO,"Test message: %s,%d\n","testMSG",count);
debug.print(DEBUG_SUCCESS,"Test message: %s,%d\n","testMSG",count);
debug.print(DEBUG_WARN,"Test message: %s,%d\n","testMSG",count);
debug.print(DEBUG_ERROR,"Test message: %s,%d\n","testMSG",count);

It is working very well. Now i want to add a prefix before the message which i have implemented like this:

/*
*   Printing a prefix before the message based on it's level.
*   Levels:
*    - INFO prefix --> [INFO] 
*    - WARN prefix --> [WARN] 
*    - ERROR prefix --> [ERROR] 
*    - SUCCESS prefix --> [SUCCESS] 
*/ 
void DebugSystem::printPrefix(byte level){
    if( !levelPrefix || level == NO_PREFIX ){ return; }
    const char* prefix = level == DEBUG_ERROR ? DEBUG_ERROR_PREFIX
        : level == DEBUG_WARN    ? DEBUG_WARN_PREFIX
        : level == DEBUG_SUCCESS ? DEBUG_SUCCESS_PREFIX
        : DEBUG_INFO_PREFIX;
    Serial.print(prefix);
}

But i have a small problem. If the user want's to print \n at the beginning of the message, the output will be ill formatted.

Here is an example:

debug.print(DEBUG_INFO,"Test message: %s\n","TEST");
debug.print(DEBUG_INFO,"\nTest message: %s\n","TEST");

Output:

[INFO] Test message: TEST
[INFO]
      Test message: TEST

For this to work properly i have two solutions in mind Either check the first param ( i don't know how ) and if it is a new line '\n' character i remove it and print it before the prefix or i have to inject my prefix after the first \n character into the message.

I'm using Arduino framework to do all of this but i can't think of an elegant solution.

Expected output of this test message would be:

[INFO] Test message: TEST

[INFO] Test message: TEST

Ofc the problem is not just with the \n but any format character in the string. I need a robust solution, some regex or something to detect if there is a formatter character in the beginning of the arguments, remove and print it before the prefix.

Dr.Random
  • 430
  • 3
  • 16

2 Answers2

0

And there might be comments with several \n somewhere in the text.

You might repeat the prefix after every \n except for the trailing one at the end. And if there no ending \n add a \n.

Of course there often is a misconception that lines start with \n; one idea that should not be "repaired" - unnecessarily accepting that.

There might be more that one debug printf, meant to be printed as one text block. That you cannot determine:

if (i++ % 10 == 0) printf("\n...
printf
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Yeah but for example i usually do a \n only if i want a new line. If this function will put a prefix before every \n the console would have prefixes before empty lines. – Dr.Random Sep 30 '22 at 09:04
  • At the start `\n` might be discarded and at the end `\n` added if is not there. Other `\n`s might be replaced with `\n`+prefix. – Joop Eggen Sep 30 '22 at 09:16
0

This not directly answer your question. But why reinvent the wheel when you could enable the ESP32 logging system from Arduino IDE Tools -> Core Debug Level?

enter image description here

And then you could use the ESP logging system as

log_i( "I'm using the ESP logging system");

I would suggest you take a look at the esp32-hal-log.h of the ESP32-Arduino Core and read more about esp-idf logging system.

hcheung
  • 3,377
  • 3
  • 11
  • 23
  • Thank you for the answer. I aware the existence of the logging system. I wanted to create my own because i do much more in my own class. It can log messages to the file system and much more. I did not stated what IDE iam using but i use PlatformIO instead of the Arduino IDE. – Dr.Random Sep 30 '22 at 14:00
  • It works on PlatformIO too. – hcheung Sep 30 '22 at 16:00