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 }