-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
JsonTemplateLayout: Cannot replace recycler factory, template always uses standard factory #3395
Comments
@rschuetz, this is indeed a bug (thanks for the report! 🙇) and your suggested fix makes sense. I will submit a PR containing the fix along with some tests. In the meantime, as a workaround, you can try extending your custom |
@rschuetz, curious: would you mind briefly explaining your custom recycler factory? How does it work? Do you use an external library for the pool? If so, which one? Where did the recyclers bundled with JTL fall short in your use case? |
@vy, excellent, thanks a lot!
The issue I face is that I need a very large maxStringLength - 10.000.000 characters (yes, I know ... I saw your comment on #2516 before ... but there is no other option for now), as one of the background services in the application generates threaddumps (for debugging/support reasons) in a standard format in the logged message in case some threads got stuck, and truncating these dumps would make them useless. Unfortunately this also means all other threads gets buffers of the same size. So if we run with this buffer size there is a risk for OOMs / wasting a lot of memory if many buffers get allocated. Therefore I added a pooling recycler that simply just uses Apache Commons Pool with a maximum size and blocks if all buffers are in use. Not more, hope it works for now, as log frequency is not high. Actually IMHO it would be better if @vy: Would it make sense if I'd open a ticket for something like that, or is it not possible at all?
Thanks a lot, but as there is no upper limit here, it wouldn't be safe. For now I put a patched copy of JsonTemplateLayoutDefaults at the beginning of the classpath. |
@rschuetz, I think you have a misunderstanding on the way queueing recycler works. It uses
or you can provide your own queue supplier where you block on 1 Unless provided, the queue capacity defaults to |
@vy: The "there is no upper limit" does not relate to the queue but the total number of simultaneously active buffers. By default, Yes, I could introduce a custom queue instead, that blocks on Closed ticked by accident ... Sorry. |
@rschuetz, you're right, my oversight.
Initially your buffer will be empty, you'll return null. @rschuetz, could you confirm that #3398 fixes the issue, please? |
@vy: Fix works for me locally. Thanks a lot! |
Description
I'm trying to plug in a new
RecyclerFactoryConverter
following https://logging.apache.org/log4j/2.x/manual/json-template-layout.html#extending-recycler. The factory is using a pool to cache the objects, hence it is using a new spec string likepool
orpool:capacity=123
, which is unknown to the defaultRecyclerFactories
class called byRecyclerFactoryConverter
.The class gets loaded properly, the log contains:
WARN Ignoring TypeConverter [org.apache.logging.log4j.layout.template.json.util.RecyclerFactoryConverter@21ca139c] for type [interface org.apache.logging.log4j.layout.template.json.util.RecyclerFactory] that conflicts with [com.XXX.messaging.log4j.ExtRecycleFactoryConverter@226f885f], since they are not comparable.
To configure the converter I use
-Dlog4j.layout.jsonTemplate.recyclerFactory=pool
However, when initializing log4j2, it fails with
i.e. it's not using the replacement at all, potentially due to the hardcoded reference in
logging-log4j2/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutDefaults.java
Line 118 in 4d0f818
Replacing it with
helps, but I'm not sure if this is correct.
Configuration
Version: 2.23.1
Operating system: Ubuntu 24.04
JDK: OpenJDK Runtime Environment Temurin-17.0.10+7 (build 17.0.10+7)
Logs
See above.
Reproduction
Due to customized build systems here a bit complicated. In general it should be sufficient to
ExampleRecyclerFactory
(from https://logging.apache.org/log4j/2.x/manual/json-template-layout.html#extending-recycler) and returnThreadLocalRecyclerFactory.INSTANCE
just to return something workingannotationProcessor("org.apache.logging.log4j", "log4j-core")
in gradle)JsonTemplateLayout
-Dlog4j.layout.jsonTemplate.recyclerFactory=pool
system property to let the defaultRecyclerFactories
class fail if it gets called despite of the configurationThe text was updated successfully, but these errors were encountered: