Logger library enables you to use unified interface to send out or receive data using one function with different parameters. You leave buffer overflows to this library as it handles it all.

Logger library howto guide.

Below is a simple program that outlines the usage of the logger library, The whole function was head-written so there might be some errors, but it is more for a live representation of usage than anything else. If someone would write a nice example program feel free to link it here.

simple usage of logger library

#include "mbed.h"
#include "logger.h"
#include "errno.h"

Ticker printout;
/**
 * \def STASH_BUFFER_LEN
 * size of stash buffer that can be used to store logged data
 */
#define STASH_BUFFER_LEN 70000
/// stash_buffer size
static char stash_buffer[STASH_BUFFER_LEN];

/**
 * Log_pop_periodic is periodically printing the messages until the buffer is empty. 
 * Once the buffer is empty it detaches and waits for another command.
*/
void log_pop_periodic(void)
{
    if( log_pop(L_BTSERIAL,stash_buffer,STASH_BUFFER_LEN) == 1 )
    {
        printout.detach();
    }
}

static int i=0;
static char read_buffer[20];
/**
 * read data from BT serial
*/
void read_from_BT()
{

    if (BTSerial.readable()) {
        read_buffer[i++] = BTSerial.getc();
        // if we read the desired character
        if (read_buffer[i-1] == 'p')
        {
            // start the printout process which will log_pop logged data
            printout.attach(&log_pop_periodic,0.5);
        }
    }    
}

int main()
{
    log_init(L_SERIAL);
    log_init(L_BTSERIAL);
    BTSerial.attach(&read_from_BT);

    // while loop to fill in loads of stinky data
    while (1) {
            // read something, then stash it
            log_stash(L_INFO,print_buffer,strlen(print_buffer),stash_buffer,STASH_BUFFER_LEN);
    }
}
Revision:
3:e1ed8ae7691e
Parent:
2:9d04753a3ad2
Child:
4:9360fdf3a818
diff -r 9d04753a3ad2 -r e1ed8ae7691e logger.cpp
--- a/logger.cpp	Mon Sep 08 20:40:27 2014 +0000
+++ b/logger.cpp	Tue Dec 30 20:50:31 2014 +0000
@@ -5,7 +5,7 @@
 /**
  * @defgroup logger_lib Logger library
  * @{
- * @author Crt Lukancic Mori (crt@tech-review.net)
+ * @author Crt Lukancic Mori (crt@tech-review.net or crt@the-mori.com)
  * @short Logging library provides more standard re-routing of output.
  * @details While data logger needs an input to define where it output should go, we
  * could also override the output using a global variable, which would be read
@@ -13,13 +13,13 @@
  *
  */ 
 
-//Serial logSerial(PA_2, PA_3);
-Serial logSerial(PA_9, PA_10);
-char endline[]="\r\n";
+Serial logSerial(PA_2, PA_3);
+Serial BTSerial(PB_6, PA_10);
+char endline[]="\n";
 
 /**
  * Log_init initializes place where messages will be storred
- * @param plc Place id to initialize
+ * @param[in] plc Place id to initialize
  *
  * @retval 1 when succcess
  * @retval -ERR linux errno.h error message
@@ -36,6 +36,12 @@
         case L_LED:
             // find out what we want here -morse code would be fun ;)
             break;
+        case L_BTSERIAL:
+            logSerial.printf("BlueTooth initializing\r\n");
+            BTSerial.baud(9600);
+            logSerial.printf("OK\r\n");
+            logSerial.printf("Serial port initialized\r\n");
+            break;
         default:
             return -EINVAL;
     }
@@ -45,10 +51,10 @@
 
 /**
  * Log_msg determines where to save message.
- * @param plc Place id, where to store message(check logger.h for more infos)
- * @param lvl Debug level (ERROR,WARNING,DEBUG)
- * @param msg pointer to message
- * @param length length of message
+ * @param[in] plc Place id, where to store message(check logger.h for more infos)
+ * @param[in] lvl Debug level (ERROR,WARNING,DEBUG)
+ * @param[in] msg pointer to message
+ * @param[in] length length of message
  *
  * @retval 1 when succcess
  * @retval -ERR linux errno error message
@@ -70,7 +76,7 @@
             snprintf(send_message,length+6,"D: %s %s",msg,endline);
             break;
         case L_INFO:
-            snprintf(send_message,length+6,"I: %s %s",msg,endline);
+            snprintf(send_message,length+3,"%s %s",msg,endline);
             break;
         default:
             return -EINVAL;
@@ -89,6 +95,13 @@
         case L_LED:
             // find out what we want here -morse code would be fun ;)
             break;
+        case L_BTSERIAL:
+            if(BTSerial.writeable()) {
+                BTSerial.printf(send_message);
+            } else {
+                return -EBUSY;
+            }
+            break;
         default:
             return -EINVAL;
 
@@ -98,14 +111,14 @@
 }
 
 /// stash_buffer size
-char stash_buffer[STASH_BUFFER_LEN];
+static char stash_buffer[STASH_BUFFER_LEN];
 /**
  * Log_stash is meant to stash logs until they are ready to be sent, using log_pop function
  * Remember that this function can return also buffer full as result, which means you have to keep
  * deciding what you want to do - it just stashes files, but it keeps them in in case of buffer overflow.
- * @param lvl Debug level (ERROR,WARNING,DEBUG)
- * @param msg pointer to message
- * @param length length of message
+ * @param[in] lvl Debug level (ERROR,WARNING,DEBUG)
+ * @param[in] msg pointer to message
+ * @param[in] length length of message
  *
  * @retval 1 success
  * @retval -ERR linux errno error message - also includes buffer full!
@@ -134,7 +147,7 @@
             snprintf(stash_buffer_tmp,length+6,"D: %s %s",msg,endline);
             break;
         case L_INFO:
-            snprintf(stash_buffer_tmp,length+6,"I: %s %s",msg,endline);
+            snprintf(stash_buffer_tmp,length+3,"%s %s",msg,endline);
             break;
         default:
             return -EINVAL;
@@ -145,16 +158,20 @@
 
 /**
  * Log_pop function sends everything log_stash stashed
- * @param plc Place to where you pop stashed messages
+ * @param[in] plc Place to where you pop stashed messages
  *
- * @retval 1 for sucess
+ * @retval 1 for success
+ * @retval 2 for partial printout - did not send everything. You need to recall the function within timer so that you do not flood the serial port. So far it is only on BTSerial.
  * @retval -ERR errno.h error message
  */
 int32_t log_pop(uint8_t plc) {
+    char *tmp_needle;
+    size_t tmp_len;
+    
     switch(plc) {
         case L_SERIAL:
             if(logSerial.writeable()) {
-                logSerial.printf(stash_buffer);
+                logSerial.printf("%s",stash_buffer);
             } else {
                 return -EBUSY;
             }
@@ -164,16 +181,34 @@
         case L_LED:
             // find out what we want here -morse code would be fun ;)
             break;
+        case L_BTSERIAL:
+            if(BTSerial.writeable()) {
+                // big chunk of text is not OK - add some delay between it
+                tmp_needle=strstr(stash_buffer,endline);
+                if(tmp_needle != NULL)
+                {
+                    // we have found a end line - now print out up to this end line
+                    tmp_len = (tmp_needle+strlen(endline))-stash_buffer;
+                    // we pray for complete printf definition
+                    BTSerial.printf("%.*s", tmp_len,stash_buffer);
+                    // move whole array to remove out the line needle is increased before tmp_len to include the endline string
+                    memmove(stash_buffer,tmp_needle+strlen(endline),STASH_BUFFER_LEN-tmp_len);
+                    return 2;
+                }
+            } else {
+                return -EBUSY;
+            }
+            break;
         default:
             return -EINVAL;
 
     }
     
     //clear stash buffer
-    int i;
+  /*  int i;
     for(i=0;i<STASH_BUFFER_LEN;++i) {
         stash_buffer[i]=0;    
-    }
+    }*/
     return 1;
 }
 /**