...

Source file src/github.com/launchdarkly/go-server-sdk/v6/server_side_diagnostics.go

Documentation: github.com/launchdarkly/go-server-sdk/v6

     1  package ldclient
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
     7  	ldevents "github.com/launchdarkly/go-sdk-events/v2"
     8  	"github.com/launchdarkly/go-server-sdk/v6/ldcomponents"
     9  	"github.com/launchdarkly/go-server-sdk/v6/subsystems"
    10  )
    11  
    12  func createDiagnosticsManager(
    13  	context subsystems.ClientContext,
    14  	sdkKey string,
    15  	config Config,
    16  	waitFor time.Duration,
    17  ) *ldevents.DiagnosticsManager {
    18  	id := ldevents.NewDiagnosticID(sdkKey)
    19  	return ldevents.NewDiagnosticsManager(
    20  		id,
    21  		makeDiagnosticConfigData(context, config, waitFor),
    22  		makeDiagnosticSDKData(),
    23  		time.Now(),
    24  		nil,
    25  	)
    26  }
    27  
    28  func makeDiagnosticConfigData(context subsystems.ClientContext, config Config, waitFor time.Duration) ldvalue.Value {
    29  	builder := ldvalue.ObjectBuild().
    30  		Set("startWaitMillis", durationToMillis(waitFor))
    31  
    32  	// Allow each pluggable component to describe its own relevant properties.
    33  	mergeComponentProperties(builder, context, config.HTTP, ldcomponents.HTTPConfiguration(), "")
    34  	mergeComponentProperties(builder, context, config.DataSource, ldcomponents.StreamingDataSource(), "")
    35  	mergeComponentProperties(builder, context, config.DataStore, ldcomponents.InMemoryDataStore(), "dataStoreType")
    36  	mergeComponentProperties(builder, context, config.Events, ldcomponents.SendEvents(), "")
    37  
    38  	return builder.Build()
    39  }
    40  
    41  var allowedDiagnosticComponentProperties = map[string]ldvalue.ValueType{ //nolint:gochecknoglobals
    42  	"allAttributesPrivate":              ldvalue.BoolType,
    43  	"connectTimeoutMillis":              ldvalue.NumberType,
    44  	"customBaseURI":                     ldvalue.BoolType,
    45  	"customEventsURI":                   ldvalue.BoolType,
    46  	"customStreamURI":                   ldvalue.BoolType,
    47  	"diagnosticRecordingIntervalMillis": ldvalue.NumberType,
    48  	"eventsCapacity":                    ldvalue.NumberType,
    49  	"eventsFlushIntervalMillis":         ldvalue.NumberType,
    50  	"pollingIntervalMillis":             ldvalue.NumberType,
    51  	"reconnectTimeMillis":               ldvalue.NumberType,
    52  	"socketTimeoutMillis":               ldvalue.NumberType,
    53  	"streamingDisabled":                 ldvalue.BoolType,
    54  	"userKeysCapacity":                  ldvalue.NumberType,
    55  	"userKeysFlushIntervalMillis":       ldvalue.NumberType,
    56  	"usingProxy":                        ldvalue.BoolType,
    57  	"usingRelayDaemon":                  ldvalue.BoolType,
    58  }
    59  
    60  // Attempts to add relevant configuration properties, if any, from a customizable component:
    61  //   - If the component does not implement DiagnosticDescription, set the defaultPropertyName property to
    62  //     "custom".
    63  //   - If it does implement DiagnosticDescription or DiagnosticDescriptionExt, call the corresponding
    64  //     interface method to get a value.
    65  //   - If the value is a string, then set the defaultPropertyName property to that value.
    66  //   - If the value is an object, then copy all of its properties as long as they are ones we recognize
    67  //     and have the expected type.
    68  func mergeComponentProperties(
    69  	builder *ldvalue.ObjectBuilder,
    70  	context subsystems.ClientContext,
    71  	component interface{},
    72  	defaultComponent interface{},
    73  	defaultPropertyName string,
    74  ) {
    75  	if component == nil {
    76  		component = defaultComponent
    77  	}
    78  	var componentDesc ldvalue.Value
    79  	if dd, ok := component.(subsystems.DiagnosticDescription); ok {
    80  		componentDesc = dd.DescribeConfiguration(context)
    81  	}
    82  	if !componentDesc.IsNull() {
    83  		if componentDesc.Type() == ldvalue.StringType && defaultPropertyName != "" {
    84  			builder.Set(defaultPropertyName, componentDesc)
    85  		} else if componentDesc.Type() == ldvalue.ObjectType {
    86  			for _, name := range componentDesc.Keys(nil) {
    87  				if allowedType, ok := allowedDiagnosticComponentProperties[name]; ok {
    88  					value := componentDesc.GetByKey(name)
    89  					if value.IsNull() || value.Type() == allowedType {
    90  						builder.Set(name, value)
    91  					}
    92  				}
    93  			}
    94  		}
    95  	} else if defaultPropertyName != "" {
    96  		builder.SetString(defaultPropertyName, "custom")
    97  	}
    98  }
    99  
   100  func makeDiagnosticSDKData() ldvalue.Value {
   101  	return ldvalue.ObjectBuild().
   102  		Set("name", ldvalue.String("go-server-sdk")).
   103  		Set("version", ldvalue.String(Version)).
   104  		Build()
   105  }
   106  
   107  func durationToMillis(d time.Duration) ldvalue.Value {
   108  	return ldvalue.Float64(float64(uint64(d / time.Millisecond)))
   109  }
   110  

View as plain text