Skip to content

Commit

Permalink
feat(log): improve dev/build logs (#62946)
Browse files Browse the repository at this point in the history
Co-authored-by: Jiachi Liu <inbox@huozhi.im>
  • Loading branch information
balazsorban44 and huozhi committed Mar 26, 2024
1 parent 740d103 commit 7569c80
Show file tree
Hide file tree
Showing 21 changed files with 324 additions and 370 deletions.
17 changes: 7 additions & 10 deletions packages/next/src/build/progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,16 @@ export const createProgress = (total: number, label: string) => {
}

const isFinished = curProgress === total
const message = `${label} (${curProgress}/${total})`
if (progressSpinner && !isFinished) {
progressSpinner.setText(`${label} (${curProgress}/${total})`)
progressSpinner.setText(message)
} else {
if (progressSpinner) {
progressSpinner.stop()
progressSpinner?.stop()
if (isFinished) {
Log.event(message)
} else {
Log.info(`${message} ${process.stdout.isTTY ? '\n' : '\r'}`)
}
console.log(
` ${
isFinished ? Log.prefixes.event : Log.prefixes.info
} ${label} (${curProgress}/${total}) ${
isFinished ? '' : process.stdout.isTTY ? '\n' : '\r'
}`
)
}
}
}
6 changes: 3 additions & 3 deletions packages/next/src/build/spinner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ export default function createSpinner(
console.warn = origWarn
console.error = origError
}
spinner.setText = (newText: string) => {
spinner.setText = (newText) => {
text = newText
prefixText = ` ${Log.prefixes.info} ${newText} `
spinner!.prefixText = prefixText
return spinner!
}
spinner.stop = (): ora.Ora => {
spinner.stop = () => {
origStop()
resetLog()
return spinner!
}
spinner.stopAndPersist = (): ora.Ora => {
spinner.stopAndPersist = () => {
// Add \r at beginning to reset the current line of loading status text
const suffixText = `\r ${Log.prefixes.event} ${text} `
if (spinner) {
Expand Down
17 changes: 4 additions & 13 deletions packages/next/src/build/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ export async function printTreeView(
if (item === '/_app' || item === '/_app.server') {
symbol = ' '
} else if (isEdgeRuntime(pageInfo?.runtime)) {
symbol = ''
symbol = 'ƒ'
} else if (pageInfo?.isPPR) {
if (
// If the page has an empty prelude, then it's equivalent to a dynamic page
Expand All @@ -490,7 +490,7 @@ export async function printTreeView(
// since in this case we're able to partially prerender it
(pageInfo.isDynamicAppRoute && !pageInfo.hasPostponed)
) {
symbol = 'λ'
symbol = 'ƒ'
} else if (!pageInfo?.hasPostponed) {
symbol = '○'
} else {
Expand All @@ -501,7 +501,7 @@ export async function printTreeView(
} else if (pageInfo?.isSSG) {
symbol = '●'
} else {
symbol = 'λ'
symbol = 'ƒ'
}

usedSymbols.add(symbol)
Expand Down Expand Up @@ -749,16 +749,7 @@ export async function printTreeView(
'(Partial Prerender)',
'prerendered as static HTML with dynamic server-streamed content',
],
usedSymbols.has('λ') && [
'λ',
'(Dynamic)',
`server-rendered on demand using Node.js`,
],
usedSymbols.has('ℇ') && [
'ℇ',
'(Edge Runtime)',
`server-rendered on demand using the Edge Runtime`,
],
usedSymbols.has('ƒ') && ['ƒ', '(Dynamic)', `server-rendered on demand`],
].filter((x) => x) as [string, string, string][],
{
align: ['l', 'l', 'l'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { normalizeAppPath } from '../../../../shared/lib/router/utils/app-paths'
import type { SizeLimit } from '../../../../../types'
import { internal_getCurrentFunctionWaitUntil } from '../../../../server/web/internal-edge-wait-until'
import type { PAGE_TYPES } from '../../../../lib/page-types'
import type { NextRequestHint } from '../../../../server/web/adapter'

export function getRender({
dev,
Expand Down Expand Up @@ -151,23 +152,23 @@ export function getRender({

const handler = server.getRequestHandler()

return async function render(request: Request, event: NextFetchEvent) {
return async function render(
request: NextRequestHint,
event?: NextFetchEvent
) {
const extendedReq = new WebNextRequest(request)
const extendedRes = new WebNextResponse()

handler(extendedReq, extendedRes)
const result = await extendedRes.toResponse()

if (event && event.waitUntil) {
if (event?.waitUntil) {
const waitUntilPromise = internal_getCurrentFunctionWaitUntil()
if (waitUntilPromise) {
event.waitUntil(waitUntilPromise)
}
}

// fetchMetrics is attached to the web request that going through the server,
// wait for the handler result is ready and attach it back to the original request.
;(request as any).fetchMetrics = extendedReq.fetchMetrics
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { AsyncLocalStorage } from 'async_hooks'
import type { IncrementalCache } from '../lib/incremental-cache'

import { createPrerenderState } from '../../server/app-render/dynamic-rendering'
import type { FetchMetric } from '../base-http'

export type StaticGenerationContext = {
urlPathname: string
Expand Down Expand Up @@ -31,6 +32,8 @@ export type StaticGenerationContext = {
*/
// TODO: remove this when we resolve accessing the store outside the execution context
store?: StaticGenerationStore
/** Fetch metrics attached in patch-fetch.ts */
fetchMetrics?: FetchMetric[]
}
}

Expand Down
7 changes: 5 additions & 2 deletions packages/next/src/server/base-http/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface BaseNextRequestConfig {
trailingSlash?: boolean | undefined
}

export type FetchMetrics = Array<{
export type FetchMetric = {
url: string
idx: number
end: number
Expand All @@ -20,11 +20,14 @@ export type FetchMetrics = Array<{
status: number
cacheReason: string
cacheStatus: 'hit' | 'miss' | 'skip'
}>
}

export type FetchMetrics = Array<FetchMetric>

export abstract class BaseNextRequest<Body = any> {
protected _cookies: NextApiRequestCookies | undefined
public abstract headers: IncomingHttpHeaders
public abstract fetchMetrics?: FetchMetric[]

constructor(public method: string, public url: string, public body: Body) {}

Expand Down
6 changes: 4 additions & 2 deletions packages/next/src/server/base-http/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ import type { NextApiRequestCookies } from '../api-utils'
import { NEXT_REQUEST_META } from '../request-meta'
import type { RequestMeta } from '../request-meta'

import { BaseNextRequest, BaseNextResponse } from './index'
import { BaseNextRequest, BaseNextResponse, type FetchMetric } from './index'
import type { OutgoingHttpHeaders } from 'node:http'

type Req = IncomingMessage & {
[NEXT_REQUEST_META]?: RequestMeta
cookies?: NextApiRequestCookies
fetchMetrics?: FetchMetric[]
}

export class NodeNextRequest extends BaseNextRequest<Readable> {
public headers = this._req.headers;
public headers = this._req.headers
public fetchMetrics?: FetchMetric[] = this._req?.fetchMetrics;

[NEXT_REQUEST_META]: RequestMeta = this._req[NEXT_REQUEST_META] || {}

Expand Down
4 changes: 3 additions & 1 deletion packages/next/src/server/base-http/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import type { FetchMetrics } from './index'
import { toNodeOutgoingHttpHeaders } from '../web/utils'
import { BaseNextRequest, BaseNextResponse } from './index'
import { DetachedPromise } from '../../lib/detached-promise'
import type { NextRequestHint } from '../web/adapter'

export class WebNextRequest extends BaseNextRequest<ReadableStream | null> {
public request: Request
public headers: IncomingHttpHeaders
public fetchMetrics?: FetchMetrics

constructor(request: Request) {
constructor(request: NextRequestHint) {
const url = new URL(request.url)

super(
Expand All @@ -19,6 +20,7 @@ export class WebNextRequest extends BaseNextRequest<ReadableStream | null> {
request.clone().body
)
this.request = request
this.fetchMetrics = request.fetchMetrics

this.headers = {}
for (const [name, value] of request.headers.entries()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ export class AppRouteRouteModule extends RouteModule<
`No response is returned from route handler '${this.resolvedPagePath}'. Ensure you return a \`Response\` or a \`NextResponse\` in all branches of your handler.`
)
}
;(context.renderOpts as any).fetchMetrics =
context.renderOpts.fetchMetrics =
staticGenerationStore.fetchMetrics

context.renderOpts.waitUntil = Promise.all(
Expand Down
30 changes: 13 additions & 17 deletions packages/next/src/server/lib/app-info-log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function logStartInfo({
appUrl,
envInfo,
expFeatureInfo,
maxExperimentalFeatures,
maxExperimentalFeatures = Infinity,
}: {
networkUrl: string | null
appUrl: string | null
Expand All @@ -21,31 +21,27 @@ export function logStartInfo({
maxExperimentalFeatures?: number
}) {
Log.bootstrap(
bold(
purple(
` ${Log.prefixes.ready} Next.js ${process.env.__NEXT_VERSION}${
process.env.TURBOPACK ? ' (turbo)' : ''
}`
)
)
`${bold(
purple(`${Log.prefixes.ready} Next.js ${process.env.__NEXT_VERSION}`)
)}${process.env.TURBOPACK ? ' (turbo)' : ''}`
)
if (appUrl) {
Log.bootstrap(` - Local: ${appUrl}`)
Log.bootstrap(`- Local: ${appUrl}`)
}
if (networkUrl) {
Log.bootstrap(` - Network: ${networkUrl}`)
Log.bootstrap(`- Network: ${networkUrl}`)
}
if (envInfo?.length) Log.bootstrap(` - Environments: ${envInfo.join(', ')}`)
if (envInfo?.length) Log.bootstrap(`- Environments: ${envInfo.join(', ')}`)

if (expFeatureInfo?.length) {
Log.bootstrap(` - Experiments (use with caution):`)
// only show maximum 3 flags
Log.bootstrap(`- Experiments (use with caution):`)
// only show a maximum number of flags
for (const exp of expFeatureInfo.slice(0, maxExperimentalFeatures)) {
Log.bootstrap(` · ${exp}`)
Log.bootstrap(` · ${exp}`)
}
/* ${expFeatureInfo.length - 3} more */
if (expFeatureInfo.length > 3 && maxExperimentalFeatures) {
Log.bootstrap(` · ...`)
/* indicate if there are more than the maximum shown no. flags */
if (expFeatureInfo.length > maxExperimentalFeatures) {
Log.bootstrap(` · ...`)
}
}

Expand Down
32 changes: 9 additions & 23 deletions packages/next/src/server/lib/patch-fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '../../lib/constants'
import * as Log from '../../build/output/log'
import { trackDynamicFetch } from '../app-render/dynamic-rendering'
import type { FetchMetric } from '../base-http'

const isEdgeRuntime = process.env.NEXT_RUNTIME === 'edge'

Expand Down Expand Up @@ -146,38 +147,23 @@ export function addImplicitTags(staticGenerationStore: StaticGenerationStore) {

function trackFetchMetric(
staticGenerationStore: StaticGenerationStore,
ctx: {
url: string
status: number
method: string
cacheReason: string
cacheStatus: 'hit' | 'miss' | 'skip'
start: number
}
ctx: Omit<FetchMetric, 'end' | 'idx'>
) {
if (!staticGenerationStore) return
if (!staticGenerationStore.fetchMetrics) {
staticGenerationStore.fetchMetrics = []
}
const dedupeFields = ['url', 'status', 'method']
staticGenerationStore.fetchMetrics ??= []

const dedupeFields = ['url', 'status', 'method'] as const

// don't add metric if one already exists for the fetch
if (
staticGenerationStore.fetchMetrics.some((metric) => {
return dedupeFields.every(
(field) => (metric as any)[field] === (ctx as any)[field]
)
})
staticGenerationStore.fetchMetrics.some((metric) =>
dedupeFields.every((field) => metric[field] === ctx[field])
)
) {
return
}
staticGenerationStore.fetchMetrics.push({
url: ctx.url,
cacheStatus: ctx.cacheStatus,
cacheReason: ctx.cacheReason,
status: ctx.status,
method: ctx.method,
start: ctx.start,
...ctx,
end: Date.now(),
idx: staticGenerationStore.nextFetchId || 0,
})
Expand Down
2 changes: 2 additions & 0 deletions packages/next/src/server/lib/start-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ export async function startServer(
maxExperimentalFeatures: 3,
})

Log.event(`Starting...`)

try {
const cleanup = () => {
debug('start-server process cleanup')
Expand Down
Loading

0 comments on commit 7569c80

Please sign in to comment.