-
Notifications
You must be signed in to change notification settings - Fork 18
/
server_side_diagnostics.go
103 lines (92 loc) · 3.95 KB
/
server_side_diagnostics.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
package ldclient
import (
"time"
"gopkg.in/launchdarkly/go-server-sdk.v5/ldcomponents"
"gopkg.in/launchdarkly/go-sdk-common.v2/ldvalue"
ldevents "gopkg.in/launchdarkly/go-sdk-events.v1"
"gopkg.in/launchdarkly/go-server-sdk.v5/interfaces"
)
func createDiagnosticsManager(sdkKey string, config Config, waitFor time.Duration) *ldevents.DiagnosticsManager {
id := ldevents.NewDiagnosticID(sdkKey)
return ldevents.NewDiagnosticsManager(
id,
makeDiagnosticConfigData(config, waitFor),
makeDiagnosticSDKData(),
time.Now(),
nil,
)
}
func makeDiagnosticConfigData(config Config, waitFor time.Duration) ldvalue.Value {
builder := ldvalue.ObjectBuild().
Set("startWaitMillis", durationToMillis(waitFor))
// Allow each pluggable component to describe its own relevant properties.
mergeComponentProperties(builder, config.HTTP, ldcomponents.HTTPConfiguration(), "")
mergeComponentProperties(builder, config.DataSource, ldcomponents.StreamingDataSource(), "")
mergeComponentProperties(builder, config.DataStore, ldcomponents.InMemoryDataStore(), "dataStoreType")
mergeComponentProperties(builder, config.Events, ldcomponents.SendEvents(), "")
return builder.Build()
}
var allowedDiagnosticComponentProperties = map[string]ldvalue.ValueType{ //nolint:gochecknoglobals
"allAttributesPrivate": ldvalue.BoolType,
"connectTimeoutMillis": ldvalue.NumberType,
"customBaseURI": ldvalue.BoolType,
"customEventsURI": ldvalue.BoolType,
"customStreamURI": ldvalue.BoolType,
"diagnosticRecordingIntervalMillis": ldvalue.NumberType,
"eventsCapacity": ldvalue.NumberType,
"eventsFlushIntervalMillis": ldvalue.NumberType,
"inlineUsersInEvents": ldvalue.BoolType,
"pollingIntervalMillis": ldvalue.NumberType,
"reconnectTimeMillis": ldvalue.NumberType,
"socketTimeoutMillis": ldvalue.NumberType,
"streamingDisabled": ldvalue.BoolType,
"userKeysCapacity": ldvalue.NumberType,
"userKeysFlushIntervalMillis": ldvalue.NumberType,
"usingProxy": ldvalue.BoolType,
"usingRelayDaemon": ldvalue.BoolType,
}
// Attempts to add relevant configuration properties, if any, from a customizable component:
// - If the component does not implement DiagnosticDescription, set the defaultPropertyName property to
// "custom".
// - If it does implement DiagnosticDescription, call its DescribeConfiguration() method to get a value.
// - If the value is a string, then set the defaultPropertyName property to that value.
// - If the value is an object, then copy all of its properties as long as they are ones we recognize
// and have the expected type.
func mergeComponentProperties(
builder ldvalue.ObjectBuilder,
component interface{},
defaultComponent interface{},
defaultPropertyName string,
) {
if component == nil {
component = defaultComponent
}
if dd, ok := component.(interfaces.DiagnosticDescription); ok {
componentDesc := dd.DescribeConfiguration()
if !componentDesc.IsNull() {
if componentDesc.Type() == ldvalue.StringType && defaultPropertyName != "" {
builder.Set(defaultPropertyName, componentDesc)
} else if componentDesc.Type() == ldvalue.ObjectType {
componentDesc.Enumerate(func(i int, name string, value ldvalue.Value) bool {
if allowedType, ok := allowedDiagnosticComponentProperties[name]; ok {
if value.IsNull() || value.Type() == allowedType {
builder.Set(name, value)
}
}
return true
})
}
}
} else if defaultPropertyName != "" {
builder.Set(defaultPropertyName, ldvalue.String("custom"))
}
}
func makeDiagnosticSDKData() ldvalue.Value {
return ldvalue.ObjectBuild().
Set("name", ldvalue.String("go-server-sdk")).
Set("version", ldvalue.String(Version)).
Build()
}
func durationToMillis(d time.Duration) ldvalue.Value {
return ldvalue.Float64(float64(uint64(d / time.Millisecond)))
}