From patchwork Thu Jul 11 18:05:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1657 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 81E2460BC8 for ; Thu, 11 Jul 2019 20:05:34 +0200 (CEST) Received: from neptunite.amanokami.net (softbank126163157105.bbtec.net [126.163.157.105]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DB1E531C; Thu, 11 Jul 2019 20:05:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562868334; bh=5HolqAh0gr2mPPgiqgeiMNcPLeRa+FqMGTkJge5RmvM=; h=From:To:Cc:Subject:Date:From; b=tL+f1WgHkzwkxPcQtv4bduDx3m3b3+JdwcRYJs8VJ20lFM/vh6/vbU2lbkLor+Av6 CzLknjncx00Dh5bF6ey8GrUk7CtB5SyT0ieOKKMCashr08HJN+LsEH7HexW2Pmo+9v KZMP0swf/DlPXNcsRstGRHNqBvt1ubYe8eOWSQL4= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Fri, 12 Jul 2019 03:05:24 +0900 Message-Id: <20190711180525.31519-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/2] libcamera: logging: add logging API for applications X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Jul 2019 18:05:34 -0000 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 Reviewed-by: Laurent Pinchart --- Changes in v3: - make setLogFile revert to stderr on empty arg - make both setLogFile and setLogLevel ignore empty args (not check for error) - better docs for setLogFile Changes in v2: - add documentation - actually set the log level include/libcamera/logging.h | 17 ++++++++++ include/libcamera/meson.build | 1 + src/libcamera/log.cpp | 60 +++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 include/libcamera/logging.h diff --git a/include/libcamera/logging.h b/include/libcamera/logging.h new file mode 100644 index 0000000..c8a048e --- /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); +void 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 972513f..920eb5f 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 0ba276e..11bac80 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 void logSetFile(const char *file); + friend void logSetLevel(const char *category, const char *level); + friend LogCategory; void registerCategory(LogCategory *category); void unregisterCategory(LogCategory *category); @@ -80,6 +83,63 @@ private: std::ostream *output_; }; +/** + * \brief Set the log file + * \param[in] file Log file + * + * This functions sets the logging output file to \a file. + * If \a file is an empty string, then the output file will be set to stderr. + */ +void logSetFile(const char *file) +{ + Logger *logger = Logger::instance(); + + if (!file[0]) { + logger->file_.close(); + logger->output_ = &std::cerr; + return; + } + + std::ofstream logFile(file); + if (!logFile.good()) + return; + + if (logger->output_ != &std::cerr) + logger->file_.close(); + logger->file_ = std::move(logFile); + logger->output_ = &logger->file_; +} + +/** + * \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(); + std::string cat(category); + std::string lev(level); + + LogSeverity severity = Logger::parseLogLevel(lev); + if (severity == LogInvalid) + return; + + for (LogCategory *c : logger->categories_) + if (!strcmp(c->name(), category)) + c->setSeverity(severity); +} + /** * \brief Retrieve the logger instance * From patchwork Thu Jul 11 18:05:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1658 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F23A960C3A for ; Thu, 11 Jul 2019 20:05:35 +0200 (CEST) Received: from neptunite.amanokami.net (softbank126163157105.bbtec.net [126.163.157.105]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9E4A731C; Thu, 11 Jul 2019 20:05:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562868335; bh=s8VIPqbYtHom8+IvFSFYRW+HZvu97OqmC3zDedcLv5A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cst2NABi0u+92z82FH86o4Sgi5mXANbi7iicKPaNDYkJH6qH4aWkMo3SvMb8coSRG xu1dqQbp0V57u3tYYYuuAE78vIdVdkyeimZ7L8ArBfhvZOEdWS6MSdvU8k7m+RgNLd hNQ+eNiY36MXPNkEowAdX+r3w+rJSj6EjgdDtpoA= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Fri, 12 Jul 2019 03:05:25 +0900 Message-Id: <20190711180525.31519-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190711180525.31519-1-paul.elder@ideasonboard.com> References: <20190711180525.31519-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/2] test: add logging API test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Jul 2019 18:05:36 -0000 Test that setting the log file and log levels works from an application point of view. The test uses the internal logging mechanism as well, just to write to the log file. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- Changes in v3: - better testing (actually check logging output) - move and rename test file into main testing directory Changes in v2: - added more test cases to catch if log level changes fail test/log.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ test/meson.build | 1 + 2 files changed, 85 insertions(+) create mode 100644 test/log.cpp diff --git a/test/log.cpp b/test/log.cpp new file mode 100644 index 0000000..ffe066f --- /dev/null +++ b/test/log.cpp @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * log_api.cpp - log API test + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "log.h" +#include "test.h" + +using namespace std; +using namespace libcamera; + +LOG_DEFINE_CATEGORY(LogAPITest) + +class LogAPITest : public Test +{ +protected: + int run() override + { + int fd = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + cerr << "Failed to open tmp log file" << endl; + return TestFail; + } + + char path[32]; + snprintf(path, sizeof(path), "/proc/self/fd/%u", fd); + + logSetFile(path); + + logSetLevel("LogAPITest", "DEBUG"); + LOG(LogAPITest, Info) << "good 1"; + + logSetLevel("LogAPITest", "WARN"); + LOG(LogAPITest, Info) << "bad"; + + logSetLevel("LogAPITest", "ERROR"); + LOG(LogAPITest, Error) << "good 3"; + LOG(LogAPITest, Info) << "bad"; + + logSetLevel("LogAPITest", "WARN"); + LOG(LogAPITest, Warning) << "good 5"; + LOG(LogAPITest, Info) << "bad"; + + char buf[1000]; + memset(buf, 0, sizeof(buf)); + lseek(fd, 0, SEEK_SET); + read(fd, buf, sizeof(buf)); + close(fd); + + std::list goodList = { 1, 3, 5 }; + std::basic_istringstream iss((std::string(buf))); + char str[100]; + while (iss.getline(str, sizeof(str))) { + char tmp = std::string(str).back(); + int i = tmp - '0'; + int j = goodList.front(); + goodList.pop_front(); + if (i != j) + return TestFail; + } + + if (!goodList.empty()) + return TestFail; + + return TestPass; + } +}; + +TEST_REGISTER(LogAPITest) diff --git a/test/meson.build b/test/meson.build index 60ce960..d308ac9 100644 --- a/test/meson.build +++ b/test/meson.build @@ -21,6 +21,7 @@ public_tests = [ internal_tests = [ ['camera-sensor', 'camera-sensor.cpp'], + ['log', 'log.cpp'], ['message', 'message.cpp'], ['signal-threads', 'signal-threads.cpp'], ['threads', 'threads.cpp'],