blob: 66b88c7a0017d830041fbdc57dfad0dcdd197379 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#ifndef AOS_COMMON_LOGGING_LOGGING_H_
brians343bc112013-02-10 01:53:46 +00002#define AOS_COMMON_LOGGING_LOGGING_H_
3
Brian Silvermanf665d692013-02-17 22:11:39 -08004// This file contains the logging client interface. It works with both C and C++
5// code.
6
7#include <stdio.h>
brians343bc112013-02-10 01:53:46 +00008#include <stdint.h>
Brian Silvermanb067abf2013-09-13 22:01:06 -07009#include <stdlib.h>
Brian Silverman01be0002014-05-10 15:44:38 -070010#include <string.h>
11#include <errno.h>
brians343bc112013-02-10 01:53:46 +000012
Brian Silvermana7234c62014-03-24 20:23:25 -070013#include "aos/common/macros.h"
Brian Silvermanaf784862014-05-13 08:14:55 -070014#include "aos/common/libc/aos_strerror.h"
Brian Silvermana7234c62014-03-24 20:23:25 -070015
brians343bc112013-02-10 01:53:46 +000016#ifdef __cplusplus
17extern "C" {
18#endif
19
20typedef uint8_t log_level;
Brian Silvermanf665d692013-02-17 22:11:39 -080021
brians343bc112013-02-10 01:53:46 +000022#define DECL_LEVELS \
23DECL_LEVEL(DEBUG, 0); /* stuff that gets printed out every cycle */ \
24DECL_LEVEL(INFO, 1); /* things like PosEdge/NegEdge */ \
Brian Silvermanf665d692013-02-17 22:11:39 -080025/* things that might still work if they happen occasionally */ \
brians343bc112013-02-10 01:53:46 +000026DECL_LEVEL(WARNING, 2); \
27/*-1 so that vxworks macro of same name will have same effect if used*/ \
28DECL_LEVEL(ERROR, -1); /* errors */ \
Brian Silvermanf665d692013-02-17 22:11:39 -080029/* serious errors. the logging code will terminate the process/task */ \
30DECL_LEVEL(FATAL, 4); \
brians343bc112013-02-10 01:53:46 +000031DECL_LEVEL(LOG_UNKNOWN, 5); /* unknown logging level */
Brian Silvermanf665d692013-02-17 22:11:39 -080032#define DECL_LEVEL(name, value) static const log_level name = value;
Brian Silvermanf665d692013-02-17 22:11:39 -080033DECL_LEVELS;
brians343bc112013-02-10 01:53:46 +000034#undef DECL_LEVEL
35
Brian Silvermanb0893882014-02-10 14:48:30 -080036// Not static const size_t for C code.
Brian Silvermanc11f3b72013-03-19 18:32:02 -070037#define LOG_MESSAGE_LEN 400
Brian Silvermanf665d692013-02-17 22:11:39 -080038
Brian Silvermanf665d692013-02-17 22:11:39 -080039#ifdef __cplusplus
40extern "C" {
41#endif
Brian Silverman01be0002014-05-10 15:44:38 -070042
Brian Silvermanf665d692013-02-17 22:11:39 -080043// Actually implements the basic logging call.
44// Does not check that level is valid.
45void log_do(log_level level, const char *format, ...)
Brian Silvermanf7986142014-04-21 17:42:35 -070046 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 3)));
Brian Silvermanf665d692013-02-17 22:11:39 -080047
48void log_cork(int line, const char *function, const char *format, ...)
Brian Silvermanf7986142014-04-21 17:42:35 -070049 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 4)));
Brian Silvermanf665d692013-02-17 22:11:39 -080050// Implements the uncork logging call.
51void log_uncork(int line, const char *function, log_level level,
52 const char *file, const char *format, ...)
Brian Silvermanf7986142014-04-21 17:42:35 -070053 __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 5, 6)));
Brian Silverman01be0002014-05-10 15:44:38 -070054
Brian Silvermanf665d692013-02-17 22:11:39 -080055#ifdef __cplusplus
56}
57#endif
58
59// A magical static const char[] or string literal that communicates the name
60// of the enclosing function.
61// It's currently using __PRETTY_FUNCTION__ because both GCC and Clang support
62// that and it gives nicer results in C++ than the standard __func__ (which
63// would also work).
Brian Silvermanc11f3b72013-03-19 18:32:02 -070064//#define LOG_CURRENT_FUNCTION __PRETTY_FUNCTION__
65#define LOG_CURRENT_FUNCTION __func__
Brian Silvermanf665d692013-02-17 22:11:39 -080066
Brian Silverman8fc7bc92013-03-13 23:15:47 -070067#define LOG_SOURCENAME __FILE__
68
Brian Silvermanf665d692013-02-17 22:11:39 -080069// The basic logging call.
Brian Silvermand6974f42014-02-14 13:39:21 -080070#define LOG(level, format, args...) \
71 do { \
72 log_do(level, LOG_SOURCENAME ": " STRINGIFY(__LINE__) ": %s: " format, \
73 LOG_CURRENT_FUNCTION, ##args); \
74 /* so that GCC knows that it won't return */ \
75 if (level == FATAL) { \
76 fprintf(stderr, "log_do(FATAL) fell through!!!!!\n"); \
77 printf("see stderr\n"); \
78 abort(); \
79 } \
80 } while (0)
brians343bc112013-02-10 01:53:46 +000081
Brian Silvermanb3efcca2014-06-03 19:47:06 -070082// Same as LOG except appends " due to %d (%s)\n" (formatted with errno and
Brian Silverman01be0002014-05-10 15:44:38 -070083// aos_strerror(errno)) to the message.
84#define PLOG(level, format, args...) PELOG(level, errno, format, ##args)
85
86// Like PLOG except allows specifying an error other than errno.
Brian Silvermanb3efcca2014-06-03 19:47:06 -070087#define PELOG(level, error_in, format, args...) \
88 do { \
89 const int error = error_in; \
90 LOG(level, format " due to %d (%s)\n", ##args, error, \
91 aos_strerror(error)); \
Brian Silverman01be0002014-05-10 15:44:38 -070092 } while (0);
93
brians343bc112013-02-10 01:53:46 +000094// Allows format to not be a string constant.
Brian Silvermand6974f42014-02-14 13:39:21 -080095#define LOG_DYNAMIC(level, format, args...) \
96 do { \
97 static char log_buf[LOG_MESSAGE_LEN]; \
98 int ret = snprintf(log_buf, sizeof(log_buf), format, ##args); \
99 if (ret < 0 || (uintmax_t)ret >= LOG_MESSAGE_LEN) { \
100 LOG(ERROR, "next message was too long so not subbing in args\n"); \
101 LOG(level, "%s", format); \
102 } else { \
103 LOG(level, "%s", log_buf); \
104 } \
105 } while (0)
brians343bc112013-02-10 01:53:46 +0000106
Brian Silvermanf665d692013-02-17 22:11:39 -0800107// Allows "bottling up" multiple log fragments which can then all be logged in
108// one message with LOG_UNCORK.
109// Calls from a given thread/task will be grouped together.
Brian Silvermand6974f42014-02-14 13:39:21 -0800110#define LOG_CORK(format, args...) \
111 do { \
112 log_cork(__LINE__, LOG_CURRENT_FUNCTION, format, ##args); \
113 } while (0)
Brian Silvermanf665d692013-02-17 22:11:39 -0800114// Actually logs all of the saved up log fragments (including format and args on
115// the end).
Brian Silvermand6974f42014-02-14 13:39:21 -0800116#define LOG_UNCORK(level, format, args...) \
117 do { \
118 log_uncork(__LINE__, LOG_CURRENT_FUNCTION, level, LOG_SOURCENAME, format, \
119 ##args); \
120 } while (0)
brians343bc112013-02-10 01:53:46 +0000121
brians343bc112013-02-10 01:53:46 +0000122#ifdef __cplusplus
123}
124#endif
125
Brian Silvermanb067abf2013-09-13 22:01:06 -0700126#ifdef __cplusplus
127
128namespace aos {
129
130// CHECK* macros, similar to glog
131// (<http://google-glog.googlecode.com/svn/trunk/doc/glog.html>)'s, except they
132// don't support streaming in extra text. Some of the implementation is borrowed
133// from there too.
134// They all LOG(FATAL) with a helpful message when the check fails.
Brian Silvermanb067abf2013-09-13 22:01:06 -0700135// Portions copyright (c) 1999, Google Inc.
136// All rights reserved.
137//
138// Redistribution and use in source and binary forms, with or without
139// modification, are permitted provided that the following conditions are
140// met:
141//
142// * Redistributions of source code must retain the above copyright
143// notice, this list of conditions and the following disclaimer.
144// * Redistributions in binary form must reproduce the above
145// copyright notice, this list of conditions and the following disclaimer
146// in the documentation and/or other materials provided with the
147// distribution.
148// * Neither the name of Google Inc. nor the names of its
149// contributors may be used to endorse or promote products derived from
150// this software without specific prior written permission.
151//
152// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
153// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
154// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
155// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
156// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
157// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
158// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
159// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
160// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
161// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
162// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
163
Brian Silverman862b1632013-09-14 15:29:59 -0700164// CHECK dies with a fatal error if condition is not true. It is *not*
165// controlled by NDEBUG, so the check will be executed regardless of
166// compilation mode. Therefore, it is safe to do things like:
167// CHECK(fp->Write(x) == 4)
Brian Silvermand6974f42014-02-14 13:39:21 -0800168#define CHECK(condition) \
169 if (__builtin_expect(!(condition), 0)) { \
Brian Silverman5d790752014-01-01 13:25:36 -0800170 LOG(FATAL, "CHECK(%s) failed\n", #condition); \
Brian Silverman862b1632013-09-14 15:29:59 -0700171 }
172
Brian Silvermanb067abf2013-09-13 22:01:06 -0700173// Helper functions for CHECK_OP macro.
174// The (int, int) specialization works around the issue that the compiler
175// will not instantiate the template version of the function on values of
176// unnamed enum type.
Brian Silverman83b71b82014-08-14 23:18:52 -0700177#define DEFINE_CHECK_OP_IMPL(name, op) \
178 template <typename T1, typename T2> \
179 inline void LogImpl##name(const T1 &v1, const T2 &v2, \
180 const char *exprtext) { \
181 if (!__builtin_expect(v1 op v2, 1)) { \
182 log_do(FATAL, \
183 LOG_SOURCENAME ": " STRINGIFY(__LINE__) ": CHECK(%s) failed\n", \
184 exprtext); \
185 fprintf(stderr, "log_do(FATAL) fell through!!!!!\n"); \
186 printf("see stderr\n"); \
187 abort(); \
188 } \
189 } \
190 inline void LogImpl##name(int v1, int v2, const char *exprtext) { \
191 ::aos::LogImpl##name<int, int>(v1, v2, exprtext); \
Brian Silvermanb067abf2013-09-13 22:01:06 -0700192 }
193
194// We use the full name Check_EQ, Check_NE, etc. in case the file including
195// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
196// This happens if, for example, those are used as token names in a
197// yacc grammar.
198DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)?
199DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead.
200DEFINE_CHECK_OP_IMPL(Check_LE, <=)
201DEFINE_CHECK_OP_IMPL(Check_LT, < )
202DEFINE_CHECK_OP_IMPL(Check_GE, >=)
203DEFINE_CHECK_OP_IMPL(Check_GT, > )
204
Brian Silvermand6974f42014-02-14 13:39:21 -0800205#define CHECK_OP(name, op, val1, val2) \
Brian Silvermanb067abf2013-09-13 22:01:06 -0700206 ::aos::LogImplCheck##name(val1, val2, \
207 STRINGIFY(val1) STRINGIFY(op) STRINGIFY(val2))
208
209#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2)
210#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2)
211#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2)
212#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2)
213#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2)
214#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2)
215
216// A small helper for CHECK_NOTNULL().
217template <typename T>
218inline T* CheckNotNull(const char *value_name, T *t) {
219 if (t == NULL) {
220 LOG(FATAL, "'%s' must not be NULL\n", value_name);
221 }
222 return t;
223}
224
225// Check that the input is non NULL. This very useful in constructor
226// initializer lists.
Brian Silvermand6974f42014-02-14 13:39:21 -0800227#define CHECK_NOTNULL(val) ::aos::CheckNotNull(STRINGIFY(val), val)
Brian Silvermanb067abf2013-09-13 22:01:06 -0700228
Brian Silvermanfe457de2014-05-26 22:04:08 -0700229inline int CheckSyscall(const char *syscall_string, int value) {
230 if (__builtin_expect(value == -1, false)) {
231 PLOG(FATAL, "%s failed", syscall_string);
232 }
233 return value;
234}
235
Brian Silvermanb20e06a2014-09-03 12:09:24 -0400236inline void CheckSyscallReturn(const char *syscall_string, int value) {
237 if (__builtin_expect(value != 0, false)) {
238 PELOG(FATAL, value, "%s failed", syscall_string);
239 }
240}
241
Brian Silvermanfe457de2014-05-26 22:04:08 -0700242// Check that syscall does not return -1. If it does, PLOG(FATAL)s. This is
243// useful for quickly checking syscalls where it's not very useful to print out
Brian Silvermanb20e06a2014-09-03 12:09:24 -0400244// the values of any of the arguments. Returns the result otherwise.
245//
246// Example: const int fd = PCHECK(open("/tmp/whatever", O_WRONLY))
Brian Silvermanfe457de2014-05-26 22:04:08 -0700247#define PCHECK(syscall) ::aos::CheckSyscall(STRINGIFY(syscall), syscall)
248
Brian Silvermanb20e06a2014-09-03 12:09:24 -0400249// PELOG(FATAL)s with the result of syscall if it returns anything other than 0.
250// This is useful for quickly checking things like many of the pthreads
251// functions where it's not very useful to print out the values of any of the
252// arguments.
253//
254// Example: PRCHECK(munmap(address, length))
255#define PRCHECK(syscall) ::aos::CheckSyscallReturn(STRINGIFY(syscall), syscall)
256
Brian Silvermanb067abf2013-09-13 22:01:06 -0700257} // namespace aos
258
259#endif // __cplusplus
260
brians343bc112013-02-10 01:53:46 +0000261#endif