Using esp_log_set_vprintf() function

kartikkman
Posts: 13
Joined: Wed Jul 19, 2017 11:27 am

Using esp_log_set_vprintf() function

Postby kartikkman » Sat Dec 16, 2017 8:09 am

Hi I am trying to do Remote Logging for the esp32 .
I have implemented a function to convert the LOG data to the string which I will be sending over the Network .

The problem I am stuck here is to use the esp_log_set_vprintf() ??
DO you have any example or what for the above ??

Code: Select all

void LOG_TO_STRING(const char *format,...)
{
    ESP_LOGI("NO TAG","Call Accepted ");

        char *string;//printf result will be sotred in this     
        va_list arguments_list;
        va_start(arguments_list,format);//Initialiasing the List
       
                    //Calculating & Allocating Size
       
                    size_t size_string=snprintf(NULL,0,format,arguments_list);//Calculating the size of the formed string
                    string=(char *)malloc(size_string+4);//Initialising the string
                   

                    vsnprintf(string,size_string,format,arguments_list);//Storing the outptut into the string
                     va_end(arguments_list);//Deinitializing the List

                     ESP_LOGI("NO TAG","Converted String is :  %s",string);

    free(string);
}

User avatar
kolban
Posts: 1531
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Using esp_log_set_vprintf() function

Postby kolban » Tue Jun 12, 2018 6:31 pm

I think to register your function as the logger you would then call:

Code: Select all

esp_log_set_vprintf(LOG_TO_STRING);


in your app code.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Available for ESP32 consulting.

User avatar
fly135
Posts: 184
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: Using esp_log_set_vprintf() function

Postby fly135 » Tue Jun 12, 2018 6:39 pm

Won't this cause a recursive loop?

Code: Select all

void LOG_TO_STRING(const char *format,...)
{
    ESP_LOGI("NO TAG","Call Accepted ");

papaluna
Posts: 12
Joined: Tue Jan 30, 2018 11:27 am

Re: Using esp_log_set_vprintf() function

Postby papaluna » Wed Jun 13, 2018 8:33 am

kartikkmann,

Maybe this example helps, this one writes to SPIFFS.

Code: Select all

    ESP_LOGI(TAG, "  ***Redirecting log output BACK to only UART0 (not to the SPIFFS log file anymore)");
    esp_log_set_vprintf(&vprintf);


Code: Select all

    ESP_LOGI(TAG, "***Redirecting log output to SPIFFS log file (also keep sending logs to UART0)");
    esp_log_set_vprintf(&_log_vprintf);


Code: Select all

// This function will be called by the ESP log library every time ESP_LOG needs to be performed.
//      @important Do NOT use the ESP_LOG* macro's in this function ELSE recursive loop and stack overflow! So use printf() instead for debug messages.
int _log_vprintf(const char *fmt, va_list args) {
    static bool static_fatal_error = false;
    static const uint32_t WRITE_CACHE_CYCLE = 5;
    static uint32_t counter_write = 0;
    int iresult;

    // #1 Write to SPIFFS
    if (_log_remote_fp == NULL) {
        printf("%s() ABORT. file handle _log_remote_fp is NULL\n", __FUNCTION__);
        return -1;
    }
    if (static_fatal_error == false) {
        iresult = vfprintf(_log_remote_fp, fmt, args);
        if (iresult < 0) {
            printf("%s() ABORT. failed vfprintf() -> disable future vfprintf(_log_remote_fp) \n", __FUNCTION__);
            // MARK FATAL
            static_fatal_error = true;
            return iresult;
        }

        // #2 Smart commit after x writes
        counter_write++;
        if (counter_write % WRITE_CACHE_CYCLE == 0) {
            /////printf("%s() fsync'ing log file on SPIFFS (WRITE_CACHE_CYCLE=%u)\n", WRITE_CACHE_CYCLE);
            fsync(fileno(_log_remote_fp));
        }
    }

    // #3 ALWAYS Write to stdout!
    return vprintf(fmt, args);
}
--
Paul.

User avatar
Vader_Mester
Posts: 152
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: Using esp_log_set_vprintf() function

Postby Vader_Mester » Thu Jun 14, 2018 6:52 am

kolban wrote:I think to register your function as the logger you would then call:

Code: Select all

esp_log_set_vprintf(LOG_TO_STRING);


in your app code.


I found this interesting. I'm not 100% sure I get how it works.
It basically sets my own function as the LOG output, so whenever I call any ESP_LOG function it will output using the function I set here?

Correct me if I wrong.
If this is the case, then I found what I was looking for :)
There are 2 types of programmer people: The Expert programmer and The Smart programmer

The Expert programmer easily writes any code from scratch.
The Smart programmer uses his google/github powers first ;)

User avatar
kolban
Posts: 1531
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Using esp_log_set_vprintf() function

Postby kolban » Thu Jun 14, 2018 2:13 pm

If we think that in C, a function is compiled piece of code that has an entry address ... then we can loosely say that a function is identified by the address in memory where it starts.

When we define a function ... for example:

Code: Select all

void x() {
   printf("Hello World");
}


Not only does this generate code, it "loosely" generates a variable called "x". The value of that variable is the address of the entry point to the function x().

We can declare a variable that can be explicitly a pointer to a function ... for example:

Code: Select all

void (*y)();


and then we can code:

Code: Select all

y = x;
y();


which says that "y" is a variable which holds a pointer to a function. We then assign y the value of x and then "call" the function that is pointed to by "y".


See also:

https://www.geeksforgeeks.org/function-pointer-in-c/
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Available for ESP32 consulting.

Who is online

Users browsing this forum: mzimmers and 7 guests