├── .gitignore ├── .travis.yml ├── ArduinoLog.cpp ├── ArduinoLog.h ├── Images └── logo.png ├── LICENSE.md ├── README.md ├── examples ├── Log-advanced │ └── Log-advanced.ino ├── Log-basic │ └── Log-basic.ino └── platformio-basic │ ├── platformio.ini │ ├── src │ └── main.cpp │ └── test │ └── test_native.cpp ├── keywords.txt ├── library.json └── library.properties /.gitignore: -------------------------------------------------------------------------------- 1 | #### Ignore file for Arduino as editted with Visual Micro 2 | 3 | ## Windows 4 | # Windows thumbnail cache files 5 | Thumbs.db 6 | Thumbs.db:encryptable 7 | ehthumbs.db 8 | ehthumbs_vista.db 9 | 10 | # Dump file 11 | *.stackdump 12 | 13 | # Folder config file 14 | [Dd]esktop.ini 15 | 16 | # Recycle Bin used on file shares 17 | $RECYCLE.BIN/ 18 | 19 | # Windows shortcuts 20 | *.lnk 21 | 22 | ## Linux 23 | *~ 24 | 25 | # temporary files which can be created if a process still has a handle open of a deleted file 26 | .fuse_hidden* 27 | 28 | # KDE directory preferences 29 | .directory 30 | 31 | # Linux trash folder which might appear on any partition or disk 32 | .Trash-* 33 | 34 | # .nfs files are created when an open file is removed but is still being accessed 35 | .nfs* 36 | 37 | ## MacOS 38 | # General 39 | .DS_Store 40 | .AppleDouble 41 | .LSOverride 42 | 43 | # Icon must end with two \r 44 | Icon 45 | 46 | # Thumbnails 47 | ._* 48 | 49 | # Files that might appear in the root of a volume 50 | .DocumentRevisions-V100 51 | .fseventsd 52 | .Spotlight-V100 53 | .TemporaryItems 54 | .Trashes 55 | .VolumeIcon.icns 56 | .com.apple.timemachine.donotpresent 57 | 58 | ## Generated files 59 | bin/ 60 | gen/ 61 | out/ 62 | release/ 63 | 64 | ## Visual Micro generated files 65 | __vm/ 66 | 67 | # Local configuration file (sdk path, etc) 68 | local.properties 69 | 70 | # Log Files 71 | *.log 72 | 73 | ##### Backup 74 | *.bak 75 | *.bck 76 | *.gho 77 | *.ori 78 | *.orig 79 | *.tmp 80 | 81 | ##### Dropbox 82 | # Dropbox settings and caches 83 | .dropbox 84 | .dropbox.attr 85 | .dropbox.cache 86 | 87 | # Log file - the following switch allows to specify the file that will be 88 | # used to write all messages from simulation: -l 89 | *.log 90 | 91 | ##### SVN 92 | .svn/ 93 | 94 | ##### TortoiseGit 95 | # Project-level settings 96 | /.tgitconfig 97 | 98 | 99 | ##### VisualStudioCode 100 | .vscode/* 101 | !.vscode/settings.json 102 | !.vscode/tasks.json 103 | !.vscode/launch.json 104 | !.vscode/extensions.json 105 | *.code-workspace 106 | 107 | # Local History for Visual Studio Code 108 | .history/ 109 | 110 | 111 | ##### VisualStudio 112 | ## Ignore Visual Studio temporary files, build results, and 113 | ## files generated by popular Visual Studio add-ons. 114 | ## 115 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 116 | 117 | # User-specific files 118 | *.rsuser 119 | *.suo 120 | *.user 121 | *.userosscache 122 | *.sln.docstates 123 | 124 | # Visual studio related SQlite files 125 | *.db-shm 126 | *.db-wal 127 | 128 | # User-specific files (MonoDevelop/Xamarin Studio) 129 | *.userprefs 130 | 131 | # Mono auto generated files 132 | mono_crash.* 133 | 134 | # Build results 135 | [Dd]ebug/ 136 | [Dd]ebugPublic/ 137 | [Rr]elease/ 138 | [Rr]eleases/ 139 | x64/ 140 | x86/ 141 | [Ww][Ii][Nn]32/ 142 | [Aa][Rr][Mm]/ 143 | [Aa][Rr][Mm]64/ 144 | bld/ 145 | [Bb]in/ 146 | [Oo]bj/ 147 | [Ll]og/ 148 | [Ll]ogs/ 149 | 150 | # Visual Studio 2017 auto generated files 151 | Generated\ Files/ 152 | 153 | # MSTest test Results 154 | [Tt]est[Rr]esult*/ 155 | [Bb]uild[Ll]og.* 156 | 157 | # Build Results of an ATL Project 158 | [Dd]ebugPS/ 159 | [Rr]eleasePS/ 160 | dlldata.c 161 | 162 | # Benchmark Results 163 | BenchmarkDotNet.Artifacts/ 164 | 165 | # .NET Core 166 | project.lock.json 167 | project.fragment.lock.json 168 | artifacts/ 169 | 170 | # Files built by Visual Studio 171 | *_i.c 172 | *_p.c 173 | *_h.h 174 | *.ilk 175 | *.meta 176 | *.obj 177 | *.iobj 178 | *.pch 179 | *.pdb 180 | *.ipdb 181 | *.pgc 182 | *.pgd 183 | *.rsp 184 | *.sbr 185 | *.tlb 186 | *.tli 187 | *.tlh 188 | *.tmp 189 | *.tmp_proj 190 | *_wpftmp.csproj 191 | *.log 192 | *.vspscc 193 | *.vssscc 194 | .builds 195 | *.pidb 196 | *.svclog 197 | *.scc 198 | 199 | # Visual C++ cache files 200 | ipch/ 201 | *.aps 202 | *.ncb 203 | *.opendb 204 | *.opensdf 205 | *.sdf 206 | *.cachefile 207 | *.VC.db 208 | *.VC.VC.opendb 209 | 210 | # Visual Studio profiler 211 | *.psess 212 | *.vsp 213 | *.vspx 214 | *.sap 215 | 216 | # Visual Studio Trace Files 217 | *.e2e 218 | 219 | # ReSharper is a .NET coding add-in 220 | _ReSharper*/ 221 | *.[Rr]e[Ss]harper 222 | *.DotSettings.user 223 | 224 | # NuGet Packages 225 | *.nupkg 226 | # NuGet Symbol Packages 227 | *.snupkg 228 | # The packages folder can be ignored because of Package Restore 229 | **/[Pp]ackages/* 230 | # except build/, which is used as an MSBuild target. 231 | !**/[Pp]ackages/build/ 232 | # Uncomment if necessary however generally it will be regenerated when needed 233 | #!**/[Pp]ackages/repositories.config 234 | # NuGet v3's project.json files produces more ignorable files 235 | *.nuget.props 236 | *.nuget.targets 237 | 238 | 239 | # Visual Studio cache files 240 | # files ending in .cache can be ignored 241 | *.[Cc]ache 242 | # but keep track of directories ending in .cache 243 | !?*.[Cc]ache/ 244 | 245 | # Including strong name files can present a security risk 246 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 247 | #*.snk 248 | 249 | # Backup & report files from converting an old project file 250 | # to a newer Visual Studio version. Backup files are not needed, 251 | # because we have git ;-) 252 | _UpgradeReport_Files/ 253 | Backup*/ 254 | UpgradeLog*.XML 255 | UpgradeLog*.htm 256 | ServiceFabricBackup/ 257 | *.rptproj.bak 258 | 259 | # Tabs Studio 260 | *.tss 261 | 262 | # Local History for Visual Studio 263 | .localhistory/ 264 | 265 | # BeatPulse healthcheck temp database 266 | healthchecksdb 267 | 268 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 269 | MigrationBackup/ 270 | 271 | ##### C++ 272 | # Prerequisites 273 | *.d 274 | 275 | # Compiled Object files 276 | *.slo 277 | *.lo 278 | *.o 279 | *.obj 280 | 281 | # Precompiled Headers 282 | *.gch 283 | *.pch 284 | 285 | # Compiled Dynamic libraries 286 | *.so 287 | *.dylib 288 | *.dll 289 | 290 | # Fortran module files 291 | *.mod 292 | *.smod 293 | 294 | # Compiled Static libraries 295 | *.lai 296 | *.la 297 | *.a 298 | *.lib 299 | 300 | # Executables 301 | *.exe 302 | *.out 303 | *.app 304 | 305 | ##### C 306 | # Prerequisites 307 | *.d 308 | 309 | # Object files 310 | *.o 311 | *.ko 312 | *.obj 313 | *.elf 314 | 315 | # Linker output 316 | *.ilk 317 | *.map 318 | *.exp 319 | 320 | # Precompiled Headers 321 | *.gch 322 | *.pch 323 | 324 | # Libraries 325 | *.lib 326 | *.a 327 | *.la 328 | *.lo 329 | 330 | # Shared objects (inc. Windows DLLs) 331 | *.dll 332 | *.so 333 | *.so.* 334 | *.dylib 335 | 336 | # Executables 337 | *.exe 338 | *.out 339 | *.app 340 | *.i*86 341 | *.x86_64 342 | *.hex 343 | 344 | # Debug files 345 | *.dSYM/ 346 | *.su 347 | *.idb 348 | *.pdb 349 | 350 | # Kernel Module Compile Results 351 | *.mod* 352 | *.cmd 353 | .tmp_versions/ 354 | modules.order 355 | Module.symvers 356 | Mkfile.old 357 | dkms.conf 358 | 359 | # Cmake 360 | cmake*/ 361 | CMakeListsPrivate.txt 362 | 363 | # PlatformIO IDE data 364 | .pio/ 365 | 366 | # Jetbrains IDE configuration 367 | .idea/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | { 2 | "language": "c", 3 | "before_install": [ 4 | "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16", 5 | "sleep 3", 6 | "export DISPLAY=:1.0", 7 | "wget http://downloads.arduino.cc/arduino-1.8.1-linux64.tar.xz", 8 | "wget http://downloads.arduino.cc/arduino-1.6.13-linux64.tar.xz", 9 | "tar xf arduino-1.6.13-linux64.tar.xz", 10 | "tar xf arduino-1.8.1-linux64.tar.xz" 11 | ], 12 | "install": [ 13 | ], 14 | "script": [ 15 | "sudo cp -r arduino-1.6.13 /usr/local/share/arduino", 16 | "sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino", 17 | "sudo ln -s $PWD /usr/local/share/arduino/libraries/ArduinoLog", 18 | "arduino --verify --board arduino:avr:uno $PWD/examples/Log-basic/Log-basic.ino" 19 | "arduino --verify --board arduino:avr:uno $PWD/examples/Log-advanced/Log-advanced.ino" 20 | 21 | "sudo rm -rf /usr/local/share/arduino", 22 | "sudo cp -r arduino-1.8.1 /usr/local/share/arduino", 23 | "sudo rm /usr/local/bin/arduino", 24 | "sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino", 25 | "sudo ln -s $PWD /usr/local/share/arduino/libraries/ArduinoLog", 26 | "arduino --verify --board arduino:avr:uno $PWD/examples/Log-basic/Log-basic.ino" 27 | "arduino --verify --board arduino:avr:uno $PWD/examples/Log-advanced/Log-advanced.ino" 28 | ], 29 | "group": "stable", 30 | "dist": "precise", 31 | "os": "linux" 32 | } -------------------------------------------------------------------------------- /ArduinoLog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | _ ___ ___ _ _ ___ _ _ ___ _ ___ ___ 3 | /_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __| 4 | / _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ | 5 | /_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___| 6 | 7 | Log library for Arduino 8 | version 1.1.1 9 | https://github.com/thijse/Arduino-Log 10 | 11 | Licensed under the MIT License . 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 | SOFTWARE. 30 | */ 31 | 32 | #include "ArduinoLog.h" 33 | 34 | void Logging::begin(int level, Print* logOutput, bool showLevel) 35 | { 36 | #ifndef DISABLE_LOGGING 37 | setLevel(level); 38 | setShowLevel(showLevel); 39 | _logOutput = logOutput; 40 | #endif 41 | } 42 | 43 | void Logging::setLevel(int level) 44 | { 45 | #ifndef DISABLE_LOGGING 46 | _level = constrain(level, LOG_LEVEL_SILENT, LOG_LEVEL_VERBOSE); 47 | #endif 48 | } 49 | 50 | int Logging::getLevel() const 51 | { 52 | #ifndef DISABLE_LOGGING 53 | return _level; 54 | #else 55 | return 0; 56 | #endif 57 | } 58 | 59 | void Logging::setShowLevel(bool showLevel) 60 | { 61 | #ifndef DISABLE_LOGGING 62 | _showLevel = showLevel; 63 | #endif 64 | } 65 | 66 | bool Logging::getShowLevel() const 67 | { 68 | #ifndef DISABLE_LOGGING 69 | return _showLevel; 70 | #else 71 | return false; 72 | #endif 73 | } 74 | 75 | void Logging::setPrefix(printfunction f) 76 | { 77 | #ifndef DISABLE_LOGGING 78 | _prefix = f; 79 | #endif 80 | } 81 | 82 | void Logging::clearPrefix() 83 | { 84 | #ifndef DISABLE_LOGGING 85 | _prefix = nullptr; 86 | #endif 87 | } 88 | 89 | void Logging::setSuffix(printfunction f) 90 | { 91 | #ifndef DISABLE_LOGGING 92 | _suffix = f; 93 | #endif 94 | } 95 | 96 | void Logging::clearSuffix() 97 | { 98 | #ifndef DISABLE_LOGGING 99 | _suffix = nullptr; 100 | #endif 101 | } 102 | 103 | void Logging::print(const __FlashStringHelper *format, va_list args) 104 | { 105 | #ifndef DISABLE_LOGGING 106 | PGM_P p = reinterpret_cast(format); 107 | // This copy is only necessary on some architectures (x86) to change a passed 108 | // array in to a va_list. 109 | #ifdef __x86_64__ 110 | va_list args_copy; 111 | va_copy(args_copy, args); 112 | #endif 113 | char c = pgm_read_byte(p++); 114 | for(;c != 0; c = pgm_read_byte(p++)) 115 | { 116 | if (c == '%') 117 | { 118 | c = pgm_read_byte(p++); 119 | #ifdef __x86_64__ 120 | printFormat(c, &args_copy); 121 | #else 122 | printFormat(c, &args); 123 | #endif 124 | } 125 | else 126 | { 127 | _logOutput->print(c); 128 | } 129 | } 130 | #ifdef __x86_64__ 131 | va_end(args_copy); 132 | #endif 133 | #endif 134 | } 135 | 136 | void Logging::print(const char *format, va_list args) { 137 | #ifndef DISABLE_LOGGING 138 | // This copy is only necessary on some architectures (x86) to change a passed 139 | // array in to a va_list. 140 | #ifdef __x86_64__ 141 | va_list args_copy; 142 | va_copy(args_copy, args); 143 | #endif 144 | for (; *format != 0; ++format) 145 | { 146 | if (*format == '%') 147 | { 148 | ++format; 149 | #ifdef __x86_64__ 150 | printFormat(*format, &args_copy); 151 | #else 152 | printFormat(*format, &args); 153 | #endif 154 | } 155 | else 156 | { 157 | _logOutput->print(*format); 158 | } 159 | } 160 | #ifdef __x86_64__ 161 | va_end(args_copy); 162 | #endif 163 | #endif 164 | } 165 | 166 | void Logging::printFormat(const char format, va_list *args) { 167 | #ifndef DISABLE_LOGGING 168 | if (format == '\0') return; 169 | if (format == '%') 170 | { 171 | _logOutput->print(format); 172 | } 173 | else if (format == 's') 174 | { 175 | register char *s = va_arg(*args, char *); 176 | _logOutput->print(s); 177 | } 178 | else if (format == 'S') 179 | { 180 | register __FlashStringHelper *s = va_arg(*args, __FlashStringHelper *); 181 | _logOutput->print(s); 182 | } 183 | else if (format == 'd' || format == 'i') 184 | { 185 | _logOutput->print(va_arg(*args, int), DEC); 186 | } 187 | else if (format == 'D' || format == 'F') 188 | { 189 | _logOutput->print(va_arg(*args, double)); 190 | } 191 | else if (format == 'x') 192 | { 193 | _logOutput->print(va_arg(*args, int), HEX); 194 | } 195 | else if (format == 'X') 196 | { 197 | _logOutput->print("0x"); 198 | //_logOutput->print(va_arg(*args, int), HEX); 199 | register uint16_t h = (uint16_t) va_arg( *args, int ); 200 | if (h<0xFFF) _logOutput->print('0'); 201 | if (h<0xFF ) _logOutput->print('0'); 202 | if (h<0xF ) _logOutput->print('0'); 203 | _logOutput->print(h,HEX); 204 | } 205 | else if (format == 'p') 206 | { 207 | register Printable *obj = (Printable *) va_arg(*args, int); 208 | _logOutput->print(*obj); 209 | } 210 | else if (format == 'b') 211 | { 212 | _logOutput->print(va_arg(*args, int), BIN); 213 | } 214 | else if (format == 'B') 215 | { 216 | _logOutput->print("0b"); 217 | _logOutput->print(va_arg(*args, int), BIN); 218 | } 219 | else if (format == 'l') 220 | { 221 | _logOutput->print(va_arg(*args, long), DEC); 222 | } 223 | else if (format == 'u') 224 | { 225 | _logOutput->print(va_arg(*args, unsigned long), DEC); 226 | } 227 | else if (format == 'c') 228 | { 229 | _logOutput->print((char) va_arg(*args, int)); 230 | } 231 | else if( format == 'C' ) { 232 | register char c = (char) va_arg( *args, int ); 233 | if (c>=0x20 && c<0x7F) { 234 | _logOutput->print(c); 235 | } else { 236 | _logOutput->print("0x"); 237 | if (c<0xF) _logOutput->print('0'); 238 | _logOutput->print(c, HEX); 239 | } 240 | } 241 | else if(format == 't') 242 | { 243 | if (va_arg(*args, int) == 1) 244 | { 245 | _logOutput->print("T"); 246 | } 247 | else 248 | { 249 | _logOutput->print("F"); 250 | } 251 | } 252 | else if (format == 'T') 253 | { 254 | if (va_arg(*args, int) == 1) 255 | { 256 | _logOutput->print(F("true")); 257 | } 258 | else 259 | { 260 | _logOutput->print(F("false")); 261 | } 262 | } 263 | #endif 264 | } 265 | 266 | Logging Log = Logging(); 267 | -------------------------------------------------------------------------------- /ArduinoLog.h: -------------------------------------------------------------------------------- 1 | /* 2 | _ ___ ___ _ _ ___ _ _ ___ _ ___ ___ 3 | /_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __| 4 | / _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ | 5 | /_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___| 6 | 7 | Log library for Arduino 8 | version 1.1.1 9 | https://github.com/thijse/Arduino-Log 10 | 11 | Licensed under the MIT License . 12 | 13 | */ 14 | #pragma once 15 | #include 16 | #include 17 | 18 | // Non standard: Arduino.h also chosen if ARDUINO is not defined. To facilitate use in non-Arduino test environments 19 | #if ARDUINO < 100 20 | #include "WProgram.h" 21 | #else 22 | #include "Arduino.h" 23 | #endif 24 | 25 | // PGM stubs to facilitate use in non-Arduino test environments 26 | #ifndef PGM_P 27 | #define PGM_P const char * 28 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 29 | #define PSTR(str) (str) 30 | #define F(string_literal) (reinterpret_cast(PSTR(string_literal))) 31 | #endif 32 | typedef void (*printfunction)(Print*, int); 33 | 34 | 35 | // ************************************************************************* 36 | // Uncomment line below to fully disable logging, and reduce project size 37 | // ************************************************************************ 38 | //#define DISABLE_LOGGING 39 | 40 | #define LOG_LEVEL_SILENT 0 41 | #define LOG_LEVEL_FATAL 1 42 | #define LOG_LEVEL_ERROR 2 43 | #define LOG_LEVEL_WARNING 3 44 | #define LOG_LEVEL_INFO 4 45 | #define LOG_LEVEL_NOTICE 4 46 | #define LOG_LEVEL_TRACE 5 47 | #define LOG_LEVEL_VERBOSE 6 48 | 49 | #define CR "\n" 50 | #define LF "\r" 51 | #define NL "\n\r" 52 | #define LOGGING_VERSION 1_0_4 53 | 54 | /** 55 | * ArduinoLog is a minimalistic framework to help the programmer output log statements to an output of choice, 56 | * fashioned after extensive logging libraries such as log4cpp ,log4j and log4net. In case of problems with an 57 | * application, it is helpful to enable logging so that the problem can be located. ArduinoLog is designed so 58 | * that log statements can remain in the code with minimal performance cost. In order to facilitate this the 59 | * loglevel can be adjusted, and (if your code is completely tested) all logging code can be compiled out. 60 | * 61 | * ---- Wildcards 62 | * 63 | * %s display as string (char*) 64 | * %S display as string from flash memory (__FlashStringHelper* or char[] PROGMEM) 65 | * %c display as single character 66 | * %C display as single character or as hexadecimal value (prefixed by `0x`) if not a printable character 67 | * %d display as integer value 68 | * %l display as long value 69 | * %u display as unsigned long value 70 | * %x display as hexadecimal value 71 | * %X display as hexadecimal value prefixed by `0x` and leading zeros 72 | * %b display as binary number 73 | * %B display as binary number, prefixed by `0b` 74 | * %t display as boolean value "t" or "f" 75 | * %T display as boolean value "true" or "false" 76 | * %D,%F display as double value 77 | * %p display a printable object 78 | * 79 | * ---- Loglevels 80 | * 81 | * 0 - LOG_LEVEL_SILENT no output 82 | * 1 - LOG_LEVEL_FATAL fatal errors 83 | * 2 - LOG_LEVEL_ERROR all errors 84 | * 3 - LOG_LEVEL_WARNING errors and warnings 85 | * 4 - LOG_LEVEL_INFO errors, warnings and notices 86 | * 4 - LOG_LEVEL_NOTICE Same as INFO, kept for backward compatibility 87 | * 5 - LOG_LEVEL_TRACE errors, warnings, notices, traces 88 | * 6 - LOG_LEVEL_VERBOSE all 89 | */ 90 | 91 | class Logging 92 | { 93 | public: 94 | /** 95 | * default Constructor 96 | */ 97 | Logging() 98 | #ifndef DISABLE_LOGGING 99 | : _level(LOG_LEVEL_SILENT), 100 | _showLevel(true), 101 | _logOutput(NULL) 102 | #endif 103 | { 104 | 105 | } 106 | 107 | /** 108 | * Initializing, must be called as first. Note that if you use 109 | * this variant of Init, you need to initialize the baud rate 110 | * yourself, if printer happens to be a serial port. 111 | * 112 | * \param level - logging levels <= this will be logged. 113 | * \param printer - place that logging output will be sent to. 114 | * \return void 115 | * 116 | */ 117 | void begin(int level, Print *output, bool showLevel = true); 118 | 119 | /** 120 | * Set the log level. 121 | * 122 | * \param level - The new log level. 123 | * \return void 124 | */ 125 | void setLevel(int level); 126 | 127 | /** 128 | * Get the log level. 129 | * 130 | * \return The current log level. 131 | */ 132 | int getLevel() const; 133 | 134 | /** 135 | * Set whether to show the log level. 136 | * 137 | * \param showLevel - true if the log level should be shown for each log 138 | * false otherwise. 139 | * \return void 140 | */ 141 | void setShowLevel(bool showLevel); 142 | 143 | /** 144 | * Get whether the log level is shown during logging 145 | * 146 | * \return true if the log level is be shown for each log 147 | * false otherwise. 148 | */ 149 | bool getShowLevel() const; 150 | 151 | /** 152 | * Sets a function to be called before each log command. 153 | * 154 | * \param f - The function to be called 155 | * \return void 156 | */ 157 | void setPrefix(printfunction f); 158 | 159 | /** 160 | * clears prefix. 161 | * 162 | * \return void 163 | */ 164 | void clearPrefix(); 165 | 166 | /** 167 | * Sets a function to be called after each log command. 168 | * 169 | * \param f - The function to be called 170 | * \return void 171 | */ 172 | void setSuffix(printfunction f); 173 | 174 | /** 175 | * clears suffix. 176 | * 177 | * \return void 178 | */ 179 | void clearSuffix(); 180 | 181 | /** 182 | * Output a fatal error message. Output message contains 183 | * F: followed by original message 184 | * Fatal error messages are printed out at 185 | * loglevels >= LOG_LEVEL_FATAL 186 | * 187 | * \param msg format string to output 188 | * \param ... any number of variables 189 | * \return void 190 | */ 191 | template void fatal(T msg, Args... args){ 192 | #ifndef DISABLE_LOGGING 193 | printLevel(LOG_LEVEL_FATAL, false, msg, args...); 194 | #endif 195 | } 196 | 197 | template void fatalln(T msg, Args... args){ 198 | #ifndef DISABLE_LOGGING 199 | printLevel(LOG_LEVEL_FATAL, true, msg, args...); 200 | #endif 201 | } 202 | 203 | /** 204 | * Output an error message. Output message contains 205 | * E: followed by original message 206 | * Error messages are printed out at 207 | * loglevels >= LOG_LEVEL_ERROR 208 | * 209 | * \param msg format string to output 210 | * \param ... any number of variables 211 | * \return void 212 | */ 213 | template void error(T msg, Args... args){ 214 | #ifndef DISABLE_LOGGING 215 | printLevel(LOG_LEVEL_ERROR, false, msg, args...); 216 | #endif 217 | } 218 | 219 | template void errorln(T msg, Args... args){ 220 | #ifndef DISABLE_LOGGING 221 | printLevel(LOG_LEVEL_ERROR, true, msg, args...); 222 | #endif 223 | } 224 | /** 225 | * Output a warning message. Output message contains 226 | * W: followed by original message 227 | * Warning messages are printed out at 228 | * loglevels >= LOG_LEVEL_WARNING 229 | * 230 | * \param msg format string to output 231 | * \param ... any number of variables 232 | * \return void 233 | */ 234 | template void warning(T msg, Args...args){ 235 | #ifndef DISABLE_LOGGING 236 | printLevel(LOG_LEVEL_WARNING, false, msg, args...); 237 | #endif 238 | } 239 | 240 | template void warningln(T msg, Args...args){ 241 | #ifndef DISABLE_LOGGING 242 | printLevel(LOG_LEVEL_WARNING, true, msg, args...); 243 | #endif 244 | } 245 | 246 | /** 247 | * Output a notice message. Output message contains 248 | * N: followed by original message 249 | * Notice messages are printed out at 250 | * loglevels >= LOG_LEVEL_NOTICE 251 | * 252 | * \param msg format string to output 253 | * \param ... any number of variables 254 | * \return void 255 | */ 256 | template void notice(T msg, Args...args){ 257 | #ifndef DISABLE_LOGGING 258 | printLevel(LOG_LEVEL_NOTICE, false, msg, args...); 259 | #endif 260 | } 261 | 262 | template void noticeln(T msg, Args...args){ 263 | #ifndef DISABLE_LOGGING 264 | printLevel(LOG_LEVEL_NOTICE, true, msg, args...); 265 | #endif 266 | } 267 | 268 | template void info(T msg, Args...args) { 269 | #ifndef DISABLE_LOGGING 270 | printLevel(LOG_LEVEL_INFO, false, msg, args...); 271 | #endif 272 | } 273 | 274 | template void infoln(T msg, Args...args) { 275 | #ifndef DISABLE_LOGGING 276 | printLevel(LOG_LEVEL_INFO, true, msg, args...); 277 | #endif 278 | } 279 | 280 | /** 281 | * Output a trace message. Output message contains 282 | * N: followed by original message 283 | * Trace messages are printed out at 284 | * loglevels >= LOG_LEVEL_TRACE 285 | * 286 | * \param msg format string to output 287 | * \param ... any number of variables 288 | * \return void 289 | */ 290 | template void trace(T msg, Args... args){ 291 | #ifndef DISABLE_LOGGING 292 | printLevel(LOG_LEVEL_TRACE, false, msg, args...); 293 | #endif 294 | } 295 | 296 | template void traceln(T msg, Args... args){ 297 | #ifndef DISABLE_LOGGING 298 | printLevel(LOG_LEVEL_TRACE, true, msg, args...); 299 | #endif 300 | } 301 | 302 | /** 303 | * Output a verbose message. Output message contains 304 | * V: followed by original message 305 | * Debug messages are printed out at 306 | * loglevels >= LOG_LEVEL_VERBOSE 307 | * 308 | * \param msg format string to output 309 | * \param ... any number of variables 310 | * \return void 311 | */ 312 | template void verbose(T msg, Args... args){ 313 | #ifndef DISABLE_LOGGING 314 | printLevel(LOG_LEVEL_VERBOSE, false, msg, args...); 315 | #endif 316 | } 317 | 318 | template void verboseln(T msg, Args... args){ 319 | #ifndef DISABLE_LOGGING 320 | printLevel(LOG_LEVEL_VERBOSE, true, msg, args...); 321 | #endif 322 | } 323 | 324 | private: 325 | void print(const char *format, va_list args); 326 | 327 | void print(const __FlashStringHelper *format, va_list args); 328 | 329 | void print(const Printable& obj, va_list args) 330 | { 331 | #ifndef DISABLE_LOGGING 332 | _logOutput->print(obj); 333 | #endif 334 | } 335 | 336 | void printFormat(const char format, va_list *args); 337 | 338 | template void printLevel(int level, bool cr, T msg, ...) 339 | { 340 | #ifndef DISABLE_LOGGING 341 | if (level > _level) 342 | { 343 | return; 344 | } 345 | if (level < LOG_LEVEL_SILENT) 346 | { 347 | level = LOG_LEVEL_SILENT; 348 | } 349 | 350 | 351 | if (_prefix != NULL) 352 | { 353 | _prefix(_logOutput, level); 354 | } 355 | 356 | if (_showLevel) { 357 | static const char levels[] = "FEWITV"; 358 | _logOutput->print(levels[level - 1]); 359 | _logOutput->print(": "); 360 | } 361 | 362 | va_list args; 363 | va_start(args, msg); 364 | print(msg, args); 365 | 366 | if(_suffix != NULL) 367 | { 368 | _suffix(_logOutput, level); 369 | } 370 | if (cr) 371 | { 372 | _logOutput->print(CR); 373 | } 374 | #endif 375 | } 376 | 377 | #ifndef DISABLE_LOGGING 378 | int _level; 379 | bool _showLevel; 380 | Print* _logOutput; 381 | 382 | printfunction _prefix = NULL; 383 | printfunction _suffix = NULL; 384 | #endif 385 | }; 386 | 387 | extern Logging Log; 388 | -------------------------------------------------------------------------------- /Images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thijse/Arduino-Log/3f4fcf5a345c1d542e56b88c0ffcb2bd2a5b0bd0/Images/logo.png -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017,2018,2021 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, 4 | dhylands, Josha, blemasle, mfalkvidd 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![ArduinoLog logo](/Images/logo.png?raw=true ) 2 | ArduinoLog - C++ Log library for Arduino devices 3 | ==================== 4 | [![Build Status](https://travis-ci.org/thijse/Arduino-Log.svg?branch=master)](https://travis-ci.org/thijse/Arduino-Log) 5 | [![License](https://img.shields.io/badge/license-MIT%20License-blue.svg)](http://doge.mit-license.org) 6 | 7 | *An minimalistic Logging framework for Arduino-compatible embedded systems.* 8 | 9 | ArduinoLog is a minimalistic framework to help the programmer output log statements to an output of choice, fashioned after extensive logging libraries such as log4cpp ,log4j and log4net. In case of problems with an application, it is helpful to enable logging so that the problem can be located. ArduinoLog is designed so that log statements can remain in the code with minimal performance cost. In order to facilitate this the loglevel can be adjusted, and (if your code is completely tested) all logging code can be compiled out. 10 | 11 | ## Features 12 | 13 | * Different log levels (Error, Info, Warn, Debug, Verbose ) 14 | * Supports multiple variables 15 | * Supports formatted strings 16 | * Supports formatted strings from flash memory 17 | * Fixed memory allocation (zero malloc) 18 | * MIT License 19 | 20 | ## Tested for 21 | 22 | * All Arduino boards (Uno, Due, Mini, Micro, Yun...) 23 | * ESP8266 24 | * ESP32 25 | 26 | ## Downloading 27 | 28 | This package has been published to the Arduino & PlatformIO package managers, but you can also download it from GitHub. 29 | 30 | - By directly loading fetching the Archive from GitHub: 31 | 1. Go to [https://github.com/thijse/Arduino-Log](https://github.com/thijse/Arduino-Log) 32 | 2. Click the DOWNLOAD ZIP button in the panel on the 33 | 3. Rename the uncompressed folder **Arduino-Log-master** to **Arduino-Log**. 34 | 4. You may need to create the libraries subfolder if its your first library. 35 | 5. Place the **Arduino-Log** library folder in your **/libraries/** folder. 36 | 5. Restart the IDE. 37 | 6. For more information, [read this extended manual](http://thijs.elenbaas.net/2012/07/installing-an-arduino-library/) 38 | 39 | 40 | ## Quick start 41 | 42 | ```c++ 43 | Serial.begin(9600); 44 | 45 | // Initialize with log level and log output. 46 | Log.begin (LOG_LEVEL_VERBOSE, &Serial); 47 | 48 | // Start logging text and formatted values 49 | Log.errorln ( "Log as Error with binary values : %b, %B" , 23 , 345808); 50 | Log.warning (F("Log as Warning with integer values from Flash : %d, %d"CR) , 34 , 799870); 51 | ``` 52 | 53 | See [Log-basic.ino](examples/Log-basic/Log-basic.ino) example 54 | 55 | 56 | ## Usage 57 | 58 | ### Initialisation 59 | 60 | The log library needs to be initialized with the log level of messages to show and the log output. The latter will often be the Serial interface. 61 | Optionally, you can indicate whether to show the log type (error, debug, etc) for each line. 62 | 63 | ``` 64 | begin(int level, Print* logOutput, bool showLevel) 65 | begin(int level, Print* logOutput) 66 | ``` 67 | 68 | The loglevels available are 69 | 70 | ``` 71 | * 0 - LOG_LEVEL_SILENT no output 72 | * 1 - LOG_LEVEL_FATAL fatal errors 73 | * 2 - LOG_LEVEL_ERROR all errors 74 | * 3 - LOG_LEVEL_WARNING errors, and warnings 75 | * 4 - LOG_LEVEL_NOTICE errors, warnings and notices 76 | * 5 - LOG_LEVEL_TRACE errors, warnings, notices & traces 77 | * 6 - LOG_LEVEL_VERBOSE all 78 | ``` 79 | 80 | example 81 | 82 | ``` 83 | Log.begin(LOG_LEVEL_ERROR, &Serial, true); 84 | ``` 85 | 86 | if you want to fully remove all logging code, uncomment `#define DISABLE_LOGGING` in `ArduinoLog.h`, this may significantly reduce your sketch/library size. 87 | 88 | ### Log events 89 | 90 | The library allows you to log on different levels by the following functions 91 | 92 | ```c++ 93 | void fatal (const char *format, va_list logVariables); 94 | void error (const char *format, va_list logVariables); 95 | void warning (const char *format, va_list logVariables); 96 | void notice (const char *format, va_list logVariables); 97 | void trace (const char *format, va_list logVariables); 98 | void verbose (const char *format, va_list logVariables); 99 | ``` 100 | 101 | where the format string can be used to format the log variables 102 | 103 | ``` 104 | * %s display as string (char*) 105 | * %S display as string from flash memory (__FlashStringHelper* or char[] PROGMEM) 106 | * %c display as single character 107 | * %C display as single character or as hexadecimal value (prefixed by `0x`) if not a printable character 108 | * %d display as integer value 109 | * %l display as long value 110 | * %u display as unsigned long value 111 | * %x display as hexadecimal value 112 | * %X display as hexadecimal value prefixed by `0x` and leading zeros 113 | * %b display as binary number 114 | * %B display as binary number, prefixed by `0b` 115 | * %t display as boolean value "t" or "f" 116 | * %T display as boolean value "true" or "false" 117 | * %D,%F display as double value 118 | * %p display a printable object 119 | ``` 120 | 121 | Newlines can be added using the `CR` keyword or by using the `...ln` version of each of the log functions. The difference when using the `...ln` is that the newline is placed after suffix, and only a single newline can be added. Some terminals prefer `NL` (New line). 122 | 123 | ### Examples 124 | 125 | ```c++ 126 | Log.fatal (F("Log as Fatal with string value from Flash : %s"CR ) , "value" ); 127 | Log.errorln ( "Log as Error with binary values : %b, %B" , 23 , 345808); 128 | Log.warning (F("Log as Warning with integer values from Flash : %d, %d"CR) , 34 , 799870); 129 | Log.notice ( "Log as Notice with hexadecimal values : %x, %X"CR , 21 , 348972); 130 | Log.trace ( "Log as Trace with Flash string : %S"CR ) , F("value") ); 131 | Log.verboseln (F("Log as Verbose with bool value from Flash : %t, %T" ) , true, false ); 132 | ``` 133 | 134 | ### Disable library 135 | 136 | (if your code is completely tested) all logging code can be compiled out. Do this by uncommenting 137 | ```c++ 138 | #define DISABLE_LOGGING 139 | ``` 140 | in `Logging.h`. This may significantly reduce your project size. 141 | 142 | 143 | ## Advanced usage 144 | 145 | Advanced features are demonstrated in [Log-advanced](examples/Log-advanced/Log-advanced.ino) example. 146 | 147 | ### Displaying a printable object 148 | 149 | Some Arduino objects are printable. That is, they implement the `Printable` interface and are able for format their own representation 150 | As an example, the IPadress object is printable: 151 | 152 | ```c++ 153 | IPAddress ipAddress(192, 168, 0, 1); 154 | Log.verboseln ("ip address : %p", ipAddress); 155 | ``` 156 | 157 | [this example](https://forum.arduino.cc/t/printable-classes/438816) shows how to make your own classes printable 158 | 159 | ### Storing messages in Flash memory 160 | 161 | Flash strings log variables can be stored and reused at several places to reduce final hex size. 162 | 163 | ```c++ 164 | const __FlashStringHelper * logAs = F("Log as"); 165 | Log.fatal (F("%S Fatal with string value from Flash : %s"CR ) , logAs, "value" ); 166 | Log.error ( "%S Error with binary values : %b, %B"CR , logAs, 23 , 345808); 167 | ``` 168 | 169 | If you want to declare that string globally (outside of a function), you will need to use the PROGMEM macro instead. 170 | 171 | ```c++ 172 | const char LOG_AS[] PROGMEM = "Log as "; 173 | 174 | void logError() { 175 | Log.error ( "%S Error with binary values : %b, %B"CR , PSTRPTR(LOG_AS), 23 , 345808); 176 | } 177 | ``` 178 | 179 | ### Custom logging format 180 | 181 | You can modify your logging format by defining a custom prefix & suffix for each log line. For example: 182 | ```c++ 183 | void printPrefix(Print* _logOutput, int logLevel) { 184 | printTimestamp(_logOutput); 185 | printLogLevel (_logOutput, logLevel); 186 | } 187 | ``` 188 | will result in log timestamps very similar to e.g. NLOG: 189 | ``` 190 | 00:47:51.432 VERBOSE Message to be logged 191 | ``` 192 | 193 | ## Credit 194 | 195 | Based on library by 196 | * [Bernd Klein](https://github.com/mrRobot62) 197 | 198 | Bugfixes & features by 199 | * [rahuldeo2047](https://github.com/rahuldeo2047) 200 | * [NOX73](https://github.com/NOX73) 201 | * [Dave Hylands](https://github.com/dhylands) 202 | * [Jos Hanon](https://github.com/Josha) 203 | * [Bertrand Lemasle](https://github.com/blemasle) 204 | * [Mikael Falkvidd](https://github.com/mfalkvidd) 205 | * [Rowan Goemans](https://github.com/rowanG077) 206 | * [Nils Bokermann](https://github.com/sanddorn) 207 | * [Florian](https://github.com/1technophile) 208 | * [wrong-kendall](https://github.com/wrong-kendall) 209 | * [bitli](https://github.com/bitli) 210 | * [ChristianBauerAMDC](https://github.com/ChristianBauerAMDC) 211 | 212 | ## On using and modifying libraries 213 | 214 | - [http://www.arduino.cc/en/Main/Libraries](http://www.arduino.cc/en/Main/Libraries) 215 | - [http://www.arduino.cc/en/Reference/Libraries](http://www.arduino.cc/en/Reference/Libraries) 216 | 217 | ## Copyright 218 | 219 | ArduinoLog (Copyright © 2017,2018, 2019, 2021) is provided under MIT License. 220 | -------------------------------------------------------------------------------- /examples/Log-advanced/Log-advanced.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | /* 4 | _ ___ ___ _ _ ___ _ _ ___ _ ___ ___ 5 | /_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __| 6 | / _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ | 7 | /_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___| 8 | 9 | Log library example showing several advanced features 10 | Licensed under the MIT License . 11 | 12 | This example sketch shows most of the features of the ArduinoLog library 13 | 14 | */ 15 | 16 | const char * charArray = "this is a string"; 17 | const char flashCharArray1[] PROGMEM = "this is a string"; 18 | String stringValue1 = "this is a string"; 19 | IPAddress ipAdress(192, 168, 0, 1); 20 | 21 | void setup() { 22 | // Set up serial port and wait until connected 23 | Serial.begin(9600); 24 | while(!Serial && !Serial.available()){} 25 | 26 | 27 | Log.setPrefix(printPrefix); // set prefix similar to NLog 28 | Log.setSuffix(printSuffix); // set suffix 29 | Log.begin(LOG_LEVEL_VERBOSE, &Serial); 30 | Log.setShowLevel(false); // Do not show loglevel, we will do this in the prefix 31 | } 32 | 33 | void loop() { 34 | // set up some random variables 35 | 36 | //__FlashStringHelper cannot be declared outside a function 37 | const __FlashStringHelper * flashCharArray2 = F("this is a string"); 38 | 39 | Log.notice ( "Log global Flash string value : %S" CR, flashCharArray1 ); 40 | Log.traceln ( "Log local Flash string value : %S" CR, flashCharArray2 ); 41 | Log.notice ( "Log string value : %s" CR, stringValue1.c_str()); 42 | Log.verboseln (F("Log ip adress : %p") , ipAdress ); 43 | 44 | delay(5000); 45 | } 46 | 47 | void printPrefix(Print* _logOutput, int logLevel) { 48 | printTimestamp(_logOutput); 49 | printLogLevel (_logOutput, logLevel); 50 | } 51 | 52 | void printTimestamp(Print* _logOutput) { 53 | 54 | // Division constants 55 | const unsigned long MSECS_PER_SEC = 1000; 56 | const unsigned long SECS_PER_MIN = 60; 57 | const unsigned long SECS_PER_HOUR = 3600; 58 | const unsigned long SECS_PER_DAY = 86400; 59 | 60 | // Total time 61 | const unsigned long msecs = millis(); 62 | const unsigned long secs = msecs / MSECS_PER_SEC; 63 | 64 | // Time in components 65 | const unsigned long MilliSeconds = msecs % MSECS_PER_SEC; 66 | const unsigned long Seconds = secs % SECS_PER_MIN ; 67 | const unsigned long Minutes = (secs / SECS_PER_MIN) % SECS_PER_MIN; 68 | const unsigned long Hours = (secs % SECS_PER_DAY) / SECS_PER_HOUR; 69 | 70 | // Time as string 71 | char timestamp[20]; 72 | sprintf(timestamp, "%02d:%02d:%02d.%03d ", Hours, Minutes, Seconds, MilliSeconds); 73 | _logOutput->print(timestamp); 74 | } 75 | 76 | 77 | void printLogLevel(Print* _logOutput, int logLevel) { 78 | /// Show log description based on log level 79 | switch (logLevel) 80 | { 81 | default: 82 | case 0:_logOutput->print("SILENT " ); break; 83 | case 1:_logOutput->print("FATAL " ); break; 84 | case 2:_logOutput->print("ERROR " ); break; 85 | case 3:_logOutput->print("WARNING "); break; 86 | case 4:_logOutput->print("INFO " ); break; 87 | case 5:_logOutput->print("TRACE " ); break; 88 | case 6:_logOutput->print("VERBOSE "); break; 89 | } 90 | } 91 | 92 | void printSuffix(Print* _logOutput, int logLevel) { 93 | _logOutput->print(""); 94 | } 95 | -------------------------------------------------------------------------------- /examples/Log-basic/Log-basic.ino: -------------------------------------------------------------------------------- 1 | #include 2 | /* 3 | _ ___ ___ _ _ ___ _ _ ___ _ ___ ___ 4 | /_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __| 5 | / _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ | 6 | /_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___| 7 | 8 | Log library basic example 9 | Licensed under the MIT License . 10 | 11 | This example sketch shows most of the most used features of the ArduinoLog library 12 | 13 | */ 14 | 15 | int intValue1 , intValue2; 16 | long longValue1, longValue2; 17 | bool boolValue1, boolValue2; 18 | const char charNotPrintable = 0x8B; 19 | const char * charArray = "this is a string"; 20 | const char flashCharArray1[] PROGMEM = "this is a string"; 21 | String stringValue1 = "this is a string"; 22 | float floatValue; 23 | double doubleValue; 24 | 25 | void setup() { 26 | // Set up serial port and wait until connected 27 | Serial.begin(9600); 28 | while(!Serial && !Serial.available()){} 29 | randomSeed(analogRead(0)); 30 | // Pass log level, whether to show log level, and print interface. 31 | // Available levels are: 32 | // LOG_LEVEL_SILENT, LOG_LEVEL_FATAL, LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, LOG_LEVEL_INFO, LOG_LEVEL_TRACE, LOG_LEVEL_VERBOSE 33 | // Note: if you want to fully remove all logging code, uncomment #define DISABLE_LOGGING in Logging.h 34 | // this will significantly reduce your project size 35 | 36 | Log.begin(LOG_LEVEL_VERBOSE, &Serial); 37 | 38 | 39 | //Start logging 40 | 41 | Log.notice(F(CR "******************************************" CR)); // Info string with Newline 42 | Log.notice( "*** Logging example " CR); // Info string in flash memory 43 | Log.notice(F("******************* ")); Log.notice("*********************** " CR); // two info strings without newline will end up on same line 44 | } 45 | 46 | void loop() { 47 | // set up some random variables 48 | intValue1 = random(100); 49 | intValue2 = random(10000); 50 | longValue1 = random(1000000); 51 | longValue2 = random(100000000); 52 | boolValue1 = random(2)==0; 53 | boolValue2 = random(2)==1; 54 | floatValue = 12.34; 55 | doubleValue= 1234.56789; 56 | 57 | 58 | Log.notice ( "Log as Info with integer values : %d, %d" CR , intValue1, intValue2); 59 | Log.notice (F("Log as Info with hex values : %x, %X" CR ), intValue1, intValue1); 60 | Log.notice ( "Log as Info with hex values : %x, %X" CR , intValue2, intValue2); 61 | Log.notice (F("Log as Info with binary values : %b, %B" CR ), intValue1, intValue1); 62 | Log.notice ( "Log as Info with binary values : %b, %B" CR , intValue2, intValue2); 63 | Log.notice (F("Log as Info with long values : %l, %l" CR ), longValue1, longValue2); 64 | Log.notice ( "Log as Info with bool values : %t, %T" CR , boolValue1, boolValue2); 65 | Log.notice (F("Log as Info with char value : %c" CR ), charArray[0]); 66 | Log.notice ( "Log as Info with char value : %C" CR , charNotPrintable); 67 | Log.notice (F("Log as Info with string value : %s" CR ), charArray); 68 | Log.notice ( "Log as Info with Flash string value : %S" CR , flashCharArray1); 69 | Log.notice ( "Log as Info with string value : %s" CR , stringValue1.c_str()); 70 | Log.notice (F("Log as Info with float value : %F" CR ), floatValue); 71 | Log.notice ( "Log as Info with float value : %F" CR , floatValue); 72 | Log.notice (F("Log as Info with double value : %D" CR ), doubleValue); 73 | Log.notice ( "Log as Info with double value : %D" CR , doubleValue); 74 | Log.notice (F("Log as Debug with mixed values : %d, %d, %l, %l, %t, %T" CR ), intValue1 , intValue2 , 75 | longValue1, longValue2, 76 | boolValue1, boolValue2); 77 | Log.trace ( "Log as Trace with bool value : %T" CR , boolValue1); 78 | Log.traceln ( "Log as Trace with bool value : %T" , boolValue1); 79 | Log.warning ( "Log as Warning with bool value : %T" CR , boolValue1); 80 | Log.warningln( "Log as Warning with bool value : %T" , boolValue1); 81 | Log.error ( "Log as Error with bool value : %T" CR , boolValue1); 82 | Log.errorln ( "Log as Error with bool value : %T" , boolValue1); 83 | Log.fatal ( "Log as Fatal with bool value : %T" CR , boolValue1); 84 | Log.fatalln ( "Log as Fatal with bool value : %T" , boolValue1); 85 | Log.verboseln(F("Log as Verbose with bool value : %T" ), boolValue2); 86 | Log.verbose (F("Log as Verbose with bool value : %T" CR ), boolValue2); 87 | 88 | 89 | delay(5000); 90 | } -------------------------------------------------------------------------------- /examples/platformio-basic/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = adafruit_feather_m4 13 | 14 | [env:adafruit_feather_m4] 15 | platform = atmelsam 16 | board = adafruit_feather_m4 17 | framework = arduino 18 | lib_deps = 19 | ; TODO(kendall): Remove if/when Arduino-Log is available through 20 | ; PlatformIO's Library Manager 21 | https://github.com/thijse/Arduino-Log.git 22 | test_ignore = test_native 23 | 24 | 25 | [env:native] 26 | platform = native 27 | build_flags = 28 | ; TODO(kendall): Remove if/when 29 | ; https://github.com/thijse/Arduino-Log/pull/13 is merged 30 | -DARDUINO=101 31 | lib_compat_mode = off 32 | lib_deps = 33 | https://github.com/FabioBatSilva/ArduinoFake.git 34 | ; TODO(kendall): Remove if/when Arduino-Log is available through 35 | ; PlatformIO's Library Manager 36 | https://github.com/thijse/Arduino-Log.git 37 | 38 | -------------------------------------------------------------------------------- /examples/platformio-basic/src/main.cpp: -------------------------------------------------------------------------------- 1 | #ifndef UNIT_TEST 2 | #include 3 | #include 4 | /* 5 | _ ___ ___ _ _ ___ _ _ ___ _ ___ ___ 6 | /_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __| 7 | / _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ | 8 | /_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___| 9 | 10 | Log library example 11 | Licensed under the MIT License . 12 | 13 | This example sketch shows most of the features of the ArduinoLog library 14 | 15 | */ 16 | 17 | int intValue1, intValue2; 18 | long longValue1, longValue2; 19 | bool boolValue1, boolValue2; 20 | const char *charArray = "this is a string"; 21 | const char flashCharArray1[] PROGMEM = "this is a string"; 22 | String stringValue1 = "this is a string"; 23 | float floatValue; 24 | double doubleValue; 25 | 26 | void printTimestamp(Print *_logOutput) { 27 | char c[12]; 28 | int m = sprintf(c, "%10lu ", millis()); 29 | _logOutput->print(c); 30 | } 31 | 32 | void printCarret(Print *_logOutput) { _logOutput->print('>'); } 33 | 34 | void setup() { 35 | // Set up serial port and wait until connected 36 | Serial.begin(9600); 37 | while (!Serial && !Serial.available()) { 38 | } 39 | randomSeed(analogRead(0)); 40 | // Pass log level, whether to show log level, and print interface. 41 | // Available levels are: 42 | // LOG_LEVEL_SILENT, LOG_LEVEL_FATAL, LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, 43 | // LOG_LEVEL_NOTICE, LOG_LEVEL_TRACE, LOG_LEVEL_VERBOSE Note: if you want to 44 | // fully remove all logging code, uncomment #define DISABLE_LOGGING in 45 | // Logging.h 46 | // this will significantly reduce your project size 47 | 48 | Log.begin(LOG_LEVEL_VERBOSE, &Serial); 49 | 50 | // Start logging 51 | 52 | Log.notice( 53 | F(CR "******************************************" CR)); // Info string 54 | // with Newline 55 | Log.notice( 56 | "*** Logging example " CR); // Info string in 57 | // flash memory 58 | Log.notice(F("******************* ")); 59 | Log.notice("*********************** " CR); // two info strings without newline 60 | } 61 | 62 | void loop() { 63 | // set up some random variables 64 | intValue1 = random(100); 65 | intValue2 = random(10000); 66 | longValue1 = random(1000000); 67 | longValue2 = random(100000000); 68 | boolValue1 = random(2) == 0; 69 | boolValue2 = random(2) == 1; 70 | floatValue = 12.34; 71 | doubleValue = 1234.56789; 72 | 73 | //__FlashStringHelper cannot be declared outside a function 74 | const __FlashStringHelper *flashCharArray2 = F("this is a string"); 75 | 76 | Log.notice("Log as Info with integer values : %d, %d" CR, intValue1, 77 | intValue2); 78 | Log.notice(F("Log as Info with hex values : %x, %X" CR), intValue1, 79 | intValue1); 80 | Log.notice("Log as Info with hex values : %x, %X" CR, intValue2, 81 | intValue2); 82 | Log.notice(F("Log as Info with binary values : %b, %B" CR), intValue1, 83 | intValue1); 84 | Log.notice("Log as Info with binary values : %b, %B" CR, intValue2, 85 | intValue2); 86 | Log.notice(F("Log as Info with long values : %l, %l" CR), longValue1, 87 | longValue2); 88 | Log.notice("Log as Info with bool values : %t, %T" CR, boolValue1, 89 | boolValue2); 90 | Log.notice(F("Log as Info with string value : %s" CR), charArray); 91 | Log.notice("Log as Info with Flash string value : %S" CR, flashCharArray1); 92 | Log.notice("Log as Info with Flash string value : %S" CR, flashCharArray2); 93 | Log.notice("Log as Info with string value : %s" CR, stringValue1.c_str()); 94 | Log.notice(F("Log as Info with float value : %F" CR), floatValue); 95 | Log.notice("Log as Info with float value : %F" CR, floatValue); 96 | Log.notice(F("Log as Info with double value : %D" CR), doubleValue); 97 | Log.notice("Log as Info with double value : %D" CR, doubleValue); 98 | Log.notice(F("Log as Debug with mixed values : %d, %d, %l, %l, %t, %T" CR), 99 | intValue1, intValue2, longValue1, longValue2, boolValue1, 100 | boolValue2); 101 | 102 | Log.trace("Log as Trace with bool value : %T" CR, boolValue1); 103 | Log.traceln("Log as Trace with bool value : %T", boolValue1); 104 | Log.warning("Log as Warning with bool value : %T" CR, boolValue1); 105 | Log.warningln("Log as Warning with bool value : %T", boolValue1); 106 | Log.error("Log as Error with bool value : %T" CR, boolValue1); 107 | Log.errorln("Log as Error with bool value : %T", boolValue1); 108 | Log.fatal("Log as Fatal with bool value : %T" CR, boolValue1); 109 | Log.fatalln("Log as Fatal with bool value : %T", boolValue1); 110 | Log.verboseln(F("Log as Verbose with bool value : %T"), boolValue2); 111 | Log.verbose(F("Log as Verbose with bool value : %T" CR), boolValue2); 112 | 113 | Log.setPrefix(printTimestamp); // set timestamp as prefix 114 | Log.setSuffix(printCarret); // set carret as suffix 115 | Log.verboseln(F("Log with suffix & prefix")); 116 | Log.setPrefix(NULL); // set timestamp as prefix 117 | Log.setSuffix(NULL); // set carret as suffix 118 | 119 | delay(5000); 120 | } 121 | #endif -------------------------------------------------------------------------------- /examples/platformio-basic/test/test_native.cpp: -------------------------------------------------------------------------------- 1 | #include "ArduinoLog.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace fakeit; 11 | std::stringstream output_; 12 | 13 | void reset_output() { 14 | output_.str(std::string()); 15 | output_.clear(); 16 | } 17 | 18 | std::string decimal_to_binary(int n) { 19 | 20 | std::string binary; 21 | while (n != 0) { 22 | binary = (n % 2 == 0 ? "0" : "1") + binary; 23 | n /= 2; 24 | } 25 | return binary; 26 | } 27 | 28 | void TEST_ASSERT_EQUAL_STRING_STREAM(std::stringstream const &expected_output, 29 | std::stringstream const &actual_output) { 30 | 31 | TEST_ASSERT_EQUAL_STRING(expected_output.str().c_str(), 32 | actual_output.str().c_str()); 33 | } 34 | 35 | void set_up_logging_captures() { 36 | When(OverloadedMethod(ArduinoFake(Serial), println, size_t(void))) 37 | .AlwaysDo([&]() -> int { 38 | output_ << "\n"; 39 | return 1; 40 | }); 41 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(char))) 42 | .AlwaysDo([&](const char x) -> int { 43 | output_ << x; 44 | return 1; 45 | }); 46 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(const char[]))) 47 | .AlwaysDo([&](const char x[]) -> int { 48 | output_ << x; 49 | return 1; 50 | }); 51 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(const String &))) 52 | .AlwaysDo([&](const String &x) -> int { 53 | output_ << x.c_str(); 54 | return 1; 55 | }); 56 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(unsigned char, int))) 57 | .AlwaysDo([&](unsigned char x, int y) -> int { 58 | if (y == 2) { 59 | output_ << decimal_to_binary(x); 60 | } else { 61 | output_ << std::setbase(y) << (unsigned long)x; 62 | } 63 | return 1; 64 | }); 65 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(unsigned long, int))) 66 | .AlwaysDo([&](unsigned long x, int y) -> int { 67 | output_ << std::fixed << std::setprecision(y) << x; 68 | return 1; 69 | }); 70 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(int, int))) 71 | .AlwaysDo([&](int x, int y) -> int { 72 | if (y == 2) { 73 | output_ << decimal_to_binary(x); 74 | } else { 75 | output_ << std::setbase(y) << x; 76 | } 77 | return 1; 78 | }); 79 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(unsigned int, int))) 80 | .AlwaysDo([&](unsigned int x, int y) -> int { 81 | if (y == 2) { 82 | output_ << decimal_to_binary(x); 83 | } else { 84 | output_ << std::setbase(y) << x; 85 | } 86 | return 1; 87 | }); 88 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(double, int))) 89 | .AlwaysDo([&](double x, int y) -> int { 90 | output_ << std::fixed << std::setprecision(y) << x; 91 | return 1; 92 | }); 93 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(long, int))) 94 | .AlwaysDo([&](long x, int y) -> int { 95 | if (y == 2) { 96 | output_ << std::bitset(x).to_string(); 97 | } else { 98 | output_ << std::setbase(y) << x; 99 | } 100 | return 1; 101 | }); 102 | When(OverloadedMethod(ArduinoFake(Serial), print, size_t(unsigned long, int))) 103 | .AlwaysDo([&](unsigned long x, int y) -> int { 104 | if (y == 2) { 105 | output_ << std::bitset(x).to_string(); 106 | } else { 107 | output_ << std::setbase(y) << x; 108 | } 109 | return 1; 110 | }); 111 | When(OverloadedMethod(ArduinoFake(Serial), print, 112 | size_t(const __FlashStringHelper *ifsh))) 113 | .AlwaysDo([&](const __FlashStringHelper *x) -> int { 114 | auto message = reinterpret_cast(x); 115 | output_ << message; 116 | return 1; 117 | }); 118 | 119 | When(Method(ArduinoFake(Serial), flush)).AlwaysReturn(); 120 | } 121 | 122 | void setUp(void) { 123 | ArduinoFakeReset(); 124 | Log.begin(LOG_LEVEL_VERBOSE, &Serial); 125 | set_up_logging_captures(); 126 | } 127 | void test_int_values() { 128 | reset_output(); 129 | int int_value1 = 173; 130 | int int_value2 = 65536; 131 | Log.notice("Log as Info with integer values : %d, %d" CR, int_value1, 132 | int_value2); 133 | std::stringstream expected_output; 134 | expected_output << "N: Log as Info with integer values : 173, 65536\n"; 135 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 136 | } 137 | 138 | void test_int_hex_values() { 139 | reset_output(); 140 | int int_value1 = 152; 141 | int int_value2 = 65010; 142 | Log.notice(F("Log as Info with hex values : %x, %X" CR), int_value1, 143 | int_value1); 144 | Log.notice("Log as Info with hex values : %x, %X" CR, int_value2, 145 | int_value2); 146 | std::stringstream expected_output; 147 | expected_output << "N: Log as Info with hex values : 98, 0x0098\n" 148 | << "N: Log as Info with hex values : fdf2, 0xfdf2\n"; 149 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 150 | } 151 | 152 | void test_int_binary_values() { 153 | reset_output(); 154 | int int_value1 = 2218; 155 | int int_value2 = 17814; 156 | Log.notice(F("Log as Info with binary values : %b, %B" CR), int_value1, 157 | int_value2); 158 | std::stringstream expected_output; 159 | expected_output << "N: Log as Info with binary values : 100010101010, " 160 | "0b100010110010110\n"; 161 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 162 | } 163 | void test_long_values() { 164 | reset_output(); 165 | long long_value1 = 34359738368; 166 | long long_value2 = 274877906944; 167 | Log.notice(F("Log as Info with long values : %l, %l" CR), long_value1, 168 | long_value2); 169 | std::stringstream expected_output; 170 | expected_output << "N: Log as Info with long values : " 171 | "34359738368, 274877906944\n"; 172 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 173 | } 174 | 175 | void test_bool_values() { 176 | reset_output(); 177 | bool true_value = true; 178 | bool false_value = false; 179 | Log.notice("Log as Info with bool values : %t, %T" CR, true_value, 180 | true_value); 181 | Log.notice("Log as Info with bool values : %t, %T" CR, false_value, 182 | false_value); 183 | std::stringstream expected_output; 184 | expected_output << "N: Log as Info with bool values : T, true\n"; 185 | expected_output << "N: Log as Info with bool values : F, false\n"; 186 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 187 | } 188 | 189 | void test_char_string_values() { 190 | reset_output(); 191 | const char *charArray = "this is a string"; 192 | Log.notice(F("Log as Info with string value : %s" CR), charArray); 193 | std::stringstream expected_output; 194 | expected_output << "N: Log as Info with string value : this is a string\n"; 195 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 196 | } 197 | 198 | void test_flash_string_values() { 199 | reset_output(); 200 | //__FlashStringHelper cannot be declared outside a function 201 | const __FlashStringHelper *flashCharArray2 = F("this is a string"); 202 | 203 | const char flashCharArray1[] PROGMEM = "this is a string"; 204 | Log.notice("Log as Info with Flash string value : %S" CR, flashCharArray1); 205 | std::stringstream expected_output; 206 | expected_output 207 | << "N: Log as Info with Flash string value : this is a string\n"; 208 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 209 | } 210 | 211 | void test_string_values() { 212 | reset_output(); 213 | String stringValue1 = "this is a string"; 214 | Log.notice("Log as Info with string value : %s" CR, stringValue1.c_str()); 215 | std::stringstream expected_output; 216 | expected_output << "N: Log as Info with string value : this is a string\n"; 217 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 218 | } 219 | 220 | void test_float_values() { 221 | reset_output(); 222 | float float_value = 12.34; 223 | Log.notice(F("Log as Info with float value : %F" CR), float_value); 224 | Log.notice("Log as Info with float value : %F" CR, float_value); 225 | std::stringstream expected_output; 226 | expected_output << "N: Log as Info with float value : 12.34\n" 227 | << "N: Log as Info with float value : 12.34\n"; 228 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 229 | } 230 | 231 | void test_double_values() { 232 | reset_output(); 233 | double double_value = 1234.56789; 234 | // Log.notice(F("%D" CR), double_value); 235 | Log.notice(F("Log as Info with double value : %D" CR), double_value); 236 | Log.notice("Log as Info with double value : %D" CR, double_value); 237 | std::stringstream expected_output; 238 | expected_output << "N: Log as Info with double value : 1234.57\n" 239 | << "N: Log as Info with double value : 1234.57\n"; 240 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 241 | } 242 | 243 | void test_mixed_values() { 244 | reset_output(); 245 | int int_value1 = 15826; 246 | int int_value2 = 31477; 247 | long long_value1 = 274877906944; 248 | long long_value2 = 68719476743; 249 | bool true_value = true; 250 | bool false_value = false; 251 | Log.notice(F("Log as Debug with mixed values : %d, %d, %l, %l, %t, %T" CR), 252 | int_value1, int_value2, long_value1, long_value2, true_value, 253 | false_value); 254 | std::stringstream expected_output; 255 | expected_output 256 | << "N: Log as Debug with mixed values : 15826, 31477, 274877906944, " 257 | "68719476743, T, false\n"; 258 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 259 | } 260 | 261 | void test_log_levels() { 262 | reset_output(); 263 | bool true_value = true; 264 | bool false_value = false; 265 | Log.trace("Log as Trace with bool value : %T" CR, true_value); 266 | Log.traceln("Log as Trace with bool value : %T", false_value); 267 | Log.warning("Log as Warning with bool value : %T" CR, true_value); 268 | Log.warningln("Log as Warning with bool value : %T", false_value); 269 | Log.error("Log as Error with bool value : %T" CR, true_value); 270 | Log.errorln("Log as Error with bool value : %T", false_value); 271 | Log.fatal("Log as Fatal with bool value : %T" CR, true_value); 272 | Log.fatalln("Log as Fatal with bool value : %T", false_value); 273 | Log.verboseln(F("Log as Verbose with bool value : %T"), true_value); 274 | Log.verbose(F("Log as Verbose with bool value : %T" CR), false_value); 275 | std::stringstream expected_output; 276 | expected_output << "T: Log as Trace with bool value : true\n" 277 | "T: Log as Trace with bool value : false\n" 278 | "W: Log as Warning with bool value : true\n" 279 | "W: Log as Warning with bool value : false\n" 280 | "E: Log as Error with bool value : true\n" 281 | "E: Log as Error with bool value : false\n" 282 | "F: Log as Fatal with bool value : true\n" 283 | "F: Log as Fatal with bool value : false\n" 284 | "V: Log as Verbose with bool value : true\n" 285 | "V: Log as Verbose with bool value : false\n"; 286 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 287 | } 288 | 289 | void printTimestamp(Print *_logOutput) { 290 | char c[12]; 291 | int m = sprintf(c, "%10lu ", millis()); 292 | _logOutput->print(c); 293 | } 294 | void printCarret(Print *_logOutput) { _logOutput->print('>'); } 295 | 296 | void test_prefix_and_suffix() { 297 | reset_output(); 298 | When(Method(ArduinoFake(), millis)).Return(1026); 299 | Log.setPrefix(printTimestamp); // set timestamp as prefix 300 | Log.setSuffix(printCarret); // set carret as suffix 301 | Log.verboseln(F("Log with suffix & prefix")); 302 | Log.setPrefix(NULL); // clear prefix 303 | Log.setSuffix(NULL); // clear suffix 304 | std::stringstream expected_output; 305 | expected_output << " 1026 V: Log with suffix & prefix>\n"; 306 | TEST_ASSERT_EQUAL_STRING_STREAM(expected_output, output_); 307 | } 308 | 309 | int main(int argc, char **argv) { 310 | UNITY_BEGIN(); 311 | RUN_TEST(test_int_values); 312 | RUN_TEST(test_int_hex_values); 313 | RUN_TEST(test_int_binary_values); 314 | RUN_TEST(test_long_values); 315 | RUN_TEST(test_bool_values); 316 | RUN_TEST(test_char_string_values); 317 | RUN_TEST(test_flash_string_values); 318 | RUN_TEST(test_string_values); 319 | RUN_TEST(test_float_values); 320 | RUN_TEST(test_double_values); 321 | RUN_TEST(test_mixed_values); 322 | RUN_TEST(test_log_levels); 323 | RUN_TEST(test_prefix_and_suffix); 324 | UNITY_END(); 325 | } -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map ArduinoLog library 3 | ####################################### 4 | 5 | ####################################### 6 | # Instances (KEYWORD1) 7 | ####################################### 8 | Logging KEYWORD1 9 | Log KEYWORD1 10 | ####################################### 11 | # Datatypes (KEYWORD1) 12 | ####################################### 13 | 14 | ####################################### 15 | # Methods and Functions (KEYWORD2) 16 | ####################################### 17 | fatal KEYWORD2 18 | fatalln KEYWORD2 19 | error KEYWORD2 20 | errorln KEYWORD2 21 | warning KEYWORD2 22 | warningln KEYWORD2 23 | info KEYWORD2 24 | infoln KEYWORD2 25 | notice KEYWORD2 26 | noticeln KEYWORD2 27 | trace KEYWORD2 28 | traceln KEYWORD2 29 | verbose KEYWORD2 30 | verboseln KEYWORD2 31 | begin KEYWORD2 32 | setLevel KEYWORD2 33 | getLevel KEYWORD2 34 | setShowLevel KEYWORD2 35 | getShowLevel KEYWORD2 36 | setPrefix KEYWORD2 37 | setSuffix KEYWORD2 38 | clearPrefix KEYWORD2 39 | clearSuffix KEYWORD2 40 | 41 | ####################################### 42 | # Instances (KEYWORD2) 43 | ####################################### 44 | Logging KEYWORD2 45 | Log KEYWORD2 46 | 47 | ####################################### 48 | # Constants (LITERAL1) 49 | ####################################### 50 | LOG_LEVEL_SILENT LITERAL1 Constants 51 | LOG_LEVEL_FATAL LITERAL1 Constants 52 | LOG_LEVEL_ERROR LITERAL1 Constants 53 | LOG_LEVEL_WARNING LITERAL1 Constants 54 | LOG_LEVEL_NOTICE LITERAL1 Constants 55 | LOG_LEVEL_INFO LITERAL1 Constants 56 | LOG_LEVEL_TRACE LITERAL1 Constants 57 | LOG_LEVEL_VERBOSE LITERAL1 Constants 58 | 59 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ArduinoLog", 3 | "keywords": "logging, debug, log, log levels, AVR, ESP8266", 4 | "description": "ArduinoLog is a minimalistic logging framework to help the programmer output log statements to a variety of output targets. ArduinoLog is designed so that log statements can remain in the code with minimal performance cost. In order to facilitate this the loglevel can be adjusted, and if the code is completely tested all logging code can be compiled out. Tested for AVR, ESP8266 & ESP32 boards. Detailed instructions for use on Github page.", 5 | "version": "1.1.1", 6 | "authors": { 7 | "name": "Thijs Elenbaas", 8 | "url": "https://github.com/thijse", 9 | "maintainer": true 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/thijse/Arduino-Log" 14 | }, 15 | "homepage": "https://github.com/thijse/Arduino-Log/", 16 | "frameworks": ["arduino"], 17 | "platforms": "*", 18 | "examples": "examples/*/*.ino" 19 | } 20 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ArduinoLog 2 | version=1.1.1 3 | author=Thijs Elenbaas 4 | maintainer=Thijs Elenbaas 5 | sentence=Small logging framework 6 | paragraph=ArduinoLog is a minimalistic logging framework to help the programmer output log statements to a variety of output targets. ArduinoLog is designed so that log statements can remain in the code with minimal performance cost. In order to facilitate this the loglevel can be adjusted, and if the code is completely tested all logging code can be compiled out. Tested for AVR, ESP8266 & ESP32 boards. Detailed instructions for use on Github page. 7 | category=Communication 8 | url=https://github.com/thijse/Arduino-Log/ 9 | architectures=* 10 | includes=ArduinoLog.h 11 | --------------------------------------------------------------------------------