最近重新温习下c语言,在linux环境下写些小功能。
做一个小项目
项目的目标如下
1 输出时间和日期,任意指定的字符串,记录文件名,行数
2 支持输出各种级别的数据
3 默认输出数据到终端
4 支持输出日志到文件
对于初次写c项目的人来说的难度。
1 各种标准库
2 理解这种模式,手动的分配内存,释放内存
涉及到的…的替代方式
__VA_ARGS__
变长数据的读取
va_start(args,fmt);
size_t buf_len = vsnprintf(buffer,MAX_LOG_LEN, str_format,args);
va_end(args);
sprintf,snprintf,vsnprintf 真是个好东东啊
基本的结构
//定义基本的结构
typedef struct Klog{
const char* logpath;//存储地址
int fd;//文件句柄
ULONG flag;//存储位置
char splite_char[5];//分隔符
short is_show_line;//是否显示行+文件名,默认不显示
}KLogger;
//初始化和关闭
int logInit(const char *str_path,ULONG type);
int logClose();
//设置各种数据
int setLogerPath(const char *str_path);
ULONG getLogerFlag();
void setLogerSaveType(ULONG flag);
void addLogerSaveType(ULONG flag);
void removeLogerSaveType(ULONG flag);
//设置切分符号
void setSpliteData(const char *split);
//设置是否显示文件信息
void setShowFile(int is_show);
//获取路径
const char* getLogPath();
void klogMesg(int level, char *file,int line,const char *fmt, ...);
//可以显示
#define klogTrace(...) klogMesg(KLOG_TRACE,__FILE__,__LINE__,__VA_ARGS__);
#define klogDebug(...) klogMesg(KLOG_DEBUG,__FILE__,__LINE__,__VA_ARGS__);
#define klogInfo(...) klogMesg(KLOG_INFO,__FILE__,__LINE__,__VA_ARGS__);
#define klogWarning(...) klogMesg(KLOG_WARING,__FILE__,__LINE__,__VA_ARGS__);
#define klogError(...) klogMesg(KLOG_ERROR,__FILE__,__LINE__,__VA_ARGS__);
#define klogFatal(...) klogMesg(KLOG_FATAL,__FILE__,__LINE__,__VA_ARGS__);
主要的方法
//获取当前时间
char *getCurrentTime(){
struct tm *ptr;
int len = SHOW_TIME_LEN;
time_t tl;
char *buf = (char*)malloc(sizeof(char) * len);
tl = time(NULL);
ptr = localtime(&tl);
buf[strftime(buf, len , "%Y-%m-%d %H:%M:%S", ptr)]='\0';
return buf;
}
/**
处理日志:
1 输出时间,文件名,行数,你需要的信息
2 注意各个数据的切分
3 注意数据的长度
**/
void klogMesg(int level, char *file,int line,const char *fmt, ...){
char str_format[MAX_LOG_LEN];
char buffer[MAX_LOG_LEN];
va_list args;
memset(str_format, '\0', MAX_LOG_LEN);
memset(buffer, '\0', MAX_LOG_LEN);
char *atime = getCurrentTime();
//获取当前的需要格式化的字符串
if (KL.is_show_line == 1){
snprintf(str_format, MAX_LOG_LEN,"%s%s%s:%d%s%s%s%s",
KLONG_NAME[level],KL.splite_char,file,line,KL.splite_char,
atime,KL.splite_char,fmt);
}else{
snprintf(str_format, MAX_LOG_LEN,"%s%s%s%s%s\n",
KLONG_NAME[level],KL.splite_char,
atime,KL.splite_char,fmt);
}
//获取需要拼接的字符串
va_start(args,fmt);
size_t buf_len = vsnprintf(buffer,MAX_LOG_LEN, str_format,args);
va_end(args);
//拼接出需要的字符串,然后根据flag输出到对应的fd里面
if ((KL.flag & PUT_STD_OUT) == PUT_STD_OUT) {
printf("%s",buffer);
fflush(stdout);
}
if ((KL.flag & PUT_STD_ERR) == PUT_STD_ERR) {
printf("%s",buffer);
fflush(stderr);
}
if ((KL.flag & PUT_SYSLOG) == PUT_SYSLOG) {
syslog(level, buffer,"");
}
if ((KL.flag & PUT_SFILE) == PUT_SFILE) {
write(KL.fd, buffer, buf_len);
}
free(atime);
}
更多的功能:线程安全–未实现
1定义一个方法类型,在各种操作前调用下即可
typedef void (*LogLockFunc)(void *toLockStr, int status);