linux下c语言简单实现写日志函数(多线程安全)
Posted Hero_HL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下c语言简单实现写日志函数(多线程安全)相关的知识,希望对你有一定的参考价值。
调用时包含hhl_log.h文件后使用宏替代函数进行写入日志操作
// eg:
FATAL("a:%d b:%s", a, b);
ALERT("a:%d b:%s", a, b);
CRITICAL("a:%d b:%s", a, b);
ERROR("a:%d b:%s", a, b);
WARNING("a:%d b:%s", a, b);
NOTICE("a:%d b:%s", a, b);
INFO("a:%d b:%s", a, b);
DEBUG("a:%d b:%s", a, b);
//CheckErrorReturn等价为
//if( (a == 1) )
//
// ERROR("a is 1, return 0 msg:%s\\n", msg);
// return 0;
//
CheckErrorReturn(a == 1, 0, "a is 1, return 0 msg:%s\\n", msg);
write_log.h
#ifndef __WRITE_LOG_H__
#define __WRITE_LOG_H__
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <time.h>
#include <pthread.h>
#include <sys/syscall.h>//Linux system call for thread id
/* exps is true, return ret */
#define CheckErrorReturn(exps, ret, msg, ...) \\
do \\
\\
if ((exps)) \\
\\
ERROR(msg, ##__VA_ARGS__); \\
return (ret); \\
\\
\\
while(0) \\
/* exps is true, return */
#define CheckErrorReturnVoid(exps, msg, ...) \\
do \\
\\
if ((exps)) \\
\\
ERROR(msg, ##__VA_ARGS__); \\
return ; \\
\\
\\
while(0) \\
/* exps is true, goto label */
#define CheckErrorGoto(exps, label, msg, ...) \\
do \\
\\
if ((exps)) \\
\\
ERROR(msg, ##__VA_ARGS__); \\
goto label; \\
\\
\\
while(0) \\
/* system is unusable */
#define FATAL(msg, ...) PrintLog("Fatal", msg, ##__VA_ARGS__)
/* action must be taken immediately */
#define ALERT(msg, ...) PrintLog("Alert", msg, ##__VA_ARGS__)
/* critical conditions */
#define CRITICAL(msg, ...) PrintLog("Critical", msg, ##__VA_ARGS__)
/* error conditions */
#define ERROR(msg, ...) PrintLog("Error", msg, ##__VA_ARGS__)
/* warning conditions */
#define WARNING(msg, ...) PrintLog("Warning", msg, ##__VA_ARGS__)
/* normal but significant condition */
#define NOTICE(msg, ...) PrintLog("Notice", msg, ##__VA_ARGS__)
/* informational */
#define INFO(msg, ...) PrintLog("Info", msg, ##__VA_ARGS__)
/* debug-level messages */
#define DEBUG(msg, ...) PrintLog("Debug", msg, ##__VA_ARGS__)
#define PrintLog(level_str, msg, ...) \\
do \\
printf("[%s][%s][%s][%d] "msg, level_str, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); \\
write_log("[%s][%s][%s][%d] "msg, level_str, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); \\
while (0)
void write_log(const char* format, ...);
#endif
write_log.c
// log.cpp: 定义应用程序的入口点。
//
#include "write_log.h"
static pthread_mutex_t fileMutex = PTHREAD_MUTEX_INITIALIZER;
int safe_check_vasprintf(char** strp, const char* fmt, va_list ap)
int retval;
retval = vasprintf(strp, fmt, ap);
if (retval == -1)
printf("Failed to vasprintf: %s. Bailing out\\n", strerror(errno));
return 1;
return retval;
int safe_asprintf(char** strp, const char* fmt, ...)
va_list ap;
int retval;
va_start(ap, fmt);
retval = safe_check_vasprintf(strp, fmt, ap);
va_end(ap);
return retval;
void write_log(const char* format, ...)
pthread_mutex_lock(&fileMutex);
FILE* fp = NULL;
va_list vlist;
char* fmt = NULL;
// Open debug info output file.
if (!(fp = fopen("log.txt", "a+")))
pthread_mutex_unlock(&fileMutex);
return;
va_start(vlist, format);
safe_check_vasprintf(&fmt, format, vlist);
va_end(vlist);
if (!fmt)
pthread_mutex_unlock(&fileMutex);
return;
time_t timep;
struct tm* ptm = NULL;
time(&timep);
ptm = localtime(&timep);
fprintf(fp, "[%04d-%02d-%02d-%02d:%02d:%02d][pid:%ld]%s",
ptm->tm_year + 1900,
ptm->tm_mon + 1,
ptm->tm_mday,
ptm->tm_hour,
ptm->tm_min,
ptm->tm_sec,
syscall(SYS_gettid),
fmt);
free(fmt);
fsync(fileno(fp));
fclose(fp);
pthread_mutex_unlock(&fileMutex);
以上是关于linux下c语言简单实现写日志函数(多线程安全)的主要内容,如果未能解决你的问题,请参考以下文章
windows环境下c语言支持ftp和http多线程下载的客户端