From 21f493ba737403cb815aa06f4c472de54cd0663a Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 8 Nov 2020 00:07:43 +0100 Subject: [PATCH] add new logger conzept --- src/LoRa_APRS_iGate.cpp | 143 ++++++++++++------------ src/configuration.cpp | 13 +-- src/display.cpp | 4 +- src/logger.cpp | 234 ++++++++++++++++++++++++++++++++++++++++ src/logger.h | 75 +++++++++++++ 5 files changed, 391 insertions(+), 78 deletions(-) create mode 100644 src/logger.cpp create mode 100644 src/logger.h diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index ae175a8..acb2a86 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -10,6 +10,8 @@ #include #include +#include "logger.h" + #include "LoRa_APRS.h" #include "pins.h" @@ -60,20 +62,22 @@ void setup() Wire.begin(SDA, SCL); if (!powerManagement.begin(Wire)) { - Serial.println("LoRa-APRS / Init / AXP192 Begin PASS"); - } else { - Serial.println("LoRa-APRS / Init / AXP192 Begin FAIL"); + logPrintlnI("AXP192 init done!"); + } + else + { + logPrintlnE("AXP192 init failed!"); } powerManagement.activateLoRa(); powerManagement.activateOLED(); powerManagement.deactivateGPS(); #endif - setup_display(); - delay(500); - Serial.println("[INFO] LoRa APRS iGate & Digi by OE5BPA (Peter Buchegger)"); - show_display("OE5BPA", "LoRa APRS iGate & Digi", "by Peter Buchegger", 3000); + logPrintlnA("LoRa APRS iGate & Digi by OE5BPA (Peter Buchegger)"); + logPrintlnA("Version: 1.0.0-dev"); + setup_display(); + show_display("OE5BPA", "LoRa APRS iGate & Digi", "by Peter Buchegger", "1.0.0-dev", 3000); load_config(); setup_lora(); @@ -100,7 +104,7 @@ void setup() } delay(500); - Serial.println("[INFO] setup done..."); + logPrintlnI("setup done..."); secondsSinceDisplay = 0; } @@ -118,7 +122,6 @@ void loop() { turn_off_display(); display_is_on = false; - Serial.println("-"); } static bool beacon_aprs_is = Config.aprs_is.active && Config.aprs_is.beacon; @@ -145,7 +148,7 @@ void loop() static bool configWasOpen = false; if(configWasOpen && ftpServer.countConnections() == 0) { - Serial.println("[WARN] Maybe the config has been changed via FTP, lets restart now to get the new config..."); + logPrintlnW("Maybe the config has been changed via FTP, lets restart now to get the new config..."); Serial.println(); ESP.restart(); } @@ -159,7 +162,7 @@ void loop() if(Config.wifi.active && WiFiMulti.run() != WL_CONNECTED) { setup_display(); secondsSinceDisplay = 0; display_is_on = true; - Serial.println("[ERROR] WiFi not connected!"); + logPrintlnE("WiFi not connected!"); show_display("ERROR", "WiFi not connected!"); delay(1000); return; @@ -167,26 +170,26 @@ void loop() if(Config.aprs_is.active && !aprs_is->connected()) { setup_display(); secondsSinceDisplay = 0; display_is_on = true; - Serial.print("[INFO] connecting to server: "); - Serial.print(Config.aprs_is.server); - Serial.print(" on port: "); - Serial.println(Config.aprs_is.port); - show_display("INFO", "Connecting to server"); + logPrintI("connecting to APRS-IS server: "); + logPrintI(Config.aprs_is.server); + logPrintI(" on port: "); + logPrintlnI(String(Config.aprs_is.port)); + show_display("INFO", "Connecting to APRS-IS server"); if(!aprs_is->connect(Config.aprs_is.server, Config.aprs_is.port)) { - Serial.println("[ERROR] Connection failed."); - Serial.println("[INFO] Waiting 5 seconds before retrying..."); + logPrintlnE("Connection failed."); + logPrintlnI("Waiting 5 seconds before retrying..."); show_display("ERROR", "Server connection failed!", "waiting 5 sec"); delay(5000); return; } - Serial.println("[INFO] Connected to server!"); + logPrintlnI("Connected to APRS-IS server!"); } if(Config.aprs_is.active && aprs_is->available() > 0) { String str = aprs_is->getMessage(); - Serial.print("[" + timeClient.getFormattedTime() + "] "); - Serial.println(str); + logPrintD("[" + timeClient.getFormattedTime() + "] "); + logPrintlnD(str); } if(lora_aprs.hasMessage()) { @@ -194,13 +197,13 @@ void loop() setup_display(); secondsSinceDisplay = 0; display_is_on = true; show_display(Config.callsign, timeClient.getFormattedTime() + " LoRa", "RSSI: " + String(lora_aprs.packetRssi()) + ", SNR: " + String(lora_aprs.packetSnr()), msg->toString()); - Serial.print("[" + timeClient.getFormattedTime() + "] "); - Serial.print(" Received packet '"); - Serial.print(msg->toString()); - Serial.print("' with RSSI "); - Serial.print(lora_aprs.packetRssi()); - Serial.print(" and SNR "); - Serial.println(lora_aprs.packetSnr()); + logPrintD("[" + timeClient.getFormattedTime() + "] "); + logPrintD(" Received packet '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(lora_aprs.packetSnr())); if(Config.aprs_is.active) { @@ -210,12 +213,12 @@ void loop() { if(msg->getSource().indexOf(Config.callsign) != -1) { - Serial.print("Message already received as repeater: '"); - Serial.print(msg->toString()); - Serial.print("' with RSSI "); - Serial.print(lora_aprs.packetRssi()); - Serial.print(" and SNR "); - Serial.println(lora_aprs.packetSnr()); + logPrintD("Message already received as repeater: '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(lora_aprs.packetSnr())); return; } @@ -235,24 +238,24 @@ void loop() { setup_display(); secondsSinceDisplay = 0; display_is_on = true; show_display(Config.callsign, "RSSI: " + String(lora_aprs.packetRssi()) + ", SNR: " + String(lora_aprs.packetSnr()), msg->toString(), 0); - Serial.print("Received packet '"); - Serial.print(msg->toString()); - Serial.print("' with RSSI "); - Serial.print(lora_aprs.packetRssi()); - Serial.print(" and SNR "); - Serial.println(lora_aprs.packetSnr()); + logPrintD("Received packet '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(lora_aprs.packetSnr())); msg->setPath(String(Config.callsign) + "*"); lora_aprs.sendMessage(msg); lastMessages.insert({secondsSinceStartup, msg}); } else { - Serial.print("Message already received (timeout): '"); - Serial.print(msg->toString()); - Serial.print("' with RSSI "); - Serial.print(lora_aprs.packetRssi()); - Serial.print(" and SNR "); - Serial.println(lora_aprs.packetSnr()); + logPrintD("Message already received (timeout): '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(lora_aprs.packetSnr())); } return; } @@ -276,19 +279,19 @@ void loop() beacon_digi = false; setup_display(); secondsSinceDisplay = 0; display_is_on = true; show_display(Config.callsign, "Beacon to HF..."); - Serial.print("[" + timeClient.getFormattedTime() + "] "); - Serial.print(BeaconMsg->encode()); + logPrintD("[" + timeClient.getFormattedTime() + "] "); + logPrintlnD(BeaconMsg->encode()); lora_aprs.sendMessage(BeaconMsg); - Serial.println("finished TXing..."); + logPrintlnD("finished TXing..."); show_display(Config.callsign, "Standby..."); } if(beacon_aprs_is) { beacon_aprs_is = false; setup_display(); secondsSinceDisplay = 0; display_is_on = true; - show_display(Config.callsign, "Beacon to APRS IS Server..."); - Serial.print("[" + timeClient.getFormattedTime() + "] "); - Serial.print(BeaconMsg->encode()); + show_display(Config.callsign, "Beacon to APRS-IS Server..."); + logPrintD("[" + timeClient.getFormattedTime() + "] "); + logPrintlnD(BeaconMsg->encode()); aprs_is->sendMessage(BeaconMsg); show_display(Config.callsign, "Standby..."); } @@ -300,7 +303,7 @@ void load_config() Config = confmg.readConfiguration(); if(Config.callsign == "NOCALL-10") { - Serial.println("[ERROR] You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!"); + logPrintlnE("You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!"); show_display("ERROR", "You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!"); while (true) {} @@ -308,7 +311,7 @@ void load_config() if(Config.aprs_is.active && !Config.wifi.active) { - Serial.println("[ERROR] You have to activate Wifi for APRS IS to work, please check your settings!"); + logPrintlnE("You have to activate Wifi for APRS IS to work, please check your settings!"); show_display("ERROR", "You have to activate Wifi for APRS IS to work, please check your settings!"); while (true) {} @@ -318,7 +321,7 @@ void load_config() { Config.display.overwritePin = KEY_BUILTIN; } - Serial.println("[INFO] Configuration loaded!"); + logPrintlnI("Configuration loaded!"); } void setup_wifi() @@ -327,22 +330,20 @@ void setup_wifi() WiFi.setHostname(Config.callsign.c_str()); for(Configuration::Wifi::AP ap : Config.wifi.APs) { - Serial.print("[INFO] Looking for AP: "); - Serial.println(ap.SSID); + logPrintD("Looking for AP: "); + logPrintlnD(ap.SSID); WiFiMulti.addAP(ap.SSID.c_str(), ap.password.c_str()); } - Serial.print("[INFO] Waiting for WiFi"); + logPrintlnI("Waiting for WiFi"); show_display("INFO", "Waiting for WiFi"); while(WiFiMulti.run() != WL_CONNECTED) { - Serial.print("."); show_display("INFO", "Waiting for WiFi", "...."); delay(500); } - Serial.println(""); - Serial.println("[INFO] WiFi connected"); - Serial.print("[INFO] IP address: "); - Serial.println(WiFi.localIP()); + logPrintlnI("WiFi connected"); + logPrintD("IP address: "); + logPrintlnD(WiFi.localIP().toString()); show_display("INFO", "WiFi connected", "IP: ", WiFi.localIP().toString(), 2000); } @@ -383,7 +384,7 @@ void setup_ota() }); ArduinoOTA.setHostname(Config.callsign.c_str()); ArduinoOTA.begin(); - Serial.println("[INFO] OTA init done!"); + logPrintlnI("OTA init done!"); } void setup_lora() @@ -392,7 +393,7 @@ void setup_lora() lora_aprs.setTxFrequency(Config.lora.frequencyTx); if (!lora_aprs.begin(lora_aprs.getRxFrequency())) { - Serial.println("[ERROR] Starting LoRa failed!"); + logPrintlnE("Starting LoRa failed!"); show_display("ERROR", "Starting LoRa failed!"); while (1); } @@ -400,7 +401,7 @@ void setup_lora() lora_aprs.setSpreadingFactor(Config.lora.spreadingFactor); lora_aprs.setSignalBandwidth(Config.lora.signalBandwidth); lora_aprs.setCodingRate4(Config.lora.codingRate4); - Serial.println("[INFO] LoRa init done!"); + logPrintlnI("LoRa init done!"); show_display("INFO", "LoRa init done!", 2000); BeaconMsg = std::shared_ptr(new APRSMessage()); @@ -416,10 +417,10 @@ void setup_ntp() timeClient.begin(); if(!timeClient.forceUpdate()) { - Serial.println("[WARN] NTP Client force update issue!"); + logPrintlnW("NTP Client force update issue!"); show_display("WARN", "NTP Client force update issue!", 2000); } - Serial.println("[INFO] NTP Client init done!"); + logPrintlnI("NTP Client init done!"); show_display("INFO", "NTP Client init done!", 2000); } @@ -454,13 +455,13 @@ void setup_ftp() } for(Configuration::Ftp::User user : Config.ftp.users) { - Serial.print("[INFO] Adding user to FTP Server: "); - Serial.println(user.name); + logPrintD("Adding user to FTP Server: "); + logPrintlnD(user.name); ftpServer.addUser(user.name, user.password); } ftpServer.addFilesystem("SPIFFS", &SPIFFS); ftpServer.begin(); - Serial.println("[INFO] FTP Server init done!"); + logPrintlnI("FTP Server init done!"); } String create_lat_aprs(double lat) diff --git a/src/configuration.cpp b/src/configuration.cpp index 92fa1e3..257f02e 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -1,17 +1,18 @@ -#include "SPIFFS.h" +#include #include "configuration.h" +#include "logger.h" ConfigurationManagement::ConfigurationManagement(String FilePath) : mFilePath(FilePath) { if(!SPIFFS.begin(true)) { - Serial.println("[ERROR] Mounting SPIFFS was not possible. Trying to format SPIFFS..."); + logPrintlnE("Mounting SPIFFS was not possible. Trying to format SPIFFS..."); SPIFFS.format(); if(!SPIFFS.begin()) { - Serial.println("[ERROR] Formating SPIFFS was not okay!"); + logPrintlnE("Formating SPIFFS was not okay!"); } } } @@ -21,14 +22,14 @@ Configuration ConfigurationManagement::readConfiguration() File file = SPIFFS.open(mFilePath); if(!file) { - Serial.println("Failed to open file for reading..."); + logPrintlnE("Failed to open file for reading..."); return Configuration(); } DynamicJsonDocument data(2048); DeserializationError error = deserializeJson(data, file); if(error) { - Serial.println("Failed to read file, using default configuration."); + logPrintlnW("Failed to read file, using default configuration."); } //serializeJson(data, Serial); //Serial.println(); @@ -102,7 +103,7 @@ void ConfigurationManagement::writeConfiguration(Configuration conf) File file = SPIFFS.open(mFilePath, "w"); if(!file) { - Serial.println("Failed to open file for writing..."); + logPrintlnE("Failed to open file for writing..."); return; } DynamicJsonDocument data(2048); diff --git a/src/display.cpp b/src/display.cpp index 09c90ab..f8a69c0 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -5,6 +5,7 @@ #include "display.h" #include "pins.h" +#include "logger.h" Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST); @@ -18,9 +19,10 @@ void setup_display() Wire.begin(OLED_SDA, OLED_SCL); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { - Serial.println("SSD1306 allocation failed"); + logPrintlnE("SSD1306 allocation failed"); while (1); } + logPrintlnI("Display init done!"); } void turn_off_display() diff --git a/src/logger.cpp b/src/logger.cpp new file mode 100644 index 0000000..97f53a4 --- /dev/null +++ b/src/logger.cpp @@ -0,0 +1,234 @@ +#include "logger.h" + +#undef LOG_RESET_COLOR +#undef LOG_COLOR_E +#undef LOG_COLOR_W +#undef LOG_COLOR_I +#undef LOG_COLOR_D +#undef LOG_COLOR_V + +#define LOG_COLOR_BLACK "30" +#define LOG_COLOR_RED "31" +#define LOG_COLOR_GREEN "32" +#define LOG_COLOR_BROWN "33" +#define LOG_COLOR_BLUE "34" +#define LOG_COLOR_PURPLE "35" +#define LOG_COLOR_CYAN "36" +#define LOG_COLOR(COLOR) "\033[0;" COLOR "m" +#define LOG_BOLD(COLOR) "\033[1;" COLOR "m" +#define LOG_RESET_COLOR "\033[0m" +#define LOG_COLOR_E LOG_COLOR(LOG_COLOR_RED) +#define LOG_COLOR_W LOG_COLOR(LOG_COLOR_BROWN) +#define LOG_COLOR_I LOG_COLOR(LOG_COLOR_GREEN) +#define LOG_COLOR_D LOG_COLOR(LOG_COLOR_BLUE) +#define LOG_COLOR_V LOG_COLOR(LOG_COLOR_CYAN) + +Logger::Logger() + : _serial(Serial), _level(DEBUG_LEVEL_DEBUG), _printIsNewline(true) +{ +} + +void Logger::setSerial(HardwareSerial & serial) +{ + _serial = serial; +} + +void Logger::setDebugLevel(debug_level_t level) +{ + _level = level; +} + +void Logger::printA(const String & text, const char * file, uint32_t line) +{ + printStartColor(DEBUG_LEVEL_NONE); + printHeader(DEBUG_LEVEL_NONE, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_NONE); +} + +void Logger::printE(const String & text, const char * file, uint32_t line) +{ + printStartColor(DEBUG_LEVEL_ERROR); + printHeader(DEBUG_LEVEL_ERROR, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_ERROR); +} + +void Logger::printlnA(const String & text, const char * file, uint32_t line) +{ + printStartColor(DEBUG_LEVEL_NONE); + printHeader(DEBUG_LEVEL_NONE, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_NONE); +} + +void Logger::printlnE(const String & text, const char * file, uint32_t line) +{ + printStartColor(DEBUG_LEVEL_ERROR); + printHeader(DEBUG_LEVEL_ERROR, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_ERROR); +} + +void Logger::printV(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_VERBOSE) + { + printStartColor(DEBUG_LEVEL_VERBOSE); + printHeader(DEBUG_LEVEL_VERBOSE, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_VERBOSE); + } +} + +void Logger::printD(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_DEBUG) + { + printStartColor(DEBUG_LEVEL_DEBUG); + printHeader(DEBUG_LEVEL_DEBUG, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_DEBUG); + } +} + +void Logger::printI(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_INFO) + { + printStartColor(DEBUG_LEVEL_INFO); + printHeader(DEBUG_LEVEL_INFO, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_INFO); + } +} + +void Logger::printW(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_WARN) + { + printStartColor(DEBUG_LEVEL_WARN); + printHeader(DEBUG_LEVEL_WARN, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_WARN); + } +} + +void Logger::printlnV(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_VERBOSE) + { + printStartColor(DEBUG_LEVEL_VERBOSE); + printHeader(DEBUG_LEVEL_VERBOSE, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_VERBOSE); + } +} + +void Logger::printlnD(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_DEBUG) + { + printStartColor(DEBUG_LEVEL_DEBUG); + printHeader(DEBUG_LEVEL_DEBUG, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_DEBUG); + } +} + +void Logger::printlnI(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_INFO) + { + printStartColor(DEBUG_LEVEL_INFO); + printHeader(DEBUG_LEVEL_INFO, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_INFO); + } +} + +void Logger::printlnW(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_WARN) + { + printStartColor(DEBUG_LEVEL_WARN); + printHeader(DEBUG_LEVEL_WARN, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_WARN); + } +} + +void Logger::printStartColor(debug_level_t level) +{ + switch (level) + { + case DEBUG_LEVEL_ERROR: + _serial.print(LOG_COLOR_E); + break; + case DEBUG_LEVEL_WARN: + _serial.print(LOG_COLOR_W); + break; + case DEBUG_LEVEL_INFO: + _serial.print(LOG_COLOR_I); + break; + case DEBUG_LEVEL_DEBUG: + _serial.print(LOG_COLOR_D); + break; + case DEBUG_LEVEL_VERBOSE: + _serial.print(LOG_COLOR_V); + break; + default: + break; + } +} + +void Logger::printHeader(debug_level_t level, const char * file, uint32_t line, bool isln) +{ + if (_printIsNewline) + { + Serial.printf("%c %25s %4d : ", levelToChar(level), file, line); + if(!isln) + { + _printIsNewline = false; + } + } + else + { + _printIsNewline = isln; + } +} + +void Logger::printEndColor(debug_level_t level) +{ + switch (level) + { + case DEBUG_LEVEL_ERROR: + case DEBUG_LEVEL_WARN: + case DEBUG_LEVEL_INFO: + case DEBUG_LEVEL_DEBUG: + case DEBUG_LEVEL_VERBOSE: + _serial.print(LOG_RESET_COLOR); + break; + default: + break; + } +} + +char Logger::levelToChar(debug_level_t level) +{ + switch (level) + { + case DEBUG_LEVEL_ERROR: + return 'E'; + case DEBUG_LEVEL_WARN: + return 'W'; + case DEBUG_LEVEL_INFO: + return 'I'; + case DEBUG_LEVEL_DEBUG: + return 'D'; + case DEBUG_LEVEL_VERBOSE: + return 'V'; + default: + return ' '; + } +} diff --git a/src/logger.h b/src/logger.h new file mode 100644 index 0000000..33ba99c --- /dev/null +++ b/src/logger.h @@ -0,0 +1,75 @@ +#ifndef _LOGGER_H_ +#define _LOGGER_H_ + +#include + +class Logger +{ +public: + enum debug_level_t { + DEBUG_LEVEL_NONE, // No debug output + DEBUG_LEVEL_ERROR, // Critical errors + DEBUG_LEVEL_WARN, // Error conditions but not critical + DEBUG_LEVEL_INFO, // Information messages + DEBUG_LEVEL_DEBUG, // Extra information - default level (if not changed) + DEBUG_LEVEL_VERBOSE, // More information than the usual + DEBUG_LEVELS_SIZE + }; + + static Logger & instance() + { + static Logger _instance; + return _instance; + } + + ~Logger() {} + + void setSerial(HardwareSerial & serial = Serial); + void setDebugLevel(debug_level_t level); + + // print always: + void printA(const String & text, const char * file, uint32_t line); // always + void printE(const String & text, const char * file, uint32_t line); // error + void printlnA(const String & text, const char * file, uint32_t line); // always with new line + void printlnE(const String & text, const char * file, uint32_t line); // error with new line + + // depending on verbose level: + void printV(const String & text, const char * file, uint32_t line); // verbose + void printD(const String & text, const char * file, uint32_t line); // debug + void printI(const String & text, const char * file, uint32_t line); // information + void printW(const String & text, const char * file, uint32_t line); // warning + + void printlnV(const String & text, const char * file, uint32_t line); // verbose with new line + void printlnD(const String & text, const char * file, uint32_t line); // debug with new line + void printlnI(const String & text, const char * file, uint32_t line); // information with new line + void printlnW(const String & text, const char * file, uint32_t line); // warning with new line + +private: + HardwareSerial & _serial; + debug_level_t _level; + bool _printIsNewline; + + void printStartColor(debug_level_t level); + void printHeader(debug_level_t level, const char * file, uint32_t line, bool isln); + void printEndColor(debug_level_t level); + char levelToChar(debug_level_t level); + + Logger(); + Logger(const Logger &); + Logger & operator = (const Logger &); +}; + +#define logPrintA(text) Logger::instance().printA(text, __FILE__, __LINE__) +#define logPrintE(text) Logger::instance().printE(text, __FILE__, __LINE__) +#define logPrintlnA(text) Logger::instance().printlnA(text, __FILE__, __LINE__) +#define logPrintlnE(text) Logger::instance().printlnE(text, __FILE__, __LINE__) +#define logPrintV(text) Logger::instance().printV(text, __FILE__, __LINE__) +#define logPrintD(text) Logger::instance().printD(text, __FILE__, __LINE__) +#define logPrintI(text) Logger::instance().printI(text, __FILE__, __LINE__) +#define logPrintW(text) Logger::instance().printW(text, __FILE__, __LINE__) +#define logPrintlnV(text) Logger::instance().printlnV(text, __FILE__, __LINE__) +#define logPrintlnD(text) Logger::instance().printlnD(text, __FILE__, __LINE__) +#define logPrintlnI(text) Logger::instance().printlnI(text, __FILE__, __LINE__) +#define logPrintlnW(text) Logger::instance().printlnW(text, __FILE__, __LINE__) + +#endif