-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
feat(logger): docs and runtime #16437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
12635f0
2117d5c
2bfb30e
8d4b558
bb73e45
e6e8dd8
d0d4df7
f57f126
fc7a021
de36899
f40f166
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| --- | ||
| 'astro': minor | ||
| --- | ||
|
|
||
| Adds experimental support for configurable log handlers. | ||
|
|
||
| This experimental feature provides better control over Astro's logging infrastructure by allowing users to replace the default console output with custom logging implementations (e.g., structured JSON). This is particularly useful for users using on-demand rendering and wishing to connect their log aggregation services such as Kibana, Logstash, CloudWatch, Grafana, or Loki. | ||
|
|
||
| By default, Astro provides three built-in log handlers (`json`, `node` and `console`), but you can also create your own. | ||
| #### JSON logging | ||
|
|
||
| JSON logging can be enabled via the CLI for the `build`, `dev`, and `sync` commands using the `experimentalJson` flag: | ||
|
|
||
|
|
||
| ```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 |
| 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 { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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', | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| // This is public module with functions exported to the user | ||
|
|
||
| import { type AstroLoggerLevel, levels } from './core.js'; | ||
|
|
||
| /** | ||
| * Returns `true` if `messageLevel` has a level equals or higher than `configuredLevel` | ||
| * | ||
| * @param messageLevel The level of the incoming message | ||
| * @param configuredLevel The level the logger is configured with | ||
| */ | ||
| export function matchesLevel( | ||
| messageLevel: AstroLoggerLevel, | ||
| configuredLevel: AstroLoggerLevel, | ||
| ): boolean { | ||
| return levels[messageLevel] >= levels[configuredLevel]; | ||
| } |
There was a problem hiding this comment.
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?