Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .changeset/silver-berries-send.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
'astro': minor
---

Adds a new experimental logger, which allows to provide better controls over Astro's logging infrastructure.

Comment thread
ematipico marked this conversation as resolved.
Outdated
#### JSON logging

JSON logging can be enabled via CLI or via configuration:

```shell
astro dev --experimentalJson
astro build --experimentalJson
astro sync --experimentalJson
```
Comment thread
ematipico marked this conversation as resolved.
Outdated

```js
// astro.config.mjs
import { defineConfig, logHandlers } from "astro/config";

export default defineConfig({
experimental: {
logger: logHandlers.json({
pretty: true,
level: 'warn'
})
}
})
```

#### Custom logger

You can also create your own custom logger by implementing the correct interface:

```js
// astro.config.mjs
import { defineConfig } from "astro/config";

export default defineConfig({
experimental: {
logger: {
entrypoint: "@org/custom-logger"
}
}
})
```

```ts
// @org/custom-logger.js
import type { AstroLoggerDestination, AstroLoggerMessage } from "astro"

const customLogger: AstroLoggerDestination = {
write(message: AstroLoggerMessage) {
// write message somewhere
}
}
export default customLogger
```
Comment thread
ematipico marked this conversation as resolved.
Comment thread
ematipico marked this conversation as resolved.
1 change: 1 addition & 0 deletions packages/astro/src/actions/runtime/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export type ActionAPIContext = Pick<
| 'session'
| 'cache'
| 'csp'
| 'logger'
>;

export type MaybePromise<T> = T | Promise<T>;
Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/container/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ function createManifest(
experimentalQueuedRendering: manifest?.experimentalQueuedRendering ?? {
enabled: false,
},
experimentalLogger: manifest?.experimentalLogger ?? false,
};
}

Expand Down Expand Up @@ -273,6 +274,7 @@ type AstroContainerManifest = Pick<
| 'assetsDir'
| 'image'
| 'experimentalQueuedRendering'
| 'experimentalLogger'
>;

type AstroContainerConstructor = {
Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/core/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ export type SSRManifest = {
};
internalFetchHeaders?: Record<string, string>;
logLevel: AstroLoggerLevel;
// This is temporary, and only used while the logger is experimental
experimentalLogger: boolean;
};

export type SSRActions = {
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/build/plugins/plugin-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,5 +388,6 @@ async function buildManifest(
internalFetchHeaders,
logLevel: settings.logLevel,
shouldInjectCspMetaTags: shouldTrackCspHashes(settings.config.security.csp),
experimentalLogger: !!settings.config.experimental?.logger,
};
}
14 changes: 11 additions & 3 deletions packages/astro/src/core/logger/core.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import colors from 'piccolore';

/**
*
*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Is this empty comment expected or you forgot to put something here?

export interface AstroLoggerDestination<T = unknown> {
/**
* It receives a message and writes it into a destination
*/
write: (chunk: T) => void;
// NOTE: will document once we actually use it
/**
* It dumps logs without closing the connection to the destination.
* Method that can be used by specialized loggers.
*/
flush?: () => Promise<void> | void;
// NOTE: will document once we actually use it
/**
* It dumps logs and closes the connection to the destination.
* Method that can be used by specialized loggers.
*/
close?: () => Promise<void> | void;
}

// NOTE: this is a public type

/**
* The level of logging. Priority is the following:
* 1. debug
Expand Down
58 changes: 56 additions & 2 deletions packages/astro/src/core/logger/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,78 @@
import type { LoggerHandlerConfig } from './config.js';
import type { JonsHandlerConfig } from './impls/json.js';
import type { NodeHandlerConfig } from './impls/node.js';
import type { ConsoleHandlerConfig } from './impls/console.js';

export const logHandlers = {
/**
* It uses the built-in Astro JSON logger.
* @example
* ```js
* export default defineConfig({
* experimental: {
* logger: logHandlers.json({ pretty: true })
* }
* })
* ```
*/
json(config?: JonsHandlerConfig): LoggerHandlerConfig {
return {
entrypoint: 'astro/logger/json',
config,
};
},
node(): LoggerHandlerConfig {
/**
* It uses the built-in Astro Node.js logger.
*
* @example
* ```js
* export default defineConfig({
* experimental: {
* logger: logHandlers.node({ pretty: true })
* }
* })
* ```
*/
node(config?: NodeHandlerConfig): LoggerHandlerConfig {
return {
entrypoint: 'astro/logger/node',
config,
};
},
console(): LoggerHandlerConfig {
/**
* It uses the built-in Astro console logger.
*
* @example
* ```js
* export default defineConfig({
* experimental: {
* logger: logHandlers.console({ pretty: true })
* }
* })
* ```
*/
console(config?: ConsoleHandlerConfig): LoggerHandlerConfig {
return {
entrypoint: 'astro/logger/console',
config,
};
},

/**
* It allows composing different loggers
*
* @example
* ```js
* export default defineConfig({
* experimental: {
* logger: logHandlers.compose([
* logHandlers.console(),
* logHandlers.json(),
* ])
* }
* })
* ```
*/
compose(...loggers: LoggerHandlerConfig[]): LoggerHandlerConfig {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe neither the documentation nor the changeset mentions this feature. Maybe for the changeset it's not important (ie. we can focus on the most important parts) but we probably want to mention it in the docs.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left it out in purpose here, I forgot to add to the docs, I will address this shortly

return {
entrypoint: 'astro/logger/compose',
Expand Down
15 changes: 9 additions & 6 deletions packages/astro/src/core/logger/impls/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ import {
type AstroLoggerLevel,
AstroLogger,
} from '../core.js';
import type { NodeHandlerConfig } from './node.js';

export type ConsoleHandlerConfig = {
level?: AstroLoggerLevel;
};

function consoleLogDestination(
level: AstroLoggerLevel = 'info',
config: ConsoleHandlerConfig = {},
): AstroLoggerDestination<AstroLoggerMessage> {
const { level = 'info' } = config;
return {
write(event: AstroLoggerMessage) {
let dest = console.error;
Expand Down Expand Up @@ -37,9 +43,6 @@ export function createConsoleLogger({ level }: { level: AstroLoggerLevel }): Ast
});
}

type Options = {
level?: AstroLoggerLevel;
};
export default function (options?: Options): AstroLoggerDestination<AstroLoggerMessage> {
return consoleLogDestination(options?.level ?? 'info');
export default function (options?: NodeHandlerConfig): AstroLoggerDestination<AstroLoggerMessage> {
return consoleLogDestination(options);
}
6 changes: 6 additions & 0 deletions packages/astro/src/core/logger/impls/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import type { Writable } from 'node:stream';
import type { AstroInlineConfig } from '../../../types/public/index.js';

export type JonsHandlerConfig = {
Comment thread
ematipico marked this conversation as resolved.
Outdated
/**
* Whether the JSON line should format on multiple lines
*/
pretty?: boolean;
/**
* The level of logs that should be printed by the logger.
*/
level?: AstroLoggerLevel;
};

Expand Down
14 changes: 8 additions & 6 deletions packages/astro/src/core/logger/impls/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ type ConsoleStream = Writable & {
fd: 1 | 2;
};

export type NodeHandlerConfig = {
level?: AstroLoggerLevel;
};

function nodeLogDestination(
level: AstroLoggerLevel = 'info',
config: NodeHandlerConfig = {},
): AstroLoggerDestination<AstroLoggerMessage> {
const { level = 'info' } = config;
return {
write(event: AstroLoggerMessage) {
let dest: ConsoleStream = process.stderr;
Expand All @@ -37,11 +42,8 @@ function nodeLogDestination(
};
}

type Options = {
level?: AstroLoggerLevel;
};
export default function (options?: Options): AstroLoggerDestination<AstroLoggerMessage> {
return nodeLogDestination(options?.level ?? 'info');
export default function (options?: NodeHandlerConfig): AstroLoggerDestination<AstroLoggerMessage> {
return nodeLogDestination(options);
}

export function createNodeLoggerFromFlags(inlineConfig: AstroInlineConfig): AstroLogger {
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/logger/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const RESOLVED_LOGGER_MODULE_ID = '\0' + LOGGER_MODULE_ID;
/**
* Generates virtual module code for a logger factory given a `LoggerHandlerConfig`.
* Handles built-in loggers (node, console, json), the compose meta-logger,
* and arbitrary user-provided entrypoints.
* and arbitrary user-provided entrypoint.
*/
export function generateLoggerCode(config: LoggerHandlerConfig): string {
switch (config.entrypoint) {
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/middleware/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ function createContext({
session: undefined,
cache: new DisabledAstroCache(),
csp: undefined,
logger: undefined,
};
return Object.assign(context, {
getActionResult: createGetActionResult(context.locals),
Expand Down
34 changes: 34 additions & 0 deletions packages/astro/src/core/render-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,27 @@ export class RenderContext {
},
};
},

get logger(): APIContext['logger'] {
if (!pipeline.manifest.experimentalLogger) {
pipeline.logger.warn(
null,
'The Astro.logger is available only when experimental.logger is defined.',
);
return undefined;
}
return {
info(msg: string) {
pipeline.logger.info(null, msg);
},
warn(msg: string) {
pipeline.logger.warn(null, msg);
},
error(msg: string) {
pipeline.logger.error(null, msg);
},
};
},
};
}

Expand Down Expand Up @@ -866,6 +887,19 @@ export class RenderContext {
},
};
},
get logger(): APIContext['logger'] {
return {
info(msg: string) {
pipeline.logger.info(null, msg);
},
warn(msg: string) {
pipeline.logger.warn(null, msg);
},
error(msg: string) {
pipeline.logger.error(null, msg);
},
};
},
};
}

Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/manifest/serialized.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,5 +237,6 @@ async function createSerializedManifest(
logLevel: settings.logLevel,
shouldInjectCspMetaTags: false,
experimentalQueuedRendering: settings.config.experimental?.queuedRendering,
experimentalLogger: !!settings.config.experimental?.logger,
};
}
3 changes: 3 additions & 0 deletions packages/astro/src/runtime/server/astro-global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,8 @@ export function createAstro(site: string | undefined): AstroGlobal {
get cache(): any {
throw createError('cache');
},
get logger(): any {
throw createError('logger');
},
};
}
21 changes: 19 additions & 2 deletions packages/astro/src/types/public/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3064,9 +3064,26 @@ export interface AstroUserConfig<
* @name experimental.logger
* @type {{ entrypoint: string; config?: Record<string, unknown> }}
* @default `undefined`
* @version 6.0.0
* @version 6.2.0
* @description
* Allows to customise how Astro logger behaves
*
* Configure a custom logger by providing the specifier to its entrypoint point and an optional, serializable configuration:
Comment thread
ematipico marked this conversation as resolved.
Outdated
*
* ```js
* // astro.config.mjs
* import { defineConfig } from 'astro/config';
*
* export default defineConfig({
* experimental: {
* logger: {
* entrypoint: "@org/astro-logger",
* config: {
* level: "error"
* }
* }
* }
* });
* ```
*/
logger?: LoggerHandlerConfig;
};
Expand Down
Loading
Loading