1 module vibejournald;
2 
3 import vibe.core.log;
4 
5 extern(C) int sd_journal_send(const char *format, ...);
6 
7 class JournaldLogger : Logger {
8 	import std.format : format;
9 	import std.string : toStringz;
10 
11 	LogLine ll;
12 	string line;
13 	const(char)* msg;
14 	const(char)* codeFile;
15 	const(char)* codeLine;
16 	const(char)* codeFunc;
17 	const(char)* priority;
18 
19 	this() {
20 		this.msg = "MESSAGE=%s".toStringz();
21 		this.codeFile = "CODE_FILE=%s".toStringz();
22 		this.codeLine = "CODE_LINE=%d".toStringz();
23 		this.codeFunc = "CODE_FUNC=%s".toStringz();
24 		this.priority = "PRIORITY=%d".toStringz();
25 	}
26 
27 	override void beginLine(ref LogLine ll) @safe {
28 		this.ll = ll;
29 		this.line = "";
30 	}
31 
32 	override void put(scope const(char)[] text) @safe {
33 		this.line ~= text;
34 	}
35 
36 	private int priorityValue() @safe {
37 		final switch(this.ll.level) {
38 			case LogLevel.critical:
39 				return 2;
40 			case LogLevel.debug_:
41 				return 7;
42 			case LogLevel.debugV:
43 				return 7;
44 			case LogLevel.diagnostic:
45 				return 5;
46 			case LogLevel.error:
47 				return 3;
48 			case LogLevel.fatal:
49 				return 0;
50 			case LogLevel.info:
51 				return 6;
52 			case LogLevel.none:
53 				return 7;
54 			case LogLevel.trace:
55 				return 7;
56 			case LogLevel.warn:
57 				return 4;
58 		}
59 	}
60 
61 	override void endLine() {
62 		() @trusted {
63 			sd_journal_send(
64 					this.msg, this.line.toStringz(),
65 					this.priority, this.priorityValue(),
66 					this.codeFile, this.ll.file.toStringz(),
67 					this.codeLine, this.ll.line,
68 					this.codeFunc, this.ll.func.toStringz(),
69 					null);
70 		}();
71 	}
72 }
73 
74 unittest {
75 	auto jl = cast(shared Logger)new JournaldLogger();
76 	registerLogger(jl);
77 	logTrace("Trace");
78 	logDebug("Debug");
79 	logInfo("Info");
80 	logError("Error");
81 	logWarn("Warning");
82 	logCritical("Critical");
83 	logFatal("Fatal");
84 }