1515// limitations under the License.
1616
1717// Package glog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup.
18- // It provides functions Info, Warning, Error, Fatal, plus formatting variants such as
19- // Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
18+ // It provides functions that have a name matched by regex:
19+ //
20+ // (Info|Warning|Error|Fatal)(Context)?(Depth)?(f)?
21+ //
22+ // If Context is present, function takes context.Context argument. The
23+ // context is used to pass through the Trace Context to log sinks that can make use
24+ // of it.
25+ // It is recommended to use the context variant of the functions over the non-context
26+ // variants if a context is available to make sure the Trace Contexts are present
27+ // in logs.
28+ //
29+ // If Depth is present, this function calls log from a different depth in the call stack.
30+ // This enables a callee to emit logs that use the callsite information of its caller
31+ // or any other callers in the stack. When depth == 0, the original callee's line
32+ // information is emitted. When depth > 0, depth frames are skipped in the call stack
33+ // and the final frame is treated like the original callee to Info.
34+ //
35+ // If 'f' is present, function formats according to a format specifier.
36+ //
37+ // This package also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
2038//
2139// Basic examples:
2240//
@@ -82,6 +100,7 @@ package glog
82100
83101import (
84102 "bytes"
103+ "context"
85104 "errors"
86105 "fmt"
87106 stdLog "log"
@@ -182,9 +201,14 @@ func appendBacktrace(depth int, format string, args []any) (string, []any) {
182201 return format , args
183202}
184203
185- // logf writes a log message for a log function call (or log function wrapper)
186- // at the given depth in the current goroutine's stack.
204+ // logf acts as ctxlogf, but doesn't expect a context.
187205func logf (depth int , severity logsink.Severity , verbose bool , stack stack , format string , args ... any ) {
206+ ctxlogf (nil , depth + 1 , severity , verbose , stack , format , args ... )
207+ }
208+
209+ // ctxlogf writes a log message for a log function call (or log function wrapper)
210+ // at the given depth in the current goroutine's stack.
211+ func ctxlogf (ctx context.Context , depth int , severity logsink.Severity , verbose bool , stack stack , format string , args ... any ) {
188212 now := timeNow ()
189213 _ , file , line , ok := runtime .Caller (depth + 1 )
190214 if ! ok {
@@ -198,6 +222,7 @@ func logf(depth int, severity logsink.Severity, verbose bool, stack stack, forma
198222
199223 metai , meta := metaPoolGet ()
200224 * meta = logsink.Meta {
225+ Context : ctx ,
201226 Time : now ,
202227 File : file ,
203228 Line : line ,
@@ -207,6 +232,9 @@ func logf(depth int, severity logsink.Severity, verbose bool, stack stack, forma
207232 Thread : int64 (pid ),
208233 }
209234 sinkf (meta , format , args ... )
235+ // Clear pointer fields so they can be garbage collected early.
236+ meta .Context = nil
237+ meta .Stack = nil
210238 metaPool .Put (metai )
211239}
212240
@@ -418,6 +446,36 @@ func (v Verbose) Infof(format string, args ...any) {
418446 }
419447}
420448
449+ // InfoContext is equivalent to the global InfoContext function, guarded by the value of v.
450+ // See the documentation of V for usage.
451+ func (v Verbose ) InfoContext (ctx context.Context , args ... any ) {
452+ v .InfoContextDepth (ctx , 1 , args ... )
453+ }
454+
455+ // InfoContextf is equivalent to the global InfoContextf function, guarded by the value of v.
456+ // See the documentation of V for usage.
457+ func (v Verbose ) InfoContextf (ctx context.Context , format string , args ... any ) {
458+ if v {
459+ ctxlogf (ctx , 1 , logsink .Info , true , noStack , format , args ... )
460+ }
461+ }
462+
463+ // InfoContextDepth is equivalent to the global InfoContextDepth function, guarded by the value of v.
464+ // See the documentation of V for usage.
465+ func (v Verbose ) InfoContextDepth (ctx context.Context , depth int , args ... any ) {
466+ if v {
467+ ctxlogf (ctx , depth + 1 , logsink .Info , true , noStack , defaultFormat (args ), args ... )
468+ }
469+ }
470+
471+ // InfoContextDepthf is equivalent to the global InfoContextDepthf function, guarded by the value of v.
472+ // See the documentation of V for usage.
473+ func (v Verbose ) InfoContextDepthf (ctx context.Context , depth int , format string , args ... any ) {
474+ if v {
475+ ctxlogf (ctx , depth + 1 , logsink .Info , true , noStack , format , args ... )
476+ }
477+ }
478+
421479// Info logs to the INFO log.
422480// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
423481func Info (args ... any ) {
@@ -450,6 +508,30 @@ func Infof(format string, args ...any) {
450508 logf (1 , logsink .Info , false , noStack , format , args ... )
451509}
452510
511+ // InfoContext is like [Info], but with an extra [context.Context] parameter. The
512+ // context is used to pass the Trace Context to log sinks.
513+ func InfoContext (ctx context.Context , args ... any ) {
514+ InfoContextDepth (ctx , 1 , args ... )
515+ }
516+
517+ // InfoContextf is like [Infof], but with an extra [context.Context] parameter. The
518+ // context is used to pass the Trace Context to log sinks.
519+ func InfoContextf (ctx context.Context , format string , args ... any ) {
520+ ctxlogf (ctx , 1 , logsink .Info , false , noStack , format , args ... )
521+ }
522+
523+ // InfoContextDepth is like [InfoDepth], but with an extra [context.Context] parameter. The
524+ // context is used to pass the Trace Context to log sinks.
525+ func InfoContextDepth (ctx context.Context , depth int , args ... any ) {
526+ ctxlogf (ctx , depth + 1 , logsink .Info , false , noStack , defaultFormat (args ), args ... )
527+ }
528+
529+ // InfoContextDepthf is like [InfoDepthf], but with an extra [context.Context] parameter. The
530+ // context is used to pass the Trace Context to log sinks.
531+ func InfoContextDepthf (ctx context.Context , depth int , format string , args ... any ) {
532+ ctxlogf (ctx , depth + 1 , logsink .Info , false , noStack , format , args ... )
533+ }
534+
453535// Warning logs to the WARNING and INFO logs.
454536// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
455537func Warning (args ... any ) {
@@ -480,6 +562,30 @@ func Warningf(format string, args ...any) {
480562 logf (1 , logsink .Warning , false , noStack , format , args ... )
481563}
482564
565+ // WarningContext is like [Warning], but with an extra [context.Context] parameter. The
566+ // context is used to pass the Trace Context to log sinks.
567+ func WarningContext (ctx context.Context , args ... any ) {
568+ WarningContextDepth (ctx , 1 , args ... )
569+ }
570+
571+ // WarningContextf is like [Warningf], but with an extra [context.Context] parameter. The
572+ // context is used to pass the Trace Context to log sinks.
573+ func WarningContextf (ctx context.Context , format string , args ... any ) {
574+ ctxlogf (ctx , 1 , logsink .Warning , false , noStack , format , args ... )
575+ }
576+
577+ // WarningContextDepth is like [WarningDepth], but with an extra [context.Context] parameter. The
578+ // context is used to pass the Trace Context to log sinks.
579+ func WarningContextDepth (ctx context.Context , depth int , args ... any ) {
580+ ctxlogf (ctx , depth + 1 , logsink .Warning , false , noStack , defaultFormat (args ), args ... )
581+ }
582+
583+ // WarningContextDepthf is like [WarningDepthf], but with an extra [context.Context] parameter. The
584+ // context is used to pass the Trace Context to log sinks.
585+ func WarningContextDepthf (ctx context.Context , depth int , format string , args ... any ) {
586+ ctxlogf (ctx , depth + 1 , logsink .Warning , false , noStack , format , args ... )
587+ }
588+
483589// Error logs to the ERROR, WARNING, and INFO logs.
484590// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
485591func Error (args ... any ) {
@@ -510,8 +616,32 @@ func Errorf(format string, args ...any) {
510616 logf (1 , logsink .Error , false , noStack , format , args ... )
511617}
512618
513- func fatalf (depth int , format string , args ... any ) {
514- logf (depth + 1 , logsink .Fatal , false , withStack , format , args ... )
619+ // ErrorContext is like [Error], but with an extra [context.Context] parameter. The
620+ // context is used to pass the Trace Context to log sinks.
621+ func ErrorContext (ctx context.Context , args ... any ) {
622+ ErrorContextDepth (ctx , 1 , args ... )
623+ }
624+
625+ // ErrorContextf is like [Errorf], but with an extra [context.Context] parameter. The
626+ // context is used to pass the Trace Context to log sinks.
627+ func ErrorContextf (ctx context.Context , format string , args ... any ) {
628+ ctxlogf (ctx , 1 , logsink .Error , false , noStack , format , args ... )
629+ }
630+
631+ // ErrorContextDepth is like [ErrorDepth], but with an extra [context.Context] parameter. The
632+ // context is used to pass the Trace Context to log sinks.
633+ func ErrorContextDepth (ctx context.Context , depth int , args ... any ) {
634+ ctxlogf (ctx , depth + 1 , logsink .Error , false , noStack , defaultFormat (args ), args ... )
635+ }
636+
637+ // ErrorContextDepthf is like [ErrorDepthf], but with an extra [context.Context] parameter. The
638+ // context is used to pass the Trace Context to log sinks.
639+ func ErrorContextDepthf (ctx context.Context , depth int , format string , args ... any ) {
640+ ctxlogf (ctx , depth + 1 , logsink .Error , false , noStack , format , args ... )
641+ }
642+
643+ func ctxfatalf (ctx context.Context , depth int , format string , args ... any ) {
644+ ctxlogf (ctx , depth + 1 , logsink .Fatal , false , withStack , format , args ... )
515645 sinks .file .Flush ()
516646
517647 err := abortProcess () // Should not return.
@@ -523,6 +653,10 @@ func fatalf(depth int, format string, args ...any) {
523653 os .Exit (2 ) // Exit with the same code as the default SIGABRT handler.
524654}
525655
656+ func fatalf (depth int , format string , args ... any ) {
657+ ctxfatalf (nil , depth + 1 , format , args ... )
658+ }
659+
526660// Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
527661// including a stack trace of all running goroutines, then calls os.Exit(2).
528662// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
@@ -556,12 +690,39 @@ func Fatalf(format string, args ...any) {
556690 fatalf (1 , format , args ... )
557691}
558692
559- func exitf (depth int , format string , args ... any ) {
560- logf (depth + 1 , logsink .Fatal , false , noStack , format , args ... )
693+ // FatalContext is like [Fatal], but with an extra [context.Context] parameter. The
694+ // context is used to pass the Trace Context to log sinks.
695+ func FatalContext (ctx context.Context , args ... any ) {
696+ FatalContextDepth (ctx , 1 , args ... )
697+ }
698+
699+ // FatalContextf is like [Fatalf], but with an extra [context.Context] parameter. The
700+ // context is used to pass the Trace Context to log sinks.
701+ func FatalContextf (ctx context.Context , format string , args ... any ) {
702+ ctxfatalf (ctx , 1 , format , args ... )
703+ }
704+
705+ // FatalContextDepth is like [FatalDepth], but with an extra [context.Context] parameter. The
706+ // context is used to pass the Trace Context to log sinks.
707+ func FatalContextDepth (ctx context.Context , depth int , args ... any ) {
708+ ctxfatalf (ctx , depth + 1 , defaultFormat (args ), args ... )
709+ }
710+
711+ // FatalContextDepthf is like [FatalDepthf], but with an extra [context.Context] parameter.
712+ func FatalContextDepthf (ctx context.Context , depth int , format string , args ... any ) {
713+ ctxfatalf (ctx , depth + 1 , format , args ... )
714+ }
715+
716+ func ctxexitf (ctx context.Context , depth int , format string , args ... any ) {
717+ ctxlogf (ctx , depth + 1 , logsink .Fatal , false , noStack , format , args ... )
561718 sinks .file .Flush ()
562719 os .Exit (1 )
563720}
564721
722+ func exitf (depth int , format string , args ... any ) {
723+ ctxexitf (nil , depth + 1 , format , args ... )
724+ }
725+
565726// Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
566727// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
567728func Exit (args ... any ) {
@@ -590,3 +751,27 @@ func Exitln(args ...any) {
590751func Exitf (format string , args ... any ) {
591752 exitf (1 , format , args ... )
592753}
754+
755+ // ExitContext is like [Exit], but with an extra [context.Context] parameter. The
756+ // context is used to pass the Trace Context to log sinks.
757+ func ExitContext (ctx context.Context , args ... any ) {
758+ ExitContextDepth (ctx , 1 , args ... )
759+ }
760+
761+ // ExitContextf is like [Exitf], but with an extra [context.Context] parameter. The
762+ // context is used to pass the Trace Context to log sinks.
763+ func ExitContextf (ctx context.Context , format string , args ... any ) {
764+ ctxexitf (ctx , 1 , format , args ... )
765+ }
766+
767+ // ExitContextDepth is like [ExitDepth], but with an extra [context.Context] parameter. The
768+ // context is used to pass the Trace Context to log sinks.
769+ func ExitContextDepth (ctx context.Context , depth int , args ... any ) {
770+ ctxexitf (ctx , depth + 1 , defaultFormat (args ), args ... )
771+ }
772+
773+ // ExitContextDepthf is like [ExitDepthf], but with an extra [context.Context] parameter. The
774+ // context is used to pass the Trace Context to log sinks.
775+ func ExitContextDepthf (ctx context.Context , depth int , format string , args ... any ) {
776+ ctxexitf (ctx , depth + 1 , format , args ... )
777+ }
0 commit comments