github.com/Aoi-hosizora/ahlib@v1.5.1-0.20230404072829-241b93cf91c7/xmodule/xmodule_logger.go (about)

     1  package xmodule
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/Aoi-hosizora/ahlib/xcolor"
     6  )
     7  
     8  // LogLevel represents ModuleContainer's logger level.
     9  type LogLevel uint8
    10  
    11  const (
    12  	// LogPrvName logs when ModuleContainer.ProvideByName invoked.
    13  	LogPrvName LogLevel = 1 << iota
    14  
    15  	// LogPrvType logs when ModuleContainer.ProvideByType invoked.
    16  	LogPrvType
    17  
    18  	// LogPrvIntf logs when ModuleContainer.ProvideByIntf invoked.
    19  	LogPrvIntf
    20  
    21  	// LogInjField logs when ModuleContainer.Inject invoked and some fields are injected.
    22  	LogInjField
    23  
    24  	// LogInjFinish logs when ModuleContainer.Inject invoked and injecting is finished.
    25  	LogInjFinish
    26  
    27  	// LogPrv logs when ModuleContainer.ProvideByName, ModuleContainer.ProvideByType and ModuleContainer.ProvideByIntf invoked.
    28  	LogPrv = LogPrvName | LogPrvType | LogPrvIntf
    29  
    30  	// LogAll logs when ModuleContainer.ProvideByName, ModuleContainer.ProvideByType, ModuleContainer.ProvideByIntf and ModuleContainer.Inject invoked.
    31  	LogAll = LogPrvName | LogPrvType | LogPrvIntf | LogInjField | LogInjFinish
    32  
    33  	// LogSilent never logs, means disable the logger.
    34  	LogSilent = LogLevel(0)
    35  )
    36  
    37  // Logger represents ModuleContainer's logger interface, a default logger can be created by DefaultLogger.
    38  type Logger interface {
    39  	// PrvName logs when ModuleContainer.ProvideByName invoked, can be enabled by LogPrvName flag.
    40  	PrvName(moduleName, moduleType string)
    41  
    42  	// PrvType logs when ModuleContainer.ProvideByType invoked, can be enabled by LogPrvType flag.
    43  	PrvType(moduleType string)
    44  
    45  	// PrvIntf logs when ModuleContainer.ProvideByIntf invoked, can be enabled by LogPrvIntf flag.
    46  	PrvIntf(interfaceType, moduleType string)
    47  
    48  	// InjField logs when ModuleContainer.Inject invoked and some fields are injected, can be enabled by LogInjField flag.
    49  	InjField(moduleName, injecteeType, fieldName, fieldType string)
    50  
    51  	// InjFinish logs when ModuleContainer.Inject invoked and injecting is finished, can be enabled by LogInjFinish flag.
    52  	InjFinish(injecteeType string, injectedCount, totalCount int)
    53  }
    54  
    55  // defaultLogger represents an unexported default Logger type.
    56  type defaultLogger struct {
    57  	level      LogLevel
    58  	logPrvFunc func(moduleName, moduleType string)
    59  	logInjFunc func(moduleName, injecteeType, addition string)
    60  }
    61  
    62  var _ Logger = (*defaultLogger)(nil)
    63  
    64  // DefaultLogger creates a default Logger instance, with given LogLevel, nillable logPrjFunc and logInjFunc.
    65  //
    66  // The default format for providing logs like:
    67  // 	[Xmodule] Prv: int                  <-- int
    68  // 	[Xmodule] Prv: ~                    <-- float64
    69  // 	[Xmodule] Prv: ~                    <-- error (*errors.errorString)
    70  // 	              |--------------------|   |---------------------------|
    71  // 	                        20                           ...
    72  //
    73  // The default format for injecting logs like:
    74  // 	[Xmodule] Inj: uint                 --> *xmodule.testStruct (Uint: uint)
    75  // 	[Xmodule] Inj: ~                    --> *xmodule.testStruct (String: string)
    76  // 	[Xmodule] Inj: ~                    --> *xmodule.testStruct (Error: error)
    77  // 	[Xmodule] Inj: ...                  --> *xmodule.testStruct (#=6/6, all injected)
    78  // 	[Xmodule] Inj: ...                  --> *xmodule.testStruct (#=4/6, partially injected)
    79  // 	              |--------------------|   |-------------------|---------------------------|
    80  // 	                        20                      ...                     ...
    81  func DefaultLogger(level LogLevel, logPrvFunc func(moduleName, moduleType string), logInjFunc func(moduleName, injecteeType, addition string)) Logger {
    82  	xcolor.ForceColor()
    83  	if logPrvFunc == nil {
    84  		logPrvFunc = func(moduleName, moduleType string) {
    85  			fmt.Printf(
    86  				"[Xmodule] Prv: %s <-- %s\n",
    87  				xcolor.Red.ASprint(-20, moduleName), xcolor.Yellow.Sprint(moduleType),
    88  			)
    89  		}
    90  	}
    91  	if logInjFunc == nil {
    92  		logInjFunc = func(moduleName, injecteeType, addition string) {
    93  			fmt.Printf(
    94  				"[Xmodule] Inj: %s --> %s %s\n",
    95  				xcolor.Red.ASprint(-20, moduleName), xcolor.Blue.Sprint(injecteeType), xcolor.Yellow.Sprintf("(%s)", addition),
    96  			)
    97  		}
    98  	}
    99  	return &defaultLogger{level: level, logPrvFunc: logPrvFunc, logInjFunc: logInjFunc}
   100  }
   101  
   102  // PrvName logs when ModuleContainer.ProvideByName or ModuleContainer.AutoProvide invoked, can be enabled by LogPrvName flag.
   103  //
   104  // The default format logs like:
   105  // 	[Xmodule] Prv: xxx-tag <-- *Module
   106  // 	              |-------|   |-------|
   107  // 	                 red       yellow
   108  // Here `xxx-tag` is module name, `*Module` is module type.
   109  func (d *defaultLogger) PrvName(moduleName, moduleType string) {
   110  	if d.level&LogPrvName != 0 {
   111  		d.logPrvFunc(moduleName, moduleType)
   112  	}
   113  }
   114  
   115  // PrvType logs when ModuleContainer.ProvideByType or ModuleContainer.AutoProvide invoked, can be enabled by LogPrvType flag.
   116  //
   117  // The default format logs like:
   118  // 	[Xmodule] Prv: ~ <-- *Module
   119  // 	              |-|   |-------|
   120  // 	              red    yellow
   121  // Here `~` is module name (means provide by type or intf), `*Module` is module type.
   122  func (d *defaultLogger) PrvType(moduleType string) {
   123  	if d.level&LogPrvType != 0 {
   124  		d.logPrvFunc("~", moduleType)
   125  	}
   126  }
   127  
   128  // PrvIntf logs when ModuleContainer.ProvideByIntf or ModuleContainer.AutoProvide invoked, can be enabled by LogInjField flag.
   129  //
   130  // The default format logs like:
   131  // 	[Xmodule] Prv: ~ <-- IModule (*Module)
   132  // 	              |-|   |-----------------|
   133  // 	              red         yellow
   134  // Here `~` is module name (means provide by type or intf), `IModule` is interface type, `*Module` is implemented module type.
   135  func (d *defaultLogger) PrvIntf(interfaceType, moduleType string) {
   136  	if d.level&LogPrvIntf != 0 {
   137  		d.logPrvFunc("~", fmt.Sprintf("%s (%s)", interfaceType, moduleType))
   138  	}
   139  }
   140  
   141  // InjField logs when ModuleContainer.Inject invoked and some fields are injected, can be enabled by LogInjField flag.
   142  //
   143  // The default format logs like:
   144  // 	[Xmodule] Inj: xxx-tag --> *Struct (Field: string)
   145  // 	[Xmodule] Inj: ~       --> *Struct (Field: string)
   146  // 	              |-------|   |-------|---------------|
   147  // 	                 red        blue       yellow
   148  // Here `xxx-tag` or `~` is module name, `*Struct` is injectee type, `Field` is injectee field name, `string` is field type.
   149  func (d *defaultLogger) InjField(moduleName, injecteeType, fieldName, fieldType string) {
   150  	if d.level&LogInjField != 0 {
   151  		d.logInjFunc(moduleName, injecteeType, fmt.Sprintf("%s: %s", fieldName, fieldType))
   152  	}
   153  }
   154  
   155  // InjFinish logs when ModuleContainer.Inject invoked and injecting is finished, can be enabled by LogInjFinish flag.
   156  //
   157  // The default format logs like:
   158  // 	[Xmodule] Inj: ... --> *Struct (#=3/3, all injected)
   159  // 	[Xmodule] Inj: ... --> *Struct (#=2/3, partially injected)
   160  // 	              |---|   |-------|---------------------------|
   161  // 	               red      blue             yellow
   162  // Here `...` means injecting is finished, `*Struct` is injectee type, `#=3/3` is injected and total fields count, `all injected`
   163  // and `partially injected` means whether all module fields are injected or not.
   164  func (d *defaultLogger) InjFinish(injecteeType string, injectedCount, totalCount int) {
   165  	if d.level&LogInjFinish != 0 {
   166  		flag := "all injected"
   167  		if injectedCount != totalCount {
   168  			flag = "partially injected"
   169  		}
   170  		d.logInjFunc("...", injecteeType, fmt.Sprintf("#=%d/%d, %s", injectedCount, totalCount, flag))
   171  	}
   172  }