[ 
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)

Reply via email to