github.com/go-spring/spring-base@v1.1.3/log/plugin_logger.go (about)

     1  /*
     2   * Copyright 2012-2019 the original author or authors.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      https://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package log
    18  
    19  import (
    20  	"github.com/go-spring/spring-base/log/queue"
    21  )
    22  
    23  func init() {
    24  	RegisterPlugin("Root", "Root", (*loggerConfig)(nil))
    25  	RegisterPlugin("Logger", "Logger", (*loggerConfig)(nil))
    26  	RegisterPlugin("AsyncRoot", "AsyncRoot", (*asyncLoggerConfig)(nil))
    27  	RegisterPlugin("AsyncLogger", "AsyncLogger", (*asyncLoggerConfig)(nil))
    28  	RegisterPlugin("AppenderRef", "AppenderRef", (*AppenderRef)(nil))
    29  }
    30  
    31  // privateConfig is the inner Logger.
    32  type privateConfig interface {
    33  	publisher
    34  	logEvent(e *Event)
    35  	getName() string
    36  	getLevel() Level
    37  	getAppenders() []*AppenderRef
    38  }
    39  
    40  // AppenderRef is a reference to an Appender.
    41  type AppenderRef struct {
    42  	appender Appender
    43  	Ref      string `PluginAttribute:"ref"`
    44  	Filter   Filter `PluginElement:"Filter"`
    45  	Level    Level  `PluginAttribute:"level,default=none"`
    46  }
    47  
    48  func (r *AppenderRef) Append(e *Event) {
    49  	if r.Level != NoneLevel && e.Level < r.Level {
    50  		return
    51  	}
    52  	if r.Filter != nil && ResultDeny == r.Filter.Filter(e) {
    53  		return
    54  	}
    55  	r.appender.Append(e)
    56  }
    57  
    58  // baseLoggerConfig is the base of loggerConfig and asyncLoggerConfig.
    59  type baseLoggerConfig struct {
    60  	root         privateConfig
    61  	Name         string         `PluginAttribute:"name"`
    62  	AppenderRefs []*AppenderRef `PluginElement:"AppenderRef"`
    63  	Level        Level          `PluginAttribute:"level,default=info"`
    64  	Additivity   bool           `PluginAttribute:"additivity,default=true"`
    65  }
    66  
    67  func (c *baseLoggerConfig) getName() string {
    68  	return c.Name
    69  }
    70  
    71  func (c *baseLoggerConfig) getLevel() Level {
    72  	return c.Level
    73  }
    74  
    75  func (c *baseLoggerConfig) getAppenders() []*AppenderRef {
    76  	return c.AppenderRefs
    77  }
    78  
    79  // filter returns whether the event should be logged.
    80  func (c *baseLoggerConfig) enableLevel(level Level) bool {
    81  	return level >= c.Level
    82  }
    83  
    84  // callAppenders calls all the appenders inherited from the hierarchy circumventing.
    85  func (c *baseLoggerConfig) callAppenders(e *Event) {
    86  	for _, r := range c.AppenderRefs {
    87  		r.Append(e)
    88  	}
    89  	if c.root != nil && c.Additivity {
    90  		c.root.logEvent(e)
    91  	}
    92  }
    93  
    94  // logEvent is used only for parent logging events.
    95  func (c *baseLoggerConfig) logEvent(e *Event) {
    96  	if !c.enableLevel(e.Level) {
    97  		return
    98  	}
    99  	c.callAppenders(e)
   100  }
   101  
   102  // loggerConfig publishes events synchronously.
   103  type loggerConfig struct {
   104  	baseLoggerConfig
   105  }
   106  
   107  func (c *loggerConfig) publish(e *Event) {
   108  	c.callAppenders(e)
   109  }
   110  
   111  // asyncLoggerConfig publishes events synchronously.
   112  type asyncLoggerConfig struct {
   113  	baseLoggerConfig
   114  }
   115  
   116  type eventWrapper struct {
   117  	c *asyncLoggerConfig
   118  	e *Event
   119  }
   120  
   121  func (w *eventWrapper) OnEvent() {
   122  	w.c.callAppenders(w.e)
   123  }
   124  
   125  // publish pushes events into the queue and these events will consumed by other
   126  // goroutine, so the current goroutine will not be blocked.
   127  func (c *asyncLoggerConfig) publish(e *Event) {
   128  	queue.Publish(&eventWrapper{c: c, e: e})
   129  }