gpt4 book ai didi

go - GO中日志文件的文本解析

转载 作者:行者123 更新时间:2023-12-02 23:35:56 25 4
gpt4 key购买 nike

这里是新手!

我正在尝试编写一个 Go 程序,该程序将解析日志文件并返回匹配行的特定信息。

为了举例说明我想要实现的目标,我将从一个如下所示的日志文件开始:

2019-09-30T04:17:02 - REQUEST-A
2019-09-30T04:18:02 - REQUEST-C
2019-09-30T04:19:02 - REQUEST-B
2019-09-30T04:20:02 - REQUEST-A
2019-09-30T04:21:02 - REQUEST-A
2019-09-30T04:22:02 - REQUEST-B

从这里我想提取所有“REQUEST-A”并将请求发生的时间打印到终端或文件。

我尝试使用 os.Open 和 Scanner,我可以使用 Scanner.Text 来记录它发现了我的字符串的出现,如下所示:

package main

import (
"bufio"
"fmt"
"os"
"strings"
)

func main() {
request := 0
f, err := os.Open("request.log")
if err != nil {
fmt.Print("There has been an error!: ", err)
}
defer f.Close()
scanner := bufio.NewScanner(f)

for scanner.Scan() {
if strings.Contains(scanner.Text(), "REQUEST-A") {
request = request + 1
}

if err := scanner.Err(); err != nil {
}
fmt.Println(request)
}
}

但我不确定如何使用它来检索我想要的信息。通常我会使用 Bash,但我想我应该扩展一下,看看是否可以使用 Go。任何建议将不胜感激。

最佳答案

在 Go 中,我们努力提高效率。不要做不必要的事情。

例如,

package main

import (
"bufio"
"bytes"
"fmt"
"os"
)

func main() {
lines, requestA := 0, 0
f, err := os.Open("request.log")
if err != nil {
fmt.Print("There has been an error!: ", err)
}
defer f.Close()

scanner := bufio.NewScanner(f)
for scanner.Scan() {
lines++
// filter request a
line := scanner.Bytes()
if len(line) <= 30 || line[30] != 'A' {
continue
}
if !bytes.Equal(line[22:], []byte("REQUEST-A")) {
continue
}
requestA++
request := string(line)

// handle request a
fmt.Println(request)
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
fmt.Println(lines, requestA)
}

输出:

$ go run request.go

2019-09-30T04:17:02 - REQUEST-A
2019-09-30T04:20:02 - REQUEST-A
2019-09-30T04:21:02 - REQUEST-A
6 3

$ cat request.log
2019-09-30T04:17:02 - REQUEST-A
2019-09-30T04:18:02 - REQUEST-C
2019-09-30T04:19:02 - REQUEST-B
2019-09-30T04:20:02 - REQUEST-A
2019-09-30T04:21:02 - REQUEST-A
2019-09-30T04:22:02 - REQUEST-B
<小时/>

为了强调效率的重要性(日志可能非常大),让我们针对 Markus W Mahlberg 运行一个基准测试。的解决方案:https://play.golang.org/p/R2D_BeiJvx9 .

$ go test log_test.go -bench=. -benchmem
BenchmarkPeterSO-4 21285 56953 ns/op 4128 B/op 2 allocs/op
BenchmarkMarkusM-4 649 1817868 ns/op 84747 B/op 2390 allocs/op

log_test.go:

package main

import (
"bufio"
"bytes"
"regexp"
"strings"
"testing"
)

var requestLog = `
2019-09-30T04:17:02 - REQUEST-A
2019-09-30T04:18:02 - REQUEST-C
2019-09-30T04:19:02 - REQUEST-B
2019-09-30T04:20:02 - REQUEST-A
2019-09-30T04:21:02 - REQUEST-A
2019-09-30T04:22:02 - REQUEST-B
`

var benchLog = strings.Repeat(requestLog[1:], 256)

func BenchmarkPeterSO(b *testing.B) {
for N := 0; N < b.N; N++ {
scanner := bufio.NewScanner(strings.NewReader(benchLog))
for scanner.Scan() {
// filter request a
line := scanner.Bytes()
if len(line) <= 30 || line[30] != 'A' {
continue
}
if !bytes.Equal(line[22:], []byte("REQUEST-A")) {
continue
}
request := string(line)
// handle request a
_ = request
}
if err := scanner.Err(); err != nil {
b.Fatal(err)
}
}
}

func BenchmarkMarkusM(b *testing.B) {
for N := 0; N < b.N; N++ {
var re *regexp.Regexp = regexp.MustCompile(`^(\S*) - REQUEST-A$`)
scanner := bufio.NewScanner(strings.NewReader(benchLog))
var res []string
for scanner.Scan() {
if res = re.FindStringSubmatch(scanner.Text()); len(res) > 0 {
_ = res[1]
}
}
if err := scanner.Err(); err != nil {
b.Fatal(err)
}
}
}

关于go - GO中日志文件的文本解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58175413/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com