You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2021/06/03 18:57:35 UTC

[incubator-nuttx] branch master updated: Added automatic log rotation, when log file is opened.

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 216194d  Added automatic log rotation, when log file is opened.
216194d is described below

commit 216194d31bee3b6bc1fa3d9b5c56f3e307b750d2
Author: Fotis Panagiotopoulos <f....@gmail.com>
AuthorDate: Thu Jun 3 16:51:10 2021 +0300

    Added automatic log rotation, when log file is opened.
---
 drivers/syslog/Kconfig              | 34 ++++++++++++++++++-
 drivers/syslog/syslog_filechannel.c | 66 +++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/drivers/syslog/Kconfig b/drivers/syslog/Kconfig
index 7608830..5f558d3 100644
--- a/drivers/syslog/Kconfig
+++ b/drivers/syslog/Kconfig
@@ -13,6 +13,8 @@ config ARCH_SYSLOG
 
 # Selected if the SYSLOG device supports multi-byte write operations
 
+comment "SYSLOG options"
+
 config SYSLOG_MAX_CHANNELS
 	int "Maximum SYSLOG channels"
 	default 1
@@ -105,6 +107,8 @@ config SYSLOG_INTBUFSIZE
 	---help---
 		The size of the interrupt buffer in bytes.
 
+comment "Formatting options"
+
 config SYSLOG_TIMESTAMP
 	bool "Prepend timestamp to syslog message"
 	default n
@@ -188,6 +192,8 @@ config SYSLOG_COLOR_OUTPUT
 	---help---
 		Enables colored output in syslog, according to message priority.
 
+comment "SYSLOG channels"
+
 if !ARCH_SYSLOG
 config SYSLOG_CHAR
 	bool "Log to a character device"
@@ -251,7 +257,7 @@ config SYSLOG_RPMSG_SERVER
 	---help---
 		Use rpmsg to receive message from remote proc.
 
-config SYSLOG_FILE
+menuconfig SYSLOG_FILE
 	bool "Syslog file output"
 	default n
 	---help---
@@ -265,6 +271,32 @@ config SYSLOG_FILE
 		NOTE interrupt level SYSLOG output will be lost in this case unless
 		the interrupt buffer is used.
 
+if SYSLOG_FILE
+
+config SYSLOG_FILE_ROTATE
+	bool "Log file rotate"
+	default n
+	depends on SYSLOG_FILE
+	---help---
+		If enabled, the log file size will be checked before opening.
+		If it is larger than the specified limit it will be "rotated",
+		i.e. the old file will be kept as a backup, and a new empty
+		file will be created.
+		
+		This option is useful to ensure that log files do not get
+		huge after prolonged periods of system operation.
+
+config SYSLOG_FILE_SIZE_LIMIT
+	int "Log file size limit"
+	default 524288
+	depends on SYSLOG_FILE_ROTATE
+	---help---
+		File size limit when the log is rotated automatically.
+		If a log file is found larger than this limit, it will
+		be rotated.
+
+endif # SYSLOG_FILE
+
 config CONSOLE_SYSLOG
 	bool "Use SYSLOG for /dev/console"
 	default n
diff --git a/drivers/syslog/syslog_filechannel.c b/drivers/syslog/syslog_filechannel.c
index 98e7e2f..94ae81d 100644
--- a/drivers/syslog/syslog_filechannel.c
+++ b/drivers/syslog/syslog_filechannel.c
@@ -25,9 +25,13 @@
 #include <nuttx/config.h>
 
 #include <sys/stat.h>
+#include <unistd.h>
 #include <sched.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
 
 #include <nuttx/syslog/syslog.h>
 
@@ -51,6 +55,62 @@
 FAR static struct syslog_channel_s *g_syslog_file_channel;
 
 /****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSLOG_FILE_ROTATE
+static void log_rotate(FAR const char *log_file)
+{
+  int fd;
+  off_t size;
+  struct stat f_stat;
+  char *backup_file;
+
+  /* Get the size of the current log file. */
+
+  fd = open(log_file, O_RDONLY);
+  if (fd < 0)
+    {
+      return;
+    }
+
+  fstat(fd, &f_stat);
+  size = f_stat.st_size;
+  close(fd);
+
+  /* If it does not exceed the limit we are OK. */
+
+  if (size < CONFIG_SYSLOG_FILE_SIZE_LIMIT)
+    {
+      return;
+    }
+
+  /* Construct the backup file name. */
+
+  backup_file = malloc(strlen(log_file) + 3);
+  if (backup_file == NULL)
+    {
+      return;
+    }
+
+  sprintf(backup_file, "%s.0", log_file);
+
+  /* Delete any old backup files. */
+
+  if (access(backup_file, F_OK) == 0)
+    {
+      remove(backup_file);
+    }
+
+  /* Rotate the log. */
+
+  rename(log_file, backup_file);
+
+  free(backup_file);
+}
+#endif
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -108,6 +168,12 @@ FAR struct syslog_channel_s *syslog_file_channel(FAR const char *devpath)
       syslog_dev_uninitialize(g_syslog_file_channel);
     }
 
+  /* Rotate the log file, if needed. */
+
+#ifdef CONFIG_SYSLOG_FILE_ROTATE
+  log_rotate(devpath);
+#endif
+
   /* Then initialize the file interface */
 
   g_syslog_file_channel = syslog_dev_initialize(devpath, OPEN_FLAGS,