Added cleanup function, added timeout to ping plugin
This commit is contained in:
		
							
								
								
									
										18
									
								
								collector.py
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								collector.py
									
									
									
									
									
								
							| @@ -53,8 +53,16 @@ class Collector(object): | |||||||
|                                    start_date=start_date, |                                    start_date=start_date, | ||||||
|                                    name=plugin.__class__.__name__) |                                    name=plugin.__class__.__name__) | ||||||
|  |  | ||||||
|  |     def schedule_cleanup(self): | ||||||
|  |         start_date = datetime.now() + timedelta(seconds=100) | ||||||
|  |         self.scheduler.add_job(self.cleanup, 'interval',  | ||||||
|  |                                hours=24, | ||||||
|  |                                start_date=start_date, | ||||||
|  |                                name='Cleanup') | ||||||
|  |  | ||||||
|     def run(self): |     def run(self): | ||||||
|         logging.basicConfig() |         logging.basicConfig() | ||||||
|  |         logging.getLogger().setLevel(logging.INFO) | ||||||
|         logging.getLogger('apscheduler').setLevel(logging.INFO) |         logging.getLogger('apscheduler').setLevel(logging.INFO) | ||||||
|  |  | ||||||
|         models = self.collect_models() |         models = self.collect_models() | ||||||
| @@ -63,6 +71,7 @@ class Collector(object): | |||||||
|             database.DB.create_tables(models) |             database.DB.create_tables(models) | ||||||
|  |  | ||||||
|         self.schedule_plugins() |         self.schedule_plugins() | ||||||
|  |         self.schedule_cleanup() | ||||||
|         logging.info('Started.') |         logging.info('Started.') | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
| @@ -72,6 +81,15 @@ class Collector(object): | |||||||
|  |  | ||||||
|         logging.info(f'Stopped.') |         logging.info(f'Stopped.') | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         for plugin in self.plugins: | ||||||
|  |             logging.info(f'Cleaning up {plugin.__class__.__name__}...') | ||||||
|  |             try: | ||||||
|  |                 items = plugin.cleanup_wrapper() | ||||||
|  |                 logging.info(f'... deleted {items} entries') | ||||||
|  |             except BaseException as e: | ||||||
|  |                 logging.error("Cleanup error:", exc_info=e) | ||||||
|  |                 pass | ||||||
|  |  | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     try: |     try: | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								config.py
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								config.py
									
									
									
									
									
								
							| @@ -29,19 +29,25 @@ DATABASE_URL = 'postgresql://system_metrics_collector:theMetrixWriteer2123@local | |||||||
| CPU_INTERVAL = DEFAULT_INTERVAL | CPU_INTERVAL = DEFAULT_INTERVAL | ||||||
| # Store statistics per CPU, not only combined | # Store statistics per CPU, not only combined | ||||||
| CPU_PER_CPU = True | CPU_PER_CPU = True | ||||||
|  | CPU_RETAIN_DAYS = 180 | ||||||
|  |  | ||||||
| ### Disk | ### Disk | ||||||
| DISK_USAGE_INTERVAL = DEFAULT_INTERVAL * 10 | DISK_USAGE_INTERVAL = DEFAULT_INTERVAL * 10 | ||||||
|  | DISK_USAGE_RETAIN_DAYS = 365*50 | ||||||
| DISK_IO_INTERVAL = DEFAULT_INTERVAL | DISK_IO_INTERVAL = DEFAULT_INTERVAL | ||||||
|  | DISK_IO_RETAIN_DAYS = 180 | ||||||
|  |  | ||||||
| ### Memory | ### Memory | ||||||
| MEMORY_INTERVAL = DEFAULT_INTERVAL | MEMORY_INTERVAL = DEFAULT_INTERVAL | ||||||
|  | MEMORY_RETAIN_DAYS = 365 * 5 | ||||||
|  |  | ||||||
| ### Network | ### Network | ||||||
| NETWORK_INTERVAL = DEFAULT_INTERVAL | NETWORK_INTERVAL = DEFAULT_INTERVAL | ||||||
|  | NETWORK_RETAIN_DAYS = 180 | ||||||
|  |  | ||||||
| ### Temperatures | ### Temperatures | ||||||
| TEMPERATURE_INTERVAL = DEFAULT_INTERVAL | TEMPERATURE_INTERVAL = DEFAULT_INTERVAL | ||||||
|  | TEMPERATURE_RETAIN_DAYS = 365 * 5 | ||||||
|  |  | ||||||
| # If true, fahrenheit is used, otherwise celsius | # If true, fahrenheit is used, otherwise celsius | ||||||
| TEMPERATURE_USE_FAHRENHEIT = False | TEMPERATURE_USE_FAHRENHEIT = False | ||||||
| @@ -59,8 +65,11 @@ PING_HOSTS = [ | |||||||
|     'tibich.com' |     'tibich.com' | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | PING_RETAIN_DAYS = 365 * 50 | ||||||
|  |  | ||||||
| ### Speedtest | ### Speedtest | ||||||
| SPEEDTEST_INTERVAL = 15 * 60        # every 15 min | SPEEDTEST_INTERVAL = 10 * 60        # every 10 min | ||||||
|  | SPEEDTEST_RETAIN_DAYS = 365 * 50 | ||||||
|  |  | ||||||
| ### Stocks | ### Stocks | ||||||
| STOCKS_INTERVAL = 12 * 60 * 60      # updates daily | STOCKS_INTERVAL = 12 * 60 * 60      # updates daily | ||||||
| @@ -75,9 +84,12 @@ STOCKS_TICKERS = { | |||||||
|     'ETH-USD' : 'Ethereum USD', |     'ETH-USD' : 'Ethereum USD', | ||||||
| } | } | ||||||
|  |  | ||||||
|  | STOCKS_RETAIN_DAYS = 365 * 50 | ||||||
|  |  | ||||||
| ### ROBOR | ### ROBOR | ||||||
| # Romanian Interbank Offer Rate | # Romanian Interbank Offer Rate | ||||||
| ROBOR_INTERVAL = 12 * 60 * 60       # updates daily, every 12 hours should be fine | ROBOR_INTERVAL = 12 * 60 * 60       # updates daily, every 12 hours should be fine | ||||||
|  | ROBOR_RETAIN_DAYS = 365 * 50 | ||||||
|  |  | ||||||
| ROBOR_FIELDS = [ | ROBOR_FIELDS = [ | ||||||
|     'ROBOR 6M' |     'ROBOR 6M' | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								plugins/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								plugins/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -14,6 +14,13 @@ class Plugin(ABC): | |||||||
|     def execute(self) -> None: |     def execute(self) -> None: | ||||||
|         pass |         pass | ||||||
|  |  | ||||||
|  |     def cleanup(self) -> None: | ||||||
|  |         return 0 | ||||||
|  |  | ||||||
|     def execute_wrapper(self) -> None: |     def execute_wrapper(self) -> None: | ||||||
|         with database.DB.connection_context(): |         with database.DB.connection_context(): | ||||||
|             self.execute() |             self.execute() | ||||||
|  |  | ||||||
|  |     def cleanup_wrapper(self) -> None: | ||||||
|  |         with database.DB.connection_context(): | ||||||
|  |             return self.cleanup() | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| from datetime import datetime | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| import psutil | import psutil | ||||||
| from peewee import * | from peewee import * | ||||||
| @@ -53,3 +53,7 @@ class CpuPlugin(Plugin): | |||||||
|             freqs = psutil.cpu_freq(percpu=True) |             freqs = psutil.cpu_freq(percpu=True) | ||||||
|             for i in range(len(times)): |             for i in range(len(times)): | ||||||
|                 self.store(i, times[i], freqs[i]) |                 self.store(i, times[i], freqs[i]) | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         limit = datetime.utcnow() - timedelta(days=config.CPU_RETAIN_DAYS) | ||||||
|  |         return Cpu.delete().where(Cpu.time < limit).execute() | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| from datetime import datetime | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| import psutil | import psutil | ||||||
| from peewee import * | from peewee import * | ||||||
| @@ -46,6 +46,10 @@ class DiskUsagePlugin(Plugin): | |||||||
|             entry.free = usage.free |             entry.free = usage.free | ||||||
|             entry.save() |             entry.save() | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         limit = datetime.utcnow() - timedelta(days=config.DISK_USAGE_RETAIN_DAYS) | ||||||
|  |         return DiskUsage.delete().where(DiskUsage.time < limit).execute() | ||||||
|  |  | ||||||
|  |  | ||||||
| class DiskIOPlugin(Plugin): | class DiskIOPlugin(Plugin): | ||||||
|     models = [DiskIO] |     models = [DiskIO] | ||||||
| @@ -77,3 +81,6 @@ class DiskIOPlugin(Plugin): | |||||||
|         for disk, current in io_reads.items(): |         for disk, current in io_reads.items(): | ||||||
|             self.store_io(disk, current) |             self.store_io(disk, current) | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         limit = datetime.utcnow() - timedelta(days=config.DISK_IO_RETAIN_DAYS) | ||||||
|  |         return DiskIO.delete().where(DiskIO.time < limit).execute() | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| from datetime import datetime | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| import psutil | import psutil | ||||||
| from peewee import * | from peewee import * | ||||||
| @@ -46,3 +46,7 @@ class MemoryPlugin(Plugin): | |||||||
|         entry.swap_free = swap.free |         entry.swap_free = swap.free | ||||||
|         entry.swap_used = swap.used |         entry.swap_used = swap.used | ||||||
|         entry.save() |         entry.save() | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         limit = datetime.utcnow() - timedelta(days=config.MEMORY_RETAIN_DAYS) | ||||||
|  |         return Memory.delete().where(Memory.time < limit).execute() | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| from datetime import datetime | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| import psutil | import psutil | ||||||
| from peewee import * | from peewee import * | ||||||
| @@ -48,3 +48,7 @@ class NetworkPlugin(Plugin): | |||||||
|         io_reads = psutil.net_io_counters(pernic=True) |         io_reads = psutil.net_io_counters(pernic=True) | ||||||
|         for nic, current in io_reads.items(): |         for nic, current in io_reads.items(): | ||||||
|             self.store_io(nic, current) |             self.store_io(nic, current) | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         limit = datetime.utcnow() - timedelta(days=config.NETWORK_RETAIN_DAYS) | ||||||
|  |         return NetworkIO.delete().where(NetworkIO.time < limit).execute() | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import subprocess | import subprocess | ||||||
| import re | import re | ||||||
| import subprocess | import subprocess | ||||||
| from datetime import datetime | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| import psutil | import psutil | ||||||
| from peewee import * | from peewee import * | ||||||
| @@ -29,19 +29,29 @@ class PingPlugin(Plugin): | |||||||
|  |  | ||||||
|     def do_ping(self, host): |     def do_ping(self, host): | ||||||
|         command = ['ping', '-c', '1', '-W', str(self.__timeout), host] |         command = ['ping', '-c', '1', '-W', str(self.__timeout), host] | ||||||
|         proc = subprocess.run(command, stdout=subprocess.PIPE) |         proc = subprocess.Popen(command, stdout=subprocess.PIPE) | ||||||
|         stdout = proc.stdout.decode() |         ping = None | ||||||
|  |  | ||||||
|  |         try: | ||||||
|  |             proc.wait(60) | ||||||
|  |             stdout = proc.stdout.read().decode() | ||||||
|  |  | ||||||
|  |             match = re.search(r'time=([\d\.]+) ms', stdout) | ||||||
|  |             if match is not None: | ||||||
|  |                 ping = float(match.group(1)) | ||||||
|  |  | ||||||
|  |         except subprocess.TimeoutExpired: | ||||||
|  |             proc.kill() | ||||||
|  |  | ||||||
|         entry = Ping() |         entry = Ping() | ||||||
|         entry.host = host |         entry.host = host | ||||||
|         entry.ping = None |         entry.ping = ping | ||||||
|  |  | ||||||
|         match = re.search(r'time=([\d\.]+) ms', stdout) |  | ||||||
|         if match is not None: |  | ||||||
|             entry.ping = float(match.group(1)) |  | ||||||
|  |  | ||||||
|         entry.save() |         entry.save() | ||||||
|  |  | ||||||
|     def execute(self): |     def execute(self): | ||||||
|         for host in config.PING_HOSTS: |         for host in config.PING_HOSTS: | ||||||
|             self.do_ping(host) |             self.do_ping(host) | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         limit = datetime.utcnow() - timedelta(days=config.PING_RETAIN_DAYS) | ||||||
|  |         return Ping.delete().where(Ping.time < limit).execute() | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| import subprocess | import subprocess | ||||||
| import re | import re | ||||||
| import subprocess | import subprocess | ||||||
| from datetime import datetime | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| import psutil | import psutil | ||||||
| from peewee import * | from peewee import * | ||||||
| @@ -53,5 +53,8 @@ class SpeedtestPlugin(Plugin): | |||||||
|         else: |         else: | ||||||
|             logging.error(f"SpeedTest nonzero return: {proc.returncode}\n-----\n{stdout}\n{stderr}\n\n") |             logging.error(f"SpeedTest nonzero return: {proc.returncode}\n-----\n{stdout}\n{stderr}\n\n") | ||||||
|              |              | ||||||
|  |  | ||||||
|         entry.save() |         entry.save() | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         limit = datetime.utcnow() - timedelta(days=config.SPEEDTEST_RETAIN_DAYS) | ||||||
|  |         return Speedtest.delete().where(Speedtest.time < limit).execute() | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| from datetime import datetime | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| import psutil | import psutil | ||||||
| from peewee import * | from peewee import * | ||||||
| @@ -35,3 +35,7 @@ class TemperaturesPlugin(Plugin): | |||||||
|                 entry.high = temp.high |                 entry.high = temp.high | ||||||
|                 entry.critical = temp.critical |                 entry.critical = temp.critical | ||||||
|                 entry.save() |                 entry.save() | ||||||
|  |  | ||||||
|  |     def cleanup(self): | ||||||
|  |         limit = datetime.utcnow() - timedelta(days=config.TEMPERATURE_RETAIN_DAYS) | ||||||
|  |         return Temperatures.delete().where(Temperatures.time < limit).execute() | ||||||
		Reference in New Issue
	
	Block a user