github.com/gogf/gf@v1.16.9/internal/intlog/intlog.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 // Package intlog provides internal logging for GoFrame development usage only. 8 package intlog 9 10 import ( 11 "bytes" 12 "context" 13 "fmt" 14 "path/filepath" 15 "time" 16 17 "go.opentelemetry.io/otel/trace" 18 19 "github.com/gogf/gf/debug/gdebug" 20 "github.com/gogf/gf/internal/utils" 21 ) 22 23 const ( 24 stackFilterKey = "/internal/intlog" 25 ) 26 27 var ( 28 // isGFDebug marks whether printing GoFrame debug information. 29 isGFDebug = false 30 ) 31 32 func init() { 33 isGFDebug = utils.IsDebugEnabled() 34 } 35 36 // SetEnabled enables/disables the internal logging manually. 37 // Note that this function is not concurrent safe, be aware of the DATA RACE. 38 func SetEnabled(enabled bool) { 39 // If they're the same, it does not write the `isGFDebug` but only reading operation. 40 if isGFDebug != enabled { 41 isGFDebug = enabled 42 } 43 } 44 45 // Print prints `v` with newline using fmt.Println. 46 // The parameter `v` can be multiple variables. 47 func Print(ctx context.Context, v ...interface{}) { 48 if !isGFDebug { 49 return 50 } 51 doPrint(ctx, fmt.Sprint(v...), false) 52 } 53 54 // Printf prints `v` with format `format` using fmt.Printf. 55 // The parameter `v` can be multiple variables. 56 func Printf(ctx context.Context, format string, v ...interface{}) { 57 if !isGFDebug { 58 return 59 } 60 doPrint(ctx, fmt.Sprintf(format, v...), false) 61 } 62 63 // Error prints `v` with newline using fmt.Println. 64 // The parameter `v` can be multiple variables. 65 func Error(ctx context.Context, v ...interface{}) { 66 if !isGFDebug { 67 return 68 } 69 doPrint(ctx, fmt.Sprint(v...), true) 70 } 71 72 // Errorf prints `v` with format `format` using fmt.Printf. 73 func Errorf(ctx context.Context, format string, v ...interface{}) { 74 if !isGFDebug { 75 return 76 } 77 doPrint(ctx, fmt.Sprintf(format, v...), true) 78 } 79 80 // PrintFunc prints the output from function `f`. 81 // It only calls function `f` if debug mode is enabled. 82 func PrintFunc(ctx context.Context, f func() string) { 83 if !isGFDebug { 84 return 85 } 86 s := f() 87 if s == "" { 88 return 89 } 90 doPrint(ctx, s, false) 91 } 92 93 // ErrorFunc prints the output from function `f`. 94 // It only calls function `f` if debug mode is enabled. 95 func ErrorFunc(ctx context.Context, f func() string) { 96 if !isGFDebug { 97 return 98 } 99 s := f() 100 if s == "" { 101 return 102 } 103 doPrint(ctx, s, true) 104 } 105 106 func doPrint(ctx context.Context, content string, stack bool) { 107 if !isGFDebug { 108 return 109 } 110 buffer := bytes.NewBuffer(nil) 111 buffer.WriteString(time.Now().Format("2006-01-02 15:04:05.000")) 112 buffer.WriteString(" [INTE] ") 113 buffer.WriteString(file()) 114 buffer.WriteString(" ") 115 if s := traceIdStr(ctx); s != "" { 116 buffer.WriteString(s + " ") 117 } 118 buffer.WriteString(content) 119 buffer.WriteString("\n") 120 if stack { 121 buffer.WriteString(gdebug.StackWithFilter([]string{stackFilterKey})) 122 } 123 fmt.Print(buffer.String()) 124 } 125 126 // traceIdStr retrieves and returns the trace id string for logging output. 127 func traceIdStr(ctx context.Context) string { 128 if ctx == nil { 129 return "" 130 } 131 spanCtx := trace.SpanContextFromContext(ctx) 132 if traceId := spanCtx.TraceID(); traceId.IsValid() { 133 return "{" + traceId.String() + "}" 134 } 135 return "" 136 } 137 138 // file returns caller file name along with its line number. 139 func file() string { 140 _, p, l := gdebug.CallerWithFilter([]string{stackFilterKey}) 141 return fmt.Sprintf(`%s:%d`, filepath.Base(p), l) 142 }