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