diff --git a/src/libckpool.c b/src/libckpool.c index aa7047ed..ca679931 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -840,6 +840,43 @@ json_t *json_object_dup(json_t *val, const char *entry) return json_copy(json_object_get(val, entry)); } +/* Creates a logfile entry which changes filename hourly with exclusive access */ +bool rotating_log(const char *path, const char *msg) +{ + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + char *filename; + struct tm *tm; + time_t now; + FILE *fp; + int fd; + + now = time(NULL); + tm = localtime(&now); + ASPRINTF(&filename, "%s%04d%02d%02d%02d.log", path, tm->tm_year + 1900, tm->tm_mon + 1, + tm->tm_mday, tm->tm_hour); + fd = open(filename, O_CREAT|O_RDWR, mode); + if (unlikely(fd == -1)) { + LOGERR("Failed to open %s in rotating_log!", filename); + return false; + } + fp = fdopen(fd, "a"); + if (unlikely(!fp)) { + close(fd); + LOGERR("Failed to fopen %s in rotating_log!", filename); + return false; + } + if (unlikely(flock(fd, LOCK_EX))) { + fclose(fp); + close(fd); + LOGERR("Failed to flock %s in rotating_log!", filename); + return false; + } + fprintf(fp, "%s\n", msg); + fclose(fp); + close(fd); + + return true; +} /* Align a size_t to 4 byte boundaries for fussy arches */ void align_len(size_t *len) diff --git a/src/libckpool.h b/src/libckpool.h index caa6274a..7ae0650b 100644 --- a/src/libckpool.h +++ b/src/libckpool.h @@ -397,6 +397,8 @@ const char *__json_array_string(json_t *val, unsigned int entry); char *json_array_string(json_t *val, unsigned int entry); json_t *json_object_dup(json_t *val, const char *entry); +bool rotating_log(const char *path, const char *msg); + void align_len(size_t *len); void realloc_strcat(char **ptr, const char *s); void trail_slash(char **buf);