Skip to content

Commit

Permalink
Add trace file for "next dev" (#29633)
Browse files Browse the repository at this point in the history
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
  • Loading branch information
timneutkens and sokra committed Oct 5, 2021
1 parent 7af61f6 commit f74ee78
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export default async function build(
.traceChild('load-next-config')
.traceAsyncFn(() => loadConfig(PHASE_PRODUCTION_BUILD, dir, conf))
const distDir = path.join(dir, config.distDir)
setGlobal('phase', PHASE_PRODUCTION_BUILD)
setGlobal('distDir', distDir)

const { target } = config
Expand Down
2 changes: 2 additions & 0 deletions packages/next/server/dev/next-dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ export default class DevServer extends Server {
}

async prepare(): Promise<void> {
setGlobal('distDir', this.distDir)
setGlobal('phase', PHASE_DEVELOPMENT_SERVER)
await verifyTypeScriptSetup(
this.dir,
this.pagesDir!,
Expand Down
79 changes: 67 additions & 12 deletions packages/next/trace/report/to-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,64 @@ 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'

let writeStream: fs.WriteStream
let writeStream: RotatingWriteStream
let traceId: string
let batch: ReturnType<typeof batcher> | undefined

const writeStreamOptions = {
flags: 'a',
encoding: 'utf8',
}
class RotatingWriteStream {
file: string
writeStream!: fs.WriteStream
size: number
sizeLimit: number
isRotating: Promise<void> | undefined
constructor(file: string, sizeLimit: number) {
this.file = file
this.size = 0
this.sizeLimit = sizeLimit
this.createWriteStream()
}
private createWriteStream() {
this.writeStream = fs.createWriteStream(this.file, writeStreamOptions)
}
// Recreate the file
private rotate(): void {
this.end()
try {
fs.unlinkSync(this.file)
} catch (err: any) {
// It's fine if the file does not exist yet
if (err.code !== 'ENOENT') {
throw err
}
}
this.size = 0
this.createWriteStream()
}
async write(data: string): Promise<void> {
this.size += data.length

if (this.size > this.sizeLimit) {
this.rotate()
}

if (!this.writeStream.write(data, 'utf8')) {
await new Promise<void>((resolve, _reject) => {
this.writeStream.once('drain', resolve)
})
}
}

end(): void {
this.writeStream.end('', 'utf8')
}
}

const reportToLocalHost = (
name: string,
duration: number,
Expand All @@ -17,7 +70,8 @@ const reportToLocalHost = (
attrs?: Object
) => {
const distDir = traceGlobals.get('distDir')
if (!distDir) {
const phase = traceGlobals.get('phase')
if (!distDir || !phase) {
return
}

Expand All @@ -30,18 +84,15 @@ const reportToLocalHost = (
if (!writeStream) {
await fs.promises.mkdir(distDir, { recursive: true })
const file = path.join(distDir, 'trace')
writeStream = fs.createWriteStream(file, {
flags: 'a',
encoding: 'utf8',
})
writeStream = new RotatingWriteStream(
file,
// Development is limited to 50MB, production is unlimited
phase === PHASE_DEVELOPMENT_SERVER ? 52428800 : Infinity
)
}
const eventsJson = JSON.stringify(events)
try {
await new Promise<void>((resolve, reject) => {
writeStream.write(eventsJson + '\n', 'utf8', (err) => {
err ? reject(err) : resolve()
})
})
await writeStream.write(eventsJson + '\n')
} catch (err) {
console.log(err)
}
Expand All @@ -63,7 +114,11 @@ export default {
flushAll: () =>
batch
? batch.flushAll().then(() => {
writeStream.end('', 'utf8')
const phase = traceGlobals.get('phase')
// Only end writeStream when manually flushing in production
if (phase !== PHASE_DEVELOPMENT_SERVER) {
writeStream.end()
}
})
: undefined,
report: reportToLocalHost,
Expand Down

0 comments on commit f74ee78

Please sign in to comment.