brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame^] | 1 | #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 |
| 11 | extern "C" { |
| 12 | #endif |
| 13 | |
| 14 | typedef uint8_t log_level; |
| 15 | #define DECL_LEVELS \ |
| 16 | DECL_LEVEL(DEBUG, 0); /* stuff that gets printed out every cycle */ \ |
| 17 | DECL_LEVEL(INFO, 1); /* things like PosEdge/NegEdge */ \ |
| 18 | /* things that might still work if they happen occasionally but should be watched */ \ |
| 19 | DECL_LEVEL(WARNING, 2); \ |
| 20 | /*-1 so that vxworks macro of same name will have same effect if used*/ \ |
| 21 | DECL_LEVEL(ERROR, -1); /* errors */ \ |
| 22 | DECL_LEVEL(FATAL, 4); /* serious errors. the logging code will terminate the process/task */ \ |
| 23 | DECL_LEVEL(LOG_UNKNOWN, 5); /* unknown logging level */ |
| 24 | #define DECL_LEVEL(name, value) extern const log_level name; |
| 25 | #undef ERROR |
| 26 | DECL_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. |
| 49 | typedef 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. |
| 61 | int log_crio_message_send(log_crio_message &to_send); |
| 62 | // Returns left > right. LOG_UNKNOWN is most important. |
| 63 | static 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". |
| 72 | static 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. |
| 82 | static 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 | |