diff --git a/packages/next/trace/report/index.ts b/packages/next/trace/report/index.ts index d817802d45356..8492670737c91 100644 --- a/packages/next/trace/report/index.ts +++ b/packages/next/trace/report/index.ts @@ -1,7 +1,4 @@ -import { TARGET, SpanId } from '../shared' -import reportToConsole from './to-console' -import reportToZipkin from './to-zipkin' -import reportToJaeger from './to-jaeger' +import { SpanId } from '../shared' import reportToTelemetry from './to-telemetry' import reportToJson from './to-json' @@ -42,28 +39,5 @@ class MultiReporter implements Reporter { } } -const target = - process.env.TRACE_TARGET && process.env.TRACE_TARGET in TARGET - ? TARGET[process.env.TRACE_TARGET as TARGET] - : TARGET.TELEMETRY - -if (process.env.TRACE_TARGET && !target) { - console.info( - 'For TRACE_TARGET, please specify one of: CONSOLE, ZIPKIN, TELEMETRY' - ) -} - -let traceTargetReporter: Reporter - -if (target === TARGET.CONSOLE) { - traceTargetReporter = reportToConsole -} else if (target === TARGET.ZIPKIN) { - traceTargetReporter = reportToZipkin -} else if (target === TARGET.JAEGER) { - traceTargetReporter = reportToJaeger -} else { - traceTargetReporter = reportToTelemetry -} - // JSON is always reported to allow for diagnostics -export const reporter = new MultiReporter([reportToJson, traceTargetReporter]) +export const reporter = new MultiReporter([reportToJson, reportToTelemetry]) diff --git a/packages/next/trace/report/to-console.ts b/packages/next/trace/report/to-console.ts deleted file mode 100644 index 13e44ffa9b9c2..0000000000000 --- a/packages/next/trace/report/to-console.ts +++ /dev/null @@ -1,32 +0,0 @@ -import * as Log from '../../build/output/log' -const idToName = new Map() - -const reportToConsole = ( - spanName: string, - duration: number, - _timestamp: number, - id: string, - parentId?: string, - attrs?: Object -) => { - idToName.set(id, spanName) - - const parentStr = - parentId && idToName.has(parentId) - ? `, parent: ${idToName.get(parentId)}` - : '' - const attrsStr = attrs - ? `, ${Object.entries(attrs) - .map(([key, val]) => `${key}: ${val}`) - .join(', ')}` - : '' - - Log.trace( - `${spanName} took ${Number(duration) / 1000} ms${parentStr}${attrsStr}` - ) -} - -export default { - flushAll: () => {}, - report: reportToConsole, -} diff --git a/packages/next/trace/report/to-jaeger.ts b/packages/next/trace/report/to-jaeger.ts deleted file mode 100644 index f66c2d7a3ac13..0000000000000 --- a/packages/next/trace/report/to-jaeger.ts +++ /dev/null @@ -1,83 +0,0 @@ -import retry from 'next/dist/compiled/async-retry' -import { randomBytes } from 'crypto' -import fetch from 'node-fetch' -import * as Log from '../../build/output/log' -// Jaeger uses Zipkin's reporting -import { batcher } from './to-zipkin' - -let traceId: string -let batch: ReturnType | 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` - -function logWebUrl() { - Log.info( - `Jaeger trace will be available on ${jaegerWebUiUrl}/trace/${traceId}` - ) -} - -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') - logWebUrl() - } - - if (!batch) { - batch = batcher((events) => { - const eventsJson = JSON.stringify(events) - // Ensure ECONNRESET error is retried 3 times before erroring out - return retry( - () => - // Send events to jaeger's zipkin endpoint - fetch(zipkinAPI, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: eventsJson, - }), - { minTimeout: 500, retries: 3, factor: 1 } - ) - .then(async (res: any) => { - if (res.status !== 202) { - console.log({ - status: res.status, - body: await res.text(), - events: eventsJson, - }) - } - }) - .catch(console.log) - }) - } - - batch.report({ - traceId, - parentId, - name, - id, - timestamp, - duration, - localEndpoint, - tags: attrs, - }) -} - -export default { - flushAll: () => - batch ? batch.flushAll().then(() => logWebUrl()) : undefined, - report: reportToLocalHost, -} diff --git a/packages/next/trace/report/to-json.ts b/packages/next/trace/report/to-json.ts index cb3d16c53b95f..188ed48bdf5e2 100644 --- a/packages/next/trace/report/to-json.ts +++ b/packages/next/trace/report/to-json.ts @@ -1,10 +1,53 @@ import { randomBytes } from 'crypto' -import { batcher } from './to-zipkin' import { traceGlobals } from '../shared' import fs from 'fs' import path from 'path' import { PHASE_DEVELOPMENT_SERVER } from '../../shared/lib/constants' +const localEndpoint = { + serviceName: 'nextjs', + ipv4: '127.0.0.1', + port: 9411, +} + +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 +export function batcher(reportEvents: (evts: Event[]) => Promise) { + const events: Event[] = [] + // Promise queue to ensure events are always sent on flushAll + const queue = new Set() + return { + flushAll: async () => { + await Promise.all(queue) + if (events.length > 0) { + await reportEvents(events) + events.length = 0 + } + }, + report: (event: Event) => { + events.push(event) + + if (events.length > 100) { + const evts = events.slice() + events.length = 0 + const report = reportEvents(evts) + queue.add(report) + report.then(() => queue.delete(report)) + } + }, + } +} + let writeStream: RotatingWriteStream let traceId: string let batch: ReturnType | undefined diff --git a/packages/next/trace/report/to-zipkin.ts b/packages/next/trace/report/to-zipkin.ts deleted file mode 100644 index 089fa74a19ac9..0000000000000 --- a/packages/next/trace/report/to-zipkin.ts +++ /dev/null @@ -1,101 +0,0 @@ -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: string -let batch: ReturnType | undefined - -const localEndpoint = { - serviceName: 'nextjs', - ipv4: '127.0.0.1', - port: 9411, -} -const zipkinUrl = `http://${localEndpoint.ipv4}:${localEndpoint.port}` -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 -export function batcher(reportEvents: (evts: Event[]) => Promise) { - const events: Event[] = [] - // Promise queue to ensure events are always sent on flushAll - const queue = new Set() - return { - flushAll: async () => { - await Promise.all(queue) - if (events.length > 0) { - await reportEvents(events) - events.length = 0 - } - }, - report: (event: Event) => { - events.push(event) - - if (events.length > 100) { - const evts = events.slice() - events.length = 0 - const report = reportEvents(evts) - queue.add(report) - report.then(() => queue.delete(report)) - } - }, - } -} - -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( - `Zipkin trace will be available on ${zipkinUrl}/zipkin/traces/${traceId}` - ) - } - - if (!batch) { - batch = batcher((events) => { - // Ensure ECONNRESET error is retried 3 times before erroring out - return 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.report({ - traceId, - parentId, - name, - id, - timestamp, - duration, - localEndpoint, - tags: attrs, - }) -} - -export default { - flushAll: () => (batch ? batch.flushAll() : undefined), - report: reportToLocalHost, -} diff --git a/packages/next/trace/shared.ts b/packages/next/trace/shared.ts index dc66e5d24b526..159218db82085 100644 --- a/packages/next/trace/shared.ts +++ b/packages/next/trace/shared.ts @@ -1,11 +1,4 @@ // eslint typescript has a bug with TS enums -/* eslint-disable no-shadow */ -export enum TARGET { - CONSOLE = 'CONSOLE', - ZIPKIN = 'ZIPKIN', - JAEGER = 'JAEGER', - TELEMETRY = 'TELEMETRY', -} export type SpanId = string