blob: e3ff8392d28c7eaf35f77d22666582f63fb53ef8 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#ifndef AOS_COMMON_LOGGING_LOGGING_H_
2// must be kept in sync with crio/logging/crio_logging.h and atom_code/logging/atom_logging.h
3#define AOS_COMMON_LOGGING_LOGGING_H_
4
5#include <stdint.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include <string.h>
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14typedef uint8_t log_level;
15#define DECL_LEVELS \
16DECL_LEVEL(DEBUG, 0); /* stuff that gets printed out every cycle */ \
17DECL_LEVEL(INFO, 1); /* things like PosEdge/NegEdge */ \
18/* things that might still work if they happen occasionally but should be watched */ \
19DECL_LEVEL(WARNING, 2); \
20/*-1 so that vxworks macro of same name will have same effect if used*/ \
21DECL_LEVEL(ERROR, -1); /* errors */ \
22DECL_LEVEL(FATAL, 4); /* serious errors. the logging code will terminate the process/task */ \
23DECL_LEVEL(LOG_UNKNOWN, 5); /* unknown logging level */
24#define DECL_LEVEL(name, value) extern const log_level name;
25#undef ERROR
26DECL_LEVELS
27#undef DECL_LEVEL
28
29#define STRINGIFY(x) TO_STRING(x)
30#define TO_STRING(x) #x
31
32//not static const size_t for c code
33#define LOG_MESSAGE_LEN 300
34
35// Allows format to not be a string constant.
36#define LOG_DYNAMIC(level, format, args...) do{ \
37 static char log_buf[LOG_MESSAGE_LEN]; \
38 int ret = snprintf(log_buf, sizeof(log_buf), format, ##args); \
39 if(ret < 0 || (uintmax_t)ret >= LOG_MESSAGE_LEN){ \
40 LOG(WARNING, "next message was too long so not subbing in args\n"); \
41 LOG(level, "%s", format); \
42 }else{ \
43 LOG(level, "%s", log_buf); \
44 } \
45}while(0)
46
47// The struct that the crio-side code uses for making logging calls.
48// Packed so it's the same on the atom and the crio.
49typedef struct {
50 // pid_t here at the front like in log_message
51 pid_t identifier; // must ALWAYS be -1 to identify that this is a crio log message
52 log_level level;
53 // still has to fit in LOG_MESSAGE_LEN on the atom side
54 char message[LOG_MESSAGE_LEN - 50];
55 double time;
56 uint8_t sequence;
57} __attribute__((packed)) log_crio_message;
58
59#ifdef __cplusplus
60// Just sticks the message into the shared memory queue.
61int log_crio_message_send(log_crio_message &to_send);
62// Returns left > right. LOG_UNKNOWN is most important.
63static inline bool log_gt_important(log_level left, log_level right) {
64 log_level l = left, r = right;
65 if (l == ERROR) l = 3;
66 if (r == ERROR) r = 3;
67 return left > right;
68}
69#endif
70
71// Returns a string representing level or "unknown".
72static inline const char *log_str(log_level level) {
73 // c doesn't really have const variables so they don't work in case statements
74 if (level == DEBUG) return "DEBUG";
75 if (level == INFO) return "INFO";
76 if (level == WARNING) return "WARNING";
77 if (level == ERROR) return "ERROR";
78 if (level == FATAL) return "FATAL";
79 return "unknown";
80}
81// Returns the log level represented by str or LOG_UNKNOWN.
82static inline log_level str_log(const char *str) {
83 if (!strcmp(str, "DEBUG")) return DEBUG;
84 if (!strcmp(str, "INFO")) return INFO;
85 if (!strcmp(str, "WARNING")) return WARNING;
86 if (!strcmp(str, "ERROR")) return ERROR;
87 if (!strcmp(str, "FATAL")) return FATAL;
88 return LOG_UNKNOWN;
89}
90
91#ifdef __cplusplus
92}
93#endif
94
95#ifdef __unix
96#include "aos/atom_code/logging/atom_logging.h" // IWYU pragma: export
97#else
98#include "aos/crio/logging/crio_logging.h" // IWYU pragma: export
99#endif
100
101#endif
102