blob: 233357da62574224c47b483004c8cd65ce5ff445 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/logging/interface.h"
Brian Silvermanb0893882014-02-10 14:48:30 -08002
Tyler Chatowbf0609c2021-07-31 16:13:27 -07003#include <cstdarg>
4#include <cstdio>
5#include <cstring>
Austin Schuh044e18b2015-10-21 20:17:09 -07006#include <functional>
Tyler Chatow4b471e12020-01-05 20:19:36 -08007#include <type_traits>
Brian Silverman88471dc2014-02-15 22:35:42 -08008
Philipp Schrader790cb542023-07-05 21:06:52 -07009#include "glog/logging.h"
10
John Park33858a32018-09-28 23:05:48 -070011#include "aos/die.h"
12#include "aos/logging/context.h"
Austin Schuh56196432020-10-24 20:15:21 -070013#include "aos/logging/implementations.h"
Brian Silvermanb0893882014-02-10 14:48:30 -080014
Brian Silvermanb0893882014-02-10 14:48:30 -080015namespace aos {
16namespace logging {
17namespace internal {
18
Brian Silverman88471dc2014-02-15 22:35:42 -080019size_t ExecuteFormat(char *output, size_t output_size, const char *format,
20 va_list ap) {
21 static const char *const continued = "...\n";
Brian Silvermanb0893882014-02-10 14:48:30 -080022 const size_t size = output_size - strlen(continued);
23 const int ret = vsnprintf(output, size, format, ap);
Alex Perrycb7da4b2019-08-28 19:35:56 -070024 typedef ::std::common_type<int, size_t>::type RetType;
Brian Silvermanb0893882014-02-10 14:48:30 -080025 if (ret < 0) {
Austin Schuh56196432020-10-24 20:15:21 -070026 PLOG(FATAL) << "vsnprintf(" << output << ", " << size << ", " << format
27 << ", args) failed";
Brian Silverman88471dc2014-02-15 22:35:42 -080028 } else if (static_cast<RetType>(ret) >= static_cast<RetType>(size)) {
Brian Silvermanb0893882014-02-10 14:48:30 -080029 // Overwrite the '\0' at the end of the existing data and
30 // copy in the one on the end of continued.
31 memcpy(&output[size - 1], continued, strlen(continued) + 1);
32 }
Brian Silverman88471dc2014-02-15 22:35:42 -080033 return ::std::min<RetType>(ret, size);
Brian Silvermanb0893882014-02-10 14:48:30 -080034}
35
Brian Silvermand6974f42014-02-14 13:39:21 -080036} // namespace internal
37
38using internal::Context;
39
Brian Silvermanb0893882014-02-10 14:48:30 -080040void VLog(log_level level, const char *format, va_list ap) {
Austin Schuh56196432020-10-24 20:15:21 -070041 va_list ap1;
42 va_copy(ap1, ap);
43
44 Context *context = Context::Get();
45
46 const std::shared_ptr<LogImplementation> implementation =
47 context->implementation;
48 // Log to the implementation if we have it, and stderr as a backup.
49 if (implementation) {
50 implementation->DoLog(level, format, ap1);
51 } else {
52 aos::logging::LogMessage message;
Austin Schuhad9e5eb2021-11-19 20:33:55 -080053 aos::logging::internal::FillInMessage(level, context->MyName(),
54 aos::monotonic_clock::now(), format,
55 ap, &message);
Austin Schuh56196432020-10-24 20:15:21 -070056 aos::logging::internal::PrintMessage(stderr, message);
57 }
58 va_end(ap1);
59
60 if (level == FATAL) {
61 VDie(format, ap);
62 }
Brian Silvermanb0893882014-02-10 14:48:30 -080063}
64
Brian Silvermanb0893882014-02-10 14:48:30 -080065} // namespace logging
66} // namespace aos
67
68void log_do(log_level level, const char *format, ...) {
69 va_list ap;
70 va_start(ap, format);
71 aos::logging::VLog(level, format, ap);
72 va_end(ap);
73}