[ https://issues.apache.org/jira/browse/LOG4J2-2269?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16761144#comment-16761144 ]
Mike Wilkinson edited comment on LOG4J2-2269 at 2/5/19 7:50 PM: ---------------------------------------------------------------- Hi Carter, Thank you so much for your prompt reply. Here is the code that is running in a JUnit test which in log4j2 2.11.0 and below works but in 2.11.1 does not ApplicationAuditor.log(AuditTopics.HIPAA, hipaaData); Assert.assertEquals(mockAppender.getLogs().size(), 1); LogEvent event = mockAppender.getLogs().get(0); System.out.println("!!!!!!!!!!!!!!! event.toString() ============== " + event.toString()); System.out.println("!!!!!!!!!!!!!!! event.getLoggerName() ============== " + event.getLoggerName()); // prints out null in 2.11.1 prior versions print logger name Assert.assertEquals("AuditHIPAA", event.getLoggerName()); // this line fails because getLoggerName() returns null in 2.11.1 Here is the logging code in ApplicationAuditor public final class ApplicationAuditor { private static final String unknown = "UNKNOWN"; private static final String topicHeader = "TOPIC:"; private static final String separator = "-SEPARATOR-"; private static final ObjectMapper mapper = new ObjectMapper() .registerModule(new JodaModule()) .configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) .registerModule(new SimpleModule("ExceptionHandlerModule").addSerializer(Exception.class,new ExceptionSerializer())); private static org.apache.logging.log4j.Logger cachedLogger = null; private ApplicationAuditor() { } /** * * @param topic - Topic for log * @param data - The data that you want to log - Error data container is already provided for logging exceptions * -If provided containers don't fit your needs. Inherit from LogData Container and add fields you want. * Make sure the data types you use are serializable using Jackson as JSON. */ public static void log(Topic topic, LogData data) { try { if (topic == null || topic.getTopic() == null || topic.getTopic().trim().equals("")) \{ topic = AuditTopics.HIPAA; } if (data != null) { validateLogData(data); if (cachedLogger == null) { cachedLogger = LogManager.getLogger("AuditHIPAA"); } System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!! cachedLogger.getName() ============== " + cachedLogger.getName()); // this prints out the proper logger name data.setLoggerName(cachedLogger.getName()); String s = topicHeader + topic.getTopic().toLowerCase() + separator + mapper.writeValueAsString(data); cachedLogger.log(Level.INFO, s); } } catch (Exception ex) { throw new RuntimeException(ex); } } private static void validateLogData(LogData data) { if(data.getUserId() == null || data.getUserId().trim().equals("")) { data.setUserId(unknown); } if(data.getApplication() == null || data.getApplication().getName() == null || data.getApplication().getName().trim().equals("")) \{ data.setApplication(new ApplicationInfo(unknown,unknown,unknown,null,unknown)); }}|| } Please let me know if you need any further information or if I should possibly open an issue and if I should open an issue, can you please send me the link to where to file an issue? Thank you very much for your prompt reply!!!! Mike was (Author: wilkystorm): Hi Carter, Thank you so much for your prompt reply. Here is the code that is running in a JUnit test which in log4j2 2.11.0 and below works but in 2.11.1 does not ApplicationAuditor.log(AuditTopics.HIPAA, hipaaData); Assert.assertEquals(mockAppender.getLogs().size(), 1); LogEvent event = mockAppender.getLogs().get(0); System.out.println("!!!!!!!!!!!!!!! event.toString() ============== " + event.toString()); System.out.println("!!!!!!!!!!!!!!! event.getLoggerName() ============== " + event.getLoggerName()); // prints out null in 2.11.1 prior versions print logger name Assert.assertEquals("AuditHIPAA", event.getLoggerName()); // this line fails because getLoggerName() returns null in 2.11.1 Here is the logging code in ApplicationAuditor public final class ApplicationAuditor { private static final String unknown = "UNKNOWN"; private static final String topicHeader = "TOPIC:"; private static final String separator = "-SEPARATOR-"; private static final ObjectMapper mapper = new ObjectMapper() .registerModule(new JodaModule()) .configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) .registerModule(new SimpleModule("ExceptionHandlerModule").addSerializer(Exception.class,new ExceptionSerializer())); private static org.apache.logging.log4j.Logger cachedLogger = null; private ApplicationAuditor() { } /** * * @param topic - Topic for log * @param data - The data that you want to log - Error data container is already provided for logging exceptions * -If provided containers don't fit your needs. Inherit from LogData Container and add fields you want. * Make sure the data types you use are serializable using Jackson as JSON. */ public static void log(Topic topic, LogData data) { try { if (topic == null || topic.getTopic() == null || topic.getTopic().trim().equals("")) \{ topic = AuditTopics.HIPAA; } if (data != null) { validateLogData(data); if (cachedLogger == null) { cachedLogger = LogManager.getLogger("AuditHIPAA"); } System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!! cachedLogger.getName() ============== " + cachedLogger.getName()); // this prints out the proper logger name data.setLoggerName(cachedLogger.getName()); String s = topicHeader + topic.getTopic().toLowerCase() + separator + mapper.writeValueAsString(data); cachedLogger.log(Level.INFO, s); } } catch (Exception ex) { throw new RuntimeException(ex); } } private static void validateLogData(LogData data) { if(data.getUserId() == null || data.getUserId().trim().equals("")) { data.setUserId(unknown); } if(data.getApplication() == null || data.getApplication().getName() == null ||data.getApplication().getName().trim().equals("")) \{ data.setApplication(new ApplicationInfo(unknown,unknown,unknown,null,unknown)); }}|| } Please let me know if you need any further information or if I should possibly open an issue and if I should open an issue, can you please send me the link to where to file an issue? Thank you very much for your prompt reply!!!! Mike > Memory leaking of replacement parameters in case of enableThreadlocals=true > --------------------------------------------------------------------------- > > Key: LOG4J2-2269 > URL: https://issues.apache.org/jira/browse/LOG4J2-2269 > Project: Log4j 2 > Issue Type: Bug > Components: Core > Reporter: Dmitry Konstantinov > Assignee: Remko Popma > Priority: Major > Fix For: 3.0.0 > > Attachments: heap_dump_references.png, > heap_dump_threadLocals_false.hprof.zip, > heap_dump_threadLocals_true.hprof.zip, test_to_reproduce.zip > > > Use case: > 1) I have a thread pool with quite large number of threads (around 100) > 2) Threads from the pool sometimes process some heavy objects. Threads are > not actively writing into logs (so, a thread may process a task and does not > log any message). > 3) As a part of processing for some objects in some non-frequently used > branch a thread logged a message with heavy replacement parameters > (parameterized log message is used). > In this case such heavy replacement parameters are not garbage collected > until another message will not written within the same thread because > thread-local ReusableParameterizedMessage and MutableLogEvent objects keep > references to the replacement parameters. > Is it possible to cleanup such references when a message is released (for > example as a part of > org.apache.logging.log4j.message.ReusableMessageFactory#release and > org.apache.logging.log4j.core.impl.ReusableLogEventFactory#release) to avoid > such kind of leaks? -- This message was sent by Atlassian JIRA (v7.6.3#76005)