master
py 80 lines 2.69 KB
Raw
1 # -*- coding: utf-8 -*-
2 # Description:
3 # SPDX-License-Identifier: GPL-3.0-or-later
4
5 from glob import glob
6 import sys
7 import os
8
9 from bases.FrameworkServices.SimpleService import SimpleService
10
11
12 class LogService(SimpleService):
13 def __init__(self, configuration=None, name=None):
14 SimpleService.__init__(self, configuration=configuration, name=name)
15 self.log_path = self.configuration.get('path')
16 self.__glob_path = self.log_path
17 self._last_position = 0
18 self.__re_find = dict(current=0, run=0, maximum=60)
19 self.__open_args = {'errors': 'replace'} if sys.version_info[0] > 2 else {}
20
21 def _get_raw_data(self):
22 """
23 Get log lines since last poll
24 :return: list
25 """
26 lines = list()
27 try:
28 if self.__re_find['current'] == self.__re_find['run']:
29 self._find_recent_log_file()
30 size = os.path.getsize(self.log_path)
31 if size == self._last_position:
32 self.__re_find['current'] += 1
33 return list() # return empty list if nothing has changed
34 elif size < self._last_position:
35 self._last_position = 0 # read from beginning if file has shrunk
36
37 with open(self.log_path, **self.__open_args) as fp:
38 fp.seek(self._last_position)
39 for line in fp:
40 lines.append(line)
41 self._last_position = fp.tell()
42 self.__re_find['current'] = 0
43 except (OSError, IOError) as error:
44 self.__re_find['current'] += 1
45 self.error(str(error))
46
47 return lines or None
48
49 def _find_recent_log_file(self):
50 """
51 :return:
52 """
53 self.__re_find['run'] = self.__re_find['maximum']
54 self.__re_find['current'] = 0
55 self.__glob_path = self.__glob_path or self.log_path # workaround for modules w/o config files
56 path_list = glob(self.__glob_path)
57 if path_list:
58 self.log_path = max(path_list)
59 return True
60 return False
61
62 def check(self):
63 """
64 Parse basic configuration and check if log file exists
65 :return: boolean
66 """
67 if not self.log_path:
68 self.error('No path to log specified')
69 return None
70
71 if self._find_recent_log_file() and os.access(self.log_path, os.R_OK) and os.path.isfile(self.log_path):
72 return True
73 self.error('Cannot access {0}'.format(self.log_path))
74 return False
75
76 def create(self):
77 # set cursor at last byte of log file
78 self._last_position = os.path.getsize(self.log_path)
79 status = SimpleService.create(self)
80 return status