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  }