[Groonga-commit] groonga/groonga at bedc481 [master] Support log rotation by size

Back to archive index

Kouhei Sutou null+****@clear*****
Tue Mar 24 15:40:28 JST 2015


Kouhei Sutou	2015-03-24 15:40:28 +0900 (Tue, 24 Mar 2015)

  New Revision: bedc4813ac283ac44bbe43edec4580f40a9093d4
  https://github.com/groonga/groonga/commit/bedc4813ac283ac44bbe43edec4580f40a9093d4

  Message:
    Support log rotation by size
    
    It's disabled by default. You need to specify size threshold explicitly
    to enable this feature.
    
    API to specify size threshold isn't implemented yet. :p

  Modified files:
    lib/ctx.c
    lib/grn.h

  Modified: lib/ctx.c (+87 -14)
===================================================================
--- lib/ctx.c    2015-03-23 18:33:17 +0900 (dc88e5e)
+++ lib/ctx.c    2015-03-24 15:40:28 +0900 (70af1fc)
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <time.h>
+#include <sys/stat.h>
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif /* HAVE_NETINET_IN_H */
@@ -129,29 +130,38 @@ grn_time_now(grn_ctx *ctx, grn_obj *obj)
                                        GRN_TIME_NSEC_TO_USEC(tv.tv_nsec)));
 }
 
-grn_rc
-grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf)
+static struct tm *
+grn_timeval2tm(grn_ctx *ctx, grn_timeval *tv, struct tm *tm_buffer)
 {
   struct tm *ltm;
   const char *function_name;
 #ifdef HAVE__LOCALTIME64_S
-  struct tm tm;
   time_t t = tv->tv_sec;
   function_name = "localtime_s";
-  ltm = (localtime_s(&tm, &t) == 0) ? &tm : NULL;
+  ltm = (localtime_s(tm_buffer, &t) == 0) ? tm_buffer : NULL;
 #else /* HAVE__LOCALTIME64_S */
 # ifdef HAVE_LOCALTIME_R
-  struct tm tm;
   time_t t = tv->tv_sec;
   function_name = "localtime_r";
-  ltm = localtime_r(&t, &tm);
+  ltm = localtime_r(&t, tm_buffer);
 # else /* HAVE_LOCALTIME_R */
   time_t tvsec = (time_t) tv->tv_sec;
   function_name = "localtime";
   ltm = localtime(&tvsec);
 # endif /* HAVE_LOCALTIME_R */
 #endif /* HAVE__LOCALTIME64_S */
-  if (!ltm) { SERR(function_name); }
+  if (!ltm) {
+    SERR(function_name);
+  }
+  return ltm;
+}
+
+grn_rc
+grn_timeval2str(grn_ctx *ctx, grn_timeval *tv, char *buf)
+{
+  struct tm tm;
+  struct tm *ltm;
+  ltm = grn_timeval2tm(ctx, tv, &tm);
   snprintf(buf, GRN_TIMEVAL_STR_SIZE - 1, GRN_TIMEVAL_STR_FORMAT,
            ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday,
            ltm->tm_hour, ltm->tm_min, ltm->tm_sec,
@@ -756,9 +766,33 @@ grn_ctx_set_finalizer(grn_ctx *ctx, grn_proc_func *finalizer)
 
 grn_timeval grn_starttime;
 
+static void
+rotate_log_file(grn_ctx *ctx, const char *current_path)
+{
+  char rotated_path[PATH_MAX];
+  grn_timeval now;
+  struct tm tm_buffer;
+  struct tm *tm;
+
+  grn_timeval_now(ctx, &now);
+  tm = grn_timeval2tm(ctx, &now, &tm_buffer);
+  snprintf(rotated_path, PATH_MAX,
+           "%s.%04d-%02d-%02d-%02d-%02d-%02d-%06d",
+           current_path,
+           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+           tm->tm_hour, tm->tm_min, tm->tm_sec,
+           (int)(GRN_TIME_NSEC_TO_USEC(now.tv_nsec)));
+  rename(current_path, rotated_path);
+}
+
 static char *default_logger_path = NULL;
 static FILE *default_logger_file = NULL;
 static grn_critical_section default_logger_lock;
+static size_t default_logger_size = 0;
+static size_t default_logger_rotate_size_threshold = 0;
+
+#define LOGGER_NEED_ROTATE(size, threshold) \
+  ((threshold) > 0 && (size) >= (threshold))
 
 static void
 default_logger_log(grn_ctx *ctx, grn_log_level level,
@@ -770,16 +804,34 @@ default_logger_log(grn_ctx *ctx, grn_log_level level,
     CRITICAL_SECTION_ENTER(default_logger_lock);
     if (!default_logger_file) {
       default_logger_file = fopen(default_logger_path, "a");
+      default_logger_size = 0;
+      if (default_logger_file) {
+        struct stat stat;
+        if (fstat(fileno(default_logger_file), &stat) != -1) {
+          default_logger_size = stat.st_size;
+        }
+      }
     }
     if (default_logger_file) {
+      int written;
       if (location && *location) {
-        fprintf(default_logger_file, "%s|%c|%s %s %s\n",
-                timestamp, *(slev + level), title, message, location);
+        written = fprintf(default_logger_file, "%s|%c|%s %s %s\n",
+                          timestamp, *(slev + level), title, message, location);
       } else {
-        fprintf(default_logger_file, "%s|%c|%s %s\n", timestamp,
-                *(slev + level), title, message);
+        written = fprintf(default_logger_file, "%s|%c|%s %s\n", timestamp,
+                          *(slev + level), title, message);
+      }
+      if (written > 0) {
+        default_logger_size += written;
+        if (LOGGER_NEED_ROTATE(default_logger_size,
+                               default_logger_rotate_size_threshold)) {
+          fclose(default_logger_file);
+          default_logger_file = NULL;
+          rotate_log_file(ctx, default_logger_path);
+        } else {
+          fflush(default_logger_file);
+        }
       }
-      fflush(default_logger_file);
     }
     CRITICAL_SECTION_LEAVE(default_logger_lock);
   }
@@ -1005,6 +1057,8 @@ logger_fin(grn_ctx *ctx)
 static char *default_query_logger_path = NULL;
 static FILE *default_query_logger_file = NULL;
 static grn_critical_section default_query_logger_lock;
+static size_t default_query_logger_size = 0;
+static size_t default_query_logger_rotate_size_threshold = 0;
 
 static void
 default_query_logger_log(grn_ctx *ctx, unsigned int flag,
@@ -1015,10 +1069,29 @@ default_query_logger_log(grn_ctx *ctx, unsigned int flag,
     CRITICAL_SECTION_ENTER(default_query_logger_lock);
     if (!default_query_logger_file) {
       default_query_logger_file = fopen(default_query_logger_path, "a");
+      default_query_logger_size = 0;
+      if (default_query_logger_file) {
+        struct stat stat;
+        if (fstat(fileno(default_query_logger_file), &stat) != -1) {
+          default_query_logger_size = stat.st_size;
+        }
+      }
     }
     if (default_query_logger_file) {
-      fprintf(default_query_logger_file, "%s|%s%s\n", timestamp, info, message);
-      fflush(default_query_logger_file);
+      int written;
+      written = fprintf(default_query_logger_file, "%s|%s%s\n",
+                        timestamp, info, message);
+      if (written > 0) {
+        default_query_logger_size += written;
+        if (LOGGER_NEED_ROTATE(default_query_logger_size,
+                               default_query_logger_rotate_size_threshold)) {
+          fclose(default_query_logger_file);
+          default_query_logger_file = NULL;
+          rotate_log_file(ctx, default_query_logger_path);
+        } else {
+          fflush(default_query_logger_file);
+        }
+      }
     }
     CRITICAL_SECTION_LEAVE(default_query_logger_lock);
   }

  Modified: lib/grn.h (+1 -0)
===================================================================
--- lib/grn.h    2015-03-23 18:33:17 +0900 (c33ad7f)
+++ lib/grn.h    2015-03-24 15:40:28 +0900 (d15ef40)
@@ -128,6 +128,7 @@
 # define getpid() _getpid()
 # if !defined(__GNUC__) && _MSC_VER < 1400
 #  define fstat(fd, buf) _fstat(fd, buf)
+#  define fileno(file) _fileno(file)
 # endif /* !defined(__GNUC__) && _MSC_VER < 1400 */
 # ifdef HAVE__STRICMP
 #  ifdef strcasecmp
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index