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 }