RemoteSyslogChannel should allow the RFC 5424 STRUCTURED-DATA field to be set #2173

This commit is contained in:
Günter Obiltschnig
2018-03-07 06:51:39 +01:00
parent 826dc92fda
commit 69588abd71
6 changed files with 120 additions and 0 deletions

View File

@@ -34,6 +34,7 @@ const std::string RemoteSyslogChannel::PROP_FACILITY("facility");
const std::string RemoteSyslogChannel::PROP_FORMAT("format");
const std::string RemoteSyslogChannel::PROP_LOGHOST("loghost");
const std::string RemoteSyslogChannel::PROP_HOST("host");
const std::string RemoteSyslogChannel::STRUCTURED_DATA("structured-data");
RemoteSyslogChannel::RemoteSyslogChannel():
@@ -137,6 +138,15 @@ void RemoteSyslogChannel::log(const Message& msg)
Poco::NumberFormatter::append(m, msg.getPid());
m += ' ';
m += msg.getSource();
m += ' ';
if (msg.has(STRUCTURED_DATA))
{
m += msg.get(STRUCTURED_DATA);
}
else
{
m += "-";
}
}
m += ' ';
m += msg.getText();

View File

@@ -178,6 +178,12 @@ private:
/// Parses until it encounters the next space char, returns the string from pos, excluding space
/// pos will point past the space char
static std::string parseStructuredData(const std::string& line, std::size_t& pos);
/// Parses the structured data field.
static std::string parseStructuredDataToken(const std::string& line, std::size_t& pos);
/// Parses a token from the structured data field.
private:
Poco::NotificationQueue& _queue;
bool _stopped;
@@ -295,6 +301,7 @@ void SyslogParser::parseNew(const std::string& line, RemoteSyslogChannel::Severi
std::string appName(parseUntilSpace(line, pos));
std::string procId(parseUntilSpace(line, pos));
std::string msgId(parseUntilSpace(line, pos));
std::string sd(parseStructuredData(line, pos));
std::string messageText(line.substr(pos));
pos = line.size();
Poco::DateTime date;
@@ -303,6 +310,7 @@ void SyslogParser::parseNew(const std::string& line, RemoteSyslogChannel::Severi
Poco::Message logEntry(msgId, messageText, prio);
logEntry[RemoteSyslogListener::LOG_PROP_HOST] = hostName;
logEntry[RemoteSyslogListener::LOG_PROP_APP] = appName;
logEntry[RemoteSyslogListener::LOG_PROP_STRUCTURED_DATA] = sd;
if (hasDate)
logEntry.setTime(date.timestamp());
@@ -393,6 +401,67 @@ std::string SyslogParser::parseUntilSpace(const std::string& line, std::size_t&
}
std::string SyslogParser::parseStructuredData(const std::string& line, std::size_t& pos)
{
std::string sd;
if (pos < line.size())
{
if (line[pos] == '-')
{
++pos;
}
else if (line[pos] == '[')
{
std::string tok = parseStructuredDataToken(line, pos);
while (tok == "[")
{
sd += tok;
tok = parseStructuredDataToken(line, pos);
while (tok != "]" && !tok.empty())
{
sd += tok;
tok = parseStructuredDataToken(line, pos);
}
sd += tok;
if (pos < line.size() && line[pos] == '[') tok = parseStructuredDataToken(line, pos);
}
}
if (pos < line.size() && Poco::Ascii::isSpace(line[pos])) ++pos;
}
return sd;
}
std::string SyslogParser::parseStructuredDataToken(const std::string& line, std::size_t& pos)
{
std::string tok;
if (pos < line.size())
{
if (Poco::Ascii::isSpace(line[pos]) || line[pos] == '=' || line[pos] == '[' || line[pos] == ']')
{
tok += line[pos++];
}
else if (line[pos] == '"')
{
tok += line[pos++];
while (pos < line.size() && line[pos] != '"')
{
tok += line[pos++];
}
tok += '"';
if (pos < line.size()) pos++;
}
else
{
while (pos < line.size() && !Poco::Ascii::isSpace(line[pos]) && line[pos] != '=')
{
tok += line[pos++];
}
}
}
return tok;
}
Poco::Message::Priority SyslogParser::convert(RemoteSyslogChannel::Severity severity)
{
switch (severity)
@@ -428,6 +497,7 @@ const std::string RemoteSyslogListener::PROP_THREADS("threads");
const std::string RemoteSyslogListener::LOG_PROP_APP("app");
const std::string RemoteSyslogListener::LOG_PROP_HOST("host");
const std::string RemoteSyslogListener::LOG_PROP_STRUCTURED_DATA("structured-data");
RemoteSyslogListener::RemoteSyslogListener():