initial commit

This commit is contained in:
Paul
2020-05-08 16:04:53 +02:00
parent 26b201ea2f
commit 30b502a1e4
538 changed files with 60624 additions and 21122 deletions

656
lib/uuid-log/src/uuid/log.h Normal file
View File

@@ -0,0 +1,656 @@
/*
* uuid-log - Microcontroller logging framework
* Copyright 2019 Simon Arlott
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UUID_LOG_H_
#define UUID_LOG_H_
#include <Arduino.h>
#include <cstdarg>
#include <cstdint>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <uuid/common.h>
namespace uuid {
/**
* Logging framework.
*
* Provides a framework for handling log messages. This library is for
* single threaded applications and cannot be used from an interrupt
* context.
*
* - <a href="https://github.com/nomis/mcu-uuid-log/">Git Repository</a>
* - <a href="https://mcu-uuid-log.readthedocs.io/">Documentation</a>
*/
// ANSI Colors - added by Proddy
// See https://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html
#define COLOR_RESET "\x1B[0m"
#define COLOR_BLACK "\x1B[0;30m"
#define COLOR_RED "\x1B[0;31m"
#define COLOR_GREEN "\x1B[0;32m"
#define COLOR_YELLOW "\x1B[0;33m"
#define COLOR_BLUE "\x1B[0;34m"
#define COLOR_MAGENTA "\x1B[0;35m"
#define COLOR_CYAN "\x1B[0;36m"
#define COLOR_WHITE "\x1B[0;37m"
#define COLOR_BOLD_ON "\x1B[1m"
#define COLOR_BOLD_OFF "\x1B[22m"
#define COLOR_BRIGHT_BLACK "\x1B[0;90m"
#define COLOR_BRIGHT_RED "\x1B[0;91m"
#define COLOR_BRIGHT_GREEN "\x1B[0;92m"
#define COLOR_BRIGHT_YELLOW "\x1B[0;99m"
#define COLOR_BRIGHT_BLUE "\x1B[0;94m"
#define COLOR_BRIGHT_MAGENTA "\x1B[0;95m"
#define COLOR_BRIGHT_CYAN "\x1B[0;96m"
#define COLOR_BRIGHT_WHITE "\x1B[0;97m"
#define COLOR_UNDERLINE "\x1B[4m"
/*
Background Black: \u001b[40m
Background Red: \u001b[41m
Background Green: \u001b[42m
Background Yellow: \u001b[43m
Background Blue: \u001b[44m
Background Magenta: \u001b[45m
Background Cyan: \u001b[46m
Background White: \u001b[47m
With the bright versions being:
Background Bright Black: \u001b[40;1m
Background Bright Red: \u001b[41;1m
Background Bright Green: \u001b[42;1m
Background Bright Yellow: \u001b[43;1m
Background Bright Blue: \u001b[44;1m
Background Bright Magenta: \u001b[45;1m
Background Bright Cyan: \u001b[46;1m
Background Bright White: \u001b[47;1m
*/
#define COLOR_BRIGHT_RED_BACKGROUND "\x1B[41;1m"
namespace log {
/**
* Severity level of log messages. Proddy added a VERBOSE
*
* @since 1.0.0
*/
enum Level : int8_t {
OFF = -1, /*!< Meta level representing no log messages. @since 1.0.0 */
EMERG = 0, /*!< System is unusable. @since 1.0.0 */
ALERT, /*!< Action must be taken immediately. @since 1.0.0 */
CRIT, /*!< Critical conditions. @since 1.0.0 */
ERR, /*!< Error conditions. @since 1.0.0 */
WARNING, /*!< Warning conditions. @since 1.0.0 */
NOTICE, /*!< Normal but significant conditions. @since 1.0.0 */
INFO, /*!< Informational messages. @since 1.0.0 */
TRACE, /*!< Trace messages. @since 1.0.0 */
DEBUG, /*!< Debug-level messages. @since 1.0.0 */
ALL, /*!< Meta level representing all log messages. @since 1.0.0 */
};
/**
* Facility type of the process logging a message.
*
* @since 1.0.0
*/
enum Facility : uint8_t {
KERN = 0, /*!< Kernel messages. @since 1.0.0 */
USER, /*!< User-level messages. @since 1.0.0 */
MAIL, /*!< Mail system. @since 1.0.0 */
DAEMON, /*!< System daemons. @since 1.0.0 */
AUTH, /*!< Security/authentication messages. @since 1.0.0 */
SYSLOG, /*!< Messages generated internally by logger. @since 1.0.0 */
LPR, /*!< Line printer subsystem. @since 1.0.0 */
NEWS, /*!< Network news subsystem. @since 1.0.0 */
UUCP, /*!< UUCP subsystem. @since 1.0.0 */
CRON, /*!< Clock daemon. @since 1.0.0 */
AUTHPRIV, /*!< Security/authentication messages (private). @since 1.0.0 */
FTP, /*!< FTP daemon. @since 1.0.0 */
NTP, /*!< NTP subsystem. @since 1.0.0 */
SECURITY, /*!< Log audit. @since 1.0.0 */
CONSOLE, /*!< Log alert. @since 1.0.0 */
CRON2, /*!< Scheduling daemon. @since 1.0.0 */
LOCAL0, /*!< Locally used facility 0. @since 1.0.0 */
LOCAL1, /*!< Locally used facility 1. @since 1.0.0 */
LOCAL2, /*!< Locally used facility 2. @since 1.0.0 */
LOCAL3, /*!< Locally used facility 3. @since 1.0.0 */
LOCAL4, /*!< Locally used facility 4. @since 1.0.0 */
LOCAL5, /*!< Locally used facility 5. @since 1.0.0 */
LOCAL6, /*!< Locally used facility 6. @since 1.0.0 */
LOCAL7, /*!< Locally used facility 7. @since 1.0.0 */
};
/**
* Format a system uptime timestamp as a string.
*
* Using the format "d+HH:mm:ss.SSS" with leading zeros for the days.
*
* @param[in] timestamp_ms System uptime in milliseconds, see uuid::get_uptime_ms().
* @param[in] days_width Leading zeros for the days part of the output.
* @return String with the formatted system uptime.
* @since 1.0.0
*/
std::string format_timestamp_ms(uint64_t timestamp_ms, unsigned int days_width = 1);
/**
* Get all log levels.
*
* @return A list of all log levels in priority order from
* uuid::log::Level::OFF to uuid::log::Level::ALL.
* @since 2.1.0
*/
std::vector<Level> levels();
/**
* Format a log level as a single character.
*
* Level::EMERG is represented as 'P' because it conflicts with
* Level::ERR and it used to be the "panic" level.
*
* @param[in] level Log level.
* @return Single character uppercase representation of the log level.
* @since 1.0.0
*/
char format_level_char(Level level);
/**
* Format a log level as an uppercase string.
*
* @param[in] level Log level.
* @return Uppercase name of the log level (flash string).
* @since 1.0.0
*/
const __FlashStringHelper * format_level_uppercase(Level level);
/**
* Get all log levels as uppercase strings.
*
* @return A list of all log levels in priority order from
* uuid::log::Level::OFF to uuid::log::Level::ALL
* as uppercase strings.
* @since 2.1.0
*/
std::vector<std::string> levels_uppercase();
/**
* Parse an uppercase string to a log level.
*
* @param[in] name Uppercase name of the log level.
* @param[out] level Log level.
* @return True if the named level is valid, otherwise false.
* @since 2.1.0
*/
bool parse_level_uppercase(const std::string & name, Level & level);
/**
* Format a log level as a lowercase string.
*
* @param[in] level Log level.
* @return Lowercase name of the log level (flash string).
* @since 1.0.0
*/
const __FlashStringHelper * format_level_lowercase(Level level);
/**
* Get all log levels as lowercase strings.
*
* @return A list of all log levels in priority order from
* uuid::log::Level::OFF to uuid::log::Level::ALL
* as lowercase strings.
* @since 2.1.0
*/
std::vector<std::string> levels_lowercase();
/**
* Parse a lowercase string to a log level.
*
* @param[in] name Lowercase name of the log level.
* @param[out] level Log level.
* @return True if the named level is valid, otherwise false.
* @since 2.1.0
*/
bool parse_level_lowercase(const std::string & name, Level & level);
/**
* Log message text with timestamp and logger attributes.
*
* These will be created when a message is logged and then passed to
* all registered handlers.
*
* @since 1.0.0
*/
struct Message {
/**
* Create a new log message (not directly useful).
*
* @param[in] uptime_ms System uptime, see uuid::get_uptime_ms().
* @param[in] level Severity level of the message.
* @param[in] facility Facility type of the process logging the message.
* @param[in] name Logger name (flash string).
* @param[in] text Log message text.
* @since 1.0.0
*/
Message(uint64_t uptime_ms, Level level, Facility facility, const __FlashStringHelper * name, const std::string && text);
~Message() = default;
/**
* System uptime at the time the message was logged.
*
* @see uuid::get_uptime_ms()
* @since 1.0.0
*/
const uint64_t uptime_ms;
/**
* Severity level of the message.
*
* @since 1.0.0
*/
const Level level;
/**
* Facility type of the process that logged the message.
*
* @since 1.0.0
*/
const Facility facility;
/**
* Name of the logger used (flash string).
*
* @since 1.0.0
*/
const __FlashStringHelper * name;
/**
* Formatted log message text.
*
* Does not include any of the other message attributes, those must
* be added by the handler when outputting messages.
*
* @since 1.0.0
*/
const std::string text;
};
/**
* Logger handler used to process log messages.
*
* @since 1.0.0
*/
class Handler {
public:
virtual ~Handler() = default;
/**
* Add a new log message.
*
* This should normally be put in a queue instead of being
* processed immediately so that log messages have minimal impact
* at the time of use.
*
* Queues should have a maximum size and discard the oldest message
* when full.
*
* @param[in] message New log message, shared by all handlers.
* @since 1.0.0
*/
virtual void operator<<(std::shared_ptr<Message> message) = 0;
protected:
Handler() = default;
};
/**
* Logger instance used to make log messages.
*
* @since 1.0.0
*/
class Logger {
public:
/**
* This is the maximum length of any log message.
*
* Determines the size of the buffer used for format string
* printing.
*
* @since 1.0.0
*/
static constexpr size_t MAX_LOG_LENGTH = 255; // proddy note, kept at 255
/**
* Create a new logger with the given name and logging facility.
*
* @param[in] name Logger name (flash string).
* @param[in] facility Default logging facility for messages.
*
* @since 1.0.0
*/
Logger(const __FlashStringHelper * name, Facility facility = Facility::LOCAL0);
~Logger() = default;
/**
* Register a log handler.
*
* Call again to change the log level.
*
* Do not call this function from a static initializer.
*
* @param[in] handler Handler object that will handle log
* messages.
* @param[in] level Minimum log level that the handler is
* interested in.
* @since 1.0.0
*/
static void register_handler(Handler * handler, Level level);
/**
* Unregister a log handler.
*
* It is safe to call this with a handler that is not registered.
*
* Do not call this function from a static initializer.
*
* @param[in] handler Handler object that will no longer handle
* log messages.
* @since 1.0.0
*/
static void unregister_handler(Handler * handler);
/**
* Get the current log level of a handler.
*
* It is safe to call this with a handler that is not registered.
*
* Do not call this function from a static initializer.
*
* @param[in] handler Handler object that may handle log
* messages.
* @return The current log level of the specified handler.
* @since 1.0.0
*/
static Level get_log_level(const Handler * handler);
/**
* Determine if the current log level is enabled by any registered
* handlers.
*
* @return The current minimum global log level across all
* handlers.
* @since 1.0.0
*/
static inline bool enabled(Level level) {
return level <= level_;
}
/**
* Log a message at level Level::EMERG.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void emerg(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::EMERG.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void emerg(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::ALERT.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void alert(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::ALERT.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void alert(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::CRIT.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void crit(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::CRIT.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void crit(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::ERR.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void err(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::ERR.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void err(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::WARNING.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void warning(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::WARNING.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void warning(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::NOTICE.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void notice(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::NOTICE.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void notice(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::INFO.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void info(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::INFO.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
*/
void info(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::DEBUG.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void debug(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::DEBUG.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void debug(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::TRACE.
*
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void trace(const char * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message at level Level::TRACE.
*
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void trace(const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 2, 3))) */;
/**
* Log a message with a custom facility.
*
* @param[in] level Severity level of the message.
* @param[in] facility Facility type of the process logging the message.
* @param[in] format Format string.
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void log(Level level, Facility facility, const char * format, ...) const /* __attribute__((format (printf, 3, 4))) */;
/**
* Log a message with a custom facility.
*
* @param[in] level Severity level of the message.
* @param[in] facility Facility type of the process logging the message.
* @param[in] format Format string (flash string).
* @param[in] ... Format string arguments.
* @since 1.0.0
*/
void log(Level level, Facility facility, const __FlashStringHelper * format, ...) const /* __attribute__((format (printf, 4, 5))) */;
private:
/**
* Refresh the minimum global log level across all handlers.
*
* @since 1.0.0
*/
static void refresh_log_level();
/**
* Log a message at the specified level.
*
* @param[in] level Severity level of the message.
* @param[in] format Format string.
* @param[in] ap Variable arguments pointer for format string.
* @since 1.0.0
*/
void vlog(Level level, const char * format, va_list ap) const;
/**
* Log a message at the specified level.
*
* @param[in] level Severity level of the message.
* @param[in] format Format string (flash string).
* @param[in] ap Variable arguments pointer for format string.
* @since 1.0.0
*/
void vlog(Level level, const __FlashStringHelper * format, va_list ap) const;
/**
* Log a message at the specified level and facility.
*
* @param[in] level Severity level of the message.
* @param[in] facility Facility type of the process logging the message.
* @param[in] format Format string.
* @param[in] ap Variable arguments pointer for format string.
* @since 1.0.0
*/
void vlog(Level level, Facility facility, const char * format, va_list ap) const;
/**
* Log a message at the specified level and facility.
*
* @param[in] level Severity level of the message.
* @param[in] facility Facility type of the process logging the message.
* @param[in] format Format string (flash string).
* @param[in] ap Variable arguments pointer for format string.
* @since 1.0.0
*/
void vlog(Level level, Facility facility, const __FlashStringHelper * format, va_list ap) const;
/**
* Dispatch a log message to all handlers that are registered to
* handle messages of the specified level.
*
* Automatically sets the timestamp of the message to the current
* system uptime.
*
* @param[in] level Severity level of the message.
* @param[in] facility Facility type of the process logging the message.
* @param[in] text Log message text.
* @since 1.0.0
*/
void dispatch(Level level, Facility facility, std::vector<char> & text) const;
static std::map<Handler *, Level> handlers_; /*!< Registered log handlers. @since 1.0.0 */
static Level level_; /*!< Minimum global log level across all handlers. @since 1.0.0 */
const __FlashStringHelper * name_; /*!< Logger name (flash string). @since 1.0.0 */
const Facility facility_; /*!< Default logging facility for messages. @since 1.0.0 */
};
} // namespace log
} // namespace uuid
#endif