in config.go [413:605]
func (t *Tracer) updateRemoteConfig(logger Logger, old, attrs map[string]string) {
warningf := func(string, ...interface{}) {}
debugf := func(string, ...interface{}) {}
errorf := func(string, ...interface{}) {}
if logger != nil {
warningf = logger.Warningf
debugf = logger.Debugf
errorf = logger.Errorf
}
envName := func(k string) string {
return "ELASTIC_APM_" + strings.ToUpper(k)
}
var updates []func(cfg *instrumentationConfig)
for k, v := range attrs {
if oldv, ok := old[k]; ok && oldv == v {
continue
}
switch envName(k) {
case envCaptureBody:
value, err := parseCaptureBody(k, v)
if err != nil {
errorf("central config failure: %s", err)
delete(attrs, k)
continue
} else {
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.captureBody = value
})
}
case envMaxSpans:
value, err := strconv.Atoi(v)
if err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
} else {
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.maxSpans = value
})
}
case envExitSpanMinDuration:
duration, err := configutil.ParseDurationOptions(v, configutil.DurationOptions{
MinimumDurationUnit: time.Microsecond,
})
if err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
}
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.exitSpanMinDuration = duration
})
case envIgnoreURLs:
matchers := configutil.ParseWildcardPatterns(v)
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.ignoreTransactionURLs = matchers
})
case envRecording:
recording, err := strconv.ParseBool(v)
if err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
} else {
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.recording = recording
})
}
case envSanitizeFieldNames:
matchers := configutil.ParseWildcardPatterns(v)
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.sanitizedFieldNames = matchers
})
case envContinuationStrategy:
if err := validateContinuationStrategy(v); err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
}
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.continuationStrategy = v
})
case envSpanStackTraceMinDuration:
duration, err := configutil.ParseDuration(v)
if err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
} else {
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.spanStackTraceMinDuration = duration
})
}
case envStackTraceLimit:
limit, err := strconv.Atoi(v)
if err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
} else {
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.stackTraceLimit = limit
})
}
case envTransactionSampleRate:
sampler, err := parseSampleRate(k, v)
if err != nil {
errorf("central config failure: %s", err)
delete(attrs, k)
continue
} else {
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.sampler = sampler
})
}
case apmlog.EnvLogLevel:
level, err := apmlog.ParseLogLevel(v)
if err != nil {
errorf("central config failure: %s", err)
delete(attrs, k)
continue
}
if dl := apmlog.DefaultLogger(); dl != nil && dl == logger {
updates = append(updates, func(*instrumentationConfig) {
dl.SetLevel(level)
})
} else {
warningf("central config ignored: %s set to %s, but custom logger in use", k, v)
delete(attrs, k)
continue
}
case envSpanCompressionEnabled:
val, err := strconv.ParseBool(v)
if err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
}
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.compressionOptions.enabled = val
})
case envSpanCompressionExactMatchMaxDuration:
duration, err := configutil.ParseDuration(v)
if err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
}
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.compressionOptions.exactMatchMaxDuration = duration
})
case envSpanCompressionSameKindMaxDuration:
duration, err := configutil.ParseDuration(v)
if err != nil {
errorf("central config failure: failed to parse %s: %s", k, err)
delete(attrs, k)
continue
}
updates = append(updates, func(cfg *instrumentationConfig) {
cfg.compressionOptions.sameKindMaxDuration = duration
})
default:
warningf("central config failure: unsupported config: %s", k)
delete(attrs, k)
continue
}
debugf("central config update: updated %s to %s", k, v)
}
for k := range old {
if _, ok := attrs[k]; ok {
continue
}
updates = append(updates, func(cfg *instrumentationConfig) {
if f, ok := cfg.local[envName(k)]; ok {
f(&cfg.instrumentationConfigValues)
}
})
debugf("central config update: reverted %s to local config", k)
}
if updates != nil {
remote := make(map[string]struct{})
for k := range attrs {
remote[envName(k)] = struct{}{}
}
t.updateInstrumentationConfig(func(cfg *instrumentationConfig) {
cfg.remote = remote
for _, update := range updates {
update(cfg)
}
})
}
}