Add logs for long-running integration hooks (#4445)

* feat: basic logging for long astro:build:done hooks

* feat: add long time msg to all build hooks

* feat: use logger for long time msg

* chore: changeset
This commit is contained in:
Ben Holmes 2022-08-23 14:07:09 -04:00 committed by GitHub
parent 77f9afa44a
commit df4e999284
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 134 additions and 40 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Add "waiting for X integration" log for long-running integration hooks

View file

@ -62,7 +62,7 @@ class AstroBuilder {
debug('build', 'Initial setup...'); debug('build', 'Initial setup...');
const { logging } = this; const { logging } = this;
this.timer.init = performance.now(); this.timer.init = performance.now();
this.config = await runHookConfigSetup({ config: this.config, command: 'build' }); this.config = await runHookConfigSetup({ config: this.config, command: 'build', logging });
this.manifest = createRouteManifest({ config: this.config }, this.logging); this.manifest = createRouteManifest({ config: this.config }, this.logging);
const viteConfig = await createVite( const viteConfig = await createVite(
@ -76,7 +76,7 @@ class AstroBuilder {
}, },
{ astroConfig: this.config, logging, mode: 'build' } { astroConfig: this.config, logging, mode: 'build' }
); );
await runHookConfigDone({ config: this.config }); await runHookConfigDone({ config: this.config, logging });
return { viteConfig }; return { viteConfig };
} }
@ -87,7 +87,7 @@ class AstroBuilder {
server: new URL('./server/', this.config.outDir), server: new URL('./server/', this.config.outDir),
serverEntry: 'entry.mjs', serverEntry: 'entry.mjs',
}; };
await runHookBuildStart({ config: this.config, buildConfig }); await runHookBuildStart({ config: this.config, buildConfig, logging: this.logging });
info(this.logging, 'build', `output target: ${colors.green(this.config.output)}`); info(this.logging, 'build', `output target: ${colors.green(this.config.output)}`);
if (this.config._ctx.adapter) { if (this.config._ctx.adapter) {
@ -145,6 +145,7 @@ class AstroBuilder {
buildConfig, buildConfig,
pages: pageNames, pages: pageNames,
routes: Object.values(allPages).map((pd) => pd.route), routes: Object.values(allPages).map((pd) => pd.route),
logging: this.logging,
}); });
if (this.logging.level && levels[this.logging.level] <= levels['info']) { if (this.logging.level && levels[this.logging.level] <= levels['info']) {

View file

@ -167,6 +167,7 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
pages: internals.pagesByComponent, pages: internals.pagesByComponent,
vite: viteBuildConfig, vite: viteBuildConfig,
target: 'server', target: 'server',
logging: opts.logging,
}); });
return await vite.build(viteBuildConfig); return await vite.build(viteBuildConfig);
@ -236,6 +237,7 @@ async function clientBuild(
pages: internals.pagesByComponent, pages: internals.pagesByComponent,
vite: viteBuildConfig, vite: viteBuildConfig,
target: 'client', target: 'client',
logging: opts.logging,
}); });
const buildResult = await vite.build(viteBuildConfig); const buildResult = await vite.build(viteBuildConfig);

View file

@ -103,7 +103,7 @@ export async function injectManifest(buildOpts: StaticBuildOptions, internals: B
const staticFiles = internals.staticFiles; const staticFiles = internals.staticFiles;
const manifest = buildManifest(buildOpts, internals, Array.from(staticFiles)); const manifest = buildManifest(buildOpts, internals, Array.from(staticFiles));
await runHookBuildSsr({ config: buildOpts.astroConfig, manifest }); await runHookBuildSsr({ config: buildOpts.astroConfig, manifest, logging: buildOpts.logging });
const chunk = internals.ssrEntryChunk; const chunk = internals.ssrEntryChunk;
const code = chunk.code; const code = chunk.code;

View file

@ -83,7 +83,7 @@ export async function createVite(
htmlVitePlugin(), htmlVitePlugin(),
jsxVitePlugin({ config: astroConfig, logging }), jsxVitePlugin({ config: astroConfig, logging }),
astroPostprocessVitePlugin({ config: astroConfig }), astroPostprocessVitePlugin({ config: astroConfig }),
astroIntegrationsContainerPlugin({ config: astroConfig }), astroIntegrationsContainerPlugin({ config: astroConfig, logging }),
astroScriptsPageSSRPlugin({ config: astroConfig }), astroScriptsPageSSRPlugin({ config: astroConfig }),
], ],
publicDir: fileURLToPath(astroConfig.publicDir), publicDir: fileURLToPath(astroConfig.publicDir),

View file

@ -31,7 +31,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
const devStart = performance.now(); const devStart = performance.now();
applyPolyfill(); applyPolyfill();
await options.telemetry.record([]); await options.telemetry.record([]);
config = await runHookConfigSetup({ config, command: 'dev' }); config = await runHookConfigSetup({ config, command: 'dev', logging: options.logging });
const { host, port } = config.server; const { host, port } = config.server;
// The client entrypoint for renderers. Since these are imported dynamically // The client entrypoint for renderers. Since these are imported dynamically
@ -50,9 +50,9 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
}, },
{ astroConfig: config, logging: options.logging, mode: 'dev' } { astroConfig: config, logging: options.logging, mode: 'dev' }
); );
await runHookConfigDone({ config }); await runHookConfigDone({ config, logging: options.logging });
const viteServer = await vite.createServer(viteConfig); const viteServer = await vite.createServer(viteConfig);
runHookServerSetup({ config, server: viteServer }); runHookServerSetup({ config, server: viteServer, logging: options.logging });
await viteServer.listen(port); await viteServer.listen(port);
const devServerAddressInfo = viteServer.httpServer!.address() as AddressInfo; const devServerAddressInfo = viteServer.httpServer!.address() as AddressInfo;
@ -77,7 +77,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
warn(options.logging, null, msg.fsStrictWarning()); warn(options.logging, null, msg.fsStrictWarning());
} }
await runHookServerStart({ config, address: devServerAddressInfo }); await runHookServerStart({ config, address: devServerAddressInfo, logging: options.logging });
return { return {
address: devServerAddressInfo, address: devServerAddressInfo,
@ -86,7 +86,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
}, },
stop: async () => { stop: async () => {
await viteServer.close(); await viteServer.close();
await runHookServerDone({ config }); await runHookServerDone({ config, logging: options.logging });
}, },
}; };
} }

View file

@ -1,5 +1,6 @@
import type { AddressInfo } from 'net'; import type { AddressInfo } from 'net';
import type { ViteDevServer } from 'vite'; import type { ViteDevServer } from 'vite';
import { bold } from 'kleur/colors';
import { import {
AstroConfig, AstroConfig,
AstroRenderer, AstroRenderer,
@ -11,13 +12,35 @@ import type { SerializedSSRManifest } from '../core/app/types';
import type { PageBuildData } from '../core/build/types'; import type { PageBuildData } from '../core/build/types';
import { mergeConfig } from '../core/config.js'; import { mergeConfig } from '../core/config.js';
import type { ViteConfigWithSSR } from '../core/create-vite.js'; import type { ViteConfigWithSSR } from '../core/create-vite.js';
import { info, LogOptions } from '../core/logger/core.js';
async function withTakingALongTimeMsg<T>({
name,
hookResult,
timeoutMs = 3000,
logging,
}: {
name: string;
hookResult: T | Promise<T>;
timeoutMs?: number;
logging: LogOptions;
}): Promise<T> {
const timeout = setTimeout(() => {
info(logging, 'build', `Waiting for the ${bold(name)} integration...`);
}, timeoutMs);
const result = await hookResult;
clearTimeout(timeout);
return result;
}
export async function runHookConfigSetup({ export async function runHookConfigSetup({
config: _config, config: _config,
command, command,
logging,
}: { }: {
config: AstroConfig; config: AstroConfig;
command: 'dev' | 'build'; command: 'dev' | 'build';
logging: LogOptions;
}): Promise<AstroConfig> { }): Promise<AstroConfig> {
// An adapter is an integration, so if one is provided push it. // An adapter is an integration, so if one is provided push it.
if (_config.adapter) { if (_config.adapter) {
@ -65,25 +88,39 @@ export async function runHookConfigSetup({
writable: false, writable: false,
enumerable: false, enumerable: false,
}); });
await integration.hooks['astro:config:setup'](hooks); await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:config:setup'](hooks),
logging,
});
} }
} }
return updatedConfig; return updatedConfig;
} }
export async function runHookConfigDone({ config }: { config: AstroConfig }) { export async function runHookConfigDone({
config,
logging,
}: {
config: AstroConfig;
logging: LogOptions;
}) {
for (const integration of config.integrations) { for (const integration of config.integrations) {
if (integration?.hooks?.['astro:config:done']) { if (integration?.hooks?.['astro:config:done']) {
await integration.hooks['astro:config:done']({ await withTakingALongTimeMsg({
config, name: integration.name,
setAdapter(adapter) { hookResult: integration.hooks['astro:config:done']({
if (config._ctx.adapter && config._ctx.adapter.name !== adapter.name) { config,
throw new Error( setAdapter(adapter) {
`Integration "${integration.name}" conflicts with "${config._ctx.adapter.name}". You can only configure one deployment integration.` if (config._ctx.adapter && config._ctx.adapter.name !== adapter.name) {
); throw new Error(
} `Integration "${integration.name}" conflicts with "${config._ctx.adapter.name}". You can only configure one deployment integration.`
config._ctx.adapter = adapter; );
}, }
config._ctx.adapter = adapter;
},
}),
logging,
}); });
} }
} }
@ -92,13 +129,19 @@ export async function runHookConfigDone({ config }: { config: AstroConfig }) {
export async function runHookServerSetup({ export async function runHookServerSetup({
config, config,
server, server,
logging,
}: { }: {
config: AstroConfig; config: AstroConfig;
server: ViteDevServer; server: ViteDevServer;
logging: LogOptions;
}) { }) {
for (const integration of config.integrations) { for (const integration of config.integrations) {
if (integration?.hooks?.['astro:server:setup']) { if (integration?.hooks?.['astro:server:setup']) {
await integration.hooks['astro:server:setup']({ server }); await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:server:setup']({ server }),
logging,
});
} }
} }
} }
@ -106,21 +149,37 @@ export async function runHookServerSetup({
export async function runHookServerStart({ export async function runHookServerStart({
config, config,
address, address,
logging,
}: { }: {
config: AstroConfig; config: AstroConfig;
address: AddressInfo; address: AddressInfo;
logging: LogOptions;
}) { }) {
for (const integration of config.integrations) { for (const integration of config.integrations) {
if (integration?.hooks?.['astro:server:start']) { if (integration?.hooks?.['astro:server:start']) {
await integration.hooks['astro:server:start']({ address }); await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:server:start']({ address }),
logging,
});
} }
} }
} }
export async function runHookServerDone({ config }: { config: AstroConfig }) { export async function runHookServerDone({
config,
logging,
}: {
config: AstroConfig;
logging: LogOptions;
}) {
for (const integration of config.integrations) { for (const integration of config.integrations) {
if (integration?.hooks?.['astro:server:done']) { if (integration?.hooks?.['astro:server:done']) {
await integration.hooks['astro:server:done'](); await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:server:done'](),
logging,
});
} }
} }
} }
@ -128,13 +187,19 @@ export async function runHookServerDone({ config }: { config: AstroConfig }) {
export async function runHookBuildStart({ export async function runHookBuildStart({
config, config,
buildConfig, buildConfig,
logging,
}: { }: {
config: AstroConfig; config: AstroConfig;
buildConfig: BuildConfig; buildConfig: BuildConfig;
logging: LogOptions;
}) { }) {
for (const integration of config.integrations) { for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:start']) { if (integration?.hooks?.['astro:build:start']) {
await integration.hooks['astro:build:start']({ buildConfig }); await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:build:start']({ buildConfig }),
logging,
});
} }
} }
} }
@ -144,21 +209,27 @@ export async function runHookBuildSetup({
vite, vite,
pages, pages,
target, target,
logging,
}: { }: {
config: AstroConfig; config: AstroConfig;
vite: ViteConfigWithSSR; vite: ViteConfigWithSSR;
pages: Map<string, PageBuildData>; pages: Map<string, PageBuildData>;
target: 'server' | 'client'; target: 'server' | 'client';
logging: LogOptions;
}) { }) {
for (const integration of config.integrations) { for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:setup']) { if (integration?.hooks?.['astro:build:setup']) {
await integration.hooks['astro:build:setup']({ await withTakingALongTimeMsg({
vite, name: integration.name,
pages, hookResult: integration.hooks['astro:build:setup']({
target, vite,
updateConfig: (newConfig) => { pages,
mergeConfig(vite, newConfig); target,
}, updateConfig: (newConfig) => {
mergeConfig(vite, newConfig);
},
}),
logging,
}); });
} }
} }
@ -167,13 +238,19 @@ export async function runHookBuildSetup({
export async function runHookBuildSsr({ export async function runHookBuildSsr({
config, config,
manifest, manifest,
logging,
}: { }: {
config: AstroConfig; config: AstroConfig;
manifest: SerializedSSRManifest; manifest: SerializedSSRManifest;
logging: LogOptions;
}) { }) {
for (const integration of config.integrations) { for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:ssr']) { if (integration?.hooks?.['astro:build:ssr']) {
await integration.hooks['astro:build:ssr']({ manifest }); await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:build:ssr']({ manifest }),
logging,
});
} }
} }
} }
@ -183,20 +260,26 @@ export async function runHookBuildDone({
buildConfig, buildConfig,
pages, pages,
routes, routes,
logging,
}: { }: {
config: AstroConfig; config: AstroConfig;
buildConfig: BuildConfig; buildConfig: BuildConfig;
pages: string[]; pages: string[];
routes: RouteData[]; routes: RouteData[];
logging: LogOptions;
}) { }) {
const dir = config.output === 'server' ? buildConfig.client : config.outDir; const dir = config.output === 'server' ? buildConfig.client : config.outDir;
for (const integration of config.integrations) { for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:done']) { if (integration?.hooks?.['astro:build:done']) {
await integration.hooks['astro:build:done']({ await withTakingALongTimeMsg({
pages: pages.map((p) => ({ pathname: p })), name: integration.name,
dir, hookResult: integration.hooks['astro:build:done']({
routes, pages: pages.map((p) => ({ pathname: p })),
dir,
routes,
}),
logging,
}); });
} }
} }

View file

@ -1,17 +1,20 @@
import { Plugin as VitePlugin } from 'vite'; import { Plugin as VitePlugin } from 'vite';
import { AstroConfig } from '../@types/astro.js'; import { AstroConfig } from '../@types/astro.js';
import { LogOptions } from '../core/logger/core.js';
import { runHookServerSetup } from '../integrations/index.js'; import { runHookServerSetup } from '../integrations/index.js';
/** Connect Astro integrations into Vite, as needed. */ /** Connect Astro integrations into Vite, as needed. */
export default function astroIntegrationsContainerPlugin({ export default function astroIntegrationsContainerPlugin({
config, config,
logging,
}: { }: {
config: AstroConfig; config: AstroConfig;
logging: LogOptions;
}): VitePlugin { }): VitePlugin {
return { return {
name: 'astro:integration-container', name: 'astro:integration-container',
configureServer(server) { configureServer(server) {
runHookServerSetup({ config, server }); runHookServerSetup({ config, server, logging });
}, },
}; };
} }