Fix SyslogLogger. Fixes #203.

This was not working at all since the release of vibe-core due to dependencies on other parts of vibe.d. The unit test has now been moved out of the template class, so that it is actually run.
This commit is contained in:
Sönke Ludwig 2020-04-10 17:42:26 +02:00
parent 1233d6a58b
commit 899a84d834

View file

@ -588,33 +588,8 @@ final class SyslogLogger(OutputStream) : Logger {
Facility m_facility; Facility m_facility;
} }
/// Facilities deprecated("Use `SyslogFacility` instead.")
enum Facility { alias Facility = SyslogFacility;
kern, /// kernel messages
user, /// user-level messages
mail, /// mail system
daemon, /// system daemons
auth, /// security/authorization messages
syslog, /// messages generated internally by syslogd
lpr, /// line printer subsystem
news, /// network news subsystem
uucp, /// UUCP subsystem
clockDaemon, /// clock daemon
authpriv, /// security/authorization messages
ftp, /// FTP daemon
ntp, /// NTP subsystem
logAudit, /// log audit
logAlert, /// log alert
cron, /// clock daemon
local0, /// local use 0
local1, /// local use 1
local2, /// local use 2
local3, /// local use 3
local4, /// local use 4
local5, /// local use 5
local6, /// local use 6
local7, /// local use 7
}
/// Severities /// Severities
private enum Severity { private enum Severity {
@ -696,9 +671,8 @@ final class SyslogLogger(OutputStream) : Logger {
auto text = msg.text; auto text = msg.text;
import std.format : formattedWrite; import std.format : formattedWrite;
import vibe.stream.wrapper : StreamOutputRange; auto str = StreamOutputRange!OutputStream(m_ostream);
auto str = StreamOutputRange(m_ostream); str.formattedWrite(SYSLOG_MESSAGE_FORMAT_VERSION1, priVal,
(&str).formattedWrite(SYSLOG_MESSAGE_FORMAT_VERSION1, priVal,
timestamp, m_hostName, BOM ~ m_appName, procId, msgId, timestamp, m_hostName, BOM ~ m_appName, procId, msgId,
structuredData, BOM); structuredData, BOM);
} }
@ -714,41 +688,118 @@ final class SyslogLogger(OutputStream) : Logger {
m_ostream.flush(); m_ostream.flush();
} }
unittest private struct StreamOutputRange(OutputStream)
{ {
import vibe.core.file; private {
auto fstream = createTempFile(); OutputStream m_stream;
auto logger = new SyslogLogger(fstream, Facility.local1, "appname", null); size_t m_fill = 0;
LogLine msg; char[256] m_data = void;
import std.datetime;
import core.thread;
static if (is(typeof(SysTime.init.fracSecs))) auto fs = 1.dur!"usecs";
else auto fs = FracSec.from!"usecs"(1);
msg.time = SysTime(DateTime(0, 1, 1, 0, 0, 0), fs);
foreach (lvl; [LogLevel.debug_, LogLevel.diagnostic, LogLevel.info, LogLevel.warn, LogLevel.error, LogLevel.critical, LogLevel.fatal]) {
msg.level = lvl;
logger.beginLine(msg);
logger.put("αβγ");
logger.endLine();
} }
fstream.close();
import std.file; @safe:
import std.string;
auto lines = splitLines(readText(fstream.path().toNativeString()), KeepTerminator.yes); @disable this(this);
assert(lines.length == 7);
assert(lines[0] == "<143>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n"); this(OutputStream stream) { m_stream = stream; }
assert(lines[1] == "<142>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n"); ~this() { flush(); }
assert(lines[2] == "<141>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n"); void flush()
assert(lines[3] == "<140>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n"); {
assert(lines[4] == "<139>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n"); if (m_fill == 0) return;
assert(lines[5] == "<138>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n"); m_stream.write(m_data[0 .. m_fill]);
assert(lines[6] == "<137>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n"); m_fill = 0;
removeFile(fstream.path().toNativeString()); }
void put(char bt)
{
m_data[m_fill++] = bt;
if (m_fill >= m_data.length) flush();
}
void put(const(char)[] bts)
{
// avoid writing more chunks than necessary
if (bts.length + m_fill >= m_data.length * 2) {
flush();
m_stream.write(bts);
return;
}
while (bts.length) {
auto len = min(m_data.length - m_fill, bts.length);
m_data[m_fill .. m_fill + len] = bts[0 .. len];
m_fill += len;
bts = bts[len .. $];
if (m_fill >= m_data.length) flush();
}
}
} }
} }
/// Syslog facilities
enum SyslogFacility {
kern, /// kernel messages
user, /// user-level messages
mail, /// mail system
daemon, /// system daemons
auth, /// security/authorization messages
syslog, /// messages generated internally by syslogd
lpr, /// line printer subsystem
news, /// network news subsystem
uucp, /// UUCP subsystem
clockDaemon, /// clock daemon
authpriv, /// security/authorization messages
ftp, /// FTP daemon
ntp, /// NTP subsystem
logAudit, /// log audit
logAlert, /// log alert
cron, /// clock daemon
local0, /// local use 0
local1, /// local use 1
local2, /// local use 2
local3, /// local use 3
local4, /// local use 4
local5, /// local use 5
local6, /// local use 6
local7, /// local use 7
}
unittest
{
import vibe.core.file;
auto fstream = createTempFile();
auto logger = new SyslogLogger!FileStream(fstream, SyslogFacility.local1, "appname", null);
LogLine msg;
import std.datetime;
import core.thread;
static if (is(typeof(SysTime.init.fracSecs))) auto fs = 1.dur!"usecs";
else auto fs = FracSec.from!"usecs"(1);
msg.time = SysTime(DateTime(0, 1, 1, 0, 0, 0), fs);
foreach (lvl; [LogLevel.debug_, LogLevel.diagnostic, LogLevel.info, LogLevel.warn, LogLevel.error, LogLevel.critical, LogLevel.fatal]) {
msg.level = lvl;
logger.beginLine(msg);
logger.put("αβγ");
logger.endLine();
}
auto path = fstream.path;
fstream.close();
import std.file;
import std.string;
auto lines = splitLines(readText(path.toString()), KeepTerminator.yes);
alias BOM = SyslogLogger!FileStream.BOM;
assert(lines.length == 7);
assert(lines[0] == "<143>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n");
assert(lines[1] == "<142>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n");
assert(lines[2] == "<141>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n");
assert(lines[3] == "<140>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n");
assert(lines[4] == "<139>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n");
assert(lines[5] == "<138>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n");
assert(lines[6] == "<137>1 0000-01-01T00:00:00.000001 - " ~ BOM ~ "appname - - - " ~ BOM ~ "αβγ\n");
removeFile(path.toString());
}
/// Returns: this host's host name. /// Returns: this host's host name.
/// ///
/// If the host name cannot be determined the function returns null. /// If the host name cannot be determined the function returns null.