C语言编程日志,用C语言打印日志(Log)

用C语言打印日志(Log)

直接上源代码。

log.h 文件:

/** log.h **/

#ifndef __LOG_H__

#define __LOG_H__

#include "stdio.h"

#include "string.h"

#include "stdlib.h"

#include "time.h"

#include "stdarg.h"

#include "unistd.h"

#define MAXLEN (2048)

#define MAXFILEPATH (512)

#define MAXFILENAME (50)

typedef enum{

ERROR_1=-1,

ERROR_2=-2,

ERROR_3=-3

}ERROR0;

typedef enum{

NONE=0,

INFO=1,

DEBUG=2,

WARN=3,

ERROR=4,

ALL=255

}LOGLEVEL;

typedef struct log{

char logtime[20];

char filepath[MAXFILEPATH];

FILE *logfile;

}LOG;

typedef struct logseting{

char filepath[MAXFILEPATH];

unsigned int maxfilelen;

unsigned char loglevel;

}LOGSET;

int LogWrite(unsigned char loglevel,char *fromat,...);

#endif /* __LOG_H__ */

log.c 文件:

/** log.c **/

#include "log.h"

#define MAXLEVELNUM (3)

LOGSET logsetting;

LOG loging;

const static char LogLevelText[4][10]={"INFO","DEBUG","WARN","ERROR"};

static char * getdate(char *date);

static unsigned char getcode(char *path){

unsigned char code=255;

if(strcmp("INFO",path)==0)

code=1;

else if(strcmp("WARN",path)==0)

code=3;

else if(strcmp("ERROR",path)==0)

code=4;

else if(strcmp("NONE",path)==0)

code=0;

else if(strcmp("DEBUG",path)==0)

code=2;

return code;

}

static unsigned char ReadConfig(char *path){

char value[512]={0x0};

char data[50]={0x0};

FILE *fpath=fopen(path,"r");

if(fpath==NULL)

return -1;

fscanf(fpath,"path=%s\n",value);

getdate(data);

strcat(data,".log");

strcat(value,"/");

strcat(value,data);

if(strcmp(value,logsetting.filepath)!=0)

memcpy(logsetting.filepath,value,strlen(value));

memset(value,0,sizeof(value));

fscanf(fpath,"level=%s\n",value);

logsetting.loglevel=getcode(value);

fclose(fpath);

return 0;

}

/*

*日志设置信息

* */

static LOGSET *getlogset(){

char path[512]={0x0};

getcwd(path,sizeof(path));

strcat(path,"/log.conf");

if(access(path,F_OK)==0){

if(ReadConfig(path)!=0){

logsetting.loglevel=INFO;

logsetting.maxfilelen=4096;

}

}else{

logsetting.loglevel=INFO;

logsetting.maxfilelen=4096;

}

return &logsetting;

}

/*

*获取日期

* */

static char * getdate(char *date){

time_t timer=time(NULL);

strftime(date,11,"%Y-%m-%d",localtime(&timer));

return date;

}

/*

*获取时间

* */

static void settime(){

time_t timer=time(NULL);

strftime(loging.logtime,20,"%Y-%m-%d %H:%M:%S",localtime(&timer));

}

/*

*不定参打印

* */

static void PrintfLog(char * fromat,va_list args){

int d;

char c,*s;

while(*fromat)

{

switch(*fromat){

case 's':{

s = va_arg(args, char *);

fprintf(loging.logfile,"%s",s);

break;}

case 'd':{

d = va_arg(args, int);

fprintf(loging.logfile,"%d",d);

break;}

case 'c':{

c = (char)va_arg(args, int);

fprintf(loging.logfile,"%c",c);

break;}

default:{

if(*fromat!='%'&&*fromat!='\n')

fprintf(loging.logfile,"%c",*fromat);

break;}

}

fromat++;

}

fprintf(loging.logfile,"%s","]\n");

}

static int initlog(unsigned char loglevel){

char strdate[30]={0x0};

LOGSET *logsetting;

//获取日志配置信息

if((logsetting=getlogset())==NULL){

perror("Get Log Set Fail!");

return -1;

}

if((loglevel&(logsetting->loglevel))!=loglevel)

return -1;

memset(&loging,0,sizeof(LOG));

//获取日志时间

settime();

if(strlen(logsetting->filepath)==0){

char *path=getenv("HOME");

memcpy(logsetting->filepath,path,strlen(path));

getdate(strdate);

strcat(strdate,".log");

strcat(logsetting->filepath,"/");

strcat(logsetting->filepath,strdate);

}

memcpy(loging.filepath,logsetting->filepath,MAXFILEPATH);

//打开日志文件

if(loging.logfile==NULL)

loging.logfile=fopen(loging.filepath,"a+");

if(loging.logfile==NULL){

perror("Open Log File Fail!");

return -1;

}

//写入日志级别,日志时间

fprintf(loging.logfile,"[%s] [%s]:[",LogLevelText[loglevel-1],loging.logtime);

return 0;

}

/*

*日志写入

* */

int LogWrite(unsigned char loglevel,char *fromat,...){

va_list args;

//初始化日志

if(initlog(loglevel)!=0)

return -1;

//打印日志信息

va_start(args,fromat);

PrintfLog(fromat,args);

va_end(args);

//文件刷出

fflush(loging.logfile);

//日志关闭

if(loging.logfile!=NULL)

fclose(loging.logfile);

loging.logfile=NULL;

return 0;

}

test.c 文件:

/** test.c **/

#include "stdio.h"

#include "stdlib.h"

#include "log.h"

int main(int argv,char**argc){

printf("%s\n",argc[0]);

LogWrite(INFO,"%s","Hello World!");

LogWrite(DEBUG,"%s","H.e.l.l.o W.o.r.l.d!");

LogWrite(WARN,"%s","H e l l o W o r l d!");

LogWrite(ERROR,"%s","Hallo World!");

return 0;

}

log.conf 文件:

path=./temp

level=ALL

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502762.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

binlog数据库不写入binlog_京东智联云MySQL数据库如何保障数据的可靠性?

MySQL作为当前最流行的关系型数据库,在各个行业的系统中扮演着最重要的角色。随着大家对数据价值认可的逐步加深,数据的可靠性是最常被问到的一个问题。MySQL是如何保证数据可靠性的?京东智联云RDS-MySQL又做了哪些优化和新特性来保证用户数据…

在职高学C语言程序设计,中职学校C语言程序设计教学方法.doc

中职学校C语言程序设计教学方法中职学校C语言程序设计的教学方法摘 要:计算机专业中,C语言是一门基础的程序设计课,但学习《C语言程序设计》相对职高学生来说难度较大,但它却是很实用的一门课程,同时又是我省计算机对口…

js和python哪个好_Python与Node.JS:哪一个比较适合您的项目?

在进行新项目时选择正确的编程语言可能是程序员经常做出的比较艰巨的决定之一。这个挑战背后的原因是,每个新项目都会遇到一个独特的问题,并且在编程世界中,没有任何行业的大师。 不同的编程语言都有其长处和短处,这使其适用于某些…

typescript的类型描述_一文学懂TypeScript的类型

你将学到什么阅读本文后,你应该能够理解以下代码的含义:interface Array{concat(...items: Array): T[];reduce(callback: (state: U, element: T, index: number, array: T[]) >U,firstState?: U): U;}如果你认为这段代码非常神秘 —— 那么我同意你…

equation在c语言中是什么意思,MathType出现此对象创建于Equation中的问题怎么办

使用MathType出错的窗口:MathType程序停止工作提醒窗口:解决方法如下:1.打开Word文件,在Word菜单中选择“工具”——“模板和加载项”,将会跳出一个模板和加载项的对话框。在Word菜单中选择“工具”——“模板和加载项…

python messagebox弹窗退出_python 弹窗提示警告框MessageBox的实例

需要安装pywin32模块,pip install pywin32 ##pip install pywin32 import win32api,win32con ##提醒OK消息框 win32api.MessageBox(0, "这是一个测试提醒OK消息框", "提醒",win32con.MB_OK) ##是否信息框 win32api.MessageBox(0, "这是一个…

gradle是否可以编译c语言,build.gradle按条件编译与cmake配置

在build.gradle里面通过productFlavors就可以方便的实现不同的编译方案。flavorDimensions定义维度flavorDimensions 从单词字面理解知道是 “风味维度”,是需要结合 “产品风味(即productFlavors)” 来一起使用的。flavorDimensions 的使用会定义出维度&#xff0c…

post请求改成body_post请求body格式

在PostMan中用Post方式,Body有form-data,x-www-form-urlencoded,raw,binary四种。其中raw又分以下7种。现在来区分一下:form-data是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。…

windows多用户 文件夹不共享_手把手教你如何使用Tekla多用户

Tekla有多用户模式,对于大模型需要多人合作很有用,可以多人同时建模互不干扰,下面简单说下多用户建立过程。 首先需要参与模型的计算机处于同一局域网内,一般来说公司都有局域网,或者办公室内就是一个小局域网&#xf…

roads 用户体验标准_世界智能大会与ROAD用户体验报告

近期由国家发展和改革委员会、科学技术部、工业和信息化部、国家互联网信息办公室等共同举办的2020年第四届世界智能大会在天津云上展开,超过百余位智能科技领域的知名专家和企业家参与了大会过程,其中车联网领域专家关于5G车联网”推进中国特色的车路协…

android 组件路由框架,XRouter:组件化路由框架

添加jitpack仓库allprojects {repositories {...maven { url https://jitpack.io }}}添加依赖:dependencies {//kotlin 使用kapt编译时依赖注解,Java使用annotationProcessorkapt com.github.roger1245.XRouter:xrouter-compiler:1.0.2api com.github.ro…

hystrix原理_面试必问的SpringCloud实现原理图

引言面试中面试官喜欢问组件的实现原理,尤其是常用技术,我们平时使用了SpringCloud还需要了解它的实现原理,这样不仅起到举一反三的作用,还能帮助轻松应对各种问题及有针对的进行扩展。以下是《Java深入微服务原理改造房产销售平台…

android 图片跑马灯动画,ImageView 图片循环跑马灯的效果

不解释了 直接上代码了main.xml布局文件,记住必须用RelativeLayout将ImageView重叠android:orientation"vertical" android:layout_width"fill_parent"android:layout_height"fill_parent" android:id"id/rl">android:…

Rust Trait

Rust 第16节 Trait Trait 告诉编译器 某种类型具有那些并且可以与其他类型共享的功能 它的本质就是 不同类型具有的相同行为 声明一个trait 关键字 trait;只有方法签名,没有方法实现 pub trait Animal {// trait 的声明,一个trait中可以有多个方法fn say(&s…

c++ string类的常用方法_【常用类方法】Object

Object类的知识点总结概述:1. Object类是所有其他类的父类2. Object类只有一个构造方法,这也是为什么所有子类在调用构造方法时都会默认先调用父类的无参构造方法3. Object类没有成员变量方法:1. public int hashCode()2. public final Class…

android 收获地址管理,android UiAutomator添加收货地址的用例

本人在学习UiAutomator的时候,遇到添加收获地址的测试用例,这里的地址的地区是一级一级选择的。所以写了一个随机选择的方法。分享出来,供大家参考。public void addAdress() throws UiObjectNotFoundException {login();waitForResourceIdAn…

python注释以符号什么开始_python注释以什么符号开始

python注释以什么符号开始,注释,中文,代码,批量,符号 python注释以什么符号开始 易采站长站,站长之家为您整理了python注释以什么符号开始的相关内容。 python中的注释有多种,有单行注释,多行注释,批量注释,中文注释也…

verilog 移位运算符 说明_Verilog学习笔记基本语法篇(二)·········运算符...

Verilog HDL的语言的运算符的范围很广&#xff0c;按照其功能大概可以分为以下几类:(1)算术运算符&#xff0c;-&#xff0c;*&#xff0c;/&#xff0c;%优先顺序&#xff01;~* / % -<< >>< < > > ! !&^ ^~|&&||&…

linux 别名,Linux中的别名就这么简单,如何使用和创建永久别名?

原标题&#xff1a;Linux中的别名就这么简单&#xff0c;如何使用和创建永久别名&#xff1f;输入文本和记命令是Linux命令行爱好者的缺点之一。如果你需要输入并记住同样长的命令&#xff0c;这可能会降低终端的工作效率。如果您可以用自己的短名称替换长命令&#xff0c;或者…

华为手机如何固定横屏_华为手机如何录屏?原来方法这么简单,手把手教你学会...

很多人都不知道&#xff0c;华为手机到底如何录屏&#xff0c;下面给大家分享4种方法&#xff0c;非常简单&#xff0c;手把手教你学会。一、通知栏录屏从手机顶端往下滑动打开通知栏&#xff0c;这个面板上有很多快捷功能&#xff0c;其中就有【屏幕录制】功能&#xff0c;点击…