为了方便已将本文所有代码放到 GitHub 上
int main(int argc, char *argv[]){
char *device = NULL;
if (argc!=2)
device = "/dev/stdout";
else
device = argv[1];
Logging_t logging = Logging(device, INFO);
logging.verbose(&logging, "%s test println", "Joseph");
logging.debug(&logging, "%s@%d: this should on new line", __FUNCTION__, __LINE__);
logging.info(&logging, "i am info message");
logging.warning(&logging, "something uncommon hanppenning you should know.");
logging.error(&logging, "something error.");
logging.critical(&logging, "thereis critical, deal with it right now.\n");
logging = Logging(device, DEBUG);
logging.verbose(&logging, "%s test println", "Joseph");
logging.debug(&logging, "%s@%d: this should on new line", __FUNCTION__, __LINE__);
logging.info(&logging, "i am info message");
logging.warning(&logging, "something uncommon hanppenning you should know.");
logging.error(&logging, "something error.");
logging.critical(&logging, "thereis critical, deal with it right now.\n");
logging = Logging(device, VERBOSE);
logging.verbose(&logging, "%s test println", "Joseph");
logging.debug(&logging, "%s@%d: this should on new line", __FUNCTION__, __LINE__);
logging.info(&logging, "i am info message");
logging.warning(&logging, "something uncommon hanppenning you should know.");
logging.error(&logging, "something error.");
logging.critical(&logging, "thereis critical, deal with it right now.\n");
logging = Logging(device, ERROR);
logging.verbose(&logging, "%s test println", "Joseph");
logging.debug(&logging, "%s@%d: this should on new line", __FUNCTION__, __LINE__);
logging.info(&logging, "i am info message");
logging.warning(&logging, "something uncommon hanppenning you should know.");
logging.error(&logging, "something error.");
logging.critical(&logging, "thereis critical, deal with it right now.\n");
return 0;
}
输出:
$ gcc main.c && ./a.out
[INFO ] <2019-06-04 09:37:55>: i am info message
[WARNING ] <2019-06-04 09:37:55>: something uncommon hanppenning you should know.
[ERROR ] <2019-06-04 09:37:55>: something error.
[CRITICAL] <2019-06-04 09:37:55>: thereis critical, deal with it right now.
[DEBUG ] <2019-06-04 09:37:55>: main@206: this should on new line
[INFO ] <2019-06-04 09:37:55>: i am info message
[WARNING ] <2019-06-04 09:37:55>: something uncommon hanppenning you should know.
[ERROR ] <2019-06-04 09:37:55>: something error.
[CRITICAL] <2019-06-04 09:37:55>: thereis critical, deal with it right now.
[VERBOSE ] <2019-06-04 09:37:55>: Joseph test println
[DEBUG ] <2019-06-04 09:37:55>: main@214: this should on new line
[INFO ] <2019-06-04 09:37:55>: i am info message
[WARNING ] <2019-06-04 09:37:55>: something uncommon hanppenning you should know.
[ERROR ] <2019-06-04 09:37:55>: something error.
[CRITICAL] <2019-06-04 09:37:55>: thereis critical, deal with it right now.
[ERROR ] <2019-06-04 09:37:55>: something error.
[CRITICAL] <2019-06-04 09:37:55>: thereis critical, deal with it right now.
#include
#include
#include
#include
#include
#include
void common_println(char *device, char *msg){
FILE *fp;
if((fp=fopen(device, "w"))==NULL){
printf("open %s failed", device);
fclose(fp);
}
else {
fprintf(fp, "%s\n", msg);
fclose(fp); fp = NULL;
}
}
typedef enum LoggingLevel {
VERBOSE=0, DEBUG, INFO, WARNING, ERROR, CRITICAL, Invalid
} LoggingLevel_t;
typedef struct Logging_s {
char *device;
LoggingLevel_t level;
void (*verbose)(struct Logging_s *me, const char*, ...);
void (*debug)(struct Logging_s *me, const char*, ...);
void (*info)(struct Logging_s *me, const char*, ...);
void (*warning)(struct Logging_s *me, const char*, ...);
void (*error)(struct Logging_s *me, const char*, ...);
void (*critical)(struct Logging_s *me, const char*, ...);
} Logging_t;
Logging_t Logging(char *device, LoggingLevel_t level);
void logging_verbose_println(struct Logging_s *me, const char *fmt, ...);
void logging_debug_println(struct Logging_s *me, const char *fmt, ...);
void logging_info_println(struct Logging_s *me, const char *fmt, ...);
void logging_warning_println(struct Logging_s *me, const char *fmt, ...);
void logging_error_println(struct Logging_s *me, const char *fmt, ...);
void logging_critical_println(struct Logging_s *me, const char *fmt, ...);
char *LEVEL_MSG[] = {"VERBOSE", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"};
short get_log_head(
char buf[128], struct Logging_s *conf, LoggingLevel_t call_level
){
if (conf->level > call_level)
return 0;
char *level_msg = LEVEL_MSG[call_level];
time_t timep;
time(&timep);
char datetime_str[80] = {'\0'};
struct tm sttime;
tzset();
sttime = *gmtime(&timep);
strftime(datetime_str, sizeof(datetime_str), "%Y-%m-%d %H:%M:%S", &sttime);
return snprintf(buf, 127, "[%-8s] <%s>: ", level_msg, datetime_str);
}
void logging_verbose_println(struct Logging_s *me, const char *fmt, ...){
const LoggingLevel_t FUNC_LOG_LEVEL = VERBOSE;
char logging_msg[512] = {'\0'};
if (get_log_head(logging_msg, me, FUNC_LOG_LEVEL) > 0){
va_list ap;
va_start(ap, fmt);
char buf[350] = {'\0'};
int len = vsprintf(buf, fmt, ap);
va_end(ap);
strcat(logging_msg, buf);
common_println(me->device, logging_msg);
}
else
return;
}
void logging_debug_println(struct Logging_s *me, const char *fmt, ...){
const LoggingLevel_t FUNC_LOG_LEVEL = DEBUG;
char logging_msg[512] = {'\0'};
if (get_log_head(logging_msg, me, FUNC_LOG_LEVEL) > 0){
va_list ap;
va_start(ap, fmt);
char buf[350] = {'\0'};
int len = vsprintf(buf, fmt, ap);
va_end(ap);
strcat(logging_msg, buf);
common_println(me->device, logging_msg);
}
else
return;
}
void logging_info_println(struct Logging_s *me, const char *fmt, ...){
const LoggingLevel_t FUNC_LOG_LEVEL = INFO;
char logging_msg[512] = {'\0'};
if (get_log_head(logging_msg, me, FUNC_LOG_LEVEL) > 0){
...同上...
}
else
return;
}
void logging_warning_println(struct Logging_s *me, const char *fmt, ...){
const LoggingLevel_t FUNC_LOG_LEVEL = WARNING;
char logging_msg[512] = {'\0'};
if (get_log_head(logging_msg, me, FUNC_LOG_LEVEL) > 0){
...同上...
}
else
return;
}
void logging_error_println(struct Logging_s *me, const char *fmt, ...){
const LoggingLevel_t FUNC_LOG_LEVEL = ERROR;
char logging_msg[512] = {'\0'};
if (get_log_head(logging_msg, me, FUNC_LOG_LEVEL) > 0){
...同上...
}
else
return;
}
void logging_critical_println(struct Logging_s *me, const char *fmt, ...){
const LoggingLevel_t FUNC_LOG_LEVEL = CRITICAL;
char logging_msg[512] = {'\0'};
if (get_log_head(logging_msg, me, FUNC_LOG_LEVEL) > 0){
...同上...
}
else
return;
}
Logging_t Logging(char *device, LoggingLevel_t level){
Logging_t logging = {
.device = device,
.level = level,
.verbose = logging_verbose_println,
.debug = logging_debug_println,
.info = logging_info_println,
.warning = logging_warning_println,
.error = logging_error_println,
.critical = logging_critical_println,
};
return logging;
}
n/a