1 /* 2 * Copyright 2017-2020, 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 15 16 // These macros allow for standardized logging to be output. 17 // The use of macros in this way means that the use of the log is concise where 18 // it is used and also because the macro unwraps to a block contained with a 19 // condition statement, if the log level is not sufficient to trigger the log 20 // line then there is no computational cost to running over the log space. This 21 // is because the arguments will not be evaluated. Avoiding all of the 22 // conditional clauses in the code to prevent this otherwise would be 23 // cumbersome. 24 25 #define HDLOGPREFIX(L) printf("{%c} ", toupper(Logger::NameForLevel(L)[0])); 26 27 #define HDLOG(L, M...) do { if (Logger::IsLevelEnabled(L)) { \ 28 HDLOGPREFIX(L) \ 29 printf(M); \ 30 putchar('\n'); \ 31 } } while (0) 32 33 #define HDINFO(M...) HDLOG(LOG_LEVEL_INFO, M) 34 #define HDDEBUG(M...) HDLOG(LOG_LEVEL_DEBUG, M) 35 #define HDTRACE(M...) HDLOG(LOG_LEVEL_TRACE, M) 36 #define HDERROR(M...) HDLOG(LOG_LEVEL_ERROR, M) 37 38 typedef enum log_level { 39 LOG_LEVEL_OFF = 1, 40 LOG_LEVEL_ERROR = 2, 41 LOG_LEVEL_INFO = 3, 42 LOG_LEVEL_DEBUG = 4, 43 LOG_LEVEL_TRACE = 5 44 } log_level; 45 46 47 class Logger { 48 public: 49 static log_level Level(); 50 static void SetLevel(log_level value); 51 static bool SetLevelByName(const char *name); 52 53 static const char* NameForLevel(log_level value); 54 55 static bool IsLevelEnabled(log_level value); 56 static bool IsInfoEnabled(); 57 static bool IsDebugEnabled(); 58 static bool IsTraceEnabled(); 59 60 private: 61 static log_level fLevel; 62 }; 63 64 65 #endif // LOGGER_H 66