make splitting of log lines configurable
- it might make sense to have newlines in a log message (e.g. when printing a backtrace) and they shouldn't be split into multiple log messages, e.g. when using syslog - the splitting was fixed to work with more than one LF (cherry picked from commit d14ce3dea1b98227dcd116acc6b175c56d9a1fb0)
This commit is contained in:
parent
7e2d1dd038
commit
dc9002de0e
|
@ -196,6 +196,12 @@ struct LogLine {
|
|||
class Logger {
|
||||
LogLevel minLevel = LogLevel.min;
|
||||
|
||||
/** Whether the logger can handle multiple lines in a single beginLine/endLine.
|
||||
|
||||
By default log text with newlines gets split into multiple log lines.
|
||||
*/
|
||||
protected bool multilineLogger = false;
|
||||
|
||||
private {
|
||||
LogLine m_curLine;
|
||||
Appender!string m_curLineText;
|
||||
|
@ -830,14 +836,23 @@ private struct LogOutputRange {
|
|||
|
||||
void put(scope const(char)[] text)
|
||||
{
|
||||
import std.string : indexOf;
|
||||
auto idx = text.indexOf('\n');
|
||||
if (idx >= 0) {
|
||||
logger.put(text[0 .. idx]);
|
||||
if (text.empty)
|
||||
return;
|
||||
|
||||
if (logger.multilineLogger)
|
||||
logger.put(text);
|
||||
else
|
||||
{
|
||||
auto rng = text.splitter('\n');
|
||||
logger.put(rng.front);
|
||||
rng.popFront;
|
||||
foreach (line; rng)
|
||||
{
|
||||
logger.endLine();
|
||||
logger.beginLine(info);
|
||||
logger.put(text[idx+1 .. $]);
|
||||
} else logger.put(text);
|
||||
logger.put(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void put(char ch) @trusted { put((&ch)[0 .. 1]); }
|
||||
|
@ -862,6 +877,31 @@ private version (Windows) {
|
|||
extern(System) HANDLE GetStdHandle(DWORD nStdHandle);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
static class TestLogger : Logger
|
||||
{
|
||||
string[] lines;
|
||||
override void beginLine(ref LogLine msg) { lines.length += 1; }
|
||||
override void put(scope const(char)[] text) { lines[$-1] ~= text; }
|
||||
override void endLine() { }
|
||||
}
|
||||
auto logger = new TestLogger;
|
||||
auto ll = (cast(shared(Logger))logger).lock();
|
||||
auto rng = LogOutputRange(ll, __FILE__, __LINE__, LogLevel.info);
|
||||
rng.formattedWrite("text\nwith\nnewlines");
|
||||
rng.finalize();
|
||||
|
||||
assert(logger.lines == ["text", "with", "newlines"]);
|
||||
logger.lines = null;
|
||||
logger.multilineLogger = true;
|
||||
|
||||
rng = LogOutputRange(ll, __FILE__, __LINE__, LogLevel.info);
|
||||
rng.formattedWrite("text\nwith\nnewlines");
|
||||
rng.finalize();
|
||||
assert(logger.lines == ["text\nwith\nnewlines"]);
|
||||
}
|
||||
|
||||
unittest { // make sure the default logger doesn't allocate/is usable within finalizers
|
||||
bool destroyed = false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue