tlog: update tlog
This commit is contained in:
57
src/tlog.c
57
src/tlog.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* tinylog
|
* tinylog
|
||||||
* Copyright (C) 2018-2020 Nick Peng <pymumu@gmail.com>
|
* Copyright (C) 2018-2019 Nick Peng <pymumu@gmail.com>
|
||||||
* https://github.com/pymumu/tinylog
|
* https://github.com/pymumu/tinylog
|
||||||
*/
|
*/
|
||||||
#ifndef _GNU_SOURCE
|
#ifndef _GNU_SOURCE
|
||||||
@@ -94,7 +94,7 @@ struct tlog {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct tlog_segment_log_head {
|
struct tlog_segment_log_head {
|
||||||
struct tlog_info info;
|
struct tlog_loginfo info;
|
||||||
unsigned short len;
|
unsigned short len;
|
||||||
char data[0];
|
char data[0];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
@@ -117,7 +117,7 @@ struct count_log {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct tlog_info_inter {
|
struct tlog_info_inter {
|
||||||
struct tlog_info info;
|
struct tlog_loginfo info;
|
||||||
void *userptr;
|
void *userptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,6 +167,10 @@ static int _tlog_mkdir(const char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(*path == ' ' && *path != '\0') {
|
||||||
|
path++;
|
||||||
|
}
|
||||||
|
|
||||||
strncpy(path_c, path, sizeof(path_c) - 1);
|
strncpy(path_c, path, sizeof(path_c) - 1);
|
||||||
path_c[sizeof(path_c) - 1] = '\0';
|
path_c[sizeof(path_c) - 1] = '\0';
|
||||||
len = strnlen(path_c, sizeof(path_c) - 1);
|
len = strnlen(path_c, sizeof(path_c) - 1);
|
||||||
@@ -181,6 +185,11 @@ static int _tlog_mkdir(const char *path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (path_end == path_c) {
|
||||||
|
path_end++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
str = *path_end;
|
str = *path_end;
|
||||||
*path_end = '\0';
|
*path_end = '\0';
|
||||||
if (access(path_c, F_OK) == 0) {
|
if (access(path_c, F_OK) == 0) {
|
||||||
@@ -203,8 +212,8 @@ static int _tlog_mkdir(const char *path)
|
|||||||
|
|
||||||
static struct tm *_tlog_localtime(time_t *timep, struct tm *tm)
|
static struct tm *_tlog_localtime(time_t *timep, struct tm *tm)
|
||||||
{
|
{
|
||||||
static time_t last_time = {0};
|
static time_t last_time;
|
||||||
static struct tm last_tm = {0};
|
static struct tm last_tm;
|
||||||
|
|
||||||
/* localtime_r has a global timezone lock, it's about 8 times slower than gmtime
|
/* localtime_r has a global timezone lock, it's about 8 times slower than gmtime
|
||||||
* this code is used to speed up localtime_r call.
|
* this code is used to speed up localtime_r call.
|
||||||
@@ -297,11 +306,14 @@ void *tlog_get_private(tlog_log *log)
|
|||||||
return log->private_data;
|
return log->private_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _tlog_format(char *buff, int maxlen, struct tlog_info *info, void *userptr, const char *format, va_list ap)
|
static int _tlog_format(char *buff, int maxlen, struct tlog_loginfo *info, void *userptr, const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int total_len = 0;
|
int total_len = 0;
|
||||||
struct tlog_time *tm = &info->time;
|
struct tlog_time *tm = &info->time;
|
||||||
|
void* unused __attribute__ ((unused));
|
||||||
|
|
||||||
|
unused = userptr;
|
||||||
|
|
||||||
if (tlog.root->multi_log) {
|
if (tlog.root->multi_log) {
|
||||||
/* format prefix */
|
/* format prefix */
|
||||||
@@ -388,6 +400,9 @@ static int _tlog_print_buffer(char *buff, int maxlen, void *userptr, const char
|
|||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int total_len = 0;
|
int total_len = 0;
|
||||||
|
void* unused __attribute__ ((unused));
|
||||||
|
|
||||||
|
unused = userptr;
|
||||||
|
|
||||||
/* format log message */
|
/* format log message */
|
||||||
len = vsnprintf(buff, maxlen, format, ap);
|
len = vsnprintf(buff, maxlen, format, ap);
|
||||||
@@ -550,8 +565,9 @@ int tlog_printf(struct tlog_log *log, const char *format, ...)
|
|||||||
static int _tlog_early_print(const char *format, va_list ap)
|
static int _tlog_early_print(const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
char log_buf[TLOG_MAX_LINE_LEN];
|
char log_buf[TLOG_MAX_LINE_LEN];
|
||||||
int len = 0;
|
size_t len = 0;
|
||||||
int out_len = 0;
|
size_t out_len = 0;
|
||||||
|
int unused __attribute__ ((unused));
|
||||||
|
|
||||||
if (tlog_disable_early_print) {
|
if (tlog_disable_early_print) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -565,9 +581,9 @@ static int _tlog_early_print(const char *format, va_list ap)
|
|||||||
out_len = sizeof(log_buf);
|
out_len = sizeof(log_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
write(STDOUT_FILENO, log_buf, out_len);
|
unused = write(STDOUT_FILENO, log_buf, out_len);
|
||||||
if (log_buf[out_len - 1] != '\n') {
|
if (log_buf[out_len - 1] != '\n') {
|
||||||
write(STDOUT_FILENO, "\n", 1);
|
unused = write(STDOUT_FILENO, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
@@ -650,6 +666,7 @@ static int _tlog_list_dir(const char *path, list_callback callback, void *userpt
|
|||||||
DIR *dir = NULL;
|
DIR *dir = NULL;
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
const char* unused __attribute__ ((unused)) = path;
|
||||||
|
|
||||||
dir = opendir(path);
|
dir = opendir(path);
|
||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
@@ -682,6 +699,7 @@ static int _tlog_count_log_callback(const char *path, struct dirent *entry, void
|
|||||||
struct count_log *count_log = (struct count_log *)userptr;
|
struct count_log *count_log = (struct count_log *)userptr;
|
||||||
struct tlog_log *log = count_log->log;
|
struct tlog_log *log = count_log->log;
|
||||||
char logname[TLOG_LOG_NAME_LEN * 2];
|
char logname[TLOG_LOG_NAME_LEN * 2];
|
||||||
|
const char* unused __attribute__ ((unused)) = path;
|
||||||
|
|
||||||
if (strstr(entry->d_name, log->suffix) == NULL) {
|
if (strstr(entry->d_name, log->suffix) == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1005,9 +1023,10 @@ static int _tlog_archive_log(struct tlog_log *log)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _tlog_write(struct tlog_log *log, char *buff, int bufflen)
|
static int _tlog_write(struct tlog_log *log, const char *buff, int bufflen)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
int unused __attribute__ ((unused));
|
||||||
|
|
||||||
if (bufflen <= 0) {
|
if (bufflen <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1015,7 +1034,7 @@ static int _tlog_write(struct tlog_log *log, char *buff, int bufflen)
|
|||||||
|
|
||||||
/* output log to screen */
|
/* output log to screen */
|
||||||
if (log->logscreen) {
|
if (log->logscreen) {
|
||||||
write(STDOUT_FILENO, buff, bufflen);
|
unused = write(STDOUT_FILENO, buff, bufflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if log file size exceeds threshold, start to compress */
|
/* if log file size exceeds threshold, start to compress */
|
||||||
@@ -1027,7 +1046,7 @@ static int _tlog_write(struct tlog_log *log, char *buff, int bufflen)
|
|||||||
if (log->filesize < lseek(log->fd, 0, SEEK_END) && log->multi_log == 0) {
|
if (log->filesize < lseek(log->fd, 0, SEEK_END) && log->multi_log == 0) {
|
||||||
const char *msg = "[Auto enable multi-process write mode, log may be lost, please enable multi-process write mode manually]\n";
|
const char *msg = "[Auto enable multi-process write mode, log may be lost, please enable multi-process write mode manually]\n";
|
||||||
log->multi_log = 1;
|
log->multi_log = 1;
|
||||||
write(log->fd, msg, strlen(msg));
|
unused = write(log->fd, msg, strlen(msg));
|
||||||
}
|
}
|
||||||
close(log->fd);
|
close(log->fd);
|
||||||
log->fd = -1;
|
log->fd = -1;
|
||||||
@@ -1083,7 +1102,7 @@ static int _tlog_write(struct tlog_log *log, char *buff, int bufflen)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tlog_write(struct tlog_log *log, char *buff, int bufflen)
|
int tlog_write(struct tlog_log *log, const char *buff, int bufflen)
|
||||||
{
|
{
|
||||||
return _tlog_write(log, buff, bufflen);
|
return _tlog_write(log, buff, bufflen);
|
||||||
}
|
}
|
||||||
@@ -1297,7 +1316,7 @@ static void _tlog_work_write(struct tlog_log *log, int log_len, int log_extlen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _tlog_root_write_log(struct tlog_log *log, char *buff, int bufflen)
|
static int _tlog_root_write_log(struct tlog_log *log, const char *buff, int bufflen)
|
||||||
{
|
{
|
||||||
struct tlog_segment_log_head *head = NULL;
|
struct tlog_segment_log_head *head = NULL;
|
||||||
static struct tlog_segment_log_head empty_info;
|
static struct tlog_segment_log_head empty_info;
|
||||||
@@ -1326,6 +1345,9 @@ static void *_tlog_work(void *arg)
|
|||||||
int log_dropped = 0;
|
int log_dropped = 0;
|
||||||
struct tlog_log *log = NULL;
|
struct tlog_log *log = NULL;
|
||||||
struct tlog_log *loop_log = NULL;
|
struct tlog_log *loop_log = NULL;
|
||||||
|
void* unused __attribute__ ((unused));
|
||||||
|
|
||||||
|
unused = arg;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
log_len = 0;
|
log_len = 0;
|
||||||
@@ -1491,6 +1513,11 @@ int tlog_setlevel(tlog_level level)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlog_level tlog_getlevel(void)
|
||||||
|
{
|
||||||
|
return tlog_set_level;
|
||||||
|
}
|
||||||
|
|
||||||
tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag)
|
tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag)
|
||||||
{
|
{
|
||||||
struct tlog_log *log = NULL;
|
struct tlog_log *log = NULL;
|
||||||
|
|||||||
83
src/tlog.h
83
src/tlog.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* tinylog
|
* tinylog
|
||||||
* Copyright (C) 2018-2020 Ruilin Peng (Nick) <pymumu@gmail.com>
|
* Copyright (C) 2018-2019 Ruilin Peng (Nick) <pymumu@gmail.com>
|
||||||
* https://github.com/pymumu/tinylog
|
* https://github.com/pymumu/tinylog
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -9,6 +9,11 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <functional>
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /*__cplusplus */
|
#endif /*__cplusplus */
|
||||||
|
|
||||||
@@ -55,7 +60,7 @@ struct tlog_time {
|
|||||||
/* enable log to screen */
|
/* enable log to screen */
|
||||||
#define TLOG_SCREEN (1 << 4)
|
#define TLOG_SCREEN (1 << 4)
|
||||||
|
|
||||||
struct tlog_info {
|
struct tlog_loginfo {
|
||||||
tlog_level level;
|
tlog_level level;
|
||||||
const char *file;
|
const char *file;
|
||||||
const char *func;
|
const char *func;
|
||||||
@@ -83,6 +88,9 @@ extern int tlog_write_log(char *buff, int bufflen);
|
|||||||
/* set log level */
|
/* set log level */
|
||||||
extern int tlog_setlevel(tlog_level level);
|
extern int tlog_setlevel(tlog_level level);
|
||||||
|
|
||||||
|
/* get log level */
|
||||||
|
extern tlog_level tlog_getlevel(void);
|
||||||
|
|
||||||
/* enalbe log to screen */
|
/* enalbe log to screen */
|
||||||
extern void tlog_setlogscreen(int enable);
|
extern void tlog_setlogscreen(int enable);
|
||||||
|
|
||||||
@@ -113,13 +121,13 @@ steps:
|
|||||||
|
|
||||||
read _tlog_format for example.
|
read _tlog_format for example.
|
||||||
*/
|
*/
|
||||||
typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_info *info, void *userptr, const char *format, va_list ap);
|
typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_loginfo *info, void *userptr, const char *format, va_list ap);
|
||||||
extern int tlog_reg_format_func(tlog_format_func func);
|
extern int tlog_reg_format_func(tlog_format_func func);
|
||||||
|
|
||||||
/* register log output callback
|
/* register log output callback
|
||||||
Note: info is invalid when flag TLOG_SEGMENT is not set.
|
Note: info is invalid when flag TLOG_SEGMENT is not set.
|
||||||
*/
|
*/
|
||||||
typedef int (*tlog_log_output_func)(struct tlog_info *info, char *buff, int bufflen, void *private_data);
|
typedef int (*tlog_log_output_func)(struct tlog_loginfo *info, const char *buff, int bufflen, void *private_data);
|
||||||
extern int tlog_reg_log_output_func(tlog_log_output_func output, void *private_data);
|
extern int tlog_reg_log_output_func(tlog_log_output_func output, void *private_data);
|
||||||
|
|
||||||
struct tlog_log;
|
struct tlog_log;
|
||||||
@@ -132,11 +140,11 @@ maxlogcount: Number of archived logs.
|
|||||||
buffsize: Buffer size, zero for default (128K)
|
buffsize: Buffer size, zero for default (128K)
|
||||||
flag: read tlog flags
|
flag: read tlog flags
|
||||||
return: log stream handler.
|
return: log stream handler.
|
||||||
*/
|
*/
|
||||||
extern tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag);
|
extern tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag);
|
||||||
|
|
||||||
/* write buff to log file */
|
/* write buff to log file */
|
||||||
extern int tlog_write(struct tlog_log *log, char *buff, int bufflen);
|
extern int tlog_write(struct tlog_log *log, const char *buff, int bufflen);
|
||||||
|
|
||||||
/* close log stream */
|
/* close log stream */
|
||||||
extern void tlog_close(tlog_log *log);
|
extern void tlog_close(tlog_log *log);
|
||||||
@@ -160,7 +168,7 @@ extern int tlog_vprintf(tlog_log *log, const char *format, va_list ap);
|
|||||||
extern void tlog_logscreen(tlog_log *log, int enable);
|
extern void tlog_logscreen(tlog_log *log, int enable);
|
||||||
|
|
||||||
/* register output callback */
|
/* register output callback */
|
||||||
typedef int (*tlog_output_func)(struct tlog_log *log, char *buff, int bufflen);
|
typedef int (*tlog_output_func)(struct tlog_log *log, const char *buff, int bufflen);
|
||||||
extern int tlog_reg_output_func(tlog_log *log, tlog_output_func output);
|
extern int tlog_reg_output_func(tlog_log *log, tlog_output_func output);
|
||||||
|
|
||||||
/* set private data */
|
/* set private data */
|
||||||
@@ -173,6 +181,63 @@ extern void *tlog_get_private(tlog_log *log);
|
|||||||
extern int tlog_localtime(struct tlog_time *tm);
|
extern int tlog_localtime(struct tlog_time *tm);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
class Tlog {
|
||||||
#endif /*__cplusplus */
|
using Stream = std::ostringstream;
|
||||||
|
using Buffer = std::unique_ptr<Stream, std::function<void(Stream*)>>;
|
||||||
|
public:
|
||||||
|
Tlog(){}
|
||||||
|
~Tlog(){}
|
||||||
|
|
||||||
|
static Tlog &Instance() {
|
||||||
|
static Tlog logger;
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer LogStream(tlog_level level, const char *file, int line, const char *func, void *userptr) {
|
||||||
|
return Buffer(new Stream, [=](Stream *st) {
|
||||||
|
tlog_ext(level, file, line, func, userptr, "%s", st->str().c_str());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TlogOut {
|
||||||
|
using Stream = std::ostringstream;
|
||||||
|
using Buffer = std::unique_ptr<Stream, std::function<void(Stream*)>>;
|
||||||
|
public:
|
||||||
|
TlogOut(){}
|
||||||
|
~TlogOut(){}
|
||||||
|
|
||||||
|
static TlogOut &Instance() {
|
||||||
|
static TlogOut logger;
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer Out(tlog_log *log) {
|
||||||
|
return Buffer(new Stream, [=](Stream *st) {
|
||||||
|
tlog_printf(log, "%s", st->str().c_str());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define Tlog_logger (Tlog::Instance())
|
||||||
|
#define Tlog_stream(level) if (tlog_getlevel() <= level) *Tlog_logger.LogStream(level, BASE_FILE_NAME, __LINE__, __func__, NULL)
|
||||||
|
#define tlog_debug Tlog_stream(TLOG_DEBUG)
|
||||||
|
#define tlog_info Tlog_stream(TLOG_INFO)
|
||||||
|
#define tlog_notice Tlog_stream(TLOG_NOTICE)
|
||||||
|
#define tlog_warn Tlog_stream(TLOG_WARN)
|
||||||
|
#define tlog_error Tlog_stream(TLOG_ERROR)
|
||||||
|
#define tlog_fatal Tlog_stream(TLOG_FATAL)
|
||||||
|
|
||||||
|
#define Tlog_out_logger (TlogOut::Instance())
|
||||||
|
#define tlog_out(stream) (*Tlog_out_logger.Out(stream))
|
||||||
|
|
||||||
|
} /*__cplusplus */
|
||||||
|
#else
|
||||||
|
#define tlog_debug(...) tlog(TLOG_DEBUG, ##__VA_ARGS__)
|
||||||
|
#define tlog_info(...) tlog(TLOG_INFO, ##__VA_ARGS__)
|
||||||
|
#define tlog_notice(...) tlog(TLOG_NOTICE, ##__VA_ARGS__)
|
||||||
|
#define tlog_warn(...) tlog(TLOG_WARN, ##__VA_ARGS__)
|
||||||
|
#define tlog_error(...) tlog(TLOG_ERROR, ##__VA_ARGS__)
|
||||||
|
#define tlog_fatal(...) tlog(TLOG_FATAL, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
#endif // !TLOG_H
|
#endif // !TLOG_H
|
||||||
|
|||||||
Reference in New Issue
Block a user