精选文章

Android下使用TCPDUMP抓包Wireshark分析数据 如果想分析Android下某个APP的网络数据交互,需要在Android手机上抓包,最常用的抓包工具非tcpdump莫属,用tcpdump生成Wireshark识别的pcap文件,然后将pcap文件下载到电脑上,用电脑上的Wireshark加载pcap文件,通过Wireshark分析tcpdump抓取的数据。...

继续阅读

Mac下部署Android开发环境附加NDK 作为开发者,我们深有体会,不管是进行什么开发,为了部署开发环境,我们往往需要折腾很长时间、查阅很多资料才能完成,而且这次折腾完了,下次到了另一台新电脑上又得重新来过,整个部署过程记得还好,要是不记得又得重新开始,而且遇到Android这种GFW阻隔了开发资源下载链接的环境部署,又尤其浪费时间。所以这也是我写下这篇教程的初衷跟动力源泉,希望大家参考了这篇教程以后可以轻轻松松在Mac系统下将Android环境部署好。...

继续阅读

稍顯嚴肅的台中 坦白說,留在腦海中的台中影像並不多,來台灣之前在Booking上只訂到了台中的一家青旅,第一次住青旅有些不習慣,幹什麼都放不開。 同屋的一個男生是台灣人,不過一年中四分之三的時間在上海跟北京,這麼說來跟我還是比較有共同話題的。得之我準備花15天的時間環島,覺得太倉促了,他們大學時期花一個半月的時間也不見得能將台灣島給逛完。我只能無奈地表示,兩岸允許的簽證時間有限,自己的空閒時間更有限,只能用打卡式的旅行了,我深知正真地旅行應該慢下來,融入當地的環境,感受他們的風土人情,但第一次只能這樣作罷,以後換成民進黨上台,形勢會變成怎樣還不得而知,能否再過來還是個未知數。而我一向信奉的人生格言是秉燭夜遊,活在當下,所以,理解自己吧。...

继续阅读

為之留戀的新竹 來新竹之前本沒有對她有過高的期待,慢慢對她加分要從桃園火車站出發前往新竹開始。 在桃園火車站的候車月台上,有醒目的旅遊資料發放處,這上面的擺放的全是新竹的旅遊宣傳資料,關鍵的是資料做得非常簡潔易懂,而接下來一天的新竹之行就全部是依據這份寶典的指引來完成的。...

继续阅读

從桃園開始台灣之行 初到台灣恰逢華夏銀行系統升級,特意準備的華夏銀聯卡在桃園機場沒能派上用場,只好用建行在機場5000塊,算下來是很不划算的,但是沒辦法,誰叫我出機場就得花錢呢。 從機場打車到桃園的酒店,花了將近六百塊新台幣,到酒店時五點多,天已經漸亮了,洗漱完等到七點吃過早餐就開始補覺囉,一覺醒來已是中午,帶著換下來的衣服外出找自助洗衣店,順便覓食。...

继续阅读

  • Prev
  • Next

封装自己的日志函数

文章分类 : C语言, 应用与编程

用C语言的时候,您是否还在使用printf函数来输出日志呢?您是否考虑过将printf函数打印的内容存到文件中去呢?您是否想拥有一个可选择的既支持输出到屏幕又支持存储到文件中的日志函数呢?很高兴的告诉您,如果您愿意的话,欢迎使用本人编写的一个一套日志函数,该套函数由五部分组成,分别是宏变量BUF_SIZE、结构体log_st、log_init函数、log_debug函数和log_checksize函数。其中宏变量BUF_SIZE用来限制每次输出的日志的最大长度;结构体用来存储用户需求,包括文件路径、文件描述符号、单个文件最大大小、输出方式标志、文件命名标志等;log_init函数用来完成用户需求录入、文件创建等功能,在mian函数的开始调用一次即可;log_debug函数的功能跟printf很类似,是在printf基础上进行的扩充,实现将日志输出到屏幕或者写入到文件,在需要打印日志的地方调用该函数;log_checksize函数用来检测日志文件大小是否超过最大大小限制,它需要您定时或者定点调用它,如果一直不调用,则日志文件将不受指定的最大大小限制。

一、定义宏变量BUF_SIZE

#define BUF_SIZE 1024

二、定义log_st结构体

typedef struct _log_st log_st;
struct _log_st
{
    char path[128];
    int fd;
    int size;
    int level;
    int num;
};

三、定义log_init函数
参数说明:path——您要存储的文件路径;size——单个文件的最大大小,如果超过该大小则新建新的文件用来存储;level——日志输出方式,建议在上层限制其值的范围为0到3,0表示日志既不输出到屏幕也不创建文件和保存到文件,1表示日志保存到文件但不输出到屏幕,2表示日志既输出到屏幕也保存到文件,3表示日志只输出到文件而不创建文件和存入文件;num——日志文件命名方式,非0表示以(int)time(NULL)作为文件名来保存文件,文件数量随着日志量的递增而递增;0表示以“.new”和“.bak”为文件名来保存文件,文件数量不超过两个,随着日志量的递增,旧的日志文件将被新的覆盖,更直观的说就是说.new”和“.bak”文件只保存最近的日志。

log_st *log_init(char *path, int size, int level, int num)
{
    char new_path[128] = {0};
    if (NULL == path || 0 == level) return NULL;
    log_st *log = (log_st *)malloc(sizeof(log_st));
    memset(log, 0, sizeof(log_st));
    if (level != 3)
    {
        //the num use to control file naming
        log->num = num;
        if(num)
            snprintf(new_path, 128, "%s%d", path, (int)time(NULL));
        else
            snprintf(new_path, 128, "%s.new", path);
        if(-1 == (log->fd = open(new_path, O_RDWR|O_APPEND|O_CREAT|O_SYNC, S_IRUSR|S_IWUSR|S_IROTH)))
        {
            free(log);
            log = NULL;
            return NULL;
        }
    }
    strncpy(log->path, path, 128);
    log->size = (size > 0 ? size:0);
    log->level = (level > 0 ? level:0);
    return log;
}

四、定义log_debug函数

void log_debug(log_st *log, const char *msg, ...)
{
    va_list ap;
    time_t now;
    char *pos;
    char _n = '\n';
    char message[BUF_SIZE] = {0};
    int nMessageLen = 0;
    int sz;
    if(NULL == log || 0 == log->level) return;
    now = time(NULL);
    pos = ctime(&now);
    sz = strlen(pos);
    pos[sz-1]=']';
    snprintf(message, BUF_SIZE, "[%s ", pos);
    for (pos = message; *pos; pos++);
    sz = pos - message;
    va_start(ap, msg);
    nMessageLen = vsnprintf(pos, BUF_SIZE - sz, msg, ap);
    va_end(ap);
    if (nMessageLen <= 0) return;
    if (3 == log->level)
    {
        printf("%s\n", message);
        return;
    }
    if (2 == log->level)
        printf("%s\n", message);
    write(log->fd, message, strlen(message));
    write(log->fd, &_n, 1);
    fsync(log->fd);
}

五、定义log_checksize函数

void log_checksize(log_st *log)
{
    struct stat stat_buf;
    char new_path[128] = {0};
    char bak_path[128] = {0};
    if(NULL == log || 3 == log->level || '\0' == log->path[0]) return;
    memset(&stat_buf, 0, sizeof(struct stat));
    fstat(log->fd, &stat_buf);
    if(stat_buf.st_size > log->size)
    {
        close(log->fd);
        if(log->num)
            snprintf(new_path, 128, "%s%d", log->path, (int)time(NULL));
        else
        {
            snprintf(bak_path, 128, "%s.bak", log->path);
            snprintf(new_path, 128, "%s.new", log->path);
            remove(bak_path); //delete the file *.bak first
            rename(new_path, bak_path); //change the name of the file *.new to *.bak
        }
        //create a new file
        log->fd = open(new_path, O_RDWR|O_APPEND|O_CREAT|O_SYNC, S_IRUSR|S_IWUSR|S_IROTH);
    }
}

除非注明,文章均为CppLive 编程在线原创,转载请注明出处,谢谢。

本文地址:https://www.cpplive.com/html/871.html

这里因为你的留言而存在!!!

You must be logged in to post a comment.