summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-02-08 16:40:57 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-02-11 11:23:51 +0200
commit8a401ed4119aac4ca994f70cb5540bc1b2c6939a (patch)
treef14a6eecb27b8db376351c331cce40d1d410cc5d
parentd8f2ed7d0d7f0de7184916da59cd2097529bd1c9 (diff)
libcamera: log: Allow extending log messages
Introduce a base Loggable class that can be inherited from by other classes to support adding per-instance information to the log messages. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
-rw-r--r--src/libcamera/include/log.h23
-rw-r--r--src/libcamera/log.cpp124
2 files changed, 145 insertions, 2 deletions
diff --git a/src/libcamera/include/log.h b/src/libcamera/include/log.h
index ad8f8452..8ea5a1eb 100644
--- a/src/libcamera/include/log.h
+++ b/src/libcamera/include/log.h
@@ -54,6 +54,7 @@ public:
LogMessage(const char *fileName, unsigned int line,
const LogCategory &category, LogSeverity severity);
LogMessage(const LogMessage &) = delete;
+ LogMessage(LogMessage &&);
~LogMessage();
std::ostream &stream() { return msgStream_; }
@@ -66,13 +67,31 @@ private:
LogSeverity severity_;
};
+class Loggable
+{
+public:
+ virtual ~Loggable();
+
+protected:
+ virtual std::string logPrefix() const = 0;
+
+ LogMessage _log(const char *file, unsigned int line,
+ LogSeverity severity);
+ LogMessage _log(const char *file, unsigned int line,
+ const LogCategory &category, LogSeverity severity);
+};
+
+LogMessage _log(const char *file, unsigned int line, LogSeverity severity);
+LogMessage _log(const char *file, unsigned int line,
+ const LogCategory &category, LogSeverity severity);
+
#ifndef __DOXYGEN__
#define _LOG_CATEGORY(name) logCategory##name
#define _LOG1(severity) \
- LogMessage(__FILE__, __LINE__, Log##severity).stream()
+ _log(__FILE__, __LINE__, Log##severity).stream()
#define _LOG2(category, severity) \
- LogMessage(__FILE__, __LINE__, _LOG_CATEGORY(category)(), Log##severity).stream()
+ _log(__FILE__, __LINE__, _LOG_CATEGORY(category)(), Log##severity).stream()
/*
* Expand the LOG() macro to _LOG1() or _LOG2() based on the number of
diff --git a/src/libcamera/log.cpp b/src/libcamera/log.cpp
index edeb5eab..26ebf410 100644
--- a/src/libcamera/log.cpp
+++ b/src/libcamera/log.cpp
@@ -405,6 +405,25 @@ LogMessage::LogMessage(const char *fileName, unsigned int line,
init(fileName, line);
}
+/**
+ * \brief Move-construct a log message
+ * \param[in] other The other message
+ *
+ * The move constructor is meant to support the _log() functions. Thanks to copy
+ * elision it will likely never be called, but C++11 only permits copy elision,
+ * it doesn't enforce it unlike C++17. To avoid potential link errors depending
+ * on the compiler type and version, and optimization level, the move
+ * constructor is defined even if it will likely never be called, and ensures
+ * that the destructor of the \a other message will not output anything to the
+ * log by setting the severity to -1.
+ */
+LogMessage::LogMessage(LogMessage &&other)
+ : msgStream_(std::move(other.msgStream_)), category_(other.category_),
+ severity_(other.severity_)
+{
+ other.severity_ = static_cast<LogSeverity>(-1);
+}
+
void LogMessage::init(const char *fileName, unsigned int line)
{
/* Log the timestamp, severity and file information. */
@@ -424,6 +443,10 @@ void LogMessage::init(const char *fileName, unsigned int line)
LogMessage::~LogMessage()
{
+ /* Don't print anything if we have been moved to another LogMessage. */
+ if (severity_ == -1)
+ return;
+
msgStream_ << std::endl;
if (severity_ >= category_.severity()) {
@@ -446,6 +469,107 @@ LogMessage::~LogMessage()
*/
/**
+ * \class Loggable
+ * \brief Base class to support log message extensions
+ *
+ * The Loggable class allows classes to extend log messages without any change
+ * to the way the LOG() macro is invoked. By inheriting from Loggable and
+ * implementing the logPrefix() virtual method, a class can specify extra
+ * information to be automatically added to messages logged from class member
+ * methods.
+ */
+
+Loggable::~Loggable()
+{
+}
+
+/**
+ * \fn Loggable::logPrefix()
+ * \brief Retrieve a string to be prefixed to the log message
+ *
+ * This method allows classes inheriting from the Loggable class to extend the
+ * logger with an object-specific prefix output right before the log message
+ * contents.
+ *
+ * \return A string to be prefixed to the log message
+ */
+
+/**
+ * \brief Create a temporary LogMessage object to log a message
+ * \param[in] fileName The file name where the message is logged from
+ * \param[in] line The line number where the message is logged from
+ * \param[in] severity The log message severity
+ *
+ * This method is used as a backeng by the LOG() macro to create a log message
+ * for locations inheriting from the Loggable class.
+ *
+ * \return A log message
+ */
+LogMessage Loggable::_log(const char *fileName, unsigned int line,
+ LogSeverity severity)
+{
+ LogMessage msg(fileName, line, severity);
+
+ msg.stream() << logPrefix() << ": ";
+ return msg;
+}
+
+/**
+ * \brief Create a temporary LogMessage object to log a message
+ * \param[in] fileName The file name where the message is logged from
+ * \param[in] line The line number where the message is logged from
+ * \param[in] category The log message category
+ * \param[in] severity The log message severity
+ *
+ * This method is used as a backeng by the LOG() macro to create a log message
+ * for locations inheriting from the Loggable class.
+ *
+ * \return A log message
+ */
+LogMessage Loggable::_log(const char *fileName, unsigned int line,
+ const LogCategory &category, LogSeverity severity)
+{
+ LogMessage msg(fileName, line, category, severity);
+
+ msg.stream() << logPrefix() << ": ";
+ return msg;
+}
+
+/**
+ * \brief Create a temporary LogMessage object to log a message
+ * \param[in] fileName The file name where the message is logged from
+ * \param[in] line The line number where the message is logged from
+ * \param[in] severity The log message severity
+ *
+ * This function is used as a backeng by the LOG() macro to create a log
+ * message for locations not inheriting from the Loggable class.
+ *
+ * \return A log message
+ */
+LogMessage _log(const char *fileName, unsigned int line, LogSeverity severity)
+{
+ return LogMessage(fileName, line, severity);
+}
+
+/**
+ * \brief Create a temporary LogMessage object to log a message
+ * \param[in] fileName The file name where the message is logged from
+ * \param[in] line The line number where the message is logged from
+ * \param[in] category The log message category
+ * \param[in] severity The log message severity
+ *
+ * This function is used as a backeng by the LOG() macro to create a log
+ * message for locations not inheriting from the Loggable class.
+ *
+ * \return A log message
+ */
+LogMessage _log(const char *fileName, unsigned int line,
+ const LogCategory &category, LogSeverity severity)
+{
+ return LogMessage(fileName, line, category, severity);
+}
+
+/**
* \def LOG_DECLARE_CATEGORY(name)
* \hideinitializer
* \brief Declare a category of log messages