@cryptotaxi247 / netdata-1 / commits / fb11e88d5

LogService: support for log file with pattern match addded

Ilya committed Jun 5, 2017 at 23:06 UTC fb11e88d5487d9c0b6de8a303917397cf46b426d
1 file changed +41 -30
python.d/python_modules/base.py
+41 -30
@@ -20,12 +20,12 @@
20 import time
21 import os
22 import socket
23 -import select
23 import threading
24 import msg
25 import ssl
26 from subprocess import Popen, PIPE
27 from sys import exc_info
28 +from glob import glob
29
30 try:
31 from urlparse import urlparse
@@ -807,57 +807,68 @@ class SocketService(SimpleService):
807
808 class LogService(SimpleService):
809 def __init__(self, configuration=None, name=None):
810 - self.log_path = ""
811 - self._last_position = 0
812 - # self._log_reader = None
810 SimpleService.__init__(self, configuration=configuration, name=name)
811 + self.log_path = self.configuration.get('path')
812 + self.__glob_path = self.log_path
813 + self._last_position = 0
814 self.retries = 100000 # basically always retry
815 + self.__re_find = dict(current=0, run=0, maximum=60)
816
817 def _get_raw_data(self):
818 """
819 Get log lines since last poll
820 :return: list
821 """
821 - lines = []
822 + lines = list()
823 try:
823 - if os.path.getsize(self.log_path) < self._last_position:
824 + if self.__re_find['current'] == self.__re_find['run']:
825 + self._find_recent_log_file()
826 + size = os.path.getsize(self.log_path)
827 + if size == self._last_position:
828 + self.__re_find['current'] += 1
829 + return list() # return empty list if nothing has changed
830 + elif size < self._last_position:
831 self._last_position = 0 # read from beginning if file has shrunk
825 - elif os.path.getsize(self.log_path) == self._last_position:
826 - self.debug("Log file hasn't changed. No new data.")
827 - return [] # return empty list if nothing has changed
828 - with open(self.log_path, "r") as fp:
832 +
833 + with open(self.log_path) as fp:
834 fp.seek(self._last_position)
830 - for i, line in enumerate(fp):
835 + for line in fp:
836 lines.append(line)
837 self._last_position = fp.tell()
833 - except Exception as e:
834 - self.error(str(e))
838 + self.__re_find['current'] = 0
839 + except (OSError, IOError) as error:
840 + self.__re_find['current'] += 1
841 + self.error(str(error))
842
836 - if len(lines) != 0:
837 - return lines
838 - else:
839 - self.error("No data collected.")
840 - return None
843 + return lines or None
844 +
845 + def _find_recent_log_file(self):
846 + """
847 + :return:
848 + """
849 + self.__re_find['run'] = self.__re_find['maximum']
850 + self.__re_find['current'] = 0
851 + path_list = glob(self.__glob_path)
852 + if path_list:
853 + self.log_path = max(path_list)
854 + return True
855 + return False
856
857 def check(self):
858 """
859 Parse basic configuration and check if log file exists
860 :return: boolean
861 """
847 - if self.name is not None or self.name != str(None):
848 - self.name = ""
849 - else:
850 - self.name = str(self.name)
851 - try:
852 - self.log_path = str(self.configuration['path'])
853 - except (KeyError, TypeError):
854 - self.info("No path to log specified. Using: '" + self.log_path + "'")
862 + if not self.log_path:
863 + self.error("No path to log specified")
864 + return None
865
856 - if os.access(self.log_path, os.R_OK):
866 + if all([self._find_recent_log_file(),
867 + os.access(self.log_path, os.R_OK),
868 + os.path.isfile(self.log_path)]):
869 return True
858 - else:
859 - self.error("Cannot access file: '" + self.log_path + "'")
860 - return False
870 + self.error("Cannot access %s" % self.log_path)
871 + return False
872
873 def create(self):
874 # set cursor at last byte of log file