Skip to content

Honor IncludeCategory in the JSON log format - #2474

Open
TemRevil wants to merge 4 commits into
aws:masterfrom
TemRevil:fix/json-log-include-category
Open

Honor IncludeCategory in the JSON log format#2474
TemRevil wants to merge 4 commits into
aws:masterfrom
TemRevil:fix/json-log-include-category

Conversation

@TemRevil

Copy link
Copy Markdown

Fixes #2469

Problem

With Amazon.Lambda.Logging.AspNetCore, the ILogger category is written on every line in text format when LambdaLoggerOptions.IncludeCategory is true (which is the default). The JSON branch of LambdaILogger.Log, however, only forwards the message template and its arguments and never emits the category, so IncludeCategory is silently ignored in JSON mode. Migrating a function from text to JSON logging drops the category entirely, with no way to opt back in.

Change

When IncludeCategory is set, the JSON branch now prepends a {Category} placeholder to the message template and supplies the category as the matching argument. Because the JSON formatter turns named template parameters into top-level properties, the category surfaces as a queryable property (and in the rendered message), matching the parity the text format already provides.

  • Text format: unchanged.
  • JSON format with IncludeCategory = false: unchanged (no extra property, same parameter count).
  • JSON format with IncludeCategory = true: the category is included.

This follows the reporter's suggested "at minimum honor IncludeCategory" approach and needs no runtime-side change. If the maintainers would rather expose it as a dedicated top-level category field emitted by JsonLogMessageFormatter (the issue's preferred option), I'm happy to take that direction instead.

Testing

Amazon.Lambda.Logging.AspNetCore.Tests on net10.0: Passed! Failed: 0, Passed: 16. Added TestJSONParameterLoggingIncludesCategoryWhenEnabled (category present, parameter count goes 3 to 4) and TestJSONParameterLoggingOmitsCategoryWhenDisabled (no category, count stays 3); the existing TestJSONParameterLogging still passes since it uses IncludeCategory = false.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates Amazon.Lambda.Logging.AspNetCore to honor LambdaLoggerOptions.IncludeCategory when Lambda JSON logging is enabled, so category information isn’t silently dropped when switching from text to JSON logs.

Changes:

  • Prepend a {Category} placeholder (and corresponding argument) to the JSON logging message template when IncludeCategory is enabled.
  • Add tests asserting JSON parameter logging includes/excludes category depending on IncludeCategory.
  • Add an autover changelog entry describing the fix.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
Libraries/src/Amazon.Lambda.Logging.AspNetCore/LambdaILogger.cs Adds category injection in the JSON logging branch when IncludeCategory is enabled.
Libraries/test/Amazon.Lambda.Logging.AspNetCore.Tests/LoggingTests.cs Adds tests validating category presence/absence impacts parameter count in JSON mode.
.autover/changes/541b1775-ecf8-4e75-99c8-675924a5c34e.json Records a patch changelog note for the logging fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +78 to +86
if (_options.IncludeCategory)
{
// Unlike the text format, the JSON format otherwise drops the
// category entirely, so IncludeCategory has no effect. Prepend a
// "{Category}" placeholder (which the JSON formatter turns into a
// queryable property) and supply the category value.
messageTemplate = "[{Category}] " + messageTemplate;
parameters.Insert(0, _categoryName);
}

@TemRevil TemRevil Jul 16, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 536f8b4. Prepending the category as literal text instead of a {Category} placeholder means it can no longer get mixed into the formatter's positional vs named argument detection, so the caller's own placeholders and their values stay untouched either way. Added a test with a positional template to cover it.

@GarrettBeatty
GarrettBeatty changed the base branch from master to dev July 15, 2026 02:57
@madmox

madmox commented Aug 21, 2026

Copy link
Copy Markdown

Reporter of #2469 here, answering the question in your description: from a consumer standpoint the dedicated category field is worth it. The literal-text form puts the information back in message, but only as a substring to match on: it doesn't allow filter Category = "..." or stats count(*) by Category in Logs Insights, which is the capability I lost moving from text to JSON. That said, this is still better than today's behavior, so shipping it now and adding the field later works for me too.

Unrelated nit: the branch normalizes LambdaILogger.cs to CRLF (upstream has mixed endings), so the diff reads +74/-63 where the real change is 11 lines.

@TemRevil

Copy link
Copy Markdown
Author

That settles the field question, thanks. A real category field is the better answer for exactly that reason: a substring in message is not something you can group or filter on. I left it out here because adding a top-level field changes the shape of the emitted JSON, and that felt like a maintainer's call rather than something to slip into a bug fix. Glad to do it as a follow-up PR if they want it.

Line endings are fixed in bd5e0f2. The first commit had normalized the whole file to CRLF where upstream is mixed, so 63 of those lines were pure churn. The diff is 11 added and 0 deleted now, and git diff -w against the previous commit comes back empty, so nothing else moved.

@TemRevil

Copy link
Copy Markdown
Author

@normj could you take a look when you get a chance? It has been open since July 11 and the workflows are still at action_required, so CI has never actually run on it.

One thing needs your call rather than mine: madmox asked above for a dedicated top-level category field instead of the category prepended into message. I left it out because a new top-level key changes the shape of the emitted JSON. Glad to do it as a follow-up if you want it.

@GarrettBeatty

Copy link
Copy Markdown
Collaborator

im fine with the change as-is for now. top level category can be a follow up pr if we want. norm is out of office until next week for reviewing

@GarrettBeatty

Copy link
Copy Markdown
Collaborator

@GarrettBeatty

Copy link
Copy Markdown
Collaborator

I will ask someone else on the team to review in meantime since norm is out

@TemRevil
TemRevil force-pushed the fix/json-log-include-category branch from bd5e0f2 to 776b763 Compare August 26, 2026 17:16
@TemRevil

Copy link
Copy Markdown
Author

Rebased onto dev. That restore failure on your run was NU1903 against PowerShellHost, not this change, my branch just predated the System.Security.Cryptography.Xml bump (8.0.3/10.0.7 on the old base against 8.0.4/10.0.10 on dev). Same three files as before, byte for byte.

@GarrettBeatty
GarrettBeatty changed the base branch from dev to master August 26, 2026 17:56
In text format the ILogger category is written on every line when
LambdaLoggerOptions.IncludeCategory is true (the default), but the JSON
branch of LambdaILogger.Log never emitted the category, so migrating a
function from text to JSON logging silently lost it with no way to opt
back in (aws#2469).

When IncludeCategory is set, prepend a {Category} placeholder to the
message template and supply the category value, so it surfaces as a
queryable property in the JSON record instead of being dropped. Text
format is unchanged, and JSON output is unchanged when IncludeCategory
is false.

Fixes aws#2469
Copilot's review on this PR caught a real issue: prepending a {Category}
placeholder to honor IncludeCategory in JSON mode makes the formatter's
positional-argument detection treat the whole template as named, which
can shift how a caller's own {0}/{1} placeholders line up with their
values. Prepend the category as literal text instead, same as the text
format already does.

Updated the two category tests and added one covering a positional
template to confirm it stays untouched. All 17 tests pass locally on
net8.0 and net10.0.
The first commit normalized the whole file to CRLF where upstream has
mixed endings, so the diff read 74 changed lines when only 11 lines
actually change. Content is unchanged: git diff -w against the previous
commit is empty.
@GarrettBeatty
GarrettBeatty force-pushed the fix/json-log-include-category branch from 776b763 to 73c7034 Compare August 26, 2026 17:59
@GarrettBeatty

Copy link
Copy Markdown
Collaborator

updated to master branch as base branch since #2542 was merged. rerunning the integ tests https://github.com/aws/aws-lambda-dotnet/actions/runs/32997374660

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logger category is silently dropped in JSON log format (IncludeCategory has no effect)

4 participants