记录 golang 读取打日志文件(27G)
package log
import (
"bufio"
"fmt"
"io"
"os"
"regexp"
"strconv"
"strings"
"time"
)
var (
filepath = "./d.log"
insertNum = 0
)
type Commands struct {
LogFile string
Ip string
LogType string
LogDate string
}
func Run() {
getFile(0)
}
func getFile(step int) {
if step == 0 {
fmt.Print("请输入包含全路径的文件:")
} else {
fmt.Print("请重新输入:")
}
step++
var c = &Commands{}
var _, _ = fmt.Scanln(&c.LogFile)
if ok := Exists(c.LogFile); !ok {
fmt.Printf("文件不存在:%s\n", c.LogFile)
getFile(step)
} else {
fmt.Print("请输入要重写的日期[格式:20210808]:")
getLogDate(c)
}
}
func getLogDate(c *Commands) {
var _, _ = fmt.Scanln(&c.LogDate)
if ok, _ := regexp.MatchString("^(20)[0-9]{6}$", c.LogDate); !ok {
fmt.Print("日期输入有误,请重新输入:")
getLogDate(c)
} else {
fmt.Print("请输入请求的IP:")
getIp(c)
}
}
func getIp(c *Commands) {
var _, _ = fmt.Scanln(&c.Ip)
if ok, _ := regexp.MatchString("^[0-9]{2,3}(.)[0-9]{1,3}(.)[0-9]{1,3}(.)[0-9]{1,3}$", c.Ip); !ok {
fmt.Print("IP 有误,请重新输入:")
getIp(c)
} else {
fmt.Print("请输入日志类型,默认[AdClient]:")
getLogType(c)
}
}
func getLogType(c *Commands) {
var _, _ = fmt.Scanln(&c.LogType)
if ok, _ := regexp.MatchString("^[A-Za-z0-9_]+$", c.LogType); !ok {
fmt.Print("类型输入有误,请重新输入:")
getLogType(c)
} else {
fmt.Println()
fmt.Println("日志日期:", c.LogDate)
fmt.Println("日志文件:", c.LogFile)
fmt.Println("IP:", c.Ip)
fmt.Println("日志类型:", c.LogType)
fmt.Println("开始扫描文件中的日志并重写...")
RedoLog(c)
}
}
func RedoLog(c *Commands) {
f, err := os.Open(c.LogFile)
if err != nil {
fmt.Println("文件打开失败")
return
}
defer f.Close()
buf := bufio.NewReader(f)
x := 0
for {
x++
line, _, err := buf.ReadLine()
if err == io.EOF {
// 文件读取结束
break
}
dataLine := strings.TrimSpace(string(line))
ok := handleLog(dataLine, c)
if !ok {
fmt.Println("当前行重写失败", dataLine)
}
}
}
// 处理读取出来的日志信息
func handleLog(logMessage string, c *Commands) bool {
// 有效数据出现的位置
//idx := strings.Index(logMessage, "AdClient")
l := strings.SplitAfter(logMessage, c.LogType)
lens := len(l)
if lens == 0 {
return false
}
//l := strings.SplitAfterN(logMessage, "AdClient", 5)
//fmt.Println(l)
logs := make([]string, 0)
for i := 1; i < lens; i++ {
d := strings.TrimRight(l[i], "\\n"+c.LogType)
dataFields := strings.Split(d, "|")
// 长度不为 51 是错误数据,字段共 51 个
if dl := len(dataFields); dl != 51 {
// 舍弃
continue
}
t, err := strconv.Atoi(dataFields[26])
if err != nil {
fmt.Println("时间格式转化 int 失败,行字段排列有误")
continue
}
dateHour := time.Unix(int64(t), 0)
if h := dateHour.Format("20060102"); h != c.LogDate {
fmt.Println("时间格式有误")
continue
}
filename := dateHour.Format("2006010215")
insertLine := make([]string, 0, 53)
insertLine = append(insertLine, c.Ip)
insertLine = append(insertLine, dataFields[26])
insertLine = append(insertLine, c.LogType)
insertLine = append(insertLine, dataFields...)
// 重组后的字符串再放入切片
reLog := strings.Join(insertLine, "|")
logs = append(logs, reLog)
filepath = "./d_" + filename + ".log"
}
writeLog(filepath, logs)
return true
}
func writeLog(filepath string, logMessage []string) {
o, err := os.OpenFile(filepath, os.O_CREATE|os.O_RDWR|os.O_APPEND, 755)
if err != nil {
fmt.Println("文件打开失败")
return
}
defer o.Close()
for _, log := range logMessage {
o.WriteString(log + "\r\n")
insertNum++
fmt.Printf("写入成功 %d 行...\n", insertNum)
}
}
// 判断文件是否存在
func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
if os.IsExist(err) {
return true
}
return false
}
return true
}
本文来自博客园,作者:Silent-Cxl,转载请注明原文链接:https://www.cnblogs.com/silent-cxl/p/15146481.html

浙公网安备 33010602011771号