blob: 92f0b10ab8b2f4019654adfe5020762918d95d75 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#ifndef AOS_LOGGING_INTERFACE_H_
2#define AOS_LOGGING_INTERFACE_H_
Austin Schuh044e18b2015-10-21 20:17:09 -07003
4#include <stdarg.h>
5
6#include <string>
7#include <functional>
8
John Park33858a32018-09-28 23:05:48 -07009#include "aos/logging/logging.h"
10#include "aos/macros.h"
Austin Schuh044e18b2015-10-21 20:17:09 -070011
Brian Silvermancb5da1f2015-12-05 22:19:58 -050012// This file has the non-C-compatible parts of the logging client interface.
13
Austin Schuh044e18b2015-10-21 20:17:09 -070014namespace aos {
15
16struct MessageType;
17
Austin Schuh044e18b2015-10-21 20:17:09 -070018namespace logging {
19
Brian Silverman17291d82015-10-24 22:30:57 -040020// Takes a message and logs it. It will set everything up and then call DoLog
21// for the current LogImplementation.
22void VLog(log_level level, const char *format, va_list ap)
23 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 0)));
24// Adds to the saved up message.
25void VCork(int line, const char *function, const char *format, va_list ap)
26 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)));
27// Actually logs the saved up message.
28void VUnCork(int line, const char *function, log_level level, const char *file,
29 const char *format, va_list ap)
30 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 5, 0)));
31
Austin Schuh044e18b2015-10-21 20:17:09 -070032// Represents a system that can actually take log messages and do something
33// useful with them.
34// All of the code (transitively too!) in the DoLog here can make
35// normal LOG and LOG_DYNAMIC calls but can NOT call LOG_CORK/LOG_UNCORK. These
36// calls will not result in DoLog recursing. However, implementations must be
37// safe to call from multiple threads/tasks at the same time. Also, any other
38// overriden methods may end up logging through a given implementation's DoLog.
39class LogImplementation {
40 public:
41 LogImplementation() : next_(NULL) {}
42
43 // The one that this one's implementation logs to.
44 // NULL means that there is no next one.
45 LogImplementation *next() { return next_; }
46 // Virtual in case a subclass wants to perform checks. There will be a valid
47 // logger other than this one available while this is called.
48 virtual void set_next(LogImplementation *next) { next_ = next; }
49
Austin Schuh1bf8a212019-05-26 22:13:14 -070050 virtual bool fill_type_cache() { return true; }
51
Brian Silvermancb5da1f2015-12-05 22:19:58 -050052 protected:
Austin Schuh044e18b2015-10-21 20:17:09 -070053 // Actually logs the given message. Implementations should somehow create a
54 // LogMessage and then call internal::FillInMessage.
55 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
56 virtual void DoLog(log_level level, const char *format, va_list ap) = 0;
57 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 4)))
58 void DoLogVariadic(log_level level, const char *format, ...) {
59 va_list ap;
60 va_start(ap, format);
61 DoLog(level, format, ap);
62 va_end(ap);
63 }
64
Brian Silvermancb5da1f2015-12-05 22:19:58 -050065 private:
Austin Schuh044e18b2015-10-21 20:17:09 -070066 // These functions call similar methods on the "current" LogImplementation or
67 // Die if they can't find one.
68 // levels is how many LogImplementations to not use off the stack.
69 static void DoVLog(log_level, const char *format, va_list ap, int levels)
70 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 0)));
Austin Schuh044e18b2015-10-21 20:17:09 -070071
Austin Schuh044e18b2015-10-21 20:17:09 -070072 friend void VLog(log_level, const char *, va_list);
Austin Schuh044e18b2015-10-21 20:17:09 -070073
74 LogImplementation *next_;
75};
76
Brian Silverman17291d82015-10-24 22:30:57 -040077namespace internal {
78
79// Prints format (with ap) into output and correctly deals with the result
80// being too long etc.
81size_t ExecuteFormat(char *output, size_t output_size, const char *format,
82 va_list ap)
83 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)));
84
85// Runs the given function with the current LogImplementation (handles switching
86// it out while running function etc).
87// levels is how many LogImplementations to not use off the stack.
88void RunWithCurrentImplementation(
89 int levels, ::std::function<void(LogImplementation *)> function);
90
91} // namespace internal
Austin Schuh044e18b2015-10-21 20:17:09 -070092} // namespace logging
93} // namespace aos
94
John Park33858a32018-09-28 23:05:48 -070095#endif // AOS_LOGGING_INTERFACE_H_