现在我们已经实现了文件读取模块,下面我们将处理模块实现,因为要从字符串中提取数据,需要用到go的正则表达式,我总结了go的正则表达是的常用方法。
下面为处理模块的代码
func (l *LogProcess) Process() {
/*
需要匹配的正则规则,每个人跟每个人写的正则都不一样,只要能提取到自己需要的数据即可,其中(...)中包含的是我们需要提取的数据,
*/
str := `([\d\.]+)\s+([^\[]+)\s+\[([\d\s\S]+?)\]\s+\"([A-Z]+)\s+([\/\S]+)\s+([[A-Z]+\/\d\.\d]?)\"\s+([\d]+)\s+([\d]+)\s+\"([\S]+)\"\s+\"([\S]+)\s+\(([\S]+)\s+`
//函数MustCompile类似Compile但会在解析失败时panic,主要用于全局正则表达式变量的安全初始化。详情请看regexp包的官方文档
reg := regexp.MustCompile(str)
for {
//从读取管道中取值,值类型为NginxLog类型
t := <-l.rc
/*
这里需要用到两个方法一个为FindAllStringSubmatch,一个为FindStringSubmatch,前一个方法返回的是一个二维的string切片,后一个方法返回的是一个string切片[]string
其中索引0为全部数据,索引1为你正则表达式中第一个()中的数据
*/
result := reg.FindStringSubmatch(t.Log)
if len(result) < 12 {
log.Printf("log err: %v", result[0])
continue
}
l.wc <- result[0]
}
}
运行结果展示
至此我们已经从文件中提取了我们想要的数据
但是还需要进一步的处理才能传到写入模块,首先定义了一个结构体,方便数据的封装
//处理模块返回结构体
type Repose struct {
//访问ip
Ip string
//访问时间
Time time.Time
//请求方法
Method string
//请求路径
Url string
//请求状态吗
Status string
//请求设备类型
Device string
//请求时间
RequestTime int
}
看下处理器模块代码
func (l *LogProcess) Process() {
/*
需要匹配的正则规则,每个人跟每个人写的正则都不一样,只要能提取到自己需要的数据即可,其中(...)中包含的是我们需要提取的数据,
*/
str := `([\d\.]+)\s+([^\[]+)\s+\[([\d\s\S]+?)\]\s+\"([A-Z]+)\s+([\/\S]+)\s+([[A-Z]+\/\d\.\d]?)\"\s+([\d]+)\s+([\d]+)\s+\"([\S]+)\"\s+\"([\S]+)\s+\(([\S]+)\s+`
//函数MustCompile类似Compile但会在解析失败时panic,主要用于全局正则表达式变量的安全初始化。详情请看regexp包的官方文档
reg := regexp.MustCompile(str)
//定义一个location准备时间的格式化
location, _ := time.LoadLocation("Asia/Shanghai")
for {
//从读取管道中取值,值类型为NginxLog类型
t := <-l.rc
/*
这里需要用到连个方法一个为FindAllStringSubmatch,一个为FindStringSubmatch,前一个方法返回的是一个二维的string切片,后一个方法返回的是一个string切片[]string
其中索引0为全部数据索引1为你正则表达式中第一个()重的数据
*/
result := reg.FindStringSubmatch(t.Log)
if len(result) < 12 {
log.Printf("log err: %v", result[0])
continue
}
//字符串改为时间格式
timeN, err := time.ParseInLocation("02/Jan/2006:15:04:05 +0800", result[3], location)
if err != nil {
log.Printf("time.ParseInLocation err:%v",err)
continue
}
//字符串改为数字
i, err := strconv.Atoi(result[8])
if err != nil {
log.Println(err)
continue
}
res := &Repose{
//访问ip
Ip: result[1],
//访问时间
Time: timeN,
//请求方法
Method: result[4],
//请求路径
Url: result[5],
//请求状态吗
Status: result[7] ,
//请求设备类型
Device: result[11],
//请求时间
RequestTime: i,
}
l.wc <- res
}
}
至此我们的处理模块完成了。