Loading Common/Servers/CustomLogger/include/expat_log_parsing.h +7 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include <vector> #include <queue> #include <string.h> #include <ctype.h> #include <boost/shared_ptr.hpp> #include <boost/lexical_cast.hpp> #include <loggingBaseLog.h> Loading Loading @@ -81,6 +82,12 @@ std::string trim_date(const std::string& str); std::string log_to_string(const LogRecord& log_record); ACS::TimeInterval log_age(const LogRecord& log_record); /** * Checks if all characters contained in the string are printable characters * and ASCII conformant. **/ std::string sanitize_xml(const char* input_text, bool brackets=false); /** * Class used to represent a log record and the necessary information Loading Common/Servers/CustomLogger/src/expat_log_parsing.cpp +57 −21 Original line number Diff line number Diff line Loading @@ -140,6 +140,37 @@ log_age(const LogRecord& log_record) return ti; }; std::string sanitize_xml(const char* input_text, bool brackets) { std::stringstream output_text; bool valid_char; for(int i =0; i<std::strlen(input_text); ++i) { valid_char = true; if(std::isprint(input_text[i]) == 0) //bad character! { output_text.put('?'); valid_char = false; } if(brackets){ if(input_text[i] == '[') { output_text.put('{'); valid_char = false; } if(input_text[i] == ']') { output_text.put('}'); valid_char = false; } } if(valid_char) output_text << input_text[i]; } return output_text.str(); } void start_parsing_element(void *data, const char *el, const char **attr) { Loading Loading @@ -199,10 +230,13 @@ void parsing_character_data(void* data, const char *chars, int len) { LogRecord *lr = (LogRecord*) data; std::string message = sanitize_xml(std::string(chars, len).c_str(), true); if(lr->_parsing_message_cdata){ lr->message.assign(chars, len); //lr->message.assign(chars, len); lr->message = message; }else if(lr->_parsing_data_cdata){ lr->add_data(lr->_data_name, std::string(chars, len)); //lr->add_data(lr->_data_name, std::string(chars, len)); lr->add_data(lr->_data_name, message); } }; Loading @@ -211,7 +245,8 @@ parsing_character_data(void* data, const char *chars, int len) */ XML_Parser init_log_parsing(){ XML_Parser log_parser = XML_ParserCreate(NULL); //XML_Parser log_parser = XML_ParserCreate(NULL); XML_Parser log_parser = XML_ParserCreate("US-ASCII"); XML_SetElementHandler(log_parser, start_parsing_element, end_parsing_element); XML_SetCdataSectionHandler(log_parser, start_parsing_cdata_element, end_parsing_cdata_element); XML_SetCharacterDataHandler(log_parser, parsing_character_data); Loading @@ -234,7 +269,8 @@ get_log_record(XML_Parser log_parser, const char *xml_text) { LogRecord_sp log_record(new LogRecord); XML_SetUserData(log_parser, log_record.get()); if(!XML_Parse(log_parser, xml_text, std::strlen(xml_text), false)){ std::string xml_string = sanitize_xml(xml_text); if(!XML_Parse(log_parser, xml_string.c_str(), std::strlen(xml_string.c_str()), false)){ /** * We must pay attention here. If we forward malformed XML to the logging * system we get alot of errors, but still we don't want to lose the Loading @@ -243,7 +279,7 @@ get_log_record(XML_Parser log_parser, const char *xml_text) std::stringstream msg; msg << "CustomLoggerMalformedXMLError: "; msg << XML_ErrorString(XML_GetErrorCode(log_parser)); msg << " (" << xml_text << ")"; msg << " (" << xml_string.c_str() << ")"; //log_record->xml_text.assign(msg.str().c_str()); //log_record->xml_text.assign("CustomLoggerMalformedXMLError"); ACE_ERROR ((LM_ERROR, msg.str().c_str() )); Loading @@ -251,7 +287,7 @@ get_log_record(XML_Parser log_parser, const char *xml_text) throw MalformedXMLError("Malformed XML error"); }else{ // XML is good to go log_record->xml_text.assign(xml_text); log_record->xml_text.assign(xml_string.c_str()); } return log_record; }; Loading Common/Servers/CustomLogger/tests/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ USER_INC=-I$(GTEST_HOME) -I$(GMOCK_HOME) EXECUTABLES_L = unittest unittest_OBJECTS = unittest unittest_LIBS = $(GTEST_LIBS) unittest_LIBS = $(GTEST_LIBS) CustomLoggerImpl unittest_LDFLAGS = -lstdc++ -lpthread # END OF CUSTOMIZATION Loading Common/Servers/CustomLogger/tests/functional/test_logging.py +70 −5 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ from __future__ import with_statement from threading import Thread import os import time import subprocess import signal import sys import unittest2 Loading Loading @@ -65,9 +68,9 @@ class LogFileTests(CustomLoggerTests): Management.MNG_FALSE) os.remove(file_path) def test_close_file_during_logging(self): def test_close_file_during_logging_thread(self): basepath = "/tmp/events" filename = "test_close2.log" filename = "test_close_thread.log" file_path = os.path.join(basepath, filename) self.custom_logger.setLogfile(basepath, filename) #start a thread for continuous messaging Loading @@ -90,7 +93,7 @@ class LogFileTests(CustomLoggerTests): Management.MNG_FALSE) os.remove(file_path) def test_set_file_during_logging(self): def test_set_file_during_logging_thread(self): basepath_first = "/tmp/events" filename_first = "test_set_first.log" file_path_first = os.path.join(basepath_first, filename_first) Loading Loading @@ -122,6 +125,57 @@ class LogFileTests(CustomLoggerTests): os.remove(file_path_first) os.remove(file_path_second) def test_close_file_during_logging_process(self): basepath = "/tmp/events" filename = "test_close_process.log" file_path = os.path.join(basepath, filename) self.custom_logger.setLogfile(basepath, filename) #start a process for continuous messaging logging_process = subprocess.Popen([sys.executable, "./functional/logging_process.py"]) time.sleep(10) self.custom_logger.flush() try: self.custom_logger.closeLogfile() except Exception, e: os.kill(logging_process.pid, signal.SIGKILL) self.fail("Exception raised closing logfile: %s" % (e,)) os.kill(logging_process.pid, signal.SIGKILL) self.assertTrue(os.path.exists(file_path)) self.assertEqual(self.custom_logger._get_filename().get_sync()[0], file_path) self.assertEqual(self.custom_logger._get_isLogging().get_sync()[0], Management.MNG_FALSE) os.remove(file_path) def test_set_file_during_logging_thread(self): basepath_first = "/tmp/events" filename_first = "test_set_first_process.log" file_path_first = os.path.join(basepath_first, filename_first) basepath_second = "/tmp/events" filename_second = "test_set_second_process.log" file_path_second = os.path.join(basepath_second, filename_second) self.custom_logger.setLogfile(basepath_first, filename_first) #start a thread for continuous messaging logging_process = subprocess.Popen([sys.executable, "./functional/logging_process.py"]) time.sleep(10) #self.custom_logger.flush() try: self.custom_logger.setLogfile(basepath_second, filename_second) except Exception, e: os.kill(logging_process.pid, signal.SIGKILL) self.fail("Exception raised setting logfile: %s" % (e,)) time.sleep(10) self.custom_logger.closeLogfile() os.kill(logging_process.pid, signal.SIGKILL) #grab the index number from log events in separate files with open(file_path_first, "rt") as first_file: first_index = int(first_file.readlines()[-3].strip().split()[-1]) with open(file_path_second, "rt") as second_file: second_index = int(second_file.readline().strip().split()[-1]) self.assertEqual(first_index + 1, second_index) os.remove(file_path_first) os.remove(file_path_second) class LogMethodsTests(CustomLoggerTests): def setUp(self): Loading @@ -145,8 +199,19 @@ class LogMethodsTests(CustomLoggerTests): self.custom_logger.closeLogfile() with open(os.path.join(self.base_path, self.filename), "rt") as logfile: last_log = logfile.readlines()[-1].strip() self.assertTrue(last_log.endswith(message), self.assertTrue(last_log.endswith("??????????????????????????"), msg = "last log: %s" % (last_log,)) def test_square_brackets_log(self): message = "ciao [Marco]" logger.logNotice(message) time.sleep(2) self.custom_logger.flush() self.assertEqual(self.custom_logger._get_isLogging().get_sync()[0], Management.MNG_TRUE) self.custom_logger.closeLogfile() with open(os.path.join(self.base_path, self.filename), "rt") as logfile: last_log = logfile.readlines()[-1].strip() self.assertTrue(last_log.endswith("ciao {Marco}"), msg = "last log: %s" % (last_log,)) Common/Servers/CustomLogger/tests/unittest.cpp +29 −2 Original line number Diff line number Diff line #include "gtest/gtest.h" #include "expat_log_parsing.h" TEST(FakeTest, Success){ EXPECT_EQ(1, 1); using namespace std; TEST(Sanitize, GoodString) { string input("<element>this is good XML</element>"); string sanitized = sanitize_xml(input.c_str()); EXPECT_STREQ(input.c_str(), sanitized.c_str()); } TEST(Sanitize, BadChars) { stringstream input_stream; input_stream.put(0x01); input_stream.put(0x1F); input_stream.put(0x81); input_stream.put(0xFF); string output("????"); string sanitized = sanitize_xml(input_stream.str().c_str()); EXPECT_STREQ(output.c_str(), sanitized.c_str()); } /* TEST(Sanitize, SquareBrackets) { string input("ciao [Marco]"); string output("ciao {Marco}"); string sanitized = sanitize_xml(input.c_str()); EXPECT_STREQ(output.c_str(), sanitized.c_str()); }*/ Loading
Common/Servers/CustomLogger/include/expat_log_parsing.h +7 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include <vector> #include <queue> #include <string.h> #include <ctype.h> #include <boost/shared_ptr.hpp> #include <boost/lexical_cast.hpp> #include <loggingBaseLog.h> Loading Loading @@ -81,6 +82,12 @@ std::string trim_date(const std::string& str); std::string log_to_string(const LogRecord& log_record); ACS::TimeInterval log_age(const LogRecord& log_record); /** * Checks if all characters contained in the string are printable characters * and ASCII conformant. **/ std::string sanitize_xml(const char* input_text, bool brackets=false); /** * Class used to represent a log record and the necessary information Loading
Common/Servers/CustomLogger/src/expat_log_parsing.cpp +57 −21 Original line number Diff line number Diff line Loading @@ -140,6 +140,37 @@ log_age(const LogRecord& log_record) return ti; }; std::string sanitize_xml(const char* input_text, bool brackets) { std::stringstream output_text; bool valid_char; for(int i =0; i<std::strlen(input_text); ++i) { valid_char = true; if(std::isprint(input_text[i]) == 0) //bad character! { output_text.put('?'); valid_char = false; } if(brackets){ if(input_text[i] == '[') { output_text.put('{'); valid_char = false; } if(input_text[i] == ']') { output_text.put('}'); valid_char = false; } } if(valid_char) output_text << input_text[i]; } return output_text.str(); } void start_parsing_element(void *data, const char *el, const char **attr) { Loading Loading @@ -199,10 +230,13 @@ void parsing_character_data(void* data, const char *chars, int len) { LogRecord *lr = (LogRecord*) data; std::string message = sanitize_xml(std::string(chars, len).c_str(), true); if(lr->_parsing_message_cdata){ lr->message.assign(chars, len); //lr->message.assign(chars, len); lr->message = message; }else if(lr->_parsing_data_cdata){ lr->add_data(lr->_data_name, std::string(chars, len)); //lr->add_data(lr->_data_name, std::string(chars, len)); lr->add_data(lr->_data_name, message); } }; Loading @@ -211,7 +245,8 @@ parsing_character_data(void* data, const char *chars, int len) */ XML_Parser init_log_parsing(){ XML_Parser log_parser = XML_ParserCreate(NULL); //XML_Parser log_parser = XML_ParserCreate(NULL); XML_Parser log_parser = XML_ParserCreate("US-ASCII"); XML_SetElementHandler(log_parser, start_parsing_element, end_parsing_element); XML_SetCdataSectionHandler(log_parser, start_parsing_cdata_element, end_parsing_cdata_element); XML_SetCharacterDataHandler(log_parser, parsing_character_data); Loading @@ -234,7 +269,8 @@ get_log_record(XML_Parser log_parser, const char *xml_text) { LogRecord_sp log_record(new LogRecord); XML_SetUserData(log_parser, log_record.get()); if(!XML_Parse(log_parser, xml_text, std::strlen(xml_text), false)){ std::string xml_string = sanitize_xml(xml_text); if(!XML_Parse(log_parser, xml_string.c_str(), std::strlen(xml_string.c_str()), false)){ /** * We must pay attention here. If we forward malformed XML to the logging * system we get alot of errors, but still we don't want to lose the Loading @@ -243,7 +279,7 @@ get_log_record(XML_Parser log_parser, const char *xml_text) std::stringstream msg; msg << "CustomLoggerMalformedXMLError: "; msg << XML_ErrorString(XML_GetErrorCode(log_parser)); msg << " (" << xml_text << ")"; msg << " (" << xml_string.c_str() << ")"; //log_record->xml_text.assign(msg.str().c_str()); //log_record->xml_text.assign("CustomLoggerMalformedXMLError"); ACE_ERROR ((LM_ERROR, msg.str().c_str() )); Loading @@ -251,7 +287,7 @@ get_log_record(XML_Parser log_parser, const char *xml_text) throw MalformedXMLError("Malformed XML error"); }else{ // XML is good to go log_record->xml_text.assign(xml_text); log_record->xml_text.assign(xml_string.c_str()); } return log_record; }; Loading
Common/Servers/CustomLogger/tests/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ USER_INC=-I$(GTEST_HOME) -I$(GMOCK_HOME) EXECUTABLES_L = unittest unittest_OBJECTS = unittest unittest_LIBS = $(GTEST_LIBS) unittest_LIBS = $(GTEST_LIBS) CustomLoggerImpl unittest_LDFLAGS = -lstdc++ -lpthread # END OF CUSTOMIZATION Loading
Common/Servers/CustomLogger/tests/functional/test_logging.py +70 −5 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ from __future__ import with_statement from threading import Thread import os import time import subprocess import signal import sys import unittest2 Loading Loading @@ -65,9 +68,9 @@ class LogFileTests(CustomLoggerTests): Management.MNG_FALSE) os.remove(file_path) def test_close_file_during_logging(self): def test_close_file_during_logging_thread(self): basepath = "/tmp/events" filename = "test_close2.log" filename = "test_close_thread.log" file_path = os.path.join(basepath, filename) self.custom_logger.setLogfile(basepath, filename) #start a thread for continuous messaging Loading @@ -90,7 +93,7 @@ class LogFileTests(CustomLoggerTests): Management.MNG_FALSE) os.remove(file_path) def test_set_file_during_logging(self): def test_set_file_during_logging_thread(self): basepath_first = "/tmp/events" filename_first = "test_set_first.log" file_path_first = os.path.join(basepath_first, filename_first) Loading Loading @@ -122,6 +125,57 @@ class LogFileTests(CustomLoggerTests): os.remove(file_path_first) os.remove(file_path_second) def test_close_file_during_logging_process(self): basepath = "/tmp/events" filename = "test_close_process.log" file_path = os.path.join(basepath, filename) self.custom_logger.setLogfile(basepath, filename) #start a process for continuous messaging logging_process = subprocess.Popen([sys.executable, "./functional/logging_process.py"]) time.sleep(10) self.custom_logger.flush() try: self.custom_logger.closeLogfile() except Exception, e: os.kill(logging_process.pid, signal.SIGKILL) self.fail("Exception raised closing logfile: %s" % (e,)) os.kill(logging_process.pid, signal.SIGKILL) self.assertTrue(os.path.exists(file_path)) self.assertEqual(self.custom_logger._get_filename().get_sync()[0], file_path) self.assertEqual(self.custom_logger._get_isLogging().get_sync()[0], Management.MNG_FALSE) os.remove(file_path) def test_set_file_during_logging_thread(self): basepath_first = "/tmp/events" filename_first = "test_set_first_process.log" file_path_first = os.path.join(basepath_first, filename_first) basepath_second = "/tmp/events" filename_second = "test_set_second_process.log" file_path_second = os.path.join(basepath_second, filename_second) self.custom_logger.setLogfile(basepath_first, filename_first) #start a thread for continuous messaging logging_process = subprocess.Popen([sys.executable, "./functional/logging_process.py"]) time.sleep(10) #self.custom_logger.flush() try: self.custom_logger.setLogfile(basepath_second, filename_second) except Exception, e: os.kill(logging_process.pid, signal.SIGKILL) self.fail("Exception raised setting logfile: %s" % (e,)) time.sleep(10) self.custom_logger.closeLogfile() os.kill(logging_process.pid, signal.SIGKILL) #grab the index number from log events in separate files with open(file_path_first, "rt") as first_file: first_index = int(first_file.readlines()[-3].strip().split()[-1]) with open(file_path_second, "rt") as second_file: second_index = int(second_file.readline().strip().split()[-1]) self.assertEqual(first_index + 1, second_index) os.remove(file_path_first) os.remove(file_path_second) class LogMethodsTests(CustomLoggerTests): def setUp(self): Loading @@ -145,8 +199,19 @@ class LogMethodsTests(CustomLoggerTests): self.custom_logger.closeLogfile() with open(os.path.join(self.base_path, self.filename), "rt") as logfile: last_log = logfile.readlines()[-1].strip() self.assertTrue(last_log.endswith(message), self.assertTrue(last_log.endswith("??????????????????????????"), msg = "last log: %s" % (last_log,)) def test_square_brackets_log(self): message = "ciao [Marco]" logger.logNotice(message) time.sleep(2) self.custom_logger.flush() self.assertEqual(self.custom_logger._get_isLogging().get_sync()[0], Management.MNG_TRUE) self.custom_logger.closeLogfile() with open(os.path.join(self.base_path, self.filename), "rt") as logfile: last_log = logfile.readlines()[-1].strip() self.assertTrue(last_log.endswith("ciao {Marco}"), msg = "last log: %s" % (last_log,))
Common/Servers/CustomLogger/tests/unittest.cpp +29 −2 Original line number Diff line number Diff line #include "gtest/gtest.h" #include "expat_log_parsing.h" TEST(FakeTest, Success){ EXPECT_EQ(1, 1); using namespace std; TEST(Sanitize, GoodString) { string input("<element>this is good XML</element>"); string sanitized = sanitize_xml(input.c_str()); EXPECT_STREQ(input.c_str(), sanitized.c_str()); } TEST(Sanitize, BadChars) { stringstream input_stream; input_stream.put(0x01); input_stream.put(0x1F); input_stream.put(0x81); input_stream.put(0xFF); string output("????"); string sanitized = sanitize_xml(input_stream.str().c_str()); EXPECT_STREQ(output.c_str(), sanitized.c_str()); } /* TEST(Sanitize, SquareBrackets) { string input("ciao [Marco]"); string output("ciao {Marco}"); string sanitized = sanitize_xml(input.c_str()); EXPECT_STREQ(output.c_str(), sanitized.c_str()); }*/