rsnext/packages/next/telemetry/trace/report/to-jaeger.ts
Tim Neutkens 76cc01f6b5
Add support for Jaeger trace target (#28129)
Adds support for Jaeger next to Zipkin as a trace target.

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes
2021-08-15 19:26:02 +00:00

90 lines
2.2 KiB
TypeScript

import retry from 'next/dist/compiled/async-retry'
import { randomBytes } from 'crypto'
import fetch from 'node-fetch'
import * as Log from '../../../build/output/log'
let traceId = process.env.TRACE_ID
let batch: ReturnType<typeof batcher> | undefined
const localEndpoint = {
serviceName: 'nextjs',
ipv4: '127.0.0.1',
port: 9411,
}
// Jaeger supports Zipkin's reporting API
const zipkinUrl = `http://${localEndpoint.ipv4}:${localEndpoint.port}`
const jaegerWebUiUrl = `http://${localEndpoint.ipv4}:16686`
const zipkinAPI = `${zipkinUrl}/api/v2/spans`
type Event = {
traceId: string
parentId?: string
name: string
id: string
timestamp: number
duration: number
localEndpoint: typeof localEndpoint
tags?: Object
}
// Batch events as zipkin allows for multiple events to be sent in one go
function batcher(reportEvents: (evts: Event[]) => void) {
const events: Event[] = []
let timeout: ReturnType<typeof setTimeout> | undefined
return (event: Event) => {
events.push(event)
// setTimeout is used instead of setInterval to ensure events sending does not block exiting the program
if (!timeout) {
timeout = setTimeout(() => {
reportEvents(events.slice())
events.length = 0
timeout = undefined
}, 1500)
}
}
}
const reportToLocalHost = (
name: string,
duration: number,
timestamp: number,
id: string,
parentId?: string,
attrs?: Object
) => {
if (!traceId) {
traceId = process.env.TRACE_ID = randomBytes(8).toString('hex')
Log.info(
`Jaeger trace will be available on ${jaegerWebUiUrl}/trace/${traceId}`
)
}
if (!batch) {
batch = batcher((events) => {
// Ensure ECONNRESET error is retried 3 times before erroring out
retry(
() =>
// Send events to zipkin
fetch(zipkinAPI, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(events),
}),
{ minTimeout: 500, retries: 3, factor: 1 }
).catch(console.log)
})
}
batch({
traceId,
parentId,
name,
id,
timestamp,
duration,
localEndpoint,
tags: attrs,
})
}
export default reportToLocalHost