Skip to content

Synchronize Log4jLogEvent-related changes from 2.x #3869

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jvz
Copy link
Member

@jvz jvz commented Aug 1, 2025

This updates Log4jLogEvent and its builder class to work similarly to what is in 2.25.0. The previously added MementoLogEvent class can be removed as the builder can make memento copies better.

This ports changes introduced in #3171 which seems somewhat inspired by changes made in main previously. However, due to the changes in Log4jLogEvent, this removes the need for the added memento class.

This updates `Log4jLogEvent` and its builder class to work similarly to
what is in 2.25.0. The previously added `MementoLogEvent` class can be
removed as the builder can make memento copies better.
@jvz jvz added this to the 3.0.0-beta4 milestone Aug 1, 2025
@vy vy assigned vy and jvz Aug 4, 2025
@vy
Copy link
Member

vy commented Aug 4, 2025

@ppkarwasz, you authored #3171, which this PR originates from. I'd appreciate it if you can help with the review.

@ppkarwasz
Copy link
Contributor

I'll review this PR later this week, but please note this is a challenging port.

The changes introduced in #3171 primarily address backward compatibility. The concept of "mutability" in version 2.x has been quite confusing, and I believe we have an opportunity to improve clarity significantly in 3.x. Specifically:

  • The methods ReusableMessage.memento() and LogEvent.toMemento() have similar names but return fundamentally different types (Message vs. LogEvent). This naming overlap can cause confusion, especially since classes like ReusableLogEvent implement both interfaces (ReusableMessage and LogEvent).

  • Introducing a method such as freeze()/isFrozen() could be beneficial in scenarios where the log event has reached its final state and is guaranteed not to change further.

  • Considering that approximately 99% of log messages utilize the standard three types (ObjectMessage, SimpleMessage, and ParameterizedMessage), it may be advantageous to streamline the logging pipeline by exclusively using either Log4jLogEvent or MutableLogEvent. These classes could implement both the Message (or ReusableMessage) and LogEvent interfaces, thereby simplifying the architecture.

These are preliminary thoughts, and since I haven't reviewed the changes thoroughly yet, some of these ideas might already be implemented.

@jvz
Copy link
Member Author

jvz commented Aug 4, 2025

  • The methods ReusableMessage.memento() and LogEvent.toMemento() have similar names but return fundamentally different types (Message vs. LogEvent). This naming overlap can cause confusion, especially since classes like ReusableLogEvent implement both interfaces (ReusableMessage and LogEvent).

The naming overlap with similar but not equal method names is related to what you identified here (classes implementing both Message and LogEvent). Perhaps it would make more sense for the methods to be renamed to toMementoMessage() and toMementoEvent(). In case it wasn't clear by the names, I used the term "memento" here as a design pattern name for a snapshot of some object. As the old implementation made somewhat more explicit, it's the logical equivalent of running a data class through some form of round trip serialization/deserialization. While a memento object might be modifiable thanks to the type system, the point of a memento object is that such accidental manipulation doesn't affect the original object. In general, though, this problem would be easier to denote in the type system if Java supported immutable types like Kotlin does. 🤷🏼

  • Introducing a method such as freeze()/isFrozen() could be beneficial in scenarios where the log event has reached its final state and is guaranteed not to change further.

That sounds a little bit of an internal detail considering these checks are largely relevant to when an object is returned a pool (which is how we got rid of the frozen flag in some reusable class after adding Recycler).

  • Considering that approximately 99% of log messages utilize the standard three types (ObjectMessage, SimpleMessage, and ParameterizedMessage), it may be advantageous to streamline the logging pipeline by exclusively using either Log4jLogEvent or MutableLogEvent. These classes could implement both the Message (or ReusableMessage) and LogEvent interfaces, thereby simplifying the architecture.

I think with the changes you made such that Log4jLogEvent is effectively immutable while Log4jLogEvent.Builder is mutable sort of works toward that idea. While I haven't verified the feasibility of it yet, perhaps MutableLogEvent can be replaced by Log4jLogEvent.Builder.

These are preliminary thoughts, and since I haven't reviewed the changes thoroughly yet, some of these ideas might already be implemented.

I did remove an extra LogEvent implementation thanks to the changes from 2.x. Perhaps there is more simplification possible with MutableLogEvent.

@jvz jvz requested a review from ppkarwasz August 4, 2025 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: To triage
Development

Successfully merging this pull request may close these issues.

3 participants