Linux C多线程日志记录

wirte函数在O_APPEND模式下,是线程安全的。所以使用线程读写锁,让写日志函数多并发运行。定时进入写模式刷新数据,并通过判断文件大小进行压缩备份。

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <pthread.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <errno.h>
#include <dirent.h>
#include <stdlib.h>
#include <fcntl.h>


#define LOGADDR     "test.log"

static int log_fd = -1;
static pthread_rwlock_t log_lock;


static void get_timestamp(char *buffer)
{
    time_t t;
    struct tm *p;
    struct timeval tv;
    int len;
    int millsec;
 
    t = time(NULL);
    p = localtime(&t);
 
    gettimeofday(&tv, NULL);
    millsec = (int)(tv.tv_usec / 1000);
 
    /* 时间格式:[2011-11-15 12:47:34:888] */
    len = snprintf(buffer, 32, "[%04d-%02d-%02d %02d:%02d:%02d:%03d] ",\
        p->tm_year+1900, p->tm_mon+1,\
        p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, millsec);
 
    buffer[len] = '\0';
}

int find_file(char *filename) 
{
    int rev = -1;
    DIR *dir;
    struct dirent *entry;
    
    char path[1024]; // 存放路径字符串
    
    int i = 1;
    
    if((dir = opendir(".")) != NULL) 
    {
        while ((entry = readdir(dir)) != NULL) 
        {
            if(strcmp(filename, entry->d_name) == 0)
            {
                rev = 0;
                break;
            }
        }
        
        closedir(dir);
    } 
    else 
    {
        perror("无法打开目录");
        return -1;
    }
    
    return rev;
}

//创建文件夹
static int create_dir(const char *sPathName)  
{  
    char dirName[256];  
    strcpy(dirName, sPathName);  
    int i,len = strlen(dirName);
    for(i=1; i<len; i++)  
    {  
        if(dirName[i]=='/')  
        {  
            dirName[i] = 0; 
            if(access(dirName, 0)!=0)  
            {  
                if(mkdir(dirName, 0755)==-1)  
                {   
                    printf("mkdir error\n");   
                    return -1;   
                }  
            }  
            dirName[i] = '/';  
 
        }  
    }  
 
    return 0;  
} 


int open_log(const char *filename)
{
    int fd;
    fd = open(filename, O_WRONLY | O_APPEND);
    if(fd < 0)
    {
        printf("%s can't open\n", filename);
        create_dir(filename);
        fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0666);
        if(fd < 0)
        {
            printf("%s can't open--2\n", filename);
        }
    }

    return fd;
}

void *pthread_func1(void *arg)
{
    int flag = 0;
    char buff[100];

    while(1)
    {
        flag = 0;
        get_timestamp(buff);
        printf("%s----pthread_rwlock_wrlock--\n", buff);
        pthread_rwlock_wrlock(&log_lock);
        get_timestamp(buff);
        printf("%s----pthread_rwlock_wrlock-1--\n", buff);
        if(log_fd < 0)
        {
            log_fd = open_log(LOGADDR);
            // if(log_fd > 0)
            // {
            //     off_t filesize = lseek(log_fd, 0, SEEK_END);
            //     if(filesize == 0)
            //     {
            //         write(log_fd, "new file\n", strlen("new file\n"));
            //     }
            // }
        }
        else
        {
            fsync(log_fd);
            off_t filesize = lseek(log_fd, 0, SEEK_END);
            if(filesize > 1024*1024)
            {
                close(log_fd);
                char cmd[1000];
                flag = 1;
                sprintf(cmd, "mv -f %s test_bak.log", LOGADDR);
                printf("cmd:%s\n", cmd);
                system(cmd);
                log_fd = open_log(LOGADDR);
            }
        }
        pthread_rwlock_unlock(&log_lock);
        if(flag == 1)
        {
            int tar_no;
            char cmd[1000];
            for(tar_no=0; tar_no<10; tar_no++)
            {
                sprintf(cmd, "test_%d.tar.gz", tar_no);
                if(find_file(cmd) < 0)
                {
                    break;
                }
            }
            sprintf(cmd, "tar -zcf  test_%d.tar.gz test_bak.log", tar_no);
            printf("cmd:%s\n", cmd);
            system(cmd);

            tar_no++;
            if(tar_no >= 10) tar_no = 0;
            sprintf(cmd, "rm -f  test_%d.tar.gz", tar_no);
            printf("cmd:%s\n", cmd);
            system(cmd);
        }
        sleep(1);
    }
}

void *pthread_func2(void *arg)
{
    int no = *(int*)arg;
    int i = 0;
    char buf[1000];


    while(1)
    {
        get_timestamp(buf);
        sprintf(buf+strlen(buf), "pthread_func2--------------%d--%d-\n", no, i++);
        printf("fd:%d-%s", log_fd, buf);
        if(log_fd > 0)
        {   
            pthread_rwlock_rdlock(&log_lock);
            write(log_fd, buf, strlen(buf));
            pthread_rwlock_unlock(&log_lock);
        }
        usleep(10000);
        if(i>=9999) break;
    }
}

// int find_file(char *filename) 
// {
//     int rev = -1;
//     DIR *dir;
//     struct dirent *entry;
    
//     char path[1024]; // 存放路径字符串
    
//     int i = 1;
    
//     if((dir = opendir(".")) != NULL) 
//     {
//         while ((entry = readdir(dir)) != NULL) 
//         {
//             if(strcmp(filename, entry->d_name) == 0)
//             {
//                 rev = 0;
//                 break;
//             }
//         }
        
//         closedir(dir);
//     } 
//     else 
//     {
//         perror("无法打开目录");
//         return -1;
//     }
    
//     return rev;
// }

// int file_touch(void)
// {
//     int i = 0;
    
//     char filename[200];
//     char cmd[1000];
//     for(i=0; i<50; i++)
//     {
//         sprintf(filename, "file_%d.log", i);
//         if(find_file(filename) < 0)
//         {
//             break;
//         }
//     }
//     sprintf(cmd, "touch %s", filename);
//     printf("%s\n", cmd);
//     system(cmd);
//     i++;
//     if(i>= 50)
//     {
//         i = 0;
//     }

//     sprintf(cmd, "rm -r file_%d.log", i);
//     printf("%s\n", cmd);
//     system(cmd);
// }



int main(void)
{
    int i;
    int num = 8;
    pthread_t threads[10];
    int list[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    pthread_rwlockattr_t attr;    
    pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
    pthread_rwlock_init(&log_lock, &attr);

    pthread_create(threads, NULL, pthread_func1, NULL);
    for(i=1; i<num; i++)
        pthread_create(threads+i, NULL, pthread_func2, &list[i]);



    for(i=0; i<num; i++)
        pthread_join(threads[i], NULL);

    // for(i=0; i<101; i++)
    // {
    //     file_touch();
    // }

    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值