1 module mysql.logger; 2 3 /* 4 The aliased log functions in this module map to equivelant functions in either vibe.core.log or std.experimental.logger. 5 For this reason, only log levels common to both are used. The exception to this is logDebug which is uses trace when 6 using std.experimental.logger, only because it's commonly used and trace/debug/verbose are all similar in use. 7 Also, I've chosen not to support fatal errors as std.experimental.logger will create an exception if you choose to 8 log at this level, which is an unhelpful side effect. 9 10 See the following table for how they are mapped: 11 12 | Our logger | vibe.core.log | LogLevel (std.experimental.logger) | 13 | --------------- | ------------- | ---------------------------------- | 14 | logTrace | logTrace | LogLevel.trace | 15 | N/A | logDebugV | N/A | 16 | logDebug | logDebug | LogLevel.trace | 17 | N/A | logDiagnostic | N/A | 18 | logInfo | logInfo | LogLevel.info | 19 | logWarn | logWarn | LogLevel.warning | 20 | logError | logError | LogLevel.error | 21 | logCritical | logCritical | LogLevel.critical | 22 | N/A | logFatal | LogLevel.fatal | 23 24 */ 25 version(Have_vibe_core) { 26 import vibe.core.log; 27 28 alias logTrace = vibe.core.log.logTrace; 29 alias logDebug = vibe.core.log.logDebug; 30 alias logInfo = vibe.core.log.logInfo; 31 alias logWarn = vibe.core.log.logWarn; 32 alias logError = vibe.core.log.logError; 33 alias logCritical = vibe.core.log.logCritical; 34 //alias logFatal = vibe.core.log.logFatal; 35 } else static if(__traits(compiles, (){ import std.experimental.logger; } )) { 36 import std.experimental.logger; 37 38 alias logTrace = std.experimental.logger.tracef; 39 alias logDebug = std.experimental.logger.tracef; // no debug level in std.experimental.logger but arguably trace/debug/verbose all mean the same 40 alias logInfo = std.experimental.logger.infof; 41 alias logWarn = std.experimental.logger.warningf; 42 alias logError = std.experimental.logger.errorf; 43 alias logCritical = std.experimental.logger.criticalf; 44 //alias logFatal = std.experimental.logger.fatalf; 45 } else static assert(false); 46 47 unittest { 48 version(Have_vibe_core) { 49 import std.stdio : writeln; 50 writeln("Running the logger tests using (vibe.core.log)"); 51 // Althouth there are no asserts here, this confirms that the alias compiles ok also the output 52 // is shown in the terminal when running 'dub test' and the levels logged using different colours. 53 logTrace("Test that a call to mysql.logger.logTrace maps to vibe.core.log.logTrace"); 54 logDebug("Test that a call to mysql.logger.logDebug maps to vibe.core.log.logDebug"); 55 logInfo("Test that a call to mysql.logger.logInfo maps to vibe.core.log.logInfo"); 56 logWarn("Test that a call to mysql.logger.logWarn maps to vibe.core.log.logWarn"); 57 logError("Test that a call to mysql.logger.logError maps to vibe.core.log.logError"); 58 logCritical("Test that a call to mysql.logger.logCritical maps to vibe.core.log.logCritical"); 59 //logFatal("Test that a call to mysql.logger.logFatal maps to vibe.core.log.logFatal"); 60 } else static if(__traits(compiles, (){ import std.experimental.logger; } )) { 61 // Checks that when using std.experimental.logger the log entry is correct. 62 // This test kicks in when commenting out the 'vibe-core' dependency and running 'dub test', although 63 // not ideal if vibe-core is availble the logging goes through vibe anyway. 64 // Output can be seen in terminal when running 'dub test'. 65 import std.experimental.logger : Logger, LogLevel, sharedLog; 66 import std.stdio : writeln, writefln; 67 import std.conv : to; 68 69 writeln("Running the logger tests using (std.experimental.logger)"); 70 71 class TestLogger : Logger { 72 LogLevel logLevel; 73 string file; 74 string moduleName; 75 string msg; 76 77 this(LogLevel lv) @safe { 78 super(lv); 79 } 80 81 override void writeLogMsg(ref LogEntry payload) @trusted { 82 this.logLevel = payload.logLevel; 83 this.file = payload.file; 84 this.moduleName = payload.moduleName; 85 this.msg = payload.msg; 86 // now output it to stdio so it can be seen in terminal when testing 87 writefln(" - testing [%s] %s(%s) : %s", payload.logLevel, payload.file, to!string(payload.line), payload.msg); 88 } 89 } 90 91 auto logger = new TestLogger(LogLevel.all); 92 sharedLog = logger; 93 94 // check that the various log alias functions get the expected results 95 logDebug("This is a TRACE message"); 96 assert(logger.logLevel == LogLevel.trace, "expected 'LogLevel.trace' got: " ~ logger.logLevel); 97 assert(logger.msg == "This is a TRACE message", "The logger should have logged 'This is a TRACE message' but instead was: " ~ logger.msg); 98 assert(logger.file == "source/mysql/logger.d", "expected 'source/mysql/logger.d' got: " ~ logger.file); 99 assert(logger.moduleName == "mysql.logger", "expected 'mysql.logger' got: " ~ logger.moduleName); 100 101 logDebug("This is a DEBUG message (maps to trace)"); 102 assert(logger.logLevel == LogLevel.trace, "expected 'LogLevel.trace' got: " ~ logger.logLevel); 103 assert(logger.msg == "This is a DEBUG message (maps to trace)", "The logger should have logged 'This is a DEBUG message (maps to trace)' but instead was: " ~ logger.msg); 104 assert(logger.file == "source/mysql/logger.d", "expected 'source/mysql/logger.d' got: " ~ logger.file); 105 assert(logger.moduleName == "mysql.logger", "expected 'mysql.logger' got: " ~ logger.moduleName); 106 107 logInfo("This is an INFO message"); 108 assert(logger.logLevel == LogLevel.info, "expected 'LogLevel.info' got: " ~ logger.logLevel); 109 assert(logger.msg == "This is an INFO message", "The logger should have logged 'This is an INFO message' but instead was: " ~ logger.msg); 110 111 logWarn("This is a WARNING message"); 112 assert(logger.logLevel == LogLevel.warning, "expected 'LogLevel.warning' got: " ~ logger.logLevel); 113 assert(logger.msg == "This is a WARNING message", "The logger should have logged 'This is a WARNING message' but instead was: " ~ logger.msg); 114 115 logError("This is a ERROR message"); 116 assert(logger.logLevel == LogLevel.error, "expected 'LogLevel.error' got: " ~ logger.logLevel); 117 assert(logger.msg == "This is a ERROR message", "The logger should have logged 'This is a ERROR message' but instead was: " ~ logger.msg); 118 119 logCritical("This is a CRITICAL message"); 120 assert(logger.logLevel == LogLevel.critical, "expected 'LogLevel.critical' got: " ~ logger.logLevel); 121 assert(logger.msg == "This is a CRITICAL message", "The logger should have logged 'This is a CRITICAL message' but instead was: " ~ logger.msg); 122 } 123 }