golang快速定位错误源代码的调试插件库errlog的使用

Golang快速定位错误源代码的调试插件库errlog的使用

介绍

使用errlog可以改进错误日志记录,并在创建代码时加快调试速度:

  • 高亮显示源代码
  • 检测并指出哪个函数调用导致了失败
  • 美观的堆栈跟踪
  • 生产环境的无操作模式
  • 易于实现,可适配的日志记录器
  • 无需改变你或团队成员的开发习惯即可集成到现有项目中
  • 可集成到你当前的日志系统中

安装

go get github.com/snwfdhmp/errlog

使用

将你的if err != nil替换为if errlog.Debug(err)来添加调试信息。

func someFunc() {
    //...
    if errlog.Debug(err) { // 如果err != nil会调试并继续,如果err == nil则忽略
        return
    }
}

在生产环境中,调用errlog.DefaultLogger.Disable(true)启用无操作模式(等同于if err != nil

自定义配置

你可以使用以下选项配置自己的日志记录器:

type Config struct {
    PrintFunc          func(format string, data ...interface{}) // 打印函数(例如:fmt.Printf)
    LinesBefore        int  // 打印错误行之前要打印多少行源代码
    LinesAfter         int  // 打印错误行之后要打印多少行源代码
    PrintStack         bool // 是否打印堆栈跟踪?是/否
    PrintSource        bool // 是否打印源代码?是/否
    PrintError         bool // 是否打印Debug(err)的错误?是/否
    ExitOnDebugSuccess bool // Debug完成日志记录后是否退出?(当err为nil时不发生)
}

示例

基础示例

func main() {
    fmt.Println("Program start")

    wrapingFunc() // 调用我们的重要函数

    fmt.Println("Program end")
}

func wrapingFunc() {
    someBigFunction() // 调用某个函数
}

func someBigFunction() {
    someDumbFunction() // 随机调用
    someSmallFunction() // 随机调用
    someDumbFunction() // 随机调用

    // 这里可能会失败,所以我们使用errlog.Debug(err)而不是if err != nil
    if err := someNastyFunction(); errlog.Debug(err) {
        return
    }

    someSmallFunction() // 随机调用
    someDumbFunction() // 随机调用
}

func someSmallFunction() {
    _ = fmt.Sprintf("I do things !")
}

func someNastyFunction() error {
    return errors.New("I'm failing for some reason") // 模拟一个错误
}

func someDumbFunction() bool {
    return false // 随机操作
}

自定义配置示例

debug := errlog.NewLogger(&errlog.Config{
    // PrintFunc的类型是`func (format string, data ...interface{})`
    // 所以你可以轻松实现自己的日志函数。
    // 在这个例子中,使用了logrus,但也可以使用任何其他日志记录器。
    // 注意在打印时应该在格式字符串末尾添加'\n'。
    PrintFunc:          logrus.Printf,
    PrintSource:        true, // 打印失败的源代码
    LinesBefore:        2, // 打印错误行之前的2行
    LinesAfter:         1, // 打印错误行之后的1行
    PrintError:         true, // 打印错误
    PrintStack:         false, // 不打印堆栈跟踪
    ExitOnDebugSuccess: true, // 如果有错误则退出
})

输出示例

基础示例输出

自定义配置输出

错误发生在代码较早位置时的输出

文档

文档可以在这里找到:errlog文档

反馈

欢迎提出任何反馈或建议,可以随时创建issue。

贡献

我们很高兴与你合作:

提交PR时,请遵循Effective Go的最佳实践。


更多关于golang快速定位错误源代码的调试插件库errlog的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang快速定位错误源代码的调试插件库errlog的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


errlog - Golang错误定位调试插件库

errlog 是一个轻量级的Golang调试工具库,可以帮助开发者快速定位错误发生的源代码位置。它通过增强标准错误输出,提供更详细的调用栈信息,大大简化了调试过程。

主要特性

  1. 自动捕获错误发生的文件和行号
  2. 显示完整的调用栈信息
  3. 可定制的错误输出格式
  4. 与标准error接口兼容
  5. 轻量级,无额外依赖

安装

go get github.com/snwfdhmp/errlog

基本使用示例

package main

import (
	"errors"
	"github.com/snwfdhmp/errlog"
)

func main() {
	// 启用调试模式
	errlog.Debug = true

	// 包装标准错误
	err := errors.New("something went wrong")
	errlog.Error(err) // 自动记录错误位置

	// 或者直接创建带位置信息的错误
	err = errlog.New("custom error message")
	errlog.Error(err)

	// 带格式化字符串的错误
	err = errlog.Errorf("value %d is invalid", 42)
	errlog.Error(err)
}

高级用法

1. 自定义输出格式

errlog.CustomFormat = func(file string, line int, err error) string {
	return fmt.Sprintf("[MYAPP] %s:%d - %v", file, line, err)
}

2. 禁用特定包的日志

errlog.IgnorePackage("database/sql") // 忽略database/sql包产生的错误

3. 获取调用栈信息

err := doSomething()
if err != nil {
	stack := errlog.StackTrace(err) // 获取完整的调用栈
	fmt.Println(stack)
}

4. 与标准库集成

func readFile(path string) error {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return errlog.Wrap(err) // 包装标准库错误
	}
	// ...
}

实际案例

package main

import (
	"database/sql"
	"fmt"
	"github.com/snwfdhmp/errlog"
	_ "github.com/go-sql-driver/mysql"
)

func connectDB() (*sql.DB, error) {
	db, err := sql.Open("mysql", "user:password@/dbname")
	if err != nil {
		return nil, errlog.Wrap(err)
	}
	return db, nil
}

func queryUser(db *sql.DB, id int) (string, error) {
	var name string
	err := db.QueryRow("SELECT name FROM users WHERE id=?", id).Scan(&name)
	if err != nil {
		return "", errlog.Wrap(err)
	}
	return name, nil
}

func main() {
	errlog.Debug = true
	
	db, err := connectDB()
	if err != nil {
		errlog.Error(err)
		return
	}
	defer db.Close()

	name, err := queryUser(db, 123)
	if err != nil {
		errlog.Error(err)
		return
	}

	fmt.Println("User name:", name)
}

性能考虑

errlog 在调试模式下会有轻微性能开销,建议:

  1. 生产环境禁用调试模式:errlog.Debug = false
  2. 使用 errlog.Enable(false) 完全禁用
  3. 通过环境变量控制:ERRLOG_DEBUG=true go run main.go

替代方案比较

  1. pkg/errors:提供类似的堆栈跟踪,但需要手动Wrap错误
  2. logrus:功能更全面的日志库,但更重量级
  3. zap:高性能日志库,但不专注于错误定位

errlog 的优势在于简单性和专注于错误定位的单一职责。

总结

errlog 是一个简单实用的Golang错误调试工具,通过自动记录错误位置和调用栈信息,可以显著减少调试时间。它特别适合在开发阶段快速定位问题,同时保持与标准error接口的兼容性。

对于更复杂的需求,可以考虑结合使用errlog和其他日志库,如将errlog用于开发调试,而使用zap或logrus用于生产环境日志记录。

回到顶部