github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/settings/registry.go (about)

     1  // Copyright 2017 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package settings
    12  
    13  import (
    14  	"fmt"
    15  	"sort"
    16  	"unicode"
    17  	"unicode/utf8"
    18  )
    19  
    20  // registry contains all defined settings, their types and default values.
    21  //
    22  // The registry does not store the current values of the settings; those are
    23  // stored separately in Values, allowing multiple independent instances
    24  // of each setting in the registry.
    25  //
    26  // registry should never be mutated after creation (except in tests), as it is
    27  // read concurrently by different callers.
    28  var registry = make(map[string]extendedSetting)
    29  
    30  // TestingSaveRegistry can be used in tests to save/restore the current
    31  // contents of the registry.
    32  func TestingSaveRegistry() func() {
    33  	var origRegistry = make(map[string]extendedSetting)
    34  	for k, v := range registry {
    35  		origRegistry[k] = v
    36  	}
    37  	return func() {
    38  		registry = origRegistry
    39  	}
    40  }
    41  
    42  // When a setting is removed, it should be added to this list so that we cannot
    43  // accidentally reuse its name, potentially mis-handling older values.
    44  var retiredSettings = map[string]struct{}{
    45  	// removed as of 2.0.
    46  	"kv.gc.batch_size":                     {},
    47  	"kv.transaction.max_intents":           {},
    48  	"diagnostics.reporting.report_metrics": {},
    49  	// removed as of 2.1.
    50  	"kv.allocator.stat_based_rebalancing.enabled": {},
    51  	"kv.allocator.stat_rebalance_threshold":       {},
    52  	// removed as of 19.1.
    53  	"kv.raft_log.synchronize": {},
    54  	// removed as of 19.2.
    55  	"schemachanger.bulk_index_backfill.enabled":            {},
    56  	"rocksdb.ingest_backpressure.delay_l0_file":            {}, // never used
    57  	"server.heap_profile.system_memory_threshold_fraction": {},
    58  	"timeseries.storage.10s_resolution_ttl":                {},
    59  	"changefeed.push.enabled":                              {},
    60  	"sql.defaults.optimizer":                               {},
    61  	"kv.bulk_io_write.addsstable_max_rate":                 {},
    62  	// removed as of 20.1.
    63  	"schemachanger.lease.duration":       {},
    64  	"schemachanger.lease.renew_fraction": {},
    65  	// removed as of 20.2.
    66  	"rocksdb.ingest_backpressure.pending_compaction_threshold": {},
    67  	"sql.distsql.temp_storage.joins":                           {},
    68  	"sql.distsql.temp_storage.sorts":                           {},
    69  	"sql.distsql.distribute_index_joins":                       {},
    70  	"sql.distsql.merge_joins.enabled":                          {},
    71  }
    72  
    73  // register adds a setting to the registry.
    74  func register(key, desc string, s extendedSetting) {
    75  	if _, ok := retiredSettings[key]; ok {
    76  		panic(fmt.Sprintf("cannot reuse previously defined setting name: %s", key))
    77  	}
    78  	if _, ok := registry[key]; ok {
    79  		panic(fmt.Sprintf("setting already defined: %s", key))
    80  	}
    81  	if len(desc) == 0 {
    82  		panic(fmt.Sprintf("setting missing description: %s", key))
    83  	}
    84  	if r, _ := utf8.DecodeRuneInString(desc); unicode.IsUpper(r) {
    85  		panic(fmt.Sprintf("setting descriptions should start with a lowercase letter: %q", desc))
    86  	}
    87  	s.setDescription(desc)
    88  	registry[key] = s
    89  	s.setSlotIdx(len(registry))
    90  }
    91  
    92  // NumRegisteredSettings returns the number of registered settings.
    93  func NumRegisteredSettings() int { return len(registry) }
    94  
    95  // Keys returns a sorted string array with all the known keys.
    96  func Keys() (res []string) {
    97  	res = make([]string, 0, len(registry))
    98  	for k := range registry {
    99  		if registry[k].isRetired() {
   100  			continue
   101  		}
   102  		res = append(res, k)
   103  	}
   104  	sort.Strings(res)
   105  	return res
   106  }
   107  
   108  // Lookup returns a Setting by name along with its description.
   109  // For non-reportable setting, it instantiates a MaskedSetting
   110  // to masquerade for the underlying setting.
   111  func Lookup(name string, purpose LookupPurpose) (Setting, bool) {
   112  	v, ok := registry[name]
   113  	var setting Setting = v
   114  	if ok && purpose == LookupForReporting && !v.isReportable() {
   115  		setting = &MaskedSetting{setting: v}
   116  	}
   117  	return setting, ok
   118  }
   119  
   120  // LookupPurpose indicates what is being done with the setting.
   121  type LookupPurpose int
   122  
   123  const (
   124  	// LookupForReporting indicates that a setting is being retrieved
   125  	// for reporting and sensitive values should be scrubbed.
   126  	LookupForReporting LookupPurpose = iota
   127  	// LookupForLocalAccess indicates that a setting is being
   128  	// retrieved for local processing within the cluster and
   129  	// all values should be accessible
   130  	LookupForLocalAccess
   131  )
   132  
   133  // ReadableTypes maps our short type identifiers to friendlier names.
   134  var ReadableTypes = map[string]string{
   135  	"s": "string",
   136  	"i": "integer",
   137  	"f": "float",
   138  	"b": "boolean",
   139  	"z": "byte size",
   140  	"d": "duration",
   141  	"e": "enumeration",
   142  	"m": "custom validation",
   143  }
   144  
   145  // RedactedValue returns a string representation of the value for settings
   146  // types the are not considered sensitive (numbers, bools, etc) or
   147  // <redacted> for those with values could store sensitive things (i.e. strings).
   148  func RedactedValue(name string, values *Values) string {
   149  	if setting, ok := Lookup(name, LookupForReporting); ok {
   150  		return setting.String(values)
   151  	}
   152  	return "<unknown>"
   153  }