-
Notifications
You must be signed in to change notification settings - Fork 0
/
log_limiter.go
116 lines (95 loc) · 3.07 KB
/
log_limiter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* Copyright(C) 2023. Huawei Technologies Co.,Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package hwlog provides the capability of processing Huawei log rules.
package hwlog
import (
"fmt"
"sync"
"time"
"github.com/gmodx/ascend-dcmi/cache"
)
const (
// MaxCacheSize indicates the maximum log cache size
MaxCacheSize = 100 * 1024
// MaxExpiredTime indicates the maximum log cache expired time
MaxExpiredTime = 60 * 60
// DefaultCacheSize indicates the default log cache size
DefaultCacheSize = 10 * 1024
// DefaultExpiredTime indicates the default log cache expired time
DefaultExpiredTime = 1
cutPreLen = 46
)
// LogLimiter encapsulates Logs and provides the log traffic limiting capability
// to prevent too many duplicate logs.
type LogLimiter struct {
// Logs is a log rotate instance
Logs *Logs
logCache *cache.ConcurrencyLRUCache
logMu sync.Mutex
doOnce sync.Once
logExpiredTime time.Duration
// CacheSize indicates the size of log cache
CacheSize int
// ExpiredTime indicates the expired time of log cache
ExpiredTime int
}
// Write implements io.Writer. It encapsulates the Write method of Los and uses
// the lru cache to prevent duplicate log writing.
func (l *LogLimiter) Write(d []byte) (int, error) {
if l == nil {
return 0, fmt.Errorf("log limiter pointer does not exist")
}
l.logMu.Lock()
defer l.logMu.Unlock()
if l.ExpiredTime == 0 || l.CacheSize == 0 {
return l.Logs.Write(d)
}
l.doOnce.Do(func() {
l.validateLimiterConf()
l.logCache = cache.New(l.CacheSize)
l.logExpiredTime = time.Duration(int64(l.ExpiredTime) * int64(time.Second))
})
if l.logCache == nil {
l.logCache = cache.New(DefaultCacheSize)
}
if !l.logCache.SetIfNX(string(d[cutPreLen:]), "v", l.logExpiredTime) {
return 0, nil
}
return l.Logs.Write(d)
}
// Close implements io.Closer. It encapsulates the Close method of Logs.
func (l *LogLimiter) Close() error {
if l == nil {
return fmt.Errorf("log limiter pointer does not exist")
}
l.logMu.Lock()
defer l.logMu.Unlock()
return l.Logs.Close()
}
// Flush encapsulates the Flush method of Logs.
func (l *LogLimiter) Flush() error {
if l == nil {
return fmt.Errorf("log limiter pointer does not exist")
}
l.logMu.Lock()
defer l.logMu.Unlock()
return l.Logs.Flush()
}
// validateLimiterConf verifies the external input parameters in the LogLimiter.
func (l *LogLimiter) validateLimiterConf() {
if l.CacheSize < 0 || l.CacheSize > MaxCacheSize {
l.CacheSize = DefaultCacheSize
}
if l.ExpiredTime < 0 || l.ExpiredTime > MaxExpiredTime {
l.ExpiredTime = DefaultExpiredTime
}
}