├── .gitignore ├── sample.c ├── sample.m ├── README.md └── macrologger.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | sample 3 | -------------------------------------------------------------------------------- /sample.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 David Rodrigues 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | * IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | #include "macrologger.h" 26 | 27 | int main(int argc, const char * argv[]) { 28 | 29 | LOG_DEBUG("Maybe i can touch this button..."); 30 | 31 | LOG_INFO("Pressure is dropping..."); 32 | 33 | LOG_ERROR("Houston we have a problem!"); 34 | 35 | int going_down = 1; 36 | LOG_IF_ERROR(going_down, "i'm going down... if only i had used macro-logger..."); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /sample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 David Rodrigues 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | * IN THE SOFTWARE. 21 | */ 22 | 23 | #import 24 | 25 | #import "macrologger.h" 26 | 27 | int main(int argc, const char * argv[]) { 28 | 29 | LOG_DEBUG("Maybe i can touch this button..."); 30 | 31 | LOG_INFO("Pressure is dropping..."); 32 | 33 | NSString *baseStation = @"Houston"; 34 | LOG_ERROR(@"%@ we have a problem!", baseStation); 35 | 36 | int going_down = 1; 37 | LOG_IF_ERROR(going_down, "i'm going down... if only i had used macro-logger..."); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Macro-Logger 2 | 3 | A simplified logging system using macros for C/C++ and Objective-C. 4 | 5 | ## Notes 6 | 7 | #### Levels 8 | 9 | There are three different logging levels. It's possible also disable all logs. 10 | 11 | - [0] NO_LOGS 12 | - [1] ERROR 13 | - [2] INFO 14 | - [3] DEBUG 15 | 16 | The log level can be specified on compilation time using the macro 17 | 18 | ``` 19 | LOG_LEVEL=level_number 20 | ``` 21 | 22 | If not specified is used the debug level. 23 | 24 | #### Technical aspects 25 | 26 | * **Each log below the log level defined will not be included on binary.** This is relevant because allows save space and resources. 27 | * Logs are printed using fprintf function in conjunction with standard error stream (stderr) in C/C++ and Objective-C. 28 | * The log functions can handle arguments like printf or just a message. The message can be a C/C++ string or an Objective-C string. 29 | 30 | ```C 31 | int x = 5; 32 | LOG_INFO("x * x = %d", x * x); 33 | LOG_DEBUG(@"Objective-C also supported"); 34 | ``` 35 | * The log functions can receive Objective-C objects as arguments. 36 | 37 | ```Objective-C 38 | NSString *baseStation = @"Houston"; 39 | LOG_ERROR(@"%@ we have a problem!", baseStation); 40 | ``` 41 | 42 | ## Basic usage 43 | 44 | The only file needed to use the macrologger is the header file, `macrologger.h`. 45 | 46 | ```C++ 47 | 48 | // C/C++ 49 | #include "macrologger.h" 50 | 51 | // Objective-C 52 | #import "macrologger.h" 53 | ``` 54 | 55 | ### Available functions 56 | 57 | ```C++ 58 | 59 | 60 | LOG_DEBUG(message, arguments); 61 | 62 | LOG_INFO(message, arguments); 63 | 64 | LOG_ERROR(message, arguments); 65 | 66 | LOG_IF_ERROR(condition, message, arguments); 67 | 68 | ``` 69 | 70 | ### Examples 71 | 72 | ```C++ 73 | 74 | 75 | // C/C++ strings 76 | LOG_DEBUG("Maybe i can touch this button..."); 77 | 78 | // Objective-C strings 79 | LOG_INFO("@Pressure is dropping..."); 80 | 81 | // printing Objective-C objects 82 | NSString *baseStation = @"Houston"; 83 | LOG_ERROR(@"%@ we have a problem!", baseStation); 84 | 85 | int going_down = 1; 86 | LOG_IF_ERROR(going_down, "i'm going down... if only i had used macro-logger..."); 87 | 88 | ``` 89 | 90 | ### Sample output 91 | 92 | ``` 93 | 2012-09-04 01:05:16 | DEBUG | sample.m | main:29 | Maybe i can touch this button... 94 | 2012-09-04 01:05:16 | INFO | sample.m | main:31 | Pressure is dropping... 95 | 2012-09-04 01:05:16 | ERROR | sample.m | main:34 | Houston we have a problem! 96 | 2012-09-04 01:05:16 | ERROR | sample.m | main:37 | i'm going down... if only i had used macro-logger... 97 | ``` -------------------------------------------------------------------------------- /macrologger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 David Rodrigues 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | * IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __MACROLOGGER_H__ 24 | #define __MACROLOGGER_H__ 25 | 26 | #ifdef __OBJC__ 27 | #import 28 | #else 29 | #include 30 | #include 31 | #endif 32 | 33 | // === auxiliar functions 34 | static inline char *timenow(); 35 | 36 | #define _FILE strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__ 37 | 38 | #define NO_LOG 0x00 39 | #define ERROR_LEVEL 0x01 40 | #define INFO_LEVEL 0x02 41 | #define DEBUG_LEVEL 0x03 42 | 43 | #ifndef LOG_LEVEL 44 | #define LOG_LEVEL DEBUG_LEVEL 45 | #endif 46 | 47 | #ifdef __OBJC__ 48 | 49 | #if __has_feature(objc_arc) 50 | #define AUTORELEASEPOOL_BEGIN @autoreleasepool { 51 | #define AUTORELEASEPOOL_END } 52 | #define RELEASE(OBJ) OBJ = nil 53 | #else 54 | #define AUTORELEASEPOOL_BEGIN NSAutoreleasePool *_pool = [[NSAutoreleasePool alloc] init]; 55 | #define AUTORELEASEPOOL_END [_pool release]; 56 | #define RELEASE(OBJ) [OBJ release]; 57 | #endif 58 | 59 | #define PRINTFUNCTION(format, ...) objc_print(@format, __VA_ARGS__) 60 | #else 61 | #define PRINTFUNCTION(format, ...) fprintf(stderr, format, __VA_ARGS__) 62 | 63 | #endif 64 | 65 | #define LOG_FMT "%s | %-7s | %-15s | %s:%d | " 66 | #define LOG_ARGS(LOG_TAG) timenow(), LOG_TAG, _FILE, __FUNCTION__, __LINE__ 67 | 68 | #define NEWLINE "\n" 69 | 70 | #define ERROR_TAG "ERROR" 71 | #define INFO_TAG "INFO" 72 | #define DEBUG_TAG "DEBUG" 73 | 74 | #if LOG_LEVEL >= DEBUG_LEVEL 75 | #define LOG_DEBUG(message, args...) PRINTFUNCTION(LOG_FMT message NEWLINE, LOG_ARGS(DEBUG_TAG), ## args) 76 | #else 77 | #define LOG_DEBUG(message, args...) 78 | #endif 79 | 80 | #if LOG_LEVEL >= INFO_LEVEL 81 | #define LOG_INFO(message, args...) PRINTFUNCTION(LOG_FMT message NEWLINE, LOG_ARGS(INFO_TAG), ## args) 82 | #else 83 | #define LOG_INFO(message, args...) 84 | #endif 85 | 86 | #if LOG_LEVEL >= ERROR_LEVEL 87 | #define LOG_ERROR(message, args...) PRINTFUNCTION(LOG_FMT message NEWLINE, LOG_ARGS(ERROR_TAG), ## args) 88 | #else 89 | #define LOG_ERROR(message, args...) 90 | #endif 91 | 92 | #if LOG_LEVEL >= NO_LOGS 93 | #define LOG_IF_ERROR(condition, message, args...) if (condition) PRINTFUNCTION(LOG_FMT message NEWLINE, LOG_ARGS(ERROR_TAG), ## args) 94 | #else 95 | #define LOG_IF_ERROR(condition, message, args...) 96 | #endif 97 | 98 | static inline char *timenow() { 99 | static char buffer[64]; 100 | time_t rawtime; 101 | struct tm *timeinfo; 102 | 103 | time(&rawtime); 104 | timeinfo = localtime(&rawtime); 105 | 106 | strftime(buffer, 64, "%Y-%m-%d %H:%M:%S", timeinfo); 107 | 108 | return buffer; 109 | } 110 | 111 | #ifdef __OBJC__ 112 | 113 | static inline void objc_print(NSString *format, ...) { 114 | AUTORELEASEPOOL_BEGIN 115 | va_list args; 116 | va_start(args, format); 117 | NSString *logStr = [[NSString alloc] initWithFormat:format arguments:args]; 118 | fprintf(stderr, "%s", [logStr UTF8String]); 119 | RELEASE(logStr); 120 | va_end(args); 121 | AUTORELEASEPOOL_END 122 | } 123 | 124 | #endif 125 | 126 | #endif --------------------------------------------------------------------------------