blob: dc59858fbb7f0e09580f334083b0ce97554eca36 [file] [log] [blame]
Brian Silvermancb5da1f2015-12-05 22:19:58 -05001#ifndef AOS_COMMON_LOGGING_INTERFACE_H_
2#define AOS_COMMON_LOGGING_INTERFACE_H_
Austin Schuh044e18b2015-10-21 20:17:09 -07003
4#include <stdarg.h>
5
6#include <string>
7#include <functional>
8
9#include "aos/common/logging/logging.h"
Brian Silverman17291d82015-10-24 22:30:57 -040010#include "aos/common/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 {
Brian Silvermancb5da1f2015-12-05 22:19:58 -050019namespace internal {
20
21// Defined in queue_logging.cc.
22void DoLogStruct(log_level level, const ::std::string &message, size_t size,
23 const MessageType *type,
24 const ::std::function<size_t(char *)> &serialize, int levels);
25
26// Defined in matrix_logging.cc.
27void DoLogMatrix(log_level level, const ::std::string &message,
28 uint32_t type_id, int rows, int cols, const void *data,
29 int levels);
30
31} // namespace internal
Austin Schuh044e18b2015-10-21 20:17:09 -070032
Brian Silverman17291d82015-10-24 22:30:57 -040033// Takes a message and logs it. It will set everything up and then call DoLog
34// for the current LogImplementation.
35void VLog(log_level level, const char *format, va_list ap)
36 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 0)));
37// Adds to the saved up message.
38void VCork(int line, const char *function, const char *format, va_list ap)
39 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)));
40// Actually logs the saved up message.
41void VUnCork(int line, const char *function, log_level level, const char *file,
42 const char *format, va_list ap)
43 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 5, 0)));
44
Austin Schuh044e18b2015-10-21 20:17:09 -070045// Represents a system that can actually take log messages and do something
46// useful with them.
47// All of the code (transitively too!) in the DoLog here can make
48// normal LOG and LOG_DYNAMIC calls but can NOT call LOG_CORK/LOG_UNCORK. These
49// calls will not result in DoLog recursing. However, implementations must be
50// safe to call from multiple threads/tasks at the same time. Also, any other
51// overriden methods may end up logging through a given implementation's DoLog.
52class LogImplementation {
53 public:
54 LogImplementation() : next_(NULL) {}
55
56 // The one that this one's implementation logs to.
57 // NULL means that there is no next one.
58 LogImplementation *next() { return next_; }
59 // Virtual in case a subclass wants to perform checks. There will be a valid
60 // logger other than this one available while this is called.
61 virtual void set_next(LogImplementation *next) { next_ = next; }
62
Brian Silvermancb5da1f2015-12-05 22:19:58 -050063 protected:
Austin Schuh044e18b2015-10-21 20:17:09 -070064 // Actually logs the given message. Implementations should somehow create a
65 // LogMessage and then call internal::FillInMessage.
66 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
67 virtual void DoLog(log_level level, const char *format, va_list ap) = 0;
68 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 4)))
69 void DoLogVariadic(log_level level, const char *format, ...) {
70 va_list ap;
71 va_start(ap, format);
72 DoLog(level, format, ap);
73 va_end(ap);
74 }
75
Brian Silvermancb5da1f2015-12-05 22:19:58 -050076 // Logs the contents of an auto-generated structure.
Austin Schuh044e18b2015-10-21 20:17:09 -070077 // size and type are the result of calling Size() and Type() on the type of
78 // the message.
79 // serialize will call Serialize on the message.
80 virtual void LogStruct(log_level level, const ::std::string &message,
81 size_t size, const MessageType *type,
Brian Silvermancb5da1f2015-12-05 22:19:58 -050082 const ::std::function<size_t(char *)> &serialize) = 0;
Austin Schuh044e18b2015-10-21 20:17:09 -070083 // Similiar to LogStruct, except for matrixes.
84 // type_id is the type of the elements of the matrix.
85 // data points to rows*cols*type_id.Size() bytes of data in row-major order.
86 virtual void LogMatrix(log_level level, const ::std::string &message,
87 uint32_t type_id, int rows, int cols,
Brian Silvermancb5da1f2015-12-05 22:19:58 -050088 const void *data) = 0;
Austin Schuh044e18b2015-10-21 20:17:09 -070089
Brian Silvermancb5da1f2015-12-05 22:19:58 -050090 private:
Austin Schuh044e18b2015-10-21 20:17:09 -070091 // These functions call similar methods on the "current" LogImplementation or
92 // Die if they can't find one.
93 // levels is how many LogImplementations to not use off the stack.
94 static void DoVLog(log_level, const char *format, va_list ap, int levels)
95 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 0)));
Austin Schuh044e18b2015-10-21 20:17:09 -070096
Austin Schuh044e18b2015-10-21 20:17:09 -070097 friend void VLog(log_level, const char *, va_list);
Brian Silvermancb5da1f2015-12-05 22:19:58 -050098 friend void internal::DoLogStruct(
99 log_level level, const ::std::string &message, size_t size,
100 const MessageType *type, const ::std::function<size_t(char *)> &serialize,
101 int levels);
102 friend void internal::DoLogMatrix(log_level level,
103 const ::std::string &message,
104 uint32_t type_id, int rows, int cols,
105 const void *data, int levels);
Austin Schuh044e18b2015-10-21 20:17:09 -0700106
107 LogImplementation *next_;
108};
109
Brian Silverman17291d82015-10-24 22:30:57 -0400110namespace internal {
111
112// Prints format (with ap) into output and correctly deals with the result
113// being too long etc.
114size_t ExecuteFormat(char *output, size_t output_size, const char *format,
115 va_list ap)
116 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)));
117
118// Runs the given function with the current LogImplementation (handles switching
119// it out while running function etc).
120// levels is how many LogImplementations to not use off the stack.
121void RunWithCurrentImplementation(
122 int levels, ::std::function<void(LogImplementation *)> function);
123
124} // namespace internal
Austin Schuh044e18b2015-10-21 20:17:09 -0700125} // namespace logging
126} // namespace aos
127
Brian Silvermancb5da1f2015-12-05 22:19:58 -0500128#endif // AOS_COMMON_LOGGING_INTERFACE_H_