/
spanfilter.go
126 lines (95 loc) · 2.69 KB
/
spanfilter.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
117
118
119
120
121
122
123
124
125
126
package trace
import (
"context"
"fmt"
"github.com/shawnfeng/sutil/sconf/center"
"github.com/shawnfeng/sutil/slog/slog"
"net/http"
"strings"
"sync"
)
const FilterUrls = "span_filter_urls"
const ListConfigSep = ","
var initApolloLock sync.Mutex
var apolloCenter center.ConfigCenter
var apolloSpanFilterConfig *spanFilterConfig
func InitTraceSpanFilter() error {
fun := "TraceSpanFilter.init --> "
ctx := context.Background()
if err := initApolloCenter(ctx); err != nil {
return err
}
urls, ok := apolloCenter.GetStringWithNamespace(ctx, center.DefaultApolloTraceNamespace, FilterUrls)
if !ok {
return fmt.Errorf("not get %s from apollo namespace %s", FilterUrls, center.DefaultApolloTraceNamespace)
}
slog.Infof(ctx, "%s get %s from apollo: %s", fun, FilterUrls, urls)
urlList := strings.Split(urls, ListConfigSep)
apolloSpanFilterConfig = &spanFilterConfig{
urls: urlList,
}
apolloCenter.RegisterObserver(ctx, apolloSpanFilterConfig)
return nil
}
func initApolloCenter(ctx context.Context) error {
if apolloCenter != nil {
return nil
}
initApolloLock.Lock()
defer initApolloLock.Unlock()
if apolloCenter != nil {
return nil
}
newCenter, err := center.NewConfigCenter(center.ApolloConfigCenter)
if err != nil {
return fmt.Errorf("new config center error, %s", err.Error())
}
namespaceList := []string{center.DefaultApolloTraceNamespace}
err = newCenter.Init(ctx, center.DefaultApolloMiddlewareService, namespaceList)
if err != nil {
return fmt.Errorf("init apollo with service %s namespace %s error, %s",
center.DefaultApolloMiddlewareService, strings.Join(namespaceList, " "), err.Error())
}
newCenter.StartWatchUpdate(ctx)
apolloCenter = newCenter
return nil
}
type spanFilterConfig struct {
mu sync.RWMutex
urls []string
}
func (m *spanFilterConfig) updateUrls(urls []string) {
m.mu.Lock()
defer m.mu.Unlock()
m.urls = urls
}
func (m *spanFilterConfig) filterUrl(url string) bool {
m.mu.RLock()
defer m.mu.RUnlock()
for _, u := range m.urls {
if u == url {
return false
}
}
return true
}
func (m *spanFilterConfig) HandleChangeEvent(event *center.ChangeEvent) {
fun := "spanFilterConfig.HandleChangeEvent --> "
ctx := context.Background()
if event.Namespace != center.DefaultApolloTraceNamespace {
return
}
for key, change := range event.Changes {
if key == FilterUrls {
slog.Infof(ctx, "%s get key %s from apollo, old value: %s, new value: %s", fun, key, change.OldValue, change.NewValue)
urlList := strings.Split(change.NewValue, ListConfigSep)
m.updateUrls(urlList)
}
}
}
func UrlSpanFilter(r *http.Request) bool {
if apolloSpanFilterConfig != nil {
return apolloSpanFilterConfig.filterUrl(r.URL.Path)
}
return true
}