blob: 3695e400cc20c045ce53478ee9b40d672e86cc1d [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
Austin Schuh044e18b2015-10-21 20:17:09 -07006#include <functional>
Tyler Chatow4b471e12020-01-05 20:19:36 -08007#include <string>
Austin Schuh044e18b2015-10-21 20:17:09 -07008
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:
Tyler Chatow4b471e12020-01-05 20:19:36 -080041 LogImplementation() {}
Austin Schuh044e18b2015-10-21 20:17:09 -070042
Tyler Chatow4b471e12020-01-05 20:19:36 -080043 virtual ~LogImplementation() {}
Austin Schuh044e18b2015-10-21 20:17:09 -070044
Austin Schuh1bf8a212019-05-26 22:13:14 -070045 virtual bool fill_type_cache() { return true; }
46
Brian Silvermancb5da1f2015-12-05 22:19:58 -050047 protected:
Austin Schuh044e18b2015-10-21 20:17:09 -070048 // Actually logs the given message. Implementations should somehow create a
49 // LogMessage and then call internal::FillInMessage.
Tyler Chatow4b471e12020-01-05 20:19:36 -080050 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0))) virtual void DoLog(
51 log_level level, const char *format, va_list ap) = 0;
52 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 4))) void DoLogVariadic(
53 log_level level, const char *format, ...) {
Austin Schuh044e18b2015-10-21 20:17:09 -070054 va_list ap;
55 va_start(ap, format);
56 DoLog(level, format, ap);
57 va_end(ap);
58 }
59
Brian Silvermancb5da1f2015-12-05 22:19:58 -050060 private:
Austin Schuh044e18b2015-10-21 20:17:09 -070061 // These functions call similar methods on the "current" LogImplementation or
62 // Die if they can't find one.
63 // levels is how many LogImplementations to not use off the stack.
Tyler Chatow4b471e12020-01-05 20:19:36 -080064 static void DoVLog(log_level, const char *format, va_list ap)
Austin Schuh044e18b2015-10-21 20:17:09 -070065 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 0)));
Austin Schuh044e18b2015-10-21 20:17:09 -070066
Austin Schuh044e18b2015-10-21 20:17:09 -070067 friend void VLog(log_level, const char *, va_list);
Austin Schuh044e18b2015-10-21 20:17:09 -070068};
69
Brian Silverman17291d82015-10-24 22:30:57 -040070namespace internal {
71
72// Prints format (with ap) into output and correctly deals with the result
73// being too long etc.
74size_t ExecuteFormat(char *output, size_t output_size, const char *format,
75 va_list ap)
76 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)));
77
78// Runs the given function with the current LogImplementation (handles switching
79// it out while running function etc).
80// levels is how many LogImplementations to not use off the stack.
81void RunWithCurrentImplementation(
82 int levels, ::std::function<void(LogImplementation *)> function);
83
84} // namespace internal
Austin Schuh044e18b2015-10-21 20:17:09 -070085} // namespace logging
86} // namespace aos
87
John Park33858a32018-09-28 23:05:48 -070088#endif // AOS_LOGGING_INTERFACE_H_