0

0

Golang新手如何做日志分析_Go语言实战案例

P粉602998670

P粉602998670

发布时间:2026-01-15 13:51:03

|

220人浏览过

|

来源于php中文网

原创

用 bufio.Scanner 流式读取大日志文件可避免内存溢出;默认按行切分,每次仅加载一行,需设置 scanner.Buffer 防止超长行报错。

golang新手如何做日志分析_go语言实战案例

直接上手做日志分析,不需要先搭整套可观测体系——用 os.Open + bufio.Scanner 读文件、strings.Containsregexp 匹配关键信息、再用 map 统计,三步就能跑通一个真实可用的分析脚本。

怎么读大日志文件不卡死?

新手常把整个日志文件 os.ReadFile 读进内存,一碰几百 MB 的 /var/log/syslog 就 panic:out of memory。Go 原生没“流式读取”封装,但 bufio.Scanner 就是干这个的。

  • 它默认按行切分,每次只加载一行到内存,适合处理任意大小的日志文件
  • 注意设置缓冲区上限,避免超长日志行触发 scanner.Err() == bufio.ErrTooLong,可加 scanner.Buffer(make([]byte, 4096), 1
  • 别用 for line := range scanner.Lines(那是 tail 库的写法),标准库 Scanner 没这个字段

匹配关键字该用 strings 还是 regexp?

看场景:查 "ERROR""timeout" 这种固定字符串,strings.Contains 快 5–10 倍,且无编译开销;要抽 ID=12345 或解析 Nginx 时间戳,必须用 regexp

  • strings.ToLower(line) 再搜,比正则忽略大小写更轻量,适合简单 case
  • 正则别在循环里反复 regexp.Compile,提成全局变量或用 sync.Once 初始化
  • 容器 JSON 日志里 "log":"panic: connection refused" 这种嵌套内容,得先 json.Unmarshal 解一层,再对 log 字段做字符串处理

统计结果不准?大概率是时间/编码/换行踩了坑

分析结果和 grep -c 对不上?常见三个隐形雷:

豆包手机助手
豆包手机助手

豆包推出的手机系统服务级AI助手

下载

立即学习go语言免费学习笔记(深入)”;

  • 日志含中文或特殊符号时,文件可能是 GBK 编码,而 Go 默认按 UTF-8 解析——scanner.Text() 返回乱码,匹配必然失败(Linux 系统日志一般为 UTF-8,但某些嵌入式设备或旧服务可能不是)
  • time.Parse 解析 [05/Feb/2024:10:23:45 +0000] 这类格式,Layout 必须严格匹配:对应的是 "02/Jan/2006:15:04:05 -0700",错一位就返回零值时间
  • scanner.Scan() 遇到 CR/LF 不一致(Windows vs Linux)可能跳行,建议统一用 strings.TrimRight(line, "\r\n") 清理
package main

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

func main() {
	file, _ := os.Open("/var/log/syslog")
	defer file.Close()

	scanner := bufio.NewScanner(file)
	scanner.Buffer(make([]byte, 4096), 1<<20) // 防超长行

	// 预编译正则:提取 "kernel:" 开头的内核消息
	kernelRe := regexp.MustCompile(`^kernel: \[.*?\] (.+)`)

	errorCount := 0
	kernelMsgs := []string{}

	for scanner.Scan() {
		line := strings.TrimRight(scanner.Text(), "\r\n")
		if strings.Contains(strings.ToLower(line), "error") {
			errorCount++
		}
		if matches := kernelRe.FindStringSubmatch([]byte(line)); matches != nil {
			kernelMsgs = append(kernelMsgs, string(matches[1]))
		}
	}

	fmt.Printf("Error count: %d\n", errorCount)
	fmt.Printf("Kernel messages: %d\n", len(kernelMsgs))
}

真正难的从来不是写代码,而是确认你读的那行日志,确实是原始日志里“那一行”——比如 Docker 容器日志是 JSON 行,tail -f 看着是纯文本,实际每行开头有时间戳和容器 ID 字段,直接字符串匹配会漏掉真实错误内容。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

178

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

226

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

337

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

391

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

196

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

191

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

192

2025.06.17

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.7万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号