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