C语言简单解析提取nignx错误日志

本文档展示了如何从包含复杂日志格式的字符串中解析时间戳、错误级别及具体事件详情,重点介绍了`strtotime`函数的应用和错误类型识别方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个我的测试可能没有遇到全面的日志,但是基本上是没问题的,有需要的可以直接使用。免得重复造轮子啦。

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>


int strtotime(char datetime[]) {
    struct tm tm_time;
    int unixtime;
    strptime(datetime, "%Y/%m/%d %H:%M:%S", &tm_time);
    unixtime = mktime(&tm_time);
    return unixtime;
}


int getErrType(char *errlevel) {
    printf("errlevel=%s\n", errlevel );
    char level[8][12] = {"debug", "info", "notice", "warn", "error", "crit", "alert", "emerg"};
    int i = 0;
    for (i = 0; i < 8; i++) {
        if (strcmp(errlevel, level[i]) == 0) {
            return i;
        }
    }
    return -1;
}
//根据逗号分割,逐个解析nginx的内容,其中遇到两种特殊情况,不好逗号分隔的,下面str的例子都是可以直接运行使用的。
int main(int argc, char **argv) {
    int i = 0;
    int total = 0;
    int res = 0;
    //char str[1024] = "2021/02/20 09:22:59 [error] 4018#0: *63301 failed (111: Connection refused) while connecting to upstream, client: 172.16.0.254, server: localhost, request: \"GET /url/index.php HTTP/1.1\", upstream: \"http://127.0.0.1:8001/url/showmianindex.php\", host: \"172.16.0.219:1443\", referrer: \"https://172.16.0.219:1443/url/fullscreen.html\"";
    char str[1024] = "2021/03/10 09:33:34 [alert] 7409#0: kill(3919, 15) failed (3: No such process)"; //特殊类型 specialflag==1//
    // char str[1024] = "2021/03/10 09:33:34 [notice] 7409#0: signal process started"; //特殊类型 specialflag==2
    char tmp[512];
    char info[512];
    char date[64];
    char errlevel[8];
    char client[256];
    char server[256];
    char requesttype[512];
    char requesturl[512];
    char requestprotocol[512];
    char upstream[512];
    char host[256];
    char referrer[512];
    char *p;
    char *ptr;
    char tmpstr[10][512];
    char errorcode[128];

    int hour = 0;
    int min = 0;
    int sec = 0;
    int iCount = 0;//sscanf结果
    char sdate[16];
    char *tpstr = NULL;
    int specialflag = 0;

    memset(tmpstr, 0, sizeof(tmpstr));
    tpstr = strchr(str, ',');
    if (tpstr) {
        if (strstr(tpstr, ")")) {
            sprintf(tmpstr[0], "%s", str);
            total = 1;
            specialflag = 1;
        } else {
            p = strtok(str, ",");
            if (p) {
                while (p) {
                    if (total == 0) {
                        sprintf(tmpstr[total], "%s", p);
                    } else if (total == 1) {
                        sprintf(tmpstr[total], "%s", p + 1);
                    } else if (total == 2) {
                        sprintf(tmpstr[total], "%s", p + 1);
                    } else if (total == 3) {
                        sprintf(tmpstr[total], "%s", p + 1);
                    } else if (total == 4) {
                        sprintf(tmpstr[total], "%s", p + 1);
                    } else if (total == 5) {
                        sprintf(tmpstr[total], "%s", p + 1);
                    } else if (total == 6) {
                        sprintf(tmpstr[total], "%s", p + 1);
                    }
                    printf("tmpstr[%d]=%s\n", total, tmpstr[total]);
                    p = strtok(NULL, ",");
                    total++;
                }
            }
        }
    } else {
        sprintf(tmpstr[0], "%s", str);
        total = 1;
        specialflag = 2;
    }
    memset(tmp, 0, sizeof(tmp));
    memset(info, 0, sizeof(info));
    memset(date, 0, sizeof(date));
    memset(errlevel, 0, sizeof(errlevel));
    memset(client, 0, sizeof(client));
    memset(server, 0, sizeof(server));
    memset(requesturl, 0, sizeof(requesturl));
    memset(requestprotocol, 0, sizeof(requestprotocol));
    memset(upstream, 0, sizeof(upstream));
    memset(host, 0, sizeof(host));
    memset(referrer, 0, sizeof(referrer));
    memset(sdate, 0, sizeof(sdate));
    memset(errorcode, 0, sizeof(errorcode));

    int rtime = 0;
    char *tptr = NULL;
    for (i = 0; i < total; ++i) {
        ptr = NULL;
        if (i == 0) {
            sscanf(tmpstr[i], "%*[^[][%[^]]", errlevel);
            printf("errlevel=%s\n", errlevel); //日志等级
            ptr = strtok(tmpstr[i], "[");
            if (ptr) {
                memcpy(date, ptr, strlen(ptr));
            }
            rtime = strtotime(date) ;
            printf("ltime=%d\n", strtotime(date) );
            time_t t = rtime;
            strftime(sdate , sizeof(sdate) , "%Y-%m-%d" , localtime(&t));
            printf("%s\n", sdate );
            memset(sdate, 0, sizeof(sdate));
            iCount = sscanf(date, "%s %02d:%02d:%02d", sdate, &hour, &min, &sec);

            printf("date=%s\n", date); //时间
            ptr = strtok(NULL, "]");
            ptr = strtok(NULL, "]");
            if (ptr) {
                memcpy(info, ptr + 1, strlen(ptr));
            }
            printf("info=%s\n", info); //信息详细

            tptr = strstr(info, "(");
            if (tptr != NULL) {
                if (strstr(tptr, "(") != NULL) {
                    printf("tptr=%s\n", tptr + 2 );
                    sscanf(tptr + 2, "%*[^(](%[^)]", errorcode);
                } else {
                    sscanf(info, "%*[^(](%[^)]", errorcode);
                }
            }  else {
                sprintf(errorcode, "%s", "-");
            }

            printf("errorcode=%s\n", errorcode); //日志等级

            char t1[256];
            char t2[256];
            char t3[256];
            if (specialflag == 1) {
                sscanf(info, "%[^ ] %[^ ] %[^,]", t1, t2, t3);
                printf("t2=%s\n", t2 );
                printf("t3=%s\n", t3 );
                memset(info, 0, sizeof(info));
                sprintf(info, "%s %s", t2, t3);

            } else if (specialflag == 2) {
                sscanf(info, "%[^ ] %[^,]", t1, t2);
                printf("t1=%s\n", t1 );
                printf("t2=%s\n", t2 );
                printf("t3=%s\n", t3 );
                memset(info, 0, sizeof(info));
                sprintf(info, "%s", t2);
            } else {
                sscanf(info, "%[^ ] %[^ ] %[^,]", t1, t2, t3);
                printf("t1=%s\n", t1 );
                printf("t2=%s\n", t2 );
                printf("t3=%s\n", t3 );
                memset(info, 0, sizeof(info));
                sprintf(info, "%s", t3);
            }
            printf("info=%s\n", info); //日志内容
        } else if (i == 1) {
            ptr = strtok(tmpstr[i], " ");
            ptr = strtok(NULL, " ");
            if (ptr) {
                memcpy(client, ptr, strlen(ptr));
                printf("client=%s\n", client); //客户端
            }
        } else if (i == 2) {
            ptr = strtok(tmpstr[i], " ");
            ptr = strtok(NULL, " ");
            if (ptr) {
                memcpy(server, ptr, strlen(ptr));
                printf("server=%s\n", server);//服务端
            }
        } else if (i == 3) {
            ptr = strtok(tmpstr[i], " ");
            ptr = strtok(NULL, " ");
            if (ptr) {
                memset(requesttype, 0, sizeof(requesttype));
                memcpy(requesttype, ptr + 1, strlen(ptr));
                printf("requesttype=%s\n", requesttype); //请求类型
                // printf("requesttype=%s\n", ptr + 1);
            }
            ptr = strtok(NULL, " ");
            if (ptr) {
                memset(requesturl, 0, sizeof(requesturl));
                memcpy(requesturl, ptr, strlen(ptr));
                printf("requesturl=%s\n", requesturl); //请求地址
                // printf("requesturl=%s\n", ptr);
            }
            ptr = strtok(NULL, " ");
            if (ptr) {
                memset(requestprotocol, 0, sizeof(requestprotocol));
                memcpy(requestprotocol, ptr, (strlen(ptr) - 1));
                printf("requestprotocol=%s\n", requestprotocol); //请求协议
                // ptr[strlen(ptr) - 1] = 0;
                // printf("requestprotocol=%s\n", ptr);
            }
        } else if (i == 4) {
            ptr = strtok(tmpstr[i], " ");
            ptr = strtok(NULL, " ");
            // ptr[strlen(ptr) - 1] = 0;
            if (ptr) {
                memset(upstream, 0, sizeof(upstream));
                memcpy(upstream, ptr + 1, (strlen(ptr) - 2));
                printf("upstream=%s\n", upstream); //上游地址
                // printf("upstream=%s\n", ptr + 1);
            }
        } else if (i == 5) {
            ptr = strtok(tmpstr[i], " ");
            ptr = strtok(NULL, " ");
            // ptr[strlen(ptr) - 1] = 0;
            if (ptr) {
                memset(host, 0, sizeof(host));
                memcpy(host, ptr + 1, (strlen(ptr) - 2));
                printf("host=%s\n", host); //主机地址
                // printf("host=%s\n", ptr + 1);
            }
        } else if (i == 6) {
            ptr = strtok(tmpstr[i], " ");
            ptr = strtok(NULL, " ");
            // ptr[strlen(ptr) - 1] = 0;
            if (ptr) {
                memset(referrer, 0, sizeof(referrer));
                memcpy(referrer, ptr + 1, (strlen(ptr) - 2));
                printf("referrer=%s\n", referrer); //来源地址
                // printf("referrer=%s\n", ptr + 1);
            }
        }
    }
    printf("%d\n", getErrType(errlevel) );
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值