-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathreporting.go
97 lines (84 loc) · 3.23 KB
/
reporting.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
package proxy
import (
"context"
"net"
"strings"
"time"
rclient "github.com/go-redis/redis/v8"
"github.com/getlantern/geo"
"github.com/getlantern/http-proxy-lantern/v2/common"
"github.com/getlantern/http-proxy-lantern/v2/listeners"
"github.com/getlantern/measured"
"github.com/getlantern/http-proxy-lantern/v2/instrument"
"github.com/getlantern/http-proxy-lantern/v2/redis"
"github.com/getlantern/http-proxy-lantern/v2/throttle"
)
var (
measuredReportingInterval = 1 * time.Minute
)
type reportingConfig struct {
enabled bool
wrapper func(ls net.Listener) net.Listener
}
func newReportingConfig(countryLookup geo.CountryLookup, rc *rclient.Client, instrument instrument.Instrument, throttleConfig throttle.Config) *reportingConfig {
proxiedBytesReporter := func(ctx map[string]interface{}, stats *measured.Stats, deltaStats *measured.Stats, final bool) {
if deltaStats.SentTotal == 0 && deltaStats.RecvTotal == 0 {
// nothing to report
return
}
// Note - sometimes we're missing the platform and version
platform := fromContext(ctx, common.Platform)
platformVersion := fromContext(ctx, common.PlatformVersion)
appVersion := fromContext(ctx, common.AppVersion)
libraryVersion := fromContext(ctx, common.LibraryVersion)
app := lowerFromContext(ctx, common.App)
locale := lowerFromContext(ctx, common.Locale)
deviceID := fromContext(ctx, common.DeviceID)
originHost := fromContext(ctx, common.OriginHost)
probingError := fromContext(ctx, common.ProbingError)
arch := fromContext(ctx, common.KernelArch)
var client_ip net.IP
_client_ip := ctx[common.ClientIP]
if _client_ip != nil {
client_ip = net.ParseIP(_client_ip.(string))
}
dataCapCohort := ""
throttleSettings, hasThrottleSettings := ctx[common.ThrottleSettings]
if hasThrottleSettings {
dataCapCohort = throttleSettings.(*throttle.Settings).Label
}
instrument.ProxiedBytes(context.Background(), deltaStats.SentTotal, deltaStats.RecvTotal, platform, platformVersion, libraryVersion, appVersion, app, locale, dataCapCohort, probingError, client_ip, deviceID, originHost, arch)
}
var reporter listeners.MeasuredReportFN
if throttleConfig == nil {
log.Debug("No throttling configured, don't bother reporting bandwidth usage to Redis")
reporter = func(ctx map[string]interface{}, stats *measured.Stats, deltaStats *measured.Stats,
final bool) {
// noop
}
} else if rc != nil {
reporter = redis.NewMeasuredReporter(countryLookup, rc, measuredReportingInterval, throttleConfig)
}
reporter = combineReporter(reporter, proxiedBytesReporter)
wrapper := func(ls net.Listener) net.Listener {
return listeners.NewMeasuredListener(ls, measuredReportingInterval, reporter)
}
return &reportingConfig{true, wrapper}
}
func fromContext(ctx map[string]interface{}, key string) string {
value := ctx[key]
if value != nil {
return value.(string)
}
return ""
}
func lowerFromContext(ctx map[string]interface{}, key string) string {
return strings.ToLower(fromContext(ctx, key))
}
func combineReporter(reporters ...listeners.MeasuredReportFN) listeners.MeasuredReportFN {
return func(ctx map[string]interface{}, stats *measured.Stats, deltaStats *measured.Stats, final bool) {
for _, r := range reporters {
r(ctx, stats, deltaStats, final)
}
}
}