in apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceState.java [83:155]
public void addTextHeader(String headerValue) {
cachedResultHeader = null;
int vendorStart = headerValue.indexOf(VENDOR_PREFIX);
if (vendorStart < 0) {
// no ES entry
tracestate.add(headerValue);
return;
}
int vendorEnd = headerValue.indexOf(VENDOR_SEPARATOR, vendorStart);
if (vendorEnd < 0) {
vendorEnd = headerValue.length();
}
int sampleRateStart = headerValue.indexOf(SAMPLE_RATE_PREFIX, vendorStart);
if (sampleRateStart < 0) {
// no sample rate, rewrite
log.warn("invalid header, no sample rate {}", headerValue);
headerValue = rewriteRemoveInvalidHeader(headerValue, vendorStart, vendorEnd);
if (headerValue.length() > 0) {
tracestate.add(headerValue);
}
return;
}
int valueStart = sampleRateStart + 2;
int valueEnd = valueStart;
if (valueEnd < headerValue.length()) {
char c = headerValue.charAt(valueEnd);
while (valueEnd < headerValue.length() && c != VENDOR_SEPARATOR && c != ENTRY_SEPARATOR) {
c = headerValue.charAt(valueEnd++);
}
if (valueEnd < headerValue.length()) {
// end due to separator char that needs to be trimmed
valueEnd--;
}
}
String headerValueString = headerValue.substring(valueStart, valueEnd);
double value = Double.NaN;
try {
value = Double.parseDouble(headerValueString);
} catch (NumberFormatException e) {
// silently ignored
}
if (Double.isNaN(value) || value < 0 || value > 1) {
log.warn("invalid sample rate header {}", headerValueString);
headerValue = rewriteRemoveInvalidHeader(headerValue, vendorStart, vendorEnd);
} else {
if (!Double.isNaN(sampleRate)) {
log.warn("sample rate already set to {}, trying to set it to {} through header will be ignored", sampleRate, value);
headerValue = rewriteRemoveInvalidHeader(headerValue, vendorStart, vendorEnd);
} else {
// ensure proper rounding of sample rate to minimize storage
// even if configuration should not allow this, any upstream value might require rounding
double rounded = DOUBLE_CONVERTER.round(value);
if (rounded != value) {
// value needs to be re-written due to rounding
headerValue = rewriteRoundedHeader(headerValue, valueStart, valueEnd, rounded);
sampleRate = rounded;
} else {
sampleRate = value;
}
}
}
if (!headerValue.isEmpty()) {
tracestate.add(headerValue);
}
}