Skip to content

Commit 6201bbe

Browse files
Logging rewrite 2 (#9105)
* update logging add back warning for header access improve labels and formatting improve error logging remove outdated error fix build new error messages and hints new error messages and hints * walk back error message changes * fix rebase issues * add changeset * Remove accidental log * revert bad env change * Update index.ts * Update packages/astro/src/core/build/index.ts Co-authored-by: Erika <[email protected]> --------- Co-authored-by: Erika <[email protected]>
1 parent 1c48ed2 commit 6201bbe

File tree

47 files changed

+395
-451
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+395
-451
lines changed

.changeset/calm-baboons-watch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': minor
3+
---
4+
5+
Update CLI logging experience

.changeset/modern-candles-sip.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'create-astro': patch
3+
---
4+
5+
Stop clearing the console on start

packages/astro/src/assets/build/generate.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export async function prepareAssetsGenerationEnv(
5858
await fs.promises.mkdir(assetsCacheDir, { recursive: true });
5959
} catch (err) {
6060
logger.warn(
61-
'astro:assets',
61+
null,
6262
`An error was encountered while creating the cache directory. Proceeding without caching. Error: ${err}`
6363
);
6464
useCache = false;
@@ -231,7 +231,7 @@ export async function generateImagesForPath(
231231
}
232232
} catch (e) {
233233
env.logger.warn(
234-
'astro:assets',
234+
null,
235235
`An error was encountered while creating the cache directory. Proceeding without caching. Error: ${e}`
236236
);
237237
} finally {

packages/astro/src/cli/install-package.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export async function getPackage<T>(
2626
packageImport = await import(packageName);
2727
} catch (e) {
2828
logger.info(
29-
'',
29+
null,
3030
`To continue, Astro requires the following dependency to be installed: ${bold(packageName)}.`
3131
);
3232
const result = await installPackage([packageName, ...otherDeps], options, logger);

packages/astro/src/cli/telemetry/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
/* eslint-disable no-console */
2-
import whichPm from 'which-pm';
32
import type yargs from 'yargs-parser';
43
import * as msg from '../../core/messages.js';
54
import { telemetry } from '../../events/index.js';
5+
import { createLoggerFromFlags } from '../flags.js';
66

77
interface TelemetryOptions {
88
flags: yargs.Arguments;
99
}
1010

1111
export async function notify() {
12-
const packageManager = (await whichPm(process.cwd()))?.name ?? 'npm';
1312
await telemetry.notify(() => {
14-
console.log(msg.telemetryNotice(packageManager) + '\n');
13+
console.log(msg.telemetryNotice() + '\n');
1514
return true;
1615
});
1716
}
1817

1918
export async function update(subcommand: string, { flags }: TelemetryOptions) {
2019
const isValid = ['enable', 'disable', 'reset'].includes(subcommand);
20+
const logger = createLoggerFromFlags(flags);
2121

2222
if (flags.help || flags.h || !isValid) {
2323
msg.printHelp({
@@ -37,17 +37,17 @@ export async function update(subcommand: string, { flags }: TelemetryOptions) {
3737
switch (subcommand) {
3838
case 'enable': {
3939
telemetry.setEnabled(true);
40-
console.log(msg.telemetryEnabled());
40+
logger.info('SKIP_FORMAT', msg.telemetryEnabled());
4141
return;
4242
}
4343
case 'disable': {
4444
telemetry.setEnabled(false);
45-
console.log(msg.telemetryDisabled());
45+
logger.info('SKIP_FORMAT', msg.telemetryDisabled());
4646
return;
4747
}
4848
case 'reset': {
4949
telemetry.clear();
50-
console.log(msg.telemetryReset());
50+
logger.info('SKIP_FORMAT', msg.telemetryReset());
5151
return;
5252
}
5353
}

packages/astro/src/content/server-listeners.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { bold, cyan } from 'kleur/colors';
1+
import { bold, cyan, underline } from 'kleur/colors';
22
import type fsMod from 'node:fs';
33
import path from 'node:path';
44
import { fileURLToPath, pathToFileURL } from 'node:url';
@@ -26,7 +26,7 @@ export async function attachContentServerListeners({
2626
const contentPaths = getContentPaths(settings.config, fs);
2727

2828
if (fs.existsSync(contentPaths.contentDir)) {
29-
logger.info(
29+
logger.debug(
3030
'content',
3131
`Watching ${cyan(
3232
contentPaths.contentDir.href.replace(settings.config.root.href, '')
@@ -39,7 +39,7 @@ export async function attachContentServerListeners({
3939
viteServer.watcher.on('addDir', contentDirListener);
4040
async function contentDirListener(dir: string) {
4141
if (appendForwardSlash(pathToFileURL(dir).href) === contentPaths.contentDir.href) {
42-
logger.info('content', `Content dir found. Watching for changes`);
42+
logger.debug('content', `Content directory found. Watching for changes`);
4343
await attachListeners();
4444
viteServer.watcher.removeListener('addDir', contentDirListener);
4545
}
@@ -55,7 +55,7 @@ export async function attachContentServerListeners({
5555
contentConfigObserver: globalContentConfigObserver,
5656
});
5757
await contentGenerator.init();
58-
logger.info('content', 'Types generated');
58+
logger.debug('content', 'Types generated');
5959

6060
viteServer.watcher.on('add', (entry) => {
6161
contentGenerator.queueEvent({ name: 'add', entry });
@@ -90,9 +90,9 @@ function warnAllowJsIsFalse({
9090
'true'
9191
)} in your ${bold(tsConfigFileName)} file to have autocompletion in your ${bold(
9292
contentConfigFileName
93-
)} file.
94-
See ${bold('https://www.typescriptlang.org/tsconfig#allowJs')} for more information.
95-
`
93+
)} file. See ${underline(
94+
cyan('https://www.typescriptlang.org/tsconfig#allowJs')
95+
)} for more information.`
9696
);
9797
}
9898

packages/astro/src/content/types-generator.ts

Lines changed: 33 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import glob from 'fast-glob';
2-
import { cyan } from 'kleur/colors';
2+
import { bold, cyan } from 'kleur/colors';
33
import type fsMod from 'node:fs';
44
import * as path from 'node:path';
55
import { fileURLToPath, pathToFileURL } from 'node:url';
@@ -56,13 +56,6 @@ type CreateContentGeneratorParams = {
5656
fs: typeof fsMod;
5757
};
5858

59-
type EventOpts = { logLevel: 'info' | 'warn' };
60-
61-
type EventWithOptions = {
62-
type: ContentEvent;
63-
opts: EventOpts | undefined;
64-
};
65-
6659
class UnsupportedFileTypeError extends Error {}
6760

6861
export async function createContentTypesGenerator({
@@ -78,7 +71,7 @@ export async function createContentTypesGenerator({
7871
const contentEntryExts = [...contentEntryConfigByExt.keys()];
7972
const dataEntryExts = getDataEntryExts(settings);
8073

81-
let events: EventWithOptions[] = [];
74+
let events: ContentEvent[] = [];
8275
let debounceTimeout: NodeJS.Timeout | undefined;
8376

8477
const typeTemplateContent = await fs.promises.readFile(contentPaths.typesTemplate, 'utf-8');
@@ -90,10 +83,7 @@ export async function createContentTypesGenerator({
9083
return { typesGenerated: false, reason: 'no-content-dir' };
9184
}
9285

93-
events.push({
94-
type: { name: 'add', entry: contentPaths.config.url },
95-
opts: { logLevel: 'warn' },
96-
});
86+
events.push({ name: 'add', entry: contentPaths.config.url });
9787

9888
const globResult = await glob('**', {
9989
cwd: fileURLToPath(contentPaths.contentDir),
@@ -110,24 +100,18 @@ export async function createContentTypesGenerator({
110100
const entryURL = pathToFileURL(fullPath);
111101
if (entryURL.href.startsWith(contentPaths.config.url.href)) continue;
112102
if (entry.dirent.isFile()) {
113-
events.push({
114-
type: { name: 'add', entry: entryURL },
115-
opts: { logLevel: 'warn' },
116-
});
103+
events.push({ name: 'add', entry: entryURL });
117104
} else if (entry.dirent.isDirectory()) {
118-
events.push({ type: { name: 'addDir', entry: entryURL }, opts: { logLevel: 'warn' } });
105+
events.push({ name: 'addDir', entry: entryURL });
119106
}
120107
}
121108
await runEvents();
122109
return { typesGenerated: true };
123110
}
124111

125112
async function handleEvent(
126-
event: ContentEvent,
127-
opts?: EventOpts
113+
event: ContentEvent
128114
): Promise<{ shouldGenerateTypes: boolean; error?: Error }> {
129-
const logLevel = opts?.logLevel ?? 'info';
130-
131115
if (event.name === 'addDir' || event.name === 'unlinkDir') {
132116
const collection = normalizePath(
133117
path.relative(fileURLToPath(contentPaths.contentDir), fileURLToPath(event.entry))
@@ -140,9 +124,7 @@ export async function createContentTypesGenerator({
140124
switch (event.name) {
141125
case 'addDir':
142126
collectionEntryMap[JSON.stringify(collection)] = { type: 'unknown', entries: {} };
143-
if (logLevel === 'info') {
144-
logger.info('content', `${cyan(collection)} collection added`);
145-
}
127+
logger.debug('content', `${cyan(collection)} collection added`);
146128
break;
147129
case 'unlinkDir':
148130
if (collectionKey in collectionEntryMap) {
@@ -186,16 +168,14 @@ export async function createContentTypesGenerator({
186168

187169
const collection = getEntryCollectionName({ entry, contentDir });
188170
if (collection === undefined) {
189-
if (['info', 'warn'].includes(logLevel)) {
190-
logger.warn(
191-
'content',
192-
`${cyan(
193-
normalizePath(
194-
path.relative(fileURLToPath(contentPaths.contentDir), fileURLToPath(event.entry))
195-
)
196-
)} must be nested in a collection directory. Skipping.`
197-
);
198-
}
171+
logger.warn(
172+
'content',
173+
`${bold(
174+
normalizePath(
175+
path.relative(fileURLToPath(contentPaths.contentDir), fileURLToPath(event.entry))
176+
)
177+
)} must live in a ${bold('content/...')} collection subdirectory.`
178+
);
199179
return { shouldGenerateTypes: false };
200180
}
201181

@@ -308,22 +288,19 @@ export async function createContentTypesGenerator({
308288
}
309289
}
310290

311-
function queueEvent(rawEvent: RawContentEvent, opts?: EventOpts) {
291+
function queueEvent(rawEvent: RawContentEvent) {
312292
const event = {
313-
type: {
314-
entry: pathToFileURL(rawEvent.entry),
315-
name: rawEvent.name,
316-
},
317-
opts,
293+
entry: pathToFileURL(rawEvent.entry),
294+
name: rawEvent.name,
318295
};
319-
if (!event.type.entry.pathname.startsWith(contentPaths.contentDir.pathname)) return;
296+
if (!event.entry.pathname.startsWith(contentPaths.contentDir.pathname)) return;
320297

321298
events.push(event);
322299

323300
debounceTimeout && clearTimeout(debounceTimeout);
324301
const runEventsSafe = async () => {
325302
try {
326-
await runEvents(opts);
303+
await runEvents();
327304
} catch {
328305
// Prevent frontmatter errors from crashing the server. The errors
329306
// are still reported on page reflects as desired.
@@ -333,30 +310,25 @@ export async function createContentTypesGenerator({
333310
debounceTimeout = setTimeout(runEventsSafe, 50 /* debounce to batch chokidar events */);
334311
}
335312

336-
async function runEvents(opts?: EventOpts) {
337-
const logLevel = opts?.logLevel ?? 'info';
313+
async function runEvents() {
338314
const eventResponses = [];
339315

340316
for (const event of events) {
341-
const response = await handleEvent(event.type, event.opts);
317+
const response = await handleEvent(event);
342318
eventResponses.push(response);
343319
}
344320

345321
events = [];
346-
let unsupportedFiles = [];
347322
for (const response of eventResponses) {
348323
if (response.error instanceof UnsupportedFileTypeError) {
349-
unsupportedFiles.push(response.error.message);
324+
logger.warn(
325+
'content',
326+
`Unsupported file type ${bold(
327+
response.error.message
328+
)} found. Prefix filename with an underscore (\`_\`) to ignore.`
329+
);
350330
}
351331
}
352-
if (unsupportedFiles.length > 0 && ['info', 'warn'].includes(logLevel)) {
353-
logger.warn(
354-
'content',
355-
`Unsupported file types found. Prefix with an underscore (\`_\`) to ignore:\n- ${unsupportedFiles.join(
356-
'\n'
357-
)}`
358-
);
359-
}
360332
const observable = contentConfigObserver.get();
361333
if (eventResponses.some((r) => r.shouldGenerateTypes)) {
362334
await writeContentFiles({
@@ -369,7 +341,7 @@ export async function createContentTypesGenerator({
369341
viteServer,
370342
});
371343
invalidateVirtualMod(viteServer);
372-
if (observable.status === 'loaded' && ['info', 'warn'].includes(logLevel)) {
344+
if (observable.status === 'loaded') {
373345
warnNonexistentCollections({
374346
logger,
375347
contentConfig: observable.config,
@@ -475,6 +447,7 @@ async function writeContentFiles({
475447
let configPathRelativeToCacheDir = normalizePath(
476448
path.relative(contentPaths.cacheDir.pathname, contentPaths.config.url.pathname)
477449
);
450+
478451
if (!isRelativePath(configPathRelativeToCacheDir))
479452
configPathRelativeToCacheDir = './' + configPathRelativeToCacheDir;
480453

@@ -514,9 +487,9 @@ function warnNonexistentCollections({
514487
if (!collectionEntryMap[JSON.stringify(configuredCollection)]) {
515488
logger.warn(
516489
'content',
517-
`The ${JSON.stringify(
518-
configuredCollection
519-
)} collection does not have an associated folder in your \`content\` directory. Make sure the folder exists, or check your content config for typos.`
490+
`The ${bold(configuredCollection)} collection is defined but no ${bold(
491+
'content/' + configuredCollection
492+
)} folder exists in the content directory. Create a new folder for the collection, or check your content configuration file for typos.`
520493
);
521494
}
522495
}

packages/astro/src/core/app/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ export class App {
190190
if (err instanceof EndpointNotFoundError) {
191191
return this.#renderError(request, { status: 404, response: err.originalResponse });
192192
} else {
193-
this.#logger.error('ssr', err.stack || err.message || String(err));
193+
this.#logger.error(null, err.stack || err.message || String(err));
194194
return this.#renderError(request, { status: 500 });
195195
}
196196
}

0 commit comments

Comments
 (0)