summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Elder <paul.elder@ideasonboard.com>2019-07-11 18:30:07 +0900
committerPaul Elder <paul.elder@ideasonboard.com>2019-07-12 13:46:48 +0900
commit60f5d472d96c9c1ffcb1887bd760bcee3c09ec2a (patch)
treefe763074927cb62a8e4edd1c1da03588b1a7259d
parentb50c5f28b14e2fb14d4de0c088949e1405d22c6a (diff)
libcamera: logging: add logging API for applications
Currently the log file and the log level can only be set via environment variables, but applications may also want to set the log file and the log level at run time. Provide an API for this. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--include/libcamera/logging.h17
-rw-r--r--include/libcamera/meson.build1
-rw-r--r--src/libcamera/log.cpp65
3 files changed, 83 insertions, 0 deletions
diff --git a/include/libcamera/logging.h b/include/libcamera/logging.h
new file mode 100644
index 00000000..a8495cf6
--- /dev/null
+++ b/include/libcamera/logging.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * logging.h - Logging infrastructure
+ */
+#ifndef __LIBCAMERA_LOGGING_H__
+#define __LIBCAMERA_LOGGING_H__
+
+namespace libcamera {
+
+void logSetFile(const char *file);
+int logSetLevel(const char *category, const char *level);
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_LOGGING_H__ */
diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index 972513fc..920eb5fc 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -9,6 +9,7 @@ libcamera_api = files([
'geometry.h',
'ipa/ipa_interface.h',
'ipa/ipa_module_info.h',
+ 'logging.h',
'object.h',
'request.h',
'signal.h',
diff --git a/src/libcamera/log.cpp b/src/libcamera/log.cpp
index 0ba276e5..709c669c 100644
--- a/src/libcamera/log.cpp
+++ b/src/libcamera/log.cpp
@@ -69,6 +69,9 @@ private:
void parseLogLevels();
static LogSeverity parseLogLevel(const std::string &level);
+ friend int logSetFile(const char *file);
+ friend void logSetLevel(const char *category, const char *level);
+
friend LogCategory;
void registerCategory(LogCategory *category);
void unregisterCategory(LogCategory *category);
@@ -81,6 +84,68 @@ private:
};
/**
+ * \brief Set the log file
+ * \param[in] file Full path to the log file
+ *
+ * This function sets the logging output file to \a file. The previous log file,
+ * if any, is closed, and all new log messages will be written to the new log
+ * file.
+ *
+ * If \a file is a null pointer, the log is directed to stderr. If the
+ * function returns an error, the log file is not changed.
+ *
+ * \return Zero on success, or a negative error code otherwise.
+ */
+int logSetFile(const char *file)
+{
+ Logger *logger = Logger::instance();
+
+ if (!file) {
+ logger->output_ = &std::cerr;
+ logger->file_.close();
+ return 0;
+ }
+
+ std::ofstream logFile(file);
+ if (!logFile.good())
+ return -EINVAL;
+
+ if (logger->output_ != &std::cerr)
+ logger->file_.close();
+ logger->file_ = std::move(logFile);
+ logger->output_ = &logger->file_;
+ return 0;
+}
+
+/**
+ * \brief Set the log level
+ * \param[in] category Logging category
+ * \param[in] level Log level
+ *
+ * This function sets the log level of \a category to \a level.
+ * \a level shall be one of the following strings:
+ * - "DEBUG"
+ * - "INFO"
+ * - "WARN"
+ * - "ERROR"
+ * - "FATAL"
+ *
+ * "*" is not a valid \a category for this function.
+ */
+void logSetLevel(const char *category, const char *level)
+{
+ Logger *logger = Logger::instance();
+
+ LogSeverity severity = Logger::parseLogLevel(level);
+ if (severity == LogInvalid)
+ return;
+
+ for (LogCategory *c : logger->categories_)
+ if (!strcmp(c->name(), category))
+ c->setSeverity(severity);
+}
+
+/**
* \brief Retrieve the logger instance
*
* The Logger is a singleton and can't be constructed manually. This function