Return-Path: X-Original-To: apmail-logging-log4j-user-archive@www.apache.org Delivered-To: apmail-logging-log4j-user-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D986F17E72 for ; Mon, 22 Jun 2015 11:35:16 +0000 (UTC) Received: (qmail 95309 invoked by uid 500); 22 Jun 2015 11:35:16 -0000 Delivered-To: apmail-logging-log4j-user-archive@logging.apache.org Received: (qmail 95255 invoked by uid 500); 22 Jun 2015 11:35:16 -0000 Mailing-List: contact log4j-user-help@logging.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Log4J Users List" Reply-To: "Log4J Users List" Delivered-To: mailing list log4j-user@logging.apache.org Received: (qmail 95244 invoked by uid 99); 22 Jun 2015 11:35:16 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 Jun 2015 11:35:16 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of dutoitns@gmail.com designates 209.85.220.171 as permitted sender) Received: from [209.85.220.171] (HELO mail-qk0-f171.google.com) (209.85.220.171) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 Jun 2015 11:33:02 +0000 Received: by qkfe185 with SMTP id e185so98560683qkf.3 for ; Mon, 22 Jun 2015 04:34:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=m+uTdemTwJt7fc6SMyAlTNLsHeScUyStO8bdcIWpCGk=; b=xWYWnFQ4UjiiM/RFDb2YwPxrr7Ury8Oj4Dpi5gMGWdpm9Brxj/ps7UkUBFpCiWYKvU YylshfKr9wzUp3WmL5JhqEH3Nbk4LPmQrNN3JP977cgs5XpX6GwJNGht0Jjz6B+miesJ WvV4CXR4jJbW21OMMW1hizi5I7C+TqpMJdEsBPtoxdmetue30jzA0EYrzrGU715u9IrR RZToMeQZwDRD0KhcFwY4UppVsuLoP/5PtKQfs1/hbgc5xsLxoxmUyb94Ttr4WpK/l6iE Dm/14J5WNNcKkAwAFVEvHsdwK9vvbafVyaW+OUS/uqO97YrgTE7FYoXox11P1uQnEaxc icww== MIME-Version: 1.0 X-Received: by 10.140.232.144 with SMTP id d138mr38554428qhc.43.1434972889441; Mon, 22 Jun 2015 04:34:49 -0700 (PDT) Received: by 10.96.204.70 with HTTP; Mon, 22 Jun 2015 04:34:49 -0700 (PDT) In-Reply-To: References: Date: Mon, 22 Jun 2015 13:34:49 +0200 Message-ID: Subject: Re: flushing async loggers From: Serdyn du Toit To: Log4J Users List Content-Type: multipart/alternative; boundary=001a113562ce566c02051919a9bc X-Virus-Checked: Checked by ClamAV on apache.org --001a113562ce566c02051919a9bc Content-Type: text/plain; charset=UTF-8 Thanks Remko! > How do you ensure your LogManager class is loaded before your app calls any other log4j code? My LogManager class separates my code from a direct dependency on log4j classes. So all interaction with log4j only happens in my LogManager class. Still - you made me doubt that my System.getProperty(..) call might be working so I 1. ran my test passing in the system property as a VM argument 2. refactored my log4j2.xml to explicitly use an async appender (sorry, I haven't had a look at jstack yet) Initially I still had a few problems but then things started working. Here is what I found - The async appender works. BUT SO DOES MY CURRENT CONFIGURATION. I NOW HAVE A MORE FINE-GRAINED IDEA ABOUT WHAT THE PROBLEM IS: If I start my test with a synchronous LogManager.trace(..) statement (in other words before kicking of a multitude of asynchronous threads) everything works!!! If I however only start logging from within the asynchronous threads then I get the following console output and logging is incomplete: SLF4J: The following loggers will not work because they were created SLF4J: during the default configuration phase of the underlying logging system. SLF4J: See also http://www.slf4j.org/codes.html#substituteLogger SLF4J: com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 SLF4J: com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 SLF4J: com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 SLF4J: com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 SLF4J: com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 SLF4J: com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 SLF4J: com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 13:18:33.654 [pool-1-thread-5] DEBUG com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 - Executing async command: com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest$1 13:18:33.655 [pool-1-thread-5] TRACE com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest - logging with log4j1996961461 13:18:33.657 [main] TRACE com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest - ALL DONE Initially I thought - meh, the logging system isn't initialized properly and a few logging statements get lost in those few milliseconds. But its more severe than that, because above you see one statement of the form: 13:18:33.655 [pool-1-thread-5] TRACE com.cq.core.util.extension.date.test.DateUtil_ConcurrentTest - logging with log4j1996961461 But I should be seeing a 100! So its not just logging statements getting dropped, but its as if the logger then fails all the time going forward... As said - if I start my test with a synchronous LogManager.trace(..) statement this error doesn't appear and I see everything I need to. So I'm thinking that Log4j initializes differently if I first start using it in a synchronous way...? Or it doesn't like a burst of asynchronous attempts initially...? Instead of starting every test with a synchronous LogManager.trace(..) statement I've added the following static block to my LogManager class: static { // this is a hack debug(LogManager.class, "Logging system initialization"); } And now everything works :) Your thoughts? But cool, everything works now - but I'm still interested in any input you might have (because it is a bit of a hack, with zero understanding of what's happening on my part) On Mon, Jun 22, 2015 at 1:30 AM, Remko Popma wrote: > Async loggers will call flush() when the queue is empty. If you are not > seeing all expected output in the file I suspect that async loggers are not > actually enabled. > > You can verify with jstack or break your program in a debugger. There > should be an "AsyncLogger..." thread. > > How do you ensure your LogManager class is loaded before your app calls > any other log4j code? > > Remko > > Sent from my iPhone > > > On 2015/06/22, at 6:54, Serdyn du Toit wrote: > > > > Hi, > > > > How do I flush async loggers? > > > > I'm currently testing some code with multiple threads - when the test is > > finished almost none of the log statements have been printed. This also > > makes me worried about my production code's logging when the server > > gracefully shuts down (will it just not log as it the case in my test, or > > will it actually flush...) > > > > The only clue I've found on how to do this is the following stackoverflow > > thread: > > > > > http://stackoverflow.com/questions/3060240/how-do-you-flush-a-buffered-log4j-fileappender > > > > But the solution just doesn't seem to work for me. > > > > I don't think its relevant to the question, but here is my log4j.xml > > > > > > > > > > > > > > > > > > > filePattern="logs/$${date:yyyy-MM}/webapplog-%d{yyyy-MM-dd}-%i.log.gz"> > > > > > > > > > > > > > > > > > > ...snip... > > > > > > > > > > > > > > > > > > And then I have a LogManager class encapsulating all my logging code that > > enables async logging: > > > > public class LogManager { > > > > // Enable Log4j2 async logging > > static { > > System.setProperty("Log4jContextSelector", > > "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"); > > } > > > > ...etc... > > } > > > > Any help appreciated!!! > > --------------------------------------------------------------------- > To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org > For additional commands, e-mail: log4j-user-help@logging.apache.org > > --001a113562ce566c02051919a9bc--