-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'zbud-msft' into syslog_telemetry_shared
- Loading branch information
Showing
17 changed files
with
451 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#include <iostream> | ||
#include <memory> | ||
#include <unistd.h> | ||
#include "rsyslog_plugin.h" | ||
|
||
#define SUCCESS_CODE 0 | ||
#define INVALID_REGEX_ERROR_CODE 1 | ||
#define EVENT_INIT_PUBLISH_ERROR_CODE 2 | ||
#define MISSING_ARGS_ERROR_CODE 3 | ||
|
||
void showUsage() { | ||
cout << "Usage for rsyslog_plugin: \n" << "options\n" | ||
<< "\t-r,required,type=string\t\tPath to regex file\n" | ||
<< "\t-m,required,type=string\t\tYANG module name of source generating syslog message\n" | ||
<< "\t-h \t\tHelp" | ||
<< endl; | ||
} | ||
|
||
int main(int argc, char** argv) { | ||
string regexPath; | ||
string moduleName; | ||
int optionVal; | ||
|
||
while((optionVal = getopt(argc, argv, "r:m:h")) != -1) { | ||
switch(optionVal) { | ||
case 'r': | ||
regexPath = optarg; | ||
break; | ||
case 'm': | ||
moduleName = optarg; | ||
break; | ||
case 'h': | ||
case '?': | ||
default: | ||
showUsage(); | ||
return 1; | ||
} | ||
} | ||
|
||
if(regexPath.empty() || moduleName.empty()) { // Missing required rc path | ||
cerr << "Error: Missing regexPath and moduleName." << endl; | ||
return MISSING_ARGS_ERROR_CODE; | ||
} | ||
|
||
unique_ptr<RsyslogPlugin> plugin(new RsyslogPlugin(moduleName, regexPath)); | ||
int returnCode = plugin->onInit(); | ||
if(returnCode == INVALID_REGEX_ERROR_CODE) { | ||
SWSS_LOG_ERROR("Rsyslog plugin was not able to be initialized due to invalid regex file provided.\n"); | ||
return returnCode; | ||
} else if(returnCode == EVENT_INIT_PUBLISH_ERROR_CODE) { | ||
SWSS_LOG_ERROR("Rsyslog plugin was not able to be initialized due to event_init_publish call failing.\n"); | ||
return returnCode; | ||
} | ||
|
||
plugin->run(); | ||
return SUCCESS_CODE; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <fstream> | ||
#include <regex> | ||
#include "rsyslog_plugin.h" | ||
#include "common/json.hpp" | ||
|
||
using json = nlohmann::json; | ||
|
||
bool RsyslogPlugin::onMessage(string msg) { | ||
string tag; | ||
event_params_t paramDict; | ||
if(!m_parser->parseMessage(msg, tag, paramDict)) { | ||
SWSS_LOG_DEBUG("%s was not able to be parsed into a structured event\n", msg.c_str()); | ||
return false; | ||
} else { | ||
int returnCode = event_publish(m_eventHandle, tag, ¶mDict); | ||
if (returnCode != 0) { | ||
SWSS_LOG_ERROR("rsyslog_plugin was not able to publish event for %s. last thrown event error: %d\n", tag.c_str(), event_last_error()); | ||
return false; | ||
} | ||
return true; | ||
} | ||
} | ||
|
||
bool RsyslogPlugin::createRegexList() { | ||
fstream regexFile; | ||
regexFile.open(m_regexPath, ios::in); | ||
if (!regexFile) { | ||
SWSS_LOG_ERROR("No such path exists: %s for source %s\n", m_regexPath.c_str(), m_moduleName.c_str()); | ||
return false; | ||
} | ||
try { | ||
regexFile >> m_parser->m_regexList; | ||
} catch (invalid_argument& iaException) { | ||
SWSS_LOG_ERROR("Invalid JSON file: %s, throws exception: %s\n", m_regexPath.c_str(), iaException.what()); | ||
return false; | ||
} | ||
|
||
string regexString; | ||
regex expression; | ||
|
||
for(long unsigned int i = 0; i < m_parser->m_regexList.size(); i++) { | ||
try { | ||
regexString = m_parser->m_regexList[i]["regex"]; | ||
string tag = m_parser->m_regexList[i]["tag"]; | ||
vector<string> params = m_parser->m_regexList[i]["params"]; | ||
regex expr(regexString); | ||
expression = expr; | ||
} catch (domain_error& deException) { | ||
SWSS_LOG_ERROR("Missing required key, throws exception: %s\n", deException.what()); | ||
return false; | ||
} catch (regex_error& reException) { | ||
SWSS_LOG_ERROR("Invalid regex, throws exception: %s\n", reException.what()); | ||
return false; | ||
} | ||
m_parser->m_expressions.push_back(expression); | ||
} | ||
if(m_parser->m_expressions.empty()) { | ||
SWSS_LOG_ERROR("Empty list of regex expressions.\n"); | ||
return false; | ||
} | ||
regexFile.close(); | ||
return true; | ||
} | ||
|
||
[[noreturn]] void RsyslogPlugin::run() { | ||
while(true) { | ||
string line; | ||
getline(cin, line); | ||
if(line.empty()) { | ||
continue; | ||
} | ||
onMessage(line); | ||
} | ||
} | ||
|
||
int RsyslogPlugin::onInit() { | ||
m_eventHandle = events_init_publisher(m_moduleName); | ||
bool success = createRegexList(); | ||
if(!success) { | ||
return 1; // invalid regex error code | ||
} else if(m_eventHandle == NULL) { | ||
return 2; // event init publish error code | ||
} | ||
return 0; | ||
} | ||
|
||
RsyslogPlugin::RsyslogPlugin(string moduleName, string regexPath) { | ||
m_parser = unique_ptr<SyslogParser>(new SyslogParser()); | ||
m_moduleName = moduleName; | ||
m_regexPath = regexPath; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef RSYSLOG_PLUGIN_H | ||
#define RSYSLOG_PLUGIN_H | ||
|
||
#include <string> | ||
#include <memory> | ||
#include "syslog_parser.h" | ||
#include "common/events.h" | ||
#include "common/logger.h" | ||
|
||
using namespace std; | ||
using namespace swss; | ||
|
||
/** | ||
* Rsyslog Plugin will utilize an instance of a syslog parser to read syslog messages from rsyslog.d and will continuously read from stdin | ||
* A plugin instance is created for each container/host. | ||
* | ||
*/ | ||
|
||
class RsyslogPlugin { | ||
public: | ||
int onInit(); | ||
bool onMessage(string msg); | ||
void run(); | ||
RsyslogPlugin(string moduleName, string regexPath); | ||
private: | ||
unique_ptr<SyslogParser> m_parser; | ||
event_handle_t m_eventHandle; | ||
string m_regexPath; | ||
string m_moduleName; | ||
bool createRegexList(); | ||
}; | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
CC := g++ | ||
|
||
RSYSLOG-PLUGIN_TEST_OBJS += ./rsyslog_plugin/rsyslog_plugin.o ./rsyslog_plugin/syslog_parser.o | ||
RSYSLOG-PLUGIN_OBJS += ./rsyslog_plugin/rsyslog_plugin.o ./rsyslog_plugin/syslog_parser.o ./rsyslog_plugin/main.o | ||
|
||
C_DEPS += ./rsyslog_plugin/rsyslog_plugin.d ./rsyslog_plugin/syslog_parser.d ./rsyslog_plugin/main.d | ||
|
||
rsyslog_plugin/%.o: rsyslog_plugin/%.cpp | ||
@echo 'Building file: $<' | ||
@echo 'Invoking: GCC C++ Compiler' | ||
$(CC) -D__FILENAME__="$(subst rsyslog_plugin/,,$<)" $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$(@)" "$<" | ||
@echo 'Finished building: $< | ||
'@echo ' ' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#include <iostream> | ||
#include "syslog_parser.h" | ||
#include "common/logger.h" | ||
|
||
/** | ||
* Parses syslog message and returns structured event | ||
* | ||
* @param nessage us syslog message being fed in by rsyslog.d | ||
* @return return structured event json for publishing | ||
* | ||
*/ | ||
|
||
bool SyslogParser::parseMessage(string message, string& eventTag, event_params_t& paramMap) { | ||
for(long unsigned int i = 0; i < m_regexList.size(); i++) { | ||
smatch matchResults; | ||
vector<string> params = m_regexList[i]["params"]; | ||
if(!regex_search(message, matchResults, m_expressions[i]) || params.size() != matchResults.size() - 1) { | ||
continue; | ||
} | ||
// found matching regex | ||
eventTag = m_regexList[i]["tag"]; | ||
transform(params.begin(), params.end(), matchResults.begin() + 1, inserter(paramMap, paramMap.end()), [](string a, string b) { | ||
return make_pair(a,b); | ||
}); | ||
return true; | ||
} | ||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#ifndef SYSLOG_PARSER_H | ||
#define SYSLOG_PARSER_H | ||
|
||
#include <vector> | ||
#include <string> | ||
#include <regex> | ||
#include "common/json.hpp" | ||
#include "common/events.h" | ||
|
||
using namespace std; | ||
using json = nlohmann::json; | ||
|
||
/** | ||
* Syslog Parser is responsible for parsing log messages fed by rsyslog.d and returns | ||
* matched result to rsyslog_plugin to use with events publish API | ||
* | ||
*/ | ||
|
||
class SyslogParser { | ||
public: | ||
vector<regex> m_expressions; | ||
json m_regexList = json::array(); | ||
bool parseMessage(string message, string& tag, event_params_t& paramDict); | ||
}; | ||
|
||
#endif |
Oops, something went wrong.