Code Monkey home page Code Monkey logo

esplogger's Introduction

ESPLogger

arduino-library-badge Compile Library Examples

ESPLogger is an Arduino library offering a simple but complete interface to log events on ESP32 and ESP8266. Given the connection-oriented applications using these MCUs, ESPLogger provides a simple way to buffer data and efficiently send them through the most appropriate communication protocol.

Motivations

Nowadays, tons of projects are related to the IoT world: this implies network connection and data collection. ESP8266 and ESP32 were born with native Wi-Fi paired with effective libraries to communicate. These libraries are very mature both in NONOS framework and in Arduino environment. Unfortunately, I noticed that often there is the need to rewrite everything about the data collection. For example, the existing libraries support perfectly raw files, but for every project, you should implement every basic control such as check if the file is open, decide the open mode, check lines terminator, check if the file is ended, check if there is enough space and so on. In my personal opinion, managing all these details every time is tedious and sloppy: avoiding them would be a plus feature in many projects. Raising the abstraction level is an unquestionable benefit for Makers interested in prototyping advanced connected objects. Moreover, abstractions always increase code sharing and reuse, without forgetting that it is a key point to promote communication among people, fundamental in Arduino-like communities. Before ending up with my library, I searched on the Internet to discover a library answering the requirements above. I didn't find anything matching all of them because, usually, data collection projects implement their custom solution, and often, searching for "log" term, you will find a lot of results regarding software development and debugging, not concrete data collection.

For all these reasons, I have developed ESPLogger library, which is built on top of flash memory and files, leaving you the decision on when logging, when flushing data, and how to flush data.

Features

  1. Log on internal flash (using LittleFS or SPIFFS) and/or on SD card
  2. Monitor and limit log size
  3. Support for multiple log files
  4. Flush data when and how you need it on different channels (HTTP, Serial, ...)

Requirements

ESPLogger v2 is compatible with the following versions of Arduino Core (PIO Platform version between parentheses):

ESP8266 ESP32
^2.6.0 (^2.3.0) ^2.0.0 (^4.0.0)
^3.0.0 (^3.0.0)

Installation

The latest version of ESPLogger is available on Arduino Library Manager and on PlatformIO registry.

Usage

There are 2 main functions to be aware of: append and flush.

Append

bool append(const char* record)

it creates and stores a Record. You cannot log data containing non-printable characters, nor new line or carriage return. It returns true if the data is saved, false otherwise.

Flush

bool flush()

it calls your callback function with the following prototype:

bool flusher(const char* chunk, int n);

where chunk is a pointer to a buffer that contains one or more records separated by '\0' char; n tells the effective data size in the chunk buffer, including '\0's. This value is always <= chuckSize. This function should return true if the flush process succeeds, false otherwise (e.g. the server wasn't reachable). If true is returned, the library deletes the flushed data and, if other data are available, it calls flusher() again, otherwise it stops. If false, the library stops the flushing process and preserves the unflushed data for the next flush().

This kind of packetization can be useful in various scenarios, especially when the log is very large and you cannot send everything in a single shot. The maximum size of a chunk can be set at run-time through setChuckSize().

Please note that the flush() method guarantees that:

* The data are sent in the order they were recorded 
* During a single flush(), a record is sent at most once
* At the first failure signalled by `flusher` callback, the flush() method ends

It returns true if flush succeeds (hence the log file is emptied), false otherwise.

File systems

ESPLogger requires a file system to read and write the log. At the time of writing, there are few supported filesystems with minor differences between ESP32 and ESP8266:

  • LittleFS: the preferred file system for ESP8266 and ESP32 and the default for ESPLogger.
  • SPIFFS: the previous default file system before LittleFS. On ESP32, you have to #include <SPIFFS.h>.
  • SDFS (only for ESP8266): the standard file system for micro SD cards on ESP8266. It supports both FAT and FAT32. You have to #include <SDFS.h>. Do not use SD since it has an incompatible interface!
  • SD (only for ESP32): the standard file system for micro SD cards on ESP32. It supports both FAT and FAT32. You have to #include <SD.h>.

Be sure that the directory tree to the log file exists before calling begin(). Some file systems create the necessary path when opening a file (like SPIFFS), other won't (like SD for esp32).

Other APIs and examples

Look at the examples folder for working sketches and at the commented header files (*.h) for the details.

Limitations

ESPLogger is designed to log human-readable data, this means that data should be composed only by readable characters (excluding also carriage return (\r) and newline (\n)).

Data corruption is not managed, hence there is no CRC or other integrity system to check that your log file is not altered. It assumes that the flash memory is reliable and no other code will access the log file.

esplogger's People

Contributors

fabianoriccardi avatar umeshwalkar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esplogger's Issues

Mounting SPIFFS failed

Hi,
This library looks awesome but I'm unable to use it. Maybe I'm doing something wrong.
This is what I see when I ran your simple example:

Basic log example
Initializing SD card... E (19) SPIFFS: mount failed, -10025
[E][SPIFFS.cpp:72] begin(): Mounting SPIFFS failed! Error: -1
Failed!

I'm using latest PlatformIO with Atom, on Windows, the board is a ESPWROOM32.
build.log

PIFFS: mount failed, -10025 Error

When I run the example code in platformiIO I'm getting the following error:

E (57) SPIFFS: mount failed, -10025
[E][SPIFFS.cpp:72] begin(): Mounting SPIFFS failed! Error: -1
[E][vfs_api.cpp:22] open(): File system is not mounted

How can I solve this issue? I've erased the flash before testing the example code.

[ESP LOGGER] Opening log file error!

With the latest build, I am getting:
[ESP LOGGER] Opening log file error!
[ESP LOGGER] getActualSize() open log file error!
[ESP LOGGER] getActualSize() open log file error!

--> We had 0 attempts before reaching a time server
[ESP LOGGER] Opening log file error!
[ESP LOGGER] getActualSize() open log file error!

Apple chip M1 compatibility

After build operation on PlatformIO I get the following error (same as other libs, but if I update them error was gone):

Error: Could not find the package with 'fabiuz7/ESP Logger @ ^2.0.0' requirements for your system 'darwin_arm64'

Serve it over HTTP

Hello,
how would you serve it over HTTP?
Is there an example?
I don't think serving the log directly from SPIFFS into the WebServer handler function is the appropriate method mainly because there is no possibility to store "\n" or "\r".

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      request->send(SPIFFS, ....);
    });

so serving the file as text to be read from the browser would be tricky to read.
I think the same applies also by using this idea with the downside that the log is flushed so my understanding is that it will be removed from SPIFFS which is not always ideal

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      logger.flush(); //set log_string via flusher handler
      request->send(200, "text/text", log_string);
    });

What's the reason why "\n" cannot be used in the text?
Regards,

Problems with using SD_MMC as the SD card protocol

Hi,

we use SD_MMC to communicate to our SD card, instead of SPI.
Is it possible to use this with your library?
We ran into a few problems while testing and are unsure about the way we should call your lib.
And it seems like the logger_sd.h only supports SPI.

Thanks for all your work.
Greetings.

File size limit ~1000 Byte

Dear dev,
first of all I want to thank you for your ESP32 library!

I guess I'm doing something wrong, because I set the file size limit to "100000". Every time I start the logging process, the logging stops at a file size of 990 Bytes. I have no flusher-function because I just want to log my data and read it out later on with the FSBrowser-Example.

Maybe you can help pointing me in the right direction. Thank you very much!

Edit: I'm logging to internal storag on an ESP32

Getting a compile error

Seems I'm getting a multiple libraries error. It has been working on this system but suddenttly I'm seeing this error. Reinstalled and downleved to IDE 1.8 from 1.9. Same error.

D:\Users\jrhol\Documents\Arduino\libraries\ESP_Logger\src\logger_sd.cpp: In function 'bool copyFile(String, String)':

D:\Users\jrhol\Documents\Arduino\libraries\ESP_Logger\src\logger_sd.cpp:121:44: error: 'O_TRUNC' was not declared in this scope

File d=SD.open(destination, FILE_WRITE | O_TRUNC);

                                        ^

D:\Users\jrhol\Documents\Arduino\libraries\ESP_Logger\src\logger_sd.cpp:121:44: note: suggested alternative:

In file included from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/FatLib/FatFile.h:36:0,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/FatLib/ArduinoFiles.h:33,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/FatLib/FatLib.h:27,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/SdFat.h:33,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\SDFS\src/SDFS.h:36,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\SD\src/SD.h:25,

             from D:\Users\jrhol\Documents\Arduino\libraries\ESP_Logger\src\logger_sd.cpp:30:

C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/FatLib/FatApiConstants.h:81:15: note: 'sdfat::O_TRUNC'

const uint8_t O_TRUNC = 0X10;

           ^

D:\Users\jrhol\Documents\Arduino\libraries\ESP_Logger\src\logger_sd.cpp: In member function 'virtual bool LoggerSD::flush()':

D:\Users\jrhol\Documents\Arduino\libraries\ESP_Logger\src\logger_sd.cpp:229:56: error: 'O_TRUNC' was not declared in this scope

     File tempFile=SD.open(tempFilePath, FILE_WRITE|O_TRUNC);

                                                    ^

D:\Users\jrhol\Documents\Arduino\libraries\ESP_Logger\src\logger_sd.cpp:229:56: note: suggested alternative:

In file included from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/FatLib/FatFile.h:36:0,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/FatLib/ArduinoFiles.h:33,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/FatLib/FatLib.h:27,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/SdFat.h:33,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\SDFS\src/SDFS.h:36,

             from C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\SD\src/SD.h:25,

             from D:\Users\jrhol\Documents\Arduino\libraries\ESP_Logger\src\logger_sd.cpp:30:

C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266SdFat\src/FatLib/FatApiConstants.h:81:15: note: 'sdfat::O_TRUNC'

const uint8_t O_TRUNC = 0X10;

           ^

Multiple libraries were found for "SD.h"
Used: C:\Users\jrhol\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\SD
Not used: C:\Program Files (x86)\Arduino\libraries\SD
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

Safely access to download

I need to download log file through web server. How can I do it safely?

First idea: create SPIFFS file("/log/mylog.log") and read all content, but I think it is dangerous cause logger also works.

LoggerSPIFFS in a class

Since your library is at a pretty low level - append(string)., I'm building a class to make structured records to append, so your libary is part of that class.

The problem that I'm having is that if I try to instantiate LoggerSpiffs mylog("/log/mylog.log") in my class, the compiler complains, but if I move it to my main. ino file, it works. Do you know why this would be?

I can pass it in, as long as LoggerSPIFFS is recognized as a type for my private copy.

Regard,

David Duehren

issue in flush function when flushing is fail

Hi,

Appreciated your effort for this library.

Please correct me if i am wrong.
I have noticed a issue regarding freeing dynamically allocated memory for "buffer" when user application returns false to "flush".
at line number 211 ("logger_spiffs.cpp") and 271 ("logger_sd.cpp"), we are returning with false without freeing "buffer".

either we can call free(buffer) at this line or simply we can avoid/comment "return false" statement. because anyway we are returning status of "successFlush" at bottom which is already tagged as "false".

probably, this could be better idea to allocate memory using char buffer[sizeLimitPerChunk];
I don't know if all platform can handle it, but ESP32+Arduino can handle this way.

Regards,
Umesh

Build error in platformIO IDE. SD.h is missing

When I run the example code in platformiIO I'm getting the following error:

Compiling .pio\build\esp32doit-devkit-v1\libfca\ESP Logger_ID5879\logger_sd.cpp.o

             ^
Compiling .pio\build\esp32doit-devkit-v1\libfca\ESP Logger_ID5879\logger_spiffs.cpp.o
C:\users\user\.platformio\lib\ESP Logger_ID5879\src\logger_sd.cpp:30:16: fatal error: SD.h: No such file or directory

************************************************************
* Looking for SD.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:SD.h"
* Web  > https://platformio.org/lib/search?query=header:SD.h
*
************************************************************

compilation terminated.

Loop logging

Thanks for you project! I'm waiting it for my IoT project: https://github.com/dontsovcmc/waterius

I need to log wake up events infinitely, so I need loop logging. Can I do it with esp-logger?
(Maybe I need to check isFull() every print and replace pointer to start?)

Library incompatible with newest version of Ticker library

`n file included from D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp:29:0:

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.h: In constructor 'LoggerRoutine::LoggerRoutine(Logger&, float)':

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.h:44:20: error: no matching function for call to 'Ticker::Ticker()'

   period(period){}; 

                ^

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.h:44:20: note: candidates are:

In file included from D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.h:32:0,

             from D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp:29:

D:\David\MyDocuments\Arduino\libraries\Ticker/Ticker.h:74:2: note: Ticker::Ticker(fptr, uint32_t, uint32_t, resolution_t)

Ticker(fptr callback, uint32_t timer, uint32_t repeat = 0, resolution_t resolution = MICROS);

^

D:\David\MyDocuments\Arduino\libraries\Ticker/Ticker.h:74:2: note: candidate expects 4 arguments, 0 provided

D:\David\MyDocuments\Arduino\libraries\Ticker/Ticker.h:62:7: note: Ticker::Ticker(const Ticker&)

class Ticker {

   ^

D:\David\MyDocuments\Arduino\libraries\Ticker/Ticker.h:62:7: note: candidate expects 1 argument, 0 provided

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp: In function 'void routine(LoggerRoutine*)':

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp:33:17: error: 'class Ticker' has no member named 'attach'

logRun->ticker.attach(logRun->period,routine,logRun);

             ^

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp: In member function 'bool LoggerRoutine::begin(bool)':

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp:41:10: error: 'class Ticker' has no member named 'attach'

ticker.attach(period, routine, this);

      ^

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp: In member function 'void LoggerRoutine::setPeriod(float, bool)':

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp:53:10: error: 'class Ticker' has no member named 'detach'

ticker.detach();

      ^

D:\David\MyDocuments\Arduino\libraries\ESP_Logger\src\logger_routine.cpp:54:10: error: 'class Ticker' has no member named 'attach'

ticker.attach(period, routine, this);

      ^`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.