-
Notifications
You must be signed in to change notification settings - Fork 18
/
server_side_diagnostics.go
109 lines (99 loc) · 4.11 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
104
105
106
107
108
109
package ldclient
import (
"time"
"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
ldevents "github.com/launchdarkly/go-sdk-events/v3"
"github.com/launchdarkly/go-server-sdk/v7/ldcomponents"
"github.com/launchdarkly/go-server-sdk/v7/subsystems"
)
func createDiagnosticsManager(
context subsystems.ClientContext,
sdkKey string,
config Config,
waitFor time.Duration,
) *ldevents.DiagnosticsManager {
id := ldevents.NewDiagnosticID(sdkKey)
return ldevents.NewDiagnosticsManager(
id,
makeDiagnosticConfigData(context, config, waitFor),
makeDiagnosticSDKData(),
time.Now(),
nil,
)
}
func makeDiagnosticConfigData(context subsystems.ClientContext, 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, context, config.HTTP, ldcomponents.HTTPConfiguration(), "")
mergeComponentProperties(builder, context, config.DataSource, ldcomponents.StreamingDataSource(), "")
mergeComponentProperties(builder, context, config.DataStore, ldcomponents.InMemoryDataStore(), "dataStoreType")
mergeComponentProperties(builder, context, 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,
"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 or DiagnosticDescriptionExt, call the corresponding
// interface 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,
context subsystems.ClientContext,
component interface{},
defaultComponent interface{},
defaultPropertyName string,
) {
if component == nil {
component = defaultComponent
}
var componentDesc ldvalue.Value
if dd, ok := component.(subsystems.DiagnosticDescription); ok {
componentDesc = dd.DescribeConfiguration(context)
}
if !componentDesc.IsNull() {
if componentDesc.Type() == ldvalue.StringType && defaultPropertyName != "" {
builder.Set(defaultPropertyName, componentDesc)
} else if componentDesc.Type() == ldvalue.ObjectType {
for _, name := range componentDesc.Keys(nil) {
if allowedType, ok := allowedDiagnosticComponentProperties[name]; ok {
value := componentDesc.GetByKey(name)
if value.IsNull() || value.Type() == allowedType {
builder.Set(name, value)
}
}
}
}
} else if defaultPropertyName != "" {
builder.SetString(defaultPropertyName, "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)))
}