1 /* 2 * Copyright 2017-2022, Andrew Lindesay <apl@lindesay.co.nz>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 #ifndef LOGGER_H 6 #define LOGGER_H 7 8 #include <String.h> 9 #include <File.h> 10 #include <Path.h> 11 12 #include <ctype.h> 13 #include <stdio.h> 14 #include <stdlib.h> 15 16 17 #define MILLIS_IN_DAY (1000 * 60 * 60 * 24) 18 19 20 // These macros allow for standardized logging to be output. 21 // The use of macros in this way means that the use of the log is concise where 22 // it is used and also because the macro unwraps to a block contained with a 23 // condition statement, if the log level is not sufficient to trigger the log 24 // line then there is no computational cost to running over the log space. This 25 // is because the arguments will not be evaluated. Avoiding all of the 26 // conditional clauses in the code to prevent this otherwise would be 27 // cumbersome. 28 29 #define HDLOGPREFIX(L) printf("@%08" B_PRId64 " {%c} <t:%" B_PRId32 "> ", \ 30 ((system_time() / 1000) % MILLIS_IN_DAY), \ 31 toupper(Logger::NameForLevel(L)[0]), \ 32 abs(find_thread(NULL) % 1000) \ 33 ); 34 35 #define HDLOG(L, M...) do { if (Logger::IsLevelEnabled(L)) { \ 36 HDLOGPREFIX(L) \ 37 printf(M); \ 38 putchar('\n'); \ 39 } } while (0) 40 41 #define HDINFO(M...) HDLOG(LOG_LEVEL_INFO, M) 42 #define HDDEBUG(M...) HDLOG(LOG_LEVEL_DEBUG, M) 43 #define HDTRACE(M...) HDLOG(LOG_LEVEL_TRACE, M) 44 #define HDERROR(M...) HDLOG(LOG_LEVEL_ERROR, M) 45 46 #define HDFATAL(M...) do { \ 47 printf("{!} (failed @ %s:%d) ", __FILE__, __LINE__); \ 48 printf(M); \ 49 putchar('\n'); \ 50 exit(EXIT_FAILURE); \ 51 } while (0) 52 53 typedef enum log_level { 54 LOG_LEVEL_OFF = 1, 55 LOG_LEVEL_ERROR = 2, 56 LOG_LEVEL_INFO = 3, 57 LOG_LEVEL_DEBUG = 4, 58 LOG_LEVEL_TRACE = 5 59 } log_level; 60 61 62 class Logger { 63 public: 64 static log_level Level(); 65 static void SetLevel(log_level value); 66 static bool SetLevelByName(const char *name); 67 68 static const char* NameForLevel(log_level value); 69 70 static bool IsLevelEnabled(log_level value); 71 static bool IsInfoEnabled(); 72 static bool IsDebugEnabled(); 73 static bool IsTraceEnabled(); 74 75 private: 76 static log_level fLevel; 77 }; 78 79 80 #endif // LOGGER_H 81