63#include "utilities/qstring.h"
64#include "extensions/qlog.h"
67static bool write_(qlog_t *log,
const char *str);
68static bool writef(qlog_t *log,
const char *format, ...);
69static bool duplicate(qlog_t *log, FILE *outfp,
bool flush);
70static bool flush_(qlog_t *log);
71static void free_(qlog_t *log);
74static bool _real_open(qlog_t *log);
105qlog_t *
qlog(
const char *filepathfmt, mode_t mode,
int rotateinterval,
110 log = (qlog_t *) calloc(1,
sizeof(qlog_t));
117 qstrcpy(log->filepathfmt,
sizeof(log->filepathfmt), filepathfmt);
119 if (rotateinterval > 0)
120 log->rotateinterval = rotateinterval;
123 if (options & QLOG_OPT_THREADSAFE) {
124 Q_MUTEX_NEW(log->qmutex,
true);
125 if (log->qmutex == NULL) {
131 if (options & QLOG_OPT_FLUSH) {
132 log->logflush =
true;
136 if (_real_open(log) ==
false) {
137 Q_MUTEX_DESTROY(log->qmutex);
160static bool write_(qlog_t *log,
const char *str) {
161 if (log == NULL || log->fp == NULL)
164 Q_MUTEX_ENTER(log->qmutex);
167 if (log->outfp != NULL) {
168 fprintf(log->outfp,
"%s\n", str);
169 if (log->outflush ==
true)
174 if (log->nextrotate > 0 && time(NULL) >= log->nextrotate) {
180 if (fprintf(log->fp,
"%s\n", str) >= 0) {
181 if (log->logflush ==
true)
186 Q_MUTEX_LEAVE(log->qmutex);
199static bool writef(qlog_t *log,
const char *format, ...) {
200 if (log == NULL || log->fp == NULL)
204 DYNAMIC_VSPRINTF(str, format);
208 bool ret =
write_(log, str);
230static bool duplicate(qlog_t *log, FILE *outfp,
bool flush) {
234 Q_MUTEX_ENTER(log->qmutex);
236 log->outflush = flush;
237 Q_MUTEX_LEAVE(log->qmutex);
254 Q_MUTEX_ENTER(log->qmutex);
255 if (log->fp != NULL && log->logflush ==
false)
257 if (log->outfp != NULL && log->outflush ==
false)
259 Q_MUTEX_LEAVE(log->qmutex);
274 Q_MUTEX_ENTER(log->qmutex);
275 if (log->fp != NULL) {
279 Q_MUTEX_LEAVE(log->qmutex);
280 Q_MUTEX_DESTROY(log->qmutex);
287static bool _real_open(qlog_t *log) {
288 const time_t nowtime = time(NULL);
291 char newfilepath[PATH_MAX];
292 strftime(newfilepath,
sizeof(newfilepath), log->filepathfmt,
293 localtime(&nowtime));
296 if (log->fp == NULL) {
297 log->fp = fopen(newfilepath,
"a");
298 if (log->fp == NULL) {
299 DEBUG(
"_real_open: Can't open log file '%s'.", newfilepath);
304 fchmod(fileno(log->fp), log->mode);
305 qstrcpy(log->filepath,
sizeof(log->filepath), newfilepath);
306 }
else if (strcmp(log->filepath, newfilepath)) {
309 FILE *newfp = fopen(newfilepath,
"a");
312 fchmod(fileno(newfp), log->mode);
315 qstrcpy(log->filepath,
sizeof(log->filepath), newfilepath);
317 DEBUG(
"_real_open: Can't open log file '%s' for rotating.",
321 DEBUG(
"_real_open: skip re-opening log file.");
325 if (log->rotateinterval > 0) {
326 time_t ct = time(NULL);
327 time_t dt = ct - mktime(gmtime(&ct));
328 log->nextrotate = (((ct + dt) / log->rotateinterval) + 1)
329 * log->rotateinterval - dt;
static bool writef(qlog_t *log, const char *format,...)
qlog->writef(): Log messages
static bool write_(qlog_t *log, const char *str)
qlog->write(): Log messages
static bool duplicate(qlog_t *log, FILE *outfp, bool flush)
qlog->duplicate(): Duplicate log string into other stream
static void free_(qlog_t *log)
qlog->free(): Close ratating-log file & de-allocate resources
static bool flush_(qlog_t *log)
qlog->flush(): Flush buffered log
qlog_t * qlog(const char *filepathfmt, mode_t mode, int rotateinterval, int options)
Open ratating-log file.
char * qstrcpy(char *dst, size_t size, const char *src)
Copy src string to dst.