第6节 解析模块的实现
❤️💕💕Go语言高级篇章,在此之前建议您先了解基础和进阶篇。Myblog:http://nsddd.top
Go语言基础篇
Go语言100篇进阶
[TOC]
解析模块的功能
- 从Read Channel中读取每行日志数据
- 正则表达式提取所需要的监控数据(path,status,method等)
- 写入到write channel
解析模块的实现
func (l *LogProcess) Process() {
//解析模块
/* 输入数据:
[07/July/2022:18:01:41 +0000] http "GET /foo?query=t HTTP/1.0" 200 2133 "-"
"KeepAliveClient" "-" 1.005 1.854
*/
//处理数据--将data中的所有字符修改为其大写格式。对于非ASCII字符,它的大写格式需要查表转换
r := regexp.MustCompile(`\[([^\]]+)\]\s+(.*?)\s+\"(.*?)\"\s+(\d{3})\s+(\d+)\s+\"([^"]+
)\"\s+\"(.*?)\"\s+\"([\d\.-]+)\"\s+([\d\.-]+)\s+([\d\.-]+)`)
loc, err := time.LoadLocation("Asia/Shanghai") //我们用的是上海时区
if err != nil { //可以忽略err一般不会有错
panic(fmt.Sprintf("time error:%s", err.Error()))
}
for v := range l.rc {
ret := r.FindStringSubmatch(string(v)) //匹配数据内容,正则括号内容匹配到返回到
//fmt.Println(ret)
if len(ret) != 14 { //正则表达式有十三个括号
log.Println("FindStringSubmatch fail:", string(v))
continue //继续下一次匹配
}
message := &Message{}
t, err := time.ParseInLocation("09/Jan/2006:15:04:05 +0000", ret[4], loc)
if err != nil {
panic(fmt.Sprintf("parseninlocation error:%s", ret[4]))
}
message.TimeLocal = t
byteSent, _ := strconv.Atoi(ret[8]) //将string类型转化为int
// if err != nil {
// panic(fmt.Sprintf("parseninlocation error:%s", err.Error(), ret[4]))
// }
message.BytesSent = byteSent
//第六个括号匹配的是GET /foo?query=t HTTP/1.0
reqSli := strings.Split(ret[6], " ") //按照空格切割第六个字段
if len(reqSli) != 3 {
log.Println("strings.split fail", ret[6]) //长度不是3说明报错了
continue
}
message.Method = reqSli[0]
u, err := url.Parse(reqSli[1])
if err != nil {
log.Println("url parse fail", ret[1])
continue
}
message.Path = u.Path //此时可以直接从结构体中取到path
message.Scheme = ret[5] //HTTP/1.0协议可以直接赋值给mess
message.Status = ret[7]
//UpstreamTime, RequestTime float64 //监控数据 1.005 1.854在十二到十三
upstreamTime, err := strconv.ParseFloat(ret[12], 64) //转化为float64
if err != nil {
fmt.Println("err = ", err, ret[1])
continue
}
requestTime, err := strconv.ParseFloat(ret[13], 64) //转化为float64
if err != nil {
fmt.Println("err = ", err, ret[1])
continue
}
message.UpstreamTime = upstreamTime
message.RequestTime = requestTime
l.wc <- message //data是byte类型,需要转化为string类型
}
}