轻量web服务器开发日记09-日志文件的实现

主流的服务器都标配一个日志文件,其文件用于记录服务器运行的日常信息,例如某个时间段的用户请求连接数、访问文件统计数、成功或完成请求连接数、服务器出错信息等等、该文件主要帮助服务器管理员更好地了解服务器的运行情况。
具体操作函数实现:
(1)打开日志文件:

int log_file_open(const char *pathname)
{
    int fd = 0;
    fd = open(pathname, O_WRONLY|O_APPEND|O_CREAT);
    return fd;
}

(2)往日志文件中写入信息:

int log_file_writen(char *logfile,char *filename, int *line, const char *fmt, ...)
{ 
    /* open the log_file and init it */
    const char *pathname;
    int fd;
    char *path = logfile;
    fd = log_file_open(path);
    if(fd == -1)
    {
        return -1;  
    }
    va_list ap;
    time_t timep;
    char *time_string = calloc(1,256), *ptr = calloc(1,1024);
    char *buf1;
    buf1 = calloc(1, 64);
    int len = 0;
    time(&timep);//取得当地时间
     struct tm *timeinfo;
    timeinfo = localtime(&timep);

    strftime(time_string, 256, "%Y年%m月%d日 %H时%M分%S秒", timeinfo); //创建字符串时间戳

    string_append(ptr, strlen(ptr), time_string, strlen(time_string));
    string_append(ptr, strlen(ptr), "(", strlen("("));

    string_append(ptr, strlen(ptr), filename, strlen(filename));
    string_append(ptr, strlen(ptr), ":", strlen(":"));
    int_to_string(buf1, line);
    string_append(ptr, strlen(ptr), buf1, strlen(buf1));
    len = string_append(ptr, strlen(ptr), ")", strlen(")"));
    for(va_start(ap, fmt); *fmt; fmt++)
    {
        int d;
        char *s;
        char *buf;
        buf = calloc(1, 64);
        //off_t o;
        switch(*fmt)
        {
            /* string */    
            case 's': 
            case 'S':  
                s = va_arg(ap, char *);
                string_append(ptr, strlen(ptr), " ", strlen(" "));
                string_append(ptr, strlen(ptr), s, strlen(s));
                break;
             /* int(digital) */ 
            case 'd': 
            case 'D': 

                d = va_arg(ap, int);
                int_to_string(buf, d);
                string_append(ptr, strlen(ptr), " ", strlen(" "));
                string_append(ptr, strlen(ptr), buf, strlen(buf));

                break;
            case '(':
            case ')':
            case '<':
            case '>':
            case ',':
            case ' ':
                *buf = *fmt;
                string_append(ptr, strlen(ptr), buf, strlen(buf));
                break;
        }
        va_end(ap);
    }

    *(ptr + strlen(ptr)) = '\r'; 
    *(ptr + strlen(ptr) + 1) = '\n'; 
    *(ptr + strlen(ptr) + 2) = '\0'; 
    writen(fd, ptr,strlen(ptr));
    free(ptr);
    free(time_string);
    close(fd);
    return 0;
}

下面是(2)中调用到的操作函数实现:

//将整型转换为字符
int int_to_string(char *buf, int val)
{ 
    char swap;
    char *fin;
    int temp = val;
    if(temp < 0)
    {
        *(buf++) = '-';
        temp = -temp;
    }
    fin = buf;
    while(temp > 9)
    {
        *fin = 48 + (temp % 10);
        fin++;
        temp = temp / 10;
    }
    *(fin) = 48 + temp;
    *(fin + 1) = '\0';
    while(buf < fin)
    {
        swap = *fin;
        *fin = *buf;
        *buf = swap;
        buf++;
        fin--;
    }
    return 0;
}

//往套接字描述符中写n个字节
 size_t writen(int fd, const void *vptr, size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    const char *ptr;
    ptr = vptr;
    nleft = n;
    while(nleft > 0)
    {
        if((nwritten = write(fd, ptr, nleft)) <= 0)
        {
            if(nwritten < 0 && errno == EINTR)
                nwritten = 0;
            else
                return -1;
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    return n;
}

//在字符串a的末尾添加字符串b
int string_append(char *a, size_t a_len, char *b, size_t b_len)
{   
    int i;
    for(i = 0;i <= b_len; i++)
    {
        *(a + a_len + i) = *(b + i);
    }
    return (a_len + b_len + 2);
}

效果例子:
19时35分19秒(test.c:69) head:accept has text/html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值