ZBLOG

go语言编写函数,生成能够解析标准的golang堆栈信息和日志信息,返回解析结果

在 Go 语言中,我们可以编写一个函数来生成并解析标准的堆栈信息和日志信息。以下示例演示了如何实现这个功能,包括解析堆栈信息和将其格式化为结构体返回。

示例代码

package main

import (
	"bytes"
	"fmt"
	"runtime"
	"strings"
)

// StackTrace holds information about the goroutine stack trace
type StackTrace struct {
	GoroutineID int
	Frames      []StackFrame
}

// StackFrame holds information about a single frame in the stack trace
type StackFrame struct {
	File     string
	Line     int
	Function string
}

// GenerateStackTrace generates and returns the parsed stack trace of the current goroutine
func GenerateStackTrace() (*StackTrace, error) {
	var buf bytes.Buffer

	// Get the current stack trace
	n := runtime.Stack(buf.Bytes(), false) // Get only the current goroutine's stack trace

	if n == 0 {
		return nil, fmt.Errorf("failed to get stack trace")
	}

	stackInfo := strings.Split(string(buf.Bytes()[:n]), "\n")

	trace := &StackTrace{}
	for _, line := range stackInfo {
		if strings.Contains(line, "goroutine") { 
			continue // Skip lines that contain 'goroutine'
		}
		
		if len(line) > 0 {
			frame, err := parseStackFrame(line)
			if err == nil {
				trace.Frames = append(trace.Frames, frame)
			}
		}
    }

	return trace, nil
}

// parseStackFrame parses a single line of stack trace into a StackFrame object.
func parseStackFrame(line string) (StackFrame, error) {
	var file string
	var lineNumber int
	var function string

	line = strings.TrimSpace(line)

	if idx := strings.Index(line, " "); idx != -1 {
        // Extract function name from beginning to first space.
        function = line[:idx]
        rest := line[idx+1:]

        // Find last ':' for file and line number.
        lastColonIndex := strings.LastIndex(rest, ":")
        if lastColonIndex != -1 && lastColonIndex+1 < len(rest) {
            file = rest[:lastColonIndex]
            var err error
            
            fmt.Sscanf(rest[lastColonIndex+1:], "%d", &lineNumber)
            
            return StackFrame{File: file, Line: lineNumber, Function: function}, nil
        }
    }

	return StackFrame{}, fmt.Errorf("invalid stack frame format: %s", line)
}

func main() {
	trace, err := GenerateStackTrace()
	if err != nil {
	    fmt.Println("Error generating stack trace:", err)
	    return 
    }

	fmt.Println("Parsed Stack Trace:")
	for _, frame := range trace.Frames {
	    fmt.Printf("Function: %s\nFile: %s\nLine: %d\n", frame.Function, frame.File, frame.Line)
    }
}

说明

  1. StackTrace 结构体

    • 存储当前 goroutine 的 ID 和帧列表,每一帧用 StackFrame 表示。
  2. generateStackTrace 函数

    • 获取当前 goroutine 的堆栈信息,并解析成 StackTrace 对象。
    • 使用 runtime.Stack 获取堆栈信息,然后将结果逐行分割。
    • 调用 parseStackFrame 来解析每一行并填充 Frames 列表。
  3. parseStackFrame 函数

    • 将单行的堆栈信息转换为 StackFrame 对象,提取文件名、行号和函数名。
    • 格式假设是类似于 "main.main.func1 /path/to/file.go:123" 的格式。
  4. 主程序 (main)

    • 调用 GenerateStackTrace() 函数并打印出解析的堆栈信息。

注意事项

  • 此代码只会获取当前 goroutine 的堆栈信息。如果你希望获取所有 goroutines 的堆栈信息,可以在调用 runtime.Stack() 时将第二个参数设置为 true,然后进行相应的修改以支持多个 goroutines。
  • 确保正确处理错误和异常情况,以便能更好地进行调试。


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=18886

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?