mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-13 10:32:57 +01:00
RemoteSyslogChannel should allow the RFC 5424 STRUCTURED-DATA field to be set #2173
This commit is contained in:
parent
826dc92fda
commit
69588abd71
@ -126,6 +126,7 @@ public:
|
||||
static const std::string PROP_FORMAT;
|
||||
static const std::string PROP_LOGHOST;
|
||||
static const std::string PROP_HOST;
|
||||
static const std::string STRUCTURED_DATA;
|
||||
|
||||
protected:
|
||||
~RemoteSyslogChannel();
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
|
||||
static const std::string LOG_PROP_APP;
|
||||
static const std::string LOG_PROP_HOST;
|
||||
static const std::string LOG_PROP_STRUCTURED_DATA;
|
||||
|
||||
protected:
|
||||
~RemoteSyslogListener();
|
||||
|
@ -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();
|
||||
|
@ -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():
|
||||
|
@ -211,6 +211,42 @@ void SyslogTest::testOldBSD()
|
||||
}
|
||||
|
||||
|
||||
void SyslogTest::testStructuredData()
|
||||
{
|
||||
Poco::AutoPtr<RemoteSyslogChannel> channel = new RemoteSyslogChannel();
|
||||
channel->setProperty("loghost", "127.0.0.1:51400");
|
||||
channel->open();
|
||||
Poco::AutoPtr<RemoteSyslogListener> listener = new RemoteSyslogListener(51400);
|
||||
listener->open();
|
||||
CachingChannel cl;
|
||||
listener->addChannel(&cl);
|
||||
assert(cl.getCurrentSize() == 0);
|
||||
Poco::Message msg1("asource", "amessage", Poco::Message::PRIO_CRITICAL);
|
||||
msg1.set("structured-data", "[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"]");
|
||||
channel->log(msg1);
|
||||
Poco::Message msg2("asource", "amessage", Poco::Message::PRIO_CRITICAL);
|
||||
msg2.set("structured-data", "[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"][examplePriority@32473 class=\"high\"]");
|
||||
channel->log(msg2);
|
||||
Poco::Thread::sleep(1000);
|
||||
listener->close();
|
||||
channel->close();
|
||||
assert(cl.getCurrentSize() == 2);
|
||||
std::vector<Poco::Message> msgs;
|
||||
cl.getMessages(msgs, 0, 10);
|
||||
assert(msgs.size() == 2);
|
||||
|
||||
assert(msgs[0].getSource() == "asource");
|
||||
assert(msgs[0].getText() == "amessage");
|
||||
assert(msgs[0].getPriority() == Poco::Message::PRIO_CRITICAL);
|
||||
assert(msgs[0].get("structured-data") == "[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"][examplePriority@32473 class=\"high\"]");
|
||||
|
||||
assert(msgs[1].getSource() == "asource");
|
||||
assert(msgs[1].getText() == "amessage");
|
||||
assert(msgs[1].getPriority() == Poco::Message::PRIO_CRITICAL);
|
||||
assert(msgs[1].get("structured-data") == "[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"]");
|
||||
}
|
||||
|
||||
|
||||
void SyslogTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -228,6 +264,7 @@ CppUnit::Test* SyslogTest::suite()
|
||||
CppUnit_addTest(pSuite, SyslogTest, testListener);
|
||||
CppUnit_addTest(pSuite, SyslogTest, testChannelOpenClose);
|
||||
CppUnit_addTest(pSuite, SyslogTest, testOldBSD);
|
||||
CppUnit_addTest(pSuite, SyslogTest, testStructuredData);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
void testListener();
|
||||
void testChannelOpenClose();
|
||||
void testOldBSD();
|
||||
void testStructuredData();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
Loading…
Reference in New Issue
Block a user