summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/log.cpp47
1 files changed, 45 insertions, 2 deletions
diff --git a/src/libcamera/log.cpp b/src/libcamera/log.cpp
index 23bb9edb..241dc539 100644
--- a/src/libcamera/log.cpp
+++ b/src/libcamera/log.cpp
@@ -8,7 +8,9 @@
#include <cstdio>
#include <cstdlib>
#include <ctime>
+#include <fstream>
#include <iomanip>
+#include <iostream>
#include <list>
#include <string.h>
#include <unordered_set>
@@ -37,6 +39,12 @@
* message with a level higher than or equal to the configured log level for
* their category are output to the log, while other messages are silently
* discarded.
+ *
+ * By default log messages are output to stderr. They can be redirected to a log
+ * file by setting the LIBCAMERA_LOG_FILE environment variable to the name of
+ * the file. The file must be writable and is truncated if it exists. If any
+ * error occurs when opening the file, the file is ignored and the log is output
+ * to stderr.
*/
namespace libcamera {
@@ -51,9 +59,12 @@ class Logger
public:
static Logger *instance();
+ void write(const std::string &msg);
+
private:
Logger();
+ void parseLogFile();
void parseLogLevels();
static LogSeverity parseLogLevel(const std::string &level);
@@ -63,6 +74,9 @@ private:
std::unordered_set<LogCategory *> categories_;
std::list<std::pair<std::string, LogSeverity>> levels_;
+
+ std::ofstream file_;
+ std::ostream *output_;
};
/**
@@ -80,14 +94,44 @@ Logger *Logger::instance()
}
/**
+ * \brief Write a message to the configured logger output
+ * \param[in] msg The message string
+ */
+void Logger::write(const std::string &msg)
+{
+ output_->write(msg.c_str(), msg.size());
+ output_->flush();
+}
+
+/**
* \brief Construct a logger
*/
Logger::Logger()
+ : output_(&std::cerr)
{
+ parseLogFile();
parseLogLevels();
}
/**
+ * \brief Parse the log output file from the environment
+ *
+ * If the LIBCAMERA_LOG_FILE environment variable is set, open the file it
+ * points to and redirect the logger output to it. Errors are silently ignored
+ * and don't affect the logger output (set to stderr).
+ */
+void Logger::parseLogFile()
+{
+ const char *file = secure_getenv("LIBCAMERA_LOG_FILE");
+ if (!file)
+ return;
+
+ file_.open(file);
+ if (file_.good())
+ output_ = &file_;
+}
+
+/**
* \brief Parse the log levels from the environment
*
* The logr levels are stored in LIBCAMERA_LOG_LEVELS environement variable as a list
@@ -384,8 +428,7 @@ LogMessage::~LogMessage()
if (severity_ >= category_.severity()) {
std::string msg(msgStream_.str());
- fwrite(msg.data(), msg.size(), 1, stderr);
- fflush(stderr);
+ Logger::instance()->write(msg);
}
if (severity_ == LogSeverity::LogFatal)