Xperience by Kentico’s October 2025 Refresh brings support for .NET's ILogger<T> as our primary logging API. Although the existing IEventLogService has not yet been deprecated, adopting ILogger<T> across an Xperience project brings many benefits.
Traditionally, getting these benefits could come at a cost - the developer's time in adapting their code to use new APIs. Today there's a way to reduce these costs, often significantly - agentic AI software development.
Let's see how I used GitHub Copilot to handle this update for the Kentico Community Portal in just a few minutes.
This post was written for Xperience by Kentico v30.11.0. Please consult the documentation for any feature or API changes when using a different version. Be sure to check the System Requirements in the product documentation.
Providing context
Recently, I've written about managing AI agents and engineering their context to get the best results when working on Xperience by Kentico projects. Successfully using GitHub Copilot to migrate from IEventLogService to ILogger<T> required the same approach.
I have the Kentico Community Portal configured to use the new Xperience by Kentico Documentation MCP server. Enabling this MCP server in your project will ensure your AI agents have access to the latest official documentation and best practice guides for Xperience.
This also gives access to the Changelog, which contains helpful details about the logging API changes I wanted to apply.
Copilot generates its own prompt
Although I enjoy building systems, I'm not as excited about authoring large amounts of Markdown to serve as context for AI agents. Thankfully, AI agents are pretty good at writing prompts for themselves thanks to their training datasets, which include lots of open-source AI prompts and instructions.
I asked GitHub Copilot, using Claude Sonnet 4, to author me a prompt for this migration.
Create a new VS Code GitHub copilot prompt that instructs an AI agent to follow Xperience by Kentico's documentation on logging in custom code and the changelog for Xperience v30.11.0
the prompt should guide the agent on how to replace
IEventLogServicewith .NET'sILogger<T>.
With the documentation MCP server enabled, it was able to create a detailed prompt file for me. I did some manual adjusting of the Apply this migration section, making it clear the exact steps that should be followed.
There are some details in the prompt that aren't 100% accurate. For example, IEventLogService isn't deprecated even though the default internal implementation is.
Most of the prompt focuses on the .NET ILogger<T> details, which is a core part of modern .NET and is going to be well represented in your LLM's training data. This means it's not going to need additional context for this.
Copilot Does the Heavy Lifting
At this point, I simply instructed Copilot to execute the prompt file, which is stored as .github/prompts/Logging-Migration.prompt.md.
In VS Code, you can execute a prompt (with its configured tools and specified LLM) by typing a / and the prompt name in the Copilot chat.
Copilot created a To-dos list based on the details in the prompt and then proceeded to modify all the files in the repository that were using IEventLogService, migrating them to ILogger<T>.
What were the results?
17 C# files updated
Adopted structured logging and
EventIdReplaced
LoggingPolicywith.LogWithIntervalPolicy()extension methodConverted a base controller to generic for
ILogger<T>injection
Provided recommendations for next steps with a new
.mdfileMade sure the solution successfully builds
Created a commit message and commit
Copilot recommended I adjust
appsettings.jsonlogging levels to manage which logs will appear in the Xperience Event Log per environment.Copilot also recommended creating some automated tests to verify there weren't any regressions.
This time, I did some simple manual tests to make sure logs were generated in key areas, but directing Copilot to generate e2e tests for log generation would be an interesting future opportunity.
Learning about EventId
I reviewed the code and found that EventId was always created with an Id of 0. I thought this looked incorrect or at least something that should be improved. So, I asked Copilot about it.
What is the value of EventId in .NET structured logging?
All the EventId integer values are 0 after the logging migration. is that a problem?
Copilot replied with a thorough review of how EventId works with .NET's logging APIs and why 0 is an ok value for the Kentico Community Portal.
Overview
In .NET’s logging abstraction, EventId is a lightweight struct (int Id, string? Name) whose purpose is to let you:
Categorize or identify a specific kind of log message beyond level & category.
Enable filtering or routing based on a stable numeric key.
Optionally carry a human‑readable code (the Name) that some providers surface (Kentico maps it to the event code in the Xperience event log).
If you pass new EventId(0, "SOME_CODE"), every log line has the same numeric id (0) but distinct names. That’s not “wrong”; it just limits what you can do with numeric‑only filtering or analytics. The Kentico migration guidance emphasizes the Name because Kentico uses it as the Event Code. The integer part is secondary there.
Is using 0 for all EventIds a problem?
Usually no, unless you need one of these:
- EventId-based filtering/routing
Example:AddFilter((category, eventId) => eventId.Id != 0)or a provider that treats numeric ID specially. With all IDs = 0 you can’t distinguish events numerically. - Aggregation by numeric id in monitoring tools
Some sinks (e.g. EventSource bridges, ETW, certain APM tools) may group by EventId.Id. All zeros collapse into one bucket. - Performance-optimized compiled logging with
LoggerMessage.Definewhere you want stable, unique ids for traceability. - Telemetry correlation rules keyed off specific IDs (e.g. 2001 = “Start”, 2002 = “End”).
If you’re not doing those things, using 0 everywhere is fine. Kentico will still show distinct Event Codes because it uses EventId.Name.
What does EventId actually do?
When you call
logger.LogInformation(eventId, messageTemplate, args...), the framework passes the struct to each logging provider.EventId.Id(int) may be ignored by most providers (Console, Debug, Serilog) unless explicitly configured.EventId.Nameis often emitted asEventId.NameorEventIdproperty (provider dependent). In Kentico,Namebecomes the event code in the Event Log UI.If you omit
EventId, it defaults toId = 0andName = null.
Summary
All zeros are acceptable and not harmful in your current setup; Kentico relies on the Name. Switch to unique numeric ids only if you want advanced filtering, clearer cross-provider analytics, or compiled logging optimizations. If you’d like, I can implement a PortalLogEvents static class and update the existing calls—just say the word.
Reflections
Overall, this only took a couple of minutes to have Copilot write the prompt, make a few adjustments, and then execute it.
Could have this been completed with a find-and-replace or complex Regex? Maybe for the simplest replacement, but this was a classic scenario where a developer needs to adjust everything to take advantage of features like log message templates, structured logging, and incorporating the EventId parameter to ensure Xperience populates the Event Log EVENT_CODE value correctly.
The AI agent had no problem executing the changes, given the clear goal and context, and the context engineering was strongly supported by the new Xperience by Kentico Documentation MCP server.
You can and should be using these tools today!
Also, I think the question I had about EventId is an important example of using AI agents to do more than just generate code. They can be great at helping you learn new concepts which you can explore further in official documentation and by experimenting and building with them in your projects.
Sean Wright
I'm Lead Product Evangelist at Kentico. I work in the Product Marketing department at Kentico along with Matej Stefanik, Miroslav Jirku, and James Turner. My responsibilities include helping partners, customers, and the entire Kentico community understand the strategy and value of Xperience by Kentico. I'm also responsible for Kentico's community programs.