log/utility.go

122 lines
2.9 KiB
Go
Raw Permalink Normal View History

package log
import (
"fmt"
"net"
"os"
"path"
"runtime"
"runtime/debug"
"strings"
)
var (
dockerImageName string
dockerImageTag string
serverName string
serverIp string
)
func init() {
dockerImageName = os.Getenv("DOCKER_IMAGE_NAME")
dockerImageTag = os.Getenv("DOCKER_IMAGE_TAG")
serverName, _ = os.Hostname()
// 获取真实局域网 IP (UDP 8.8.8.8 伪拨号法)
conn, err := net.Dial("udp", "8.8.8.8:80")
if err == nil {
localAddr := conn.LocalAddr().(*net.UDPAddr)
serverIp = localAddr.IP.String()
_ = conn.Close()
}
if serverIp == "" {
addrs, err := net.InterfaceAddrs()
if err == nil {
for _, a := range addrs {
if an, ok := a.(*net.IPNet); ok {
if an.IP.IsGlobalUnicast() {
serverIp = an.IP.To4().String()
break
}
}
}
}
}
}
// fixField 格式化字段名(去横线、下划线,小写)
func fixField(s string) string {
s = strings.ReplaceAll(s, "-", "")
s = strings.ReplaceAll(s, "_", "")
return strings.ToLower(s)
}
// isLogPkgFile checks whether a runtime.Caller file path belongs to the log
// package's internal implementation files. It handles both local paths
// (.../log/file.go) and Go module paths with version suffixes
// (.../log@v1.5.6/file.go).
func isLogPkgFile(file, name string) bool {
return strings.HasSuffix(file, "/log/"+name) ||
(strings.Contains(file, "/log@") && strings.HasSuffix(file, "/"+name))
}
// getCallStacks 获取调用栈
func getCallStacks(truncations []string) []string {
callStacks := make([]string, 0)
inLogger := true
for i := 0; i < 50; i++ {
_, file, line, ok := runtime.Caller(i)
if !ok {
break
}
if strings.Contains(file, "/go/src/") {
continue
}
// 只有在 logger.go, extra.go 等核心实现文件中的帧才被认为是 "inLogger"
// 兼容本地路径 (.../log/file.go) 和 module 路径 (.../log@v1.5.6/file.go)
isLogInternal := isLogPkgFile(file, "logger.go") ||
isLogPkgFile(file, "utility.go") ||
isLogPkgFile(file, "standard.go") ||
isLogPkgFile(file, "default_logger.go") ||
isLogPkgFile(file, "extra.go")
if isLogInternal {
if inLogger {
continue
}
} else {
inLogger = false
}
if truncations != nil {
for _, truncation := range truncations {
if pos := strings.Index(file, truncation); pos != -1 {
file = file[pos+len(truncation):]
}
}
}
callStacks = append(callStacks, fmt.Sprintf("%s:%d", file, line))
}
return callStacks
}
var globalDefaultName string
// getDefaultName 获取默认应用名称
func getDefaultName() string {
if globalDefaultName != "" {
return globalDefaultName
}
name := ""
if info, ok := debug.ReadBuildInfo(); ok && info.Path != "" && info.Path != "command-line-arguments" {
name = path.Base(info.Path)
}
if name == "" {
name = path.Base(os.Args[0])
}
// 处理 Windows 下的 .exe 后缀
name = strings.TrimSuffix(name, ".exe")
return name
}