github.com/go-spring/spring-base@v1.1.3/log/plugin_filter.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  	"context"
    21  	"errors"
    22  	"fmt"
    23  	"strings"
    24  	"time"
    25  )
    26  
    27  func init() {
    28  	RegisterPlugin("AcceptAllFilter", PluginTypeFilter, (Filter)((*AcceptAllFilter)(nil)))
    29  	RegisterPlugin("DenyAllFilter", PluginTypeFilter, (Filter)((*DenyAllFilter)(nil)))
    30  	RegisterPlugin("LevelFilter", PluginTypeFilter, (Filter)((*LevelFilter)(nil)))
    31  	RegisterPlugin("LevelMatchFilter", PluginTypeFilter, (Filter)((*LevelMatchFilter)(nil)))
    32  	RegisterPlugin("LevelRangeFilter", PluginTypeFilter, (Filter)((*LevelRangeFilter)(nil)))
    33  	RegisterPlugin("TimeFilter", PluginTypeFilter, (Filter)((*TimeFilter)(nil)))
    34  	RegisterPlugin("TagFilter", PluginTypeFilter, (Filter)((*TagFilter)(nil)))
    35  	RegisterPlugin("Filters", PluginTypeFilter, (Filter)((*CompositeFilter)(nil)))
    36  }
    37  
    38  type Result int
    39  
    40  const (
    41  	ResultAccept = Result(iota)
    42  	ResultDeny
    43  )
    44  
    45  // Filter is an interface that tells the logger a log message should
    46  // be dropped when the Filter method returns ResultDeny.
    47  // Filter 只应该出现在两个地方,一个是 Logger 上,用于控制消息是否打印,另一个是
    48  // AppenderRef,用于控制消息是否输出到 Appender 上,即控制消息路由。
    49  type Filter interface {
    50  	Filter(e *Event) Result
    51  }
    52  
    53  // AcceptAllFilter causes all logging events to be accepted.
    54  type AcceptAllFilter struct{}
    55  
    56  func (f *AcceptAllFilter) Filter(e *Event) Result {
    57  	return ResultAccept
    58  }
    59  
    60  // DenyAllFilter causes all logging events to be dropped.
    61  type DenyAllFilter struct{}
    62  
    63  func (f *DenyAllFilter) Filter(e *Event) Result {
    64  	return ResultDeny
    65  }
    66  
    67  // LevelFilter logs events if the level in the Event is same or more specific
    68  // than the configured level.
    69  type LevelFilter struct {
    70  	Level Level `PluginAttribute:"level"`
    71  }
    72  
    73  func (f *LevelFilter) Filter(e *Event) Result {
    74  	if e.Level >= f.Level {
    75  		return ResultAccept
    76  	}
    77  	return ResultDeny
    78  }
    79  
    80  // LevelMatchFilter logs events if the level in the Event matches the specified
    81  // logging level exactly.
    82  type LevelMatchFilter struct {
    83  	Level Level `PluginAttribute:"level"`
    84  }
    85  
    86  func (f *LevelMatchFilter) Filter(e *Event) Result {
    87  	if e.Level == f.Level {
    88  		return ResultAccept
    89  	}
    90  	return ResultDeny
    91  }
    92  
    93  // LevelRangeFilter logs events if the level in the Event is in the range of the
    94  // configured min and max levels.
    95  type LevelRangeFilter struct {
    96  	Min Level `PluginAttribute:"min"`
    97  	Max Level `PluginAttribute:"max"`
    98  }
    99  
   100  func (f *LevelRangeFilter) Filter(e *Event) Result {
   101  	if e.Level >= f.Min && e.Level <= f.Max {
   102  		return ResultAccept
   103  	}
   104  	return ResultDeny
   105  }
   106  
   107  // TimeFilter filters events that fall within a specified time period in each day.
   108  type TimeFilter struct {
   109  	Timezone string `PluginAttribute:"timezone,default=Local"`
   110  	Start    string `PluginAttribute:"start"`
   111  	End      string `PluginAttribute:"end"`
   112  	location *time.Location
   113  	abs      time.Time
   114  	start    int
   115  	end      int
   116  }
   117  
   118  func (f *TimeFilter) Init() error {
   119  	const layout = "15:04:05"
   120  	location, err := time.LoadLocation(f.Timezone)
   121  	if err != nil {
   122  		return err
   123  	}
   124  	startTime0, err := time.ParseInLocation(layout, "00:00:00", location)
   125  	if err != nil {
   126  		return err
   127  	}
   128  	endTime0, err := time.ParseInLocation(layout, "00:00:00", location)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	startTime1, err := time.ParseInLocation(layout, f.Start, location)
   133  	if err != nil {
   134  		return err
   135  	}
   136  	endTime1, err := time.ParseInLocation(layout, f.End, location)
   137  	if err != nil {
   138  		return err
   139  	}
   140  	f.location = location
   141  	f.start = int(startTime1.Sub(startTime0) / time.Second)
   142  	f.end = int(endTime1.Sub(endTime0) / time.Second)
   143  	f.abs = time.Date(2020, 1, 1, 0, 0, 0, 0, location)
   144  	return nil
   145  }
   146  
   147  func (f *TimeFilter) Filter(e *Event) Result {
   148  	t := int(e.Time.Sub(f.abs)/time.Second) % 86400
   149  	if t >= f.start && t <= f.end {
   150  		return ResultAccept
   151  	}
   152  	return ResultDeny
   153  }
   154  
   155  type TagFilter struct {
   156  	Prefix string `PluginAttribute:"prefix,default="`
   157  	Suffix string `PluginAttribute:"suffix,default="`
   158  	Tag    string `PluginAttribute:"tag,default="`
   159  	tags   []string
   160  }
   161  
   162  func (f *TagFilter) Init() error {
   163  	if f.Prefix == "" && f.Suffix == "" && f.Tag == "" {
   164  		return errors.New("TagFilter needs tag/prefix/suffix attribute")
   165  	}
   166  	f.tags = strings.Split(f.Tag, ",")
   167  	return nil
   168  }
   169  
   170  func (f *TagFilter) Filter(e *Event) Result {
   171  	if f.Prefix != "" && strings.HasPrefix(e.Tag, f.Prefix) {
   172  		return ResultAccept
   173  	}
   174  	if f.Suffix != "" && strings.HasSuffix(e.Tag, f.Suffix) {
   175  		return ResultAccept
   176  	}
   177  	for _, tag := range f.tags {
   178  		if e.Tag == tag {
   179  			return ResultAccept
   180  		}
   181  	}
   182  	return ResultDeny
   183  }
   184  
   185  type Operator int
   186  
   187  const (
   188  	OperatorAnd Operator = iota
   189  	OperatorOr
   190  	OperatorNone
   191  )
   192  
   193  func ParseOperator(s string) (Operator, error) {
   194  	switch strings.ToLower(s) {
   195  	case "and":
   196  		return OperatorAnd, nil
   197  	case "or":
   198  		return OperatorOr, nil
   199  	case "none":
   200  		return OperatorNone, nil
   201  	default:
   202  		return -1, fmt.Errorf("invalid operator '%s'", s)
   203  	}
   204  }
   205  
   206  type CompositeFilter struct {
   207  	Filters  []Filter `PluginElement:"Filter"`
   208  	Operator Operator //`PluginAttribute:"operator,default=and"`
   209  }
   210  
   211  func (f *CompositeFilter) Start() error {
   212  	for _, filter := range f.Filters {
   213  		if v, ok := filter.(LifeCycle); ok {
   214  			if err := v.Start(); err != nil {
   215  				return err
   216  			}
   217  		}
   218  	}
   219  	return nil
   220  }
   221  
   222  func (f *CompositeFilter) Stop(ctx context.Context) {
   223  	for _, filter := range f.Filters {
   224  		if v, ok := filter.(LifeCycle); ok {
   225  			v.Stop(ctx)
   226  		}
   227  	}
   228  }
   229  
   230  func (f *CompositeFilter) Filter(e *Event) Result {
   231  	switch f.Operator {
   232  	case OperatorAnd:
   233  		for _, filter := range f.Filters {
   234  			if ResultDeny == filter.Filter(e) {
   235  				return ResultDeny
   236  			}
   237  		}
   238  		return ResultAccept
   239  	case OperatorOr:
   240  		for _, filter := range f.Filters {
   241  			if ResultAccept == filter.Filter(e) {
   242  				return ResultAccept
   243  			}
   244  		}
   245  		return ResultDeny
   246  	case OperatorNone:
   247  		for _, filter := range f.Filters {
   248  			if ResultAccept == filter.Filter(e) {
   249  				return ResultDeny
   250  			}
   251  		}
   252  		return ResultAccept
   253  	}
   254  	return ResultAccept
   255  }