[PATCH 2/2] libcamera: log: add logTargetCros for ChromeOS logs
Cheng-Hao Yang
chenghaoyang at chromium.org
Tue Oct 15 13:03:37 CEST 2024
Hi Laurent,
On Tue, Oct 15, 2024 at 6:22 PM Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> Hi Harvey, Han-Lin,
>
> Thank you for the patch.
>
> On Mon, Oct 14, 2024 at 08:13:55AM +0000, Harvey Yang wrote:
> > From: Han-Lin Chen <hanlinchen at chromium.org>
> >
> > ChromeOS logging requires that the logs export to both syslog and
> > std::cerr. Add a logTargetCros for the specific case.
> >
> > Signed-off-by: Han-Lin Chen <hanlinchen at chromium.org>
> > Co-developed-by: Harvey Yang <chenghaoyang at chromium.org>
> > Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
> > ---
> > include/libcamera/logging.h | 1 +
> > src/libcamera/base/log.cpp | 61 +++++++++++++++++++++++++++++++------
> > 2 files changed, 53 insertions(+), 9 deletions(-)
> >
> > diff --git a/include/libcamera/logging.h b/include/libcamera/logging.h
> > index e1c6341ce..b88acf23b 100644
> > --- a/include/libcamera/logging.h
> > +++ b/include/libcamera/logging.h
> > @@ -16,6 +16,7 @@ enum LoggingTarget {
> > LoggingTargetSyslog,
> > LoggingTargetFile,
> > LoggingTargetStream,
> > + LoggingTargetCros,
>
> I'm not a big fan of this being exposed in the public API :-(
Sure, but as you can see, this CL tries to enable multiple
outputs. The naming can be discussed.
>
> > };
> >
> > int logSetFile(const char *path, bool color = false);
> > diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
> > index 3a656b8f0..930e2329e 100644
> > --- a/src/libcamera/base/log.cpp
> > +++ b/src/libcamera/base/log.cpp
> > @@ -107,6 +107,7 @@ class LogOutput
> > public:
> > LogOutput(const char *path, bool color);
> > LogOutput(std::ostream *stream, bool color);
> > + LogOutput(bool color);
> > LogOutput();
> > ~LogOutput();
> >
> > @@ -144,6 +145,19 @@ LogOutput::LogOutput(std::ostream *stream, bool color)
> > {
> > }
> >
> > +/**
> > + * \brief Construct a log output to both std:err and syslog
>
> s/std:err/std::cerr/
>
> > + * \param[in] color True to output colored messages
> > + *
> > + * Currently this is only needed for CrOS. Therefore, the target is set to
> > + * `LoggingTargetCros`.
> > + */
> > +LogOutput::LogOutput(bool color)
> > + : stream_(&std::cerr), target_(LoggingTargetCros), color_(color)
> > +{
> > + openlog("libcamera", LOG_PID, 0);
> > +}
>
> Brainstorming mode, I wonder if it wouldn't be cleaner to add support
> for multiple LogOutput instances. That may be overkill though.
True, that's an approach.
>
> > +
> > /**
> > * \brief Construct a log output to syslog
> > */
> > @@ -160,6 +174,7 @@ LogOutput::~LogOutput()
> > delete stream_;
> > break;
> > case LoggingTargetSyslog:
> > + case LoggingTargetCros:
> > closelog();
> > break;
> > default:
> > @@ -230,17 +245,26 @@ void LogOutput::write(const LogMessage &msg)
> > severityColor = kColorBrightWhite;
> > }
> >
> > + bool toStream = false;
> > + bool toSyslog = false;
> > +
> > switch (target_) {
> > case LoggingTargetSyslog:
> > - str = std::string(log_severity_name(severity)) + " "
> > - + msg.category().name() + " " + msg.fileInfo() + " ";
> > - if (!msg.prefix().empty())
> > - str += msg.prefix() + ": ";
> > - str += msg.msg();
> > - writeSyslog(severity, str);
> > + toSyslog = true;
> > break;
> > case LoggingTargetStream:
> > case LoggingTargetFile:
> > + toStream = true;
> > + break;
> > + case LoggingTargetCros:
> > + toSyslog = true;
> > + toStream = true;
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + if (toStream) {
> > str = "[" + utils::time_point_to_string(msg.timestamp()) + "] ["
> > + std::to_string(Thread::currentId()) + "] "
> > + severityColor + log_severity_name(severity) + " "
> > @@ -250,9 +274,15 @@ void LogOutput::write(const LogMessage &msg)
> > str += prefixColor + msg.prefix() + ": ";
> > str += resetColor + msg.msg();
> > writeStream(str);
> > - break;
> > - default:
> > - break;
> > + }
> > +
> > + if (toSyslog) {
> > + str = std::string(log_severity_name(severity)) + " "
> > + + msg.category().name() + " " + msg.fileInfo() + " ";
> > + if (!msg.prefix().empty())
> > + str += msg.prefix() + ": ";
> > + str += msg.msg();
> > + writeSyslog(severity, str);
> > }
> > }
> >
> > @@ -270,6 +300,10 @@ void LogOutput::write(const std::string &str)
> > case LoggingTargetFile:
> > writeStream(str);
> > break;
> > + case LoggingTargetCros:
> > + writeSyslog(LogDebug, str);
> > + writeStream(str);
> > + break;
> > default:
> > break;
> > }
> > @@ -549,6 +583,9 @@ int Logger::logSetTarget(enum LoggingTarget target)
> > case LoggingTargetNone:
> > std::atomic_store(&output_, std::shared_ptr<LogOutput>());
> > break;
> > + case LoggingTargetCros:
> > + std::atomic_store(&output_, std::make_shared<LogOutput>(true));
> > + break;
> > default:
> > return -EINVAL;
> > }
> > @@ -586,6 +623,12 @@ void Logger::logSetLevel(const char *category, const char *level)
> > */
> > Logger::Logger()
> > {
> > +#if defined(OS_CHROMEOS)
> > + logSetTarget(LoggingTargetCros);
> > + parseLogLevels();
> > + return;
> > +#endif
>
> I'd like to avoid an #ifdef here. Is there a way to expose this feature
> through the libcamera API in a clean way, and select the right target
> using the API from the HAL code ?
We're trying not to use environment variables in CrOS, as there will
be some confusion and mis-usages.
It's not a critical patch though. If we couldn't find a good approach,
we can skip this. CrOS just keep this in our own branches.
BR,
Harvey
>
> > +
> > bool color = !utils::secure_getenv("LIBCAMERA_LOG_NO_COLOR");
> > logSetStream(&std::cerr, color);
> >
>
> --
> Regards,
>
> Laurent Pinchart
More information about the libcamera-devel
mailing list