1 module ws.log; 2 3 import 4 core.sync.mutex, 5 std.array, 6 std.conv, 7 std.algorithm; 8 9 10 class Log { 11 12 enum Level { 13 info, 14 warning, 15 error 16 } 17 18 alias Logger = void delegate(Level, string, string, size_t); 19 20 private __gshared Logger[] loggers; 21 private __gshared Mutex lock; 22 23 shared static this(){ 24 lock = new Mutex; 25 } 26 27 static auto addLogger(Logger logger){ 28 synchronized(lock){ 29 loggers ~= logger; 30 } 31 return logger; 32 } 33 34 static void removeLogger(Logger logger){ 35 synchronized(lock){ 36 loggers = loggers.filter!(a => a != logger).array; 37 } 38 } 39 40 static string format(Args...)(Args args){ 41 string result; 42 foreach(s; args){ 43 result ~= s.to!string; 44 } 45 return result; 46 } 47 48 static void log(Level level, string s, string file, size_t line){ 49 synchronized(lock){ 50 foreach(logger; loggers){ 51 logger(level, s, file, line); 52 } 53 } 54 } 55 56 static void info(string file=__FILE__, size_t line=__LINE__, Args...)(Args args){ 57 log(Level.info, format(args), file, line); 58 } 59 60 static void warning(string file=__FILE__, size_t line=__LINE__, Args...)(Args args){ 61 log(Level.warning, format(args), file, line); 62 } 63 64 static void error(string file=__FILE__, size_t line=__LINE__, Args...)(Args args){ 65 log(Level.error, format(args), file, line); 66 } 67 68 }