X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=nfvbench%2Ffluentd.py;h=ad0ea3423fd4dd056f4481f700d9c42b94f2d277;hb=refs%2Fheads%2Fstable%2Ffraser;hp=683d4ce9d26074ec924ab47ae519f9f19331e002;hpb=2d55474511a5057015e77547c326120c1649c0b7;p=nfvbench.git diff --git a/nfvbench/fluentd.py b/nfvbench/fluentd.py index 683d4ce..ad0ea34 100644 --- a/nfvbench/fluentd.py +++ b/nfvbench/fluentd.py @@ -12,9 +12,12 @@ # License for the specific language governing permissions and limitations # under the License. +import logging + from datetime import datetime from fluent import sender -import logging +import pytz + class FluentLogHandler(logging.Handler): '''This is a minimalist log handler for use with Fluentd @@ -25,23 +28,110 @@ class FluentLogHandler(logging.Handler): - the level name - the runlogdate (to tie multiple run-related logs together) The timestamp is retrieved by the fluentd library. + There will be only one instance of FluentLogHandler running. ''' - def __init__(self, tag, fluentd_ip='127.0.0.1', fluentd_port=24224): + + def __init__(self, fluentd_configs): logging.Handler.__init__(self) - self.tag = tag + self.log_senders = [] + self.result_senders = [] + self.runlogdate = "1970-01-01T00:00:00.000000+0000" self.formatter = logging.Formatter('%(message)s') - self.sender = sender.FluentSender(self.tag, port=fluentd_port) - self.start_new_run() + for fluentd_config in fluentd_configs: + if fluentd_config.logging_tag: + self.log_senders.append( + sender.FluentSender(fluentd_config.logging_tag, host=fluentd_config.ip, + port=fluentd_config.port)) + if fluentd_config.result_tag: + self.result_senders.append( + sender.FluentSender(fluentd_config.result_tag, host=fluentd_config.ip, + port=fluentd_config.port)) + self.__warning_counter = 0 + self.__error_counter = 0 def start_new_run(self): '''Delimitate a new run in the stream of records with a new timestamp ''' - self.runlogdate = str(datetime.now()) + # reset counters + self.__warning_counter = 0 + self.__error_counter = 0 + self.runlogdate = self.__get_timestamp() + # send start record + self.__send_start_record() def emit(self, record): data = { - "runlogdate": self.runlogdate, "loglevel": record.levelname, - "message": self.formatter.format(record) + "message": self.formatter.format(record), + "@timestamp": self.__get_timestamp() } - self.sender.emit(None, data) + # if runlogdate is Jan 1st 1970, it's a log from server (not an nfvbench run) + # so do not send runlogdate + if self.runlogdate != "1970-01-01T00:00:00.000000+0000": + data["runlogdate"] = self.runlogdate + + self.__update_stats(record.levelno) + for log_sender in self.log_senders: + log_sender.emit(None, data) + + # this function is called by summarizer, and used for sending results + def record_send(self, record): + for result_sender in self.result_senders: + result_sender.emit(None, record) + + # send START log record for each run + def __send_start_record(self): + data = { + "runlogdate": self.runlogdate, + "loglevel": "START", + "message": "NFVBENCH run is started", + "numloglevel": 0, + "numerrors": 0, + "numwarnings": 0, + "@timestamp": self.__get_timestamp() + } + for log_sender in self.log_senders: + log_sender.emit(None, data) + + # send stats related to the current run and reset state for a new run + def send_run_summary(self, run_summary_required): + if run_summary_required or self.__get_highest_level() == logging.ERROR: + data = { + "loglevel": "RUN_SUMMARY", + "message": self.__get_highest_level_desc(), + "numloglevel": self.__get_highest_level(), + "numerrors": self.__error_counter, + "numwarnings": self.__warning_counter, + "@timestamp": self.__get_timestamp() + } + # if runlogdate is Jan 1st 1970, it's a log from server (not an nfvbench run) + # so don't send runlogdate + if self.runlogdate != "1970-01-01T00:00:00.000000+0000": + data["runlogdate"] = self.runlogdate + for log_sender in self.log_senders: + log_sender.emit(None, data) + + def __get_highest_level(self): + if self.__error_counter > 0: + return logging.ERROR + elif self.__warning_counter > 0: + return logging.WARNING + return logging.INFO + + def __get_highest_level_desc(self): + highest_level = self.__get_highest_level() + if highest_level == logging.INFO: + return "GOOD RUN" + elif highest_level == logging.WARNING: + return "RUN WITH WARNINGS" + return "RUN WITH ERRORS" + + def __update_stats(self, levelno): + if levelno == logging.WARNING: + self.__warning_counter += 1 + elif levelno == logging.ERROR: + self.__error_counter += 1 + + def __get_timestamp(self): + return datetime.utcnow().replace(tzinfo=pytz.utc).strftime( + "%Y-%m-%dT%H:%M:%S.%f%z")