feat: add inset config option - ability to set log json data#42
feat: add inset config option - ability to set log json data#42saltytostitos wants to merge 5 commits intoHugoRCD:mainfrom
inset config option - ability to set log json data#42Conversation
Add feature to allow nesting evlog data into another property
|
@saltytostitos is attempting to deploy a commit to the HRCD Projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Thank you for following the naming conventions! 🙏 |
saltytostitos
left a comment
There was a problem hiding this comment.
Accidentally snuck in another change that shouldn't have been here. Removed this change for another PR.
nitro/plugin.ts
There was a problem hiding this comment.
Pull request overview
This PR adds an inset configuration option to evlog that allows nesting log data under a custom property (automatically prefixed with $). This feature is designed for observability platforms like Cloudflare Workers that inject their own root-level metadata, making it easier to separate application logs from platform metadata.
Changes:
- Added
insetconfig option to type definitions, allowing users to specify a property name for nesting logs - Implemented inset logic in the logger that wraps log data when
pretty: falseandinsetis configured - Updated documentation across multiple files explaining the feature, use cases, and platform compatibility warnings
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/evlog/src/types.ts | Added inset property to LoggerConfig and defined InsetWideEvent type |
| packages/evlog/src/logger.ts | Implemented inset logic to conditionally nest log data and added global inset variable |
| packages/evlog/src/nuxt/module.ts | Added inset option to Nuxt module configuration with detailed JSDoc |
| packages/evlog/src/nitro/plugin.ts | Added inset config to Nitro plugin interface and initialization |
| packages/evlog/src/index.ts | Exported InsetWideEvent type for public API |
| skills/evlog/references/wide-events.md | Added comprehensive documentation section with examples and important considerations |
| skills/evlog/references/code-review.md | Added code review checklist item for verifying proper inset usage |
| skills/evlog/SKILL.md | Added inset feature documentation and code review guidance |
| apps/docs/content/1.getting-started/2.installation.md | Added installation guide section with configuration examples and warnings |
| README.md | Added inset feature documentation with examples |
| AGENTS.md | Added inset config option to agent reference table |
| bun.lock | Automated lockfile update adding configVersion field |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| | `exclude` | `string[]` | `undefined` | Route patterns to exclude from logging. Supports glob (`/api/_nuxt_icon/**`). Exclusions take precedence over inclusions | | ||
| | `routes` | `Record<string, RouteConfig>` | `undefined` | Route-specific service configuration. Allows setting different service names for different routes using glob patterns | | ||
| | `pretty` | `boolean` | `true` in dev | Pretty print with tree formatting | | ||
| | `inset` | `string` | `'evlog'` | Nested property name for wide events | |
There was a problem hiding this comment.
Incorrect default value in documentation: The table shows inset with a default value of 'evlog', but according to the type definitions and code, the default value is undefined (no inset). The default should be undefined or - to indicate it's not set by default.
| | `inset` | `string` | `'evlog'` | Nested property name for wide events | | |
| | `inset` | `string` | `undefined` | Nested property name for wide events | |
| | `env.environment` | `string` | Auto-detected | Environment name | | ||
| | `include` | `string[]` | `undefined` | Route patterns to log (glob). If not set, all routes are logged | | ||
| | `pretty` | `boolean` | `true` in dev | Pretty print logs with tree formatting | | ||
| | `inset` | `string` | `undefined` | Next evlog data inside a property when pretty is disabled | |
There was a problem hiding this comment.
Spelling error: "Next" should be "Nest" in the description "Next evlog data inside a property".
| | `inset` | `string` | `undefined` | Next evlog data inside a property when pretty is disabled | | |
| | `inset` | `string` | `undefined` | Nest evlog data inside a property when pretty is disabled | |
| @@ -29,6 +30,7 @@ export function initLogger(config: LoggerConfig = {}): void { | |||
| globalPretty = config.pretty ?? isDev() | |||
| globalSampling = config.sampling ?? {} | |||
| globalStringify = config.stringify ?? true | |||
| globalInset = config.inset ?? undefined | |||
There was a problem hiding this comment.
Missing test coverage for the inset configuration option. The logger test file (packages/evlog/test/logger.test.ts) has comprehensive tests for other configuration options like pretty, sampling, etc., but there are no tests to verify:
- That logs are nested under the configured property name (e.g.,
$evlog) wheninsetis set andpretty: false - That the
$prefix is automatically added to the inset property name - That
insethas no effect whenpretty: true(development mode) - That the nested structure contains all expected fields (timestamp, level, service, custom fields, etc.)
| globalPretty = config.pretty ?? isDev() | ||
| globalSampling = config.sampling ?? {} | ||
| globalStringify = config.stringify ?? true | ||
| globalInset = config.inset ?? undefined |
There was a problem hiding this comment.
Edge case not handled: If inset is set to an empty string (""), the condition !globalPretty && globalInset will evaluate to false (since empty string is falsy), which is correct behavior. However, this should be explicitly documented or validated. Consider adding validation in initLogger to reject empty strings or falsy values, or document that only truthy string values are valid for inset.
| globalInset = config.inset ?? undefined | |
| // Only accept non-empty strings for inset; treat empty or invalid values as undefined | |
| globalInset = typeof config.inset === 'string' && config.inset.trim() ? config.inset : undefined |
| } | ||
|
|
||
| const formatted: WideEvent = { | ||
| const formatted: InsetWideEvent | WideEvent = !globalPretty && globalInset && globalInset !== undefined ? { |
There was a problem hiding this comment.
Redundant check: globalInset && globalInset !== undefined is redundant. The first condition globalInset already handles the undefined check since an empty string is falsy. This can be simplified to just globalInset.
| const formatted: InsetWideEvent | WideEvent = !globalPretty && globalInset && globalInset !== undefined ? { | |
| const formatted: InsetWideEvent | WideEvent = !globalPretty && globalInset ? { |
| } | ||
|
|
||
| /** | ||
| * Wide event inside a nested propery from global config: inset |
There was a problem hiding this comment.
Spelling error in comment: "propery" should be "property".
| * Wide event inside a nested propery from global config: inset | |
| * Wide event inside a nested property from global config: inset |
|
|
||
| ### Nesting log data | ||
|
|
||
| By default, evlog will log the object at root level when logging without ```pretty``` enabled (see [Configuration Options](/getting-started/installation#configuration-options)); however, for services like Cloudflare Observability, you may wish to nest the data inside an arbitrary property name. This can help organize your data and make it easier to query and analyze. |
There was a problem hiding this comment.
Inconsistent formatting: There are triple backticks (```) used inline instead of single backticks (`). The word "pretty" should use single backticks for inline code formatting, not triple backticks.
| By default, evlog will log the object at root level when logging without ```pretty``` enabled (see [Configuration Options](/getting-started/installation#configuration-options)); however, for services like Cloudflare Observability, you may wish to nest the data inside an arbitrary property name. This can help organize your data and make it easier to query and analyze. | |
| By default, evlog will log the object at root level when logging without `pretty` enabled (see [Configuration Options](/getting-started/installation#configuration-options)); however, for services like Cloudflare Observability, you may wish to nest the data inside an arbitrary property name. This can help organize your data and make it easier to query and analyze. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
commit: |
| } | ||
| ``` | ||
|
|
||
|
|
There was a problem hiding this comment.
Can you pls remove this blank line
This PR adds a likely niche enhancement to allow nesting the log data when logging json.
With systems like Cloudflare Observability, that dump tons of logging data, this makes it easy for me to digest and query the data that I'm providing.
config:
Current flat logs
{ "timestamp": "...", "level": "...", "service": "...", ... }With inset: "evlog":
{ "$evlog": { "timestamp": "...", "level": "...", "service": "...", ... }, "$metadata": { // ...cloudflareData { }I don't normally public formal PRs so if you're interested in this one, let me know if there's anything you need.