From: Lidong Zhong <lzhong@suse.com>
Subject: log: add two options(log_file_count and log_file_maxbytes) in the main config file
References: bsc#1098395
Patch-Mainline: yes
Git-commit: 4791290f9b1a5c54fcc2c805b2cae0a7d1d9d08b
Git-repo: git://github.com/redhat-performance/tuned

Currently the logrotation is not configurable. On system with large
amount of cpus a tuned start creates a lot of entries and older log
entries are lost.

Signed-off-by: Thomas Renninger <trenn@suse.com>

Index: tuned-2.8.0/tuned-main.conf
===================================================================
--- tuned-2.8.0.orig/tuned-main.conf	2017-04-26 16:55:04.000000000 +0200
+++ tuned-2.8.0/tuned-main.conf	2018-11-16 17:57:57.025282709 +0100
@@ -29,3 +29,9 @@ reapply_sysctl = 1
 
 # Default priority assigned to instances
 default_instance_priority = 0
+
+# Log file count
+log_file_count = 2
+
+# Log file max size
+log_file_max_size = 100KB
Index: tuned-2.8.0/tuned.py
===================================================================
--- tuned-2.8.0.orig/tuned.py	2017-04-26 16:55:04.000000000 +0200
+++ tuned-2.8.0/tuned.py	2018-11-16 17:57:57.025282709 +0100
@@ -54,13 +54,15 @@ if __name__ == "__main__":
 		log.setLevel("DEBUG")
 
 	try:
+		maxBytes = config.get_size("log_file_max_size", consts.LOG_FILE_MAXBYTES)
+		backupCount = config.get("log_file_count", consts.LOG_FILE_COUNT)
 		if args.daemon:
 			if args.log is None:
 				args.log = consts.LOG_FILE
-			log.switch_to_file(args.log)
+			log.switch_to_file(args.log, maxBytes, backupCount)
 		else:
 			if args.log is not None:
-				log.switch_to_file(args.log)
+				log.switch_to_file(args.log, maxBytes, backupCount)
 
 		app = tuned.daemon.Application(args.profile, config)
 
Index: tuned-2.8.0/tuned/logs.py
===================================================================
--- tuned-2.8.0.orig/tuned/logs.py	2017-04-26 16:55:04.000000000 +0200
+++ tuned-2.8.0/tuned/logs.py	2018-11-16 17:57:57.025282709 +0100
@@ -51,8 +51,10 @@ class TunedLogger(logging.getLoggerClass
 		self.remove_all_handlers()
 		self.addHandler(self._console_handler)
 
-	def switch_to_file(self, filename = consts.LOG_FILE):
-		self._setup_file_handler(filename)
+	def switch_to_file(self, filename = consts.LOG_FILE, 
+			   maxBytes = consts.LOG_FILE_MAXBYTES,
+			   backupCount = consts.LOG_FILE_COUNT):
+		self._setup_file_handler(filename, maxBytes, backupCount)
 		self.remove_all_handlers()
 		self.addHandler(self._file_handler)
 
@@ -69,7 +71,7 @@ class TunedLogger(logging.getLoggerClass
 		cls._console_handler.setFormatter(cls._formatter)
 
 	@classmethod
-	def _setup_file_handler(cls, filename):
+	def _setup_file_handler(cls, filename, maxBytes, backupCount):
 		if cls._file_handler is not None:
 			return
 
@@ -80,7 +82,7 @@ class TunedLogger(logging.getLoggerClass
 			os.makedirs(log_directory)
 
 		cls._file_handler = logging.handlers.RotatingFileHandler(
-			filename, maxBytes = consts.LOG_FILE_MAXBYTES, backupCount = consts.LOG_FILE_COUNT)
+			filename, maxBytes = maxBytes, backupCount = backupCount)
 		cls._file_handler.setFormatter(cls._formatter)
 
 logging.setLoggerClass(TunedLogger)
Index: tuned-2.8.0/tuned/utils/global_config.py
===================================================================
--- tuned-2.8.0.orig/tuned/utils/global_config.py	2017-04-26 16:55:04.000000000 +0200
+++ tuned-2.8.0/tuned/utils/global_config.py	2018-11-16 17:59:40.693288295 +0100
@@ -47,3 +47,14 @@ class GlobalConfig():
 
 	def set(self, key, value):
 		self._cfg[key] = value
+
+	def get_size(self, key, default = None):
+		val = self.get(key)
+		if val is None:
+			return default
+		ret = self._cmd.get_size(val)
+		if ret is None:
+			log.error("Error parsing value '%s', using '%s'." %(val, default))
+			return default
+		else:
+			return ret
Index: tuned-2.8.0/tuned/utils/commands.py
===================================================================
--- tuned-2.8.0.orig/tuned/utils/commands.py	2017-04-26 16:55:04.000000000 +0200
+++ tuned-2.8.0/tuned/utils/commands.py	2018-11-16 18:05:20.205306589 +0100
@@ -391,3 +391,24 @@ class commands:
 			return terminate.wait(time, False)
 		except:
 			return terminate.wait(time)
+
+	def get_size(self, s):
+		s = str(s).strip().upper()
+		for unit in ["KB", "MB", "GB", ""]:
+			unit_ix = s.rfind(unit)
+			if unit_ix == -1:
+				continue
+			try:
+				val = int(s[:unit_ix])
+				u = s[unit_ix:]
+				if u == "KB":
+					val *= 1024
+				elif u == "MB":
+					val *= 1024 * 1024
+				elif u == "GB":
+					val *= 1024 * 1024 * 1024
+				elif u != "":
+					val = None
+				return val
+			except ValueError:
+				return None
