blob: 39492ad9932d9cd147393dedde62f402aa9fcd7f [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
John Park33858a32018-09-28 23:05:48 -07009#include "aos/die.h"
10#include "aos/logging/context.h"
Austin Schuh56196432020-10-24 20:15:21 -070011#include "aos/logging/implementations.h"
12#include "glog/logging.h"
Brian Silvermanb0893882014-02-10 14:48:30 -080013
Brian Silvermanb0893882014-02-10 14:48:30 -080014namespace aos {
15namespace logging {
16namespace internal {
17
Brian Silverman88471dc2014-02-15 22:35:42 -080018size_t ExecuteFormat(char *output, size_t output_size, const char *format,
19 va_list ap) {
20 static const char *const continued = "...\n";
Brian Silvermanb0893882014-02-10 14:48:30 -080021 const size_t size = output_size - strlen(continued);
22 const int ret = vsnprintf(output, size, format, ap);
Alex Perrycb7da4b2019-08-28 19:35:56 -070023 typedef ::std::common_type<int, size_t>::type RetType;
Brian Silvermanb0893882014-02-10 14:48:30 -080024 if (ret < 0) {
Austin Schuh56196432020-10-24 20:15:21 -070025 PLOG(FATAL) << "vsnprintf(" << output << ", " << size << ", " << format
26 << ", args) failed";
Brian Silverman88471dc2014-02-15 22:35:42 -080027 } else if (static_cast<RetType>(ret) >= static_cast<RetType>(size)) {
Brian Silvermanb0893882014-02-10 14:48:30 -080028 // Overwrite the '\0' at the end of the existing data and
29 // copy in the one on the end of continued.
30 memcpy(&output[size - 1], continued, strlen(continued) + 1);
31 }
Brian Silverman88471dc2014-02-15 22:35:42 -080032 return ::std::min<RetType>(ret, size);
Brian Silvermanb0893882014-02-10 14:48:30 -080033}
34
Brian Silvermand6974f42014-02-14 13:39:21 -080035} // namespace internal
36
37using internal::Context;
38
Brian Silvermanb0893882014-02-10 14:48:30 -080039void VLog(log_level level, const char *format, va_list ap) {
Austin Schuh56196432020-10-24 20:15:21 -070040 va_list ap1;
41 va_copy(ap1, ap);
42
43 Context *context = Context::Get();
44
45 const std::shared_ptr<LogImplementation> implementation =
46 context->implementation;
47 // Log to the implementation if we have it, and stderr as a backup.
48 if (implementation) {
49 implementation->DoLog(level, format, ap1);
50 } else {
51 aos::logging::LogMessage message;
52 aos::logging::internal::FillInMessage(level, aos::monotonic_clock::now(),
53 format, ap, &message);
54 aos::logging::internal::PrintMessage(stderr, message);
55 }
56 va_end(ap1);
57
58 if (level == FATAL) {
59 VDie(format, ap);
60 }
Brian Silvermanb0893882014-02-10 14:48:30 -080061}
62
Brian Silvermanb0893882014-02-10 14:48:30 -080063} // namespace logging
64} // namespace aos
65
66void log_do(log_level level, const char *format, ...) {
67 va_list ap;
68 va_start(ap, format);
69 aos::logging::VLog(level, format, ap);
70 va_end(ap);
71}