@bugsnag/core-performance
Version:
Core performance client
63 lines (60 loc) • 2.39 kB
JavaScript
import { spanToJson } from './span.js';
class TracePayloadEncoder {
constructor(clock, configuration, resourceAttributeSource) {
this.clock = clock;
this.configuration = configuration;
this.resourceAttributeSource = resourceAttributeSource;
}
async encode(spans) {
const resourceAttributes = await this.resourceAttributeSource(this.configuration);
const jsonSpans = Array(spans.length);
for (let i = 0; i < spans.length; ++i) {
jsonSpans[i] = spanToJson(spans[i], this.clock);
}
const deliveryPayload = {
resourceSpans: [
{
resource: { attributes: resourceAttributes.toJson() },
scopeSpans: [{ spans: jsonSpans }]
}
]
};
return {
body: deliveryPayload,
headers: {
'Bugsnag-Api-Key': this.configuration.apiKey,
'Content-Type': 'application/json',
// Do not set 'Bugsnag-Span-Sampling' if the SDK is configured with samplingProbability
...(this.configuration.samplingProbability !== undefined ? {} : { 'Bugsnag-Span-Sampling': this.generateSamplingHeader(spans) })
}
};
}
generateSamplingHeader(spans) {
if (spans.length === 0) {
return '1:0';
}
const spanCounts = Object.create(null);
for (const span of spans) {
const existingValue = spanCounts[span.samplingProbability.raw] || 0;
spanCounts[span.samplingProbability.raw] = existingValue + 1;
}
const rawProbabilities = Object.keys(spanCounts);
const pairs = Array(rawProbabilities.length);
for (let i = 0; i < rawProbabilities.length; ++i) {
const rawProbability = rawProbabilities[i];
pairs[i] = `${rawProbability}:${spanCounts[rawProbability]}`;
}
return pairs.join(';');
}
}
const retryCodes = new Set([402, 407, 408, 429]);
function responseStateFromStatusCode(statusCode) {
if (statusCode >= 200 && statusCode < 300) {
return 'success';
}
if (statusCode >= 400 && statusCode < 500 && !retryCodes.has(statusCode)) {
return 'failure-discard';
}
return 'failure-retryable';
}
export { TracePayloadEncoder, responseStateFromStatusCode };