(spans: [SentrySpan, ...SentrySpan[]], client?: Client)
| 122 | * Takes an optional client and runs spans through `beforeSendSpan` if available. |
| 123 | */ |
| 124 | export function createSpanEnvelope(spans: [SentrySpan, ...SentrySpan[]], client?: Client): SpanEnvelope { |
| 125 | function dscHasRequiredProps(dsc: Partial<DynamicSamplingContext>): dsc is DynamicSamplingContext { |
| 126 | return !!dsc.trace_id && !!dsc.public_key; |
| 127 | } |
| 128 | |
| 129 | // For the moment we'll obtain the DSC from the first span in the array |
| 130 | // This might need to be changed if we permit sending multiple spans from |
| 131 | // different segments in one envelope |
| 132 | const dsc = getDynamicSamplingContextFromSpan(spans[0]); |
| 133 | |
| 134 | const dsn = client?.getDsn(); |
| 135 | const tunnel = client?.getOptions().tunnel; |
| 136 | |
| 137 | const headers: SpanEnvelope[0] = { |
| 138 | sent_at: new Date(safeDateNow()).toISOString(), |
| 139 | ...(dscHasRequiredProps(dsc) && { trace: dsc }), |
| 140 | ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }), |
| 141 | }; |
| 142 | |
| 143 | const { beforeSendSpan, ignoreSpans } = client?.getOptions() || {}; |
| 144 | |
| 145 | const filteredSpans = ignoreSpans?.length |
| 146 | ? spans.filter(span => { |
| 147 | const json = spanToJSON(span); |
| 148 | return !shouldIgnoreSpan({ description: json.description, op: json.op, attributes: json.data }, ignoreSpans); |
| 149 | }) |
| 150 | : spans; |
| 151 | const droppedSpans = spans.length - filteredSpans.length; |
| 152 | |
| 153 | if (droppedSpans) { |
| 154 | client?.recordDroppedEvent('before_send', 'span', droppedSpans); |
| 155 | } |
| 156 | |
| 157 | const convertToSpanJSON = beforeSendSpan |
| 158 | ? (span: SentrySpan) => { |
| 159 | const spanJson = spanToJSON(span); |
| 160 | const processedSpan = !isStreamedBeforeSendSpanCallback(beforeSendSpan) ? beforeSendSpan(spanJson) : spanJson; |
| 161 | |
| 162 | if (!processedSpan) { |
| 163 | showSpanDropWarning(); |
| 164 | return spanJson; |
| 165 | } |
| 166 | |
| 167 | return processedSpan; |
| 168 | } |
| 169 | : spanToJSON; |
| 170 | |
| 171 | const items: SpanItem[] = []; |
| 172 | for (const span of filteredSpans) { |
| 173 | const spanJson = convertToSpanJSON(span); |
| 174 | if (spanJson) { |
| 175 | items.push(createSpanEnvelopeItem(spanJson)); |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | return createEnvelope<SpanEnvelope>(headers, items); |
| 180 | } |
| 181 |
no test coverage detected