0

I configure my application to use a logging class rather than the logging.properties file in the jre conf folder using -Djava.util.logging.config.class=com.jthink.songkong.logging.StandardLogging

And it works, except that I notice that information that is just mean to be going to my log file is also going to console window, this is being noticed when using --win-console with jpackage on Windows but I think it was already happening before I was using JPackage

This is my logging class:

public final class StandardLogging
{

public static int LOG_SIZE_IN_BYTES = 10000000;

//Default parent logger
public static  Logger  defaultLogger                = Logger.getLogger("");

//jaudiotagger logger
public static  Logger  ioLogger                     = Logger.getLogger("org.jaudiotagger");

//SongKong logger
public static  Logger  debugLogger                  = Logger.getLogger("com.jthink");

//SongKong usaer Message Logger
public static  Logger  userInfoLogger               = Logger.getLogger("com.jthink.songkong.ui.MainWindow");

//General c3p0
public static  Logger  c3p0Logger                   = Logger.getLogger("com.mchange.v2.c3p0");

//For capturing Preapred stament Cache hits
//public static  Logger  c3p0ConnectionLogger         = Logger.getLogger("com.mchange.v2.c3p0.stmt");

//For capturing stack traces when connection lasted too long
public static  Logger  c3p0PooledConnectionLogger   = Logger.getLogger("com.mchange.v2.resourcepool.BasicResourcePool");

//HIbernate SQL
public static  Logger  hibernateLogger              = Logger.getLogger("org.hibernate.SQL");



//TODO not sure this even used, I think CmdLogger just does System.out
private static Logger cmdlineLogger = Logger.getLogger("cmdline");

protected void configureLoggerLevels()
{
    //Default Log Level, used by any 3rd party libs we are using if not configured further
    defaultLogger.setLevel(Level.WARNING);

    //For Debug (songKong and jaudiotagger)
    ioLogger.setLevel(Level.WARNING);
    ioLogger.setUseParentHandlers(false);

    try
    {
        //If GeneralPreferences exist and we can access set from user value
        ioLogger.setLevel(Level.parse(String.valueOf(GeneralPreferences.getInstance().getIoDebugLevel())));
    }
    catch(Exception ex)
    {

    }

    debugLogger.setLevel(Level.WARNING);
    debugLogger.setUseParentHandlers(false);
    try
    {
        //If GeneralPreferences exist and we cBuildBuiklan access set from user value
        debugLogger.setLevel(Level.parse(String.valueOf(GeneralPreferences.getInstance().getDebugLevel())));
    }
    catch(Exception ex)
    {

    }

    //C3p0 Logger
    c3p0Logger.setLevel(Level.INFO);
    c3p0Logger.setUseParentHandlers(false);

    //Set to FINEST to see SQL
    hibernateLogger.setLevel(Level.WARNING);
    hibernateLogger.setUseParentHandlers(false);

    //For Capturing CheckIn/Outs nad Prepared Statement Cache Hits
    //c3p0ConnectionLogger.setLevel(Level.FINEST);
    //c3p0ConnectionLogger.setUseParentHandlers(false);

    //For capturing stacktrace from timed out connections
    c3p0PooledConnectionLogger.setLevel(Level.INFO);
    c3p0PooledConnectionLogger.setUseParentHandlers(false);

    //For user message log
    userInfoLogger.setUseParentHandlers(false);
    userInfoLogger.setLevel(Level.FINEST);

    userInfoLogger.setUseParentHandlers(false);
    userInfoLogger.setLevel(Level.FINEST);

}

protected void configureHandlers() throws Exception
{
    //Set Filehandler used for writing to debug log
    String logFileName = Platform.getPlatformLogFolderInLogfileFormat() + "songkong_debug%u-%g.log";
    FileHandler fe = new FileHandler(logFileName, LOG_SIZE_IN_BYTES, 10, true);
    fe.setEncoding(StandardCharsets.UTF_8.name());
    fe.setFormatter(new LogFormatter());
    fe.setLevel(Level.FINEST);

    //Set Filehandler used for writing to user log
    String userLogFileName = Platform.getPlatformLogFolderInLogfileFormat() + "songkong_user%u-%g.log";
    FileHandler userFe = new FileHandler(userLogFileName, LOG_SIZE_IN_BYTES, 10, true);
    userFe.setFormatter(new com.jthink.songkong.logging.UserLogFormatter());
    userFe.setLevel(Level.FINEST);

    //Write this output to debug log file
    //defaultLogger.addHandler(fe);
    c3p0Logger.addHandler(fe);
    c3p0PooledConnectionLogger.addHandler(fe);
    //c3p0ConnectionLogger.addHandler(fe);
    ioLogger.addHandler(fe);
    debugLogger.addHandler(fe);
    hibernateLogger.addHandler(fe);

    //Write this output to user log file
    userInfoLogger.addHandler(userFe);

    //For cmd line output, is this still used
    cmdlineLogger.setUseParentHandlers(false);
    ConsoleHandler cmdLineHandler = new java.util.logging.ConsoleHandler();
    cmdLineHandler.setLevel(Level.FINEST);
    cmdLineHandler.setFormatter(new CmdLineFormatter());
    cmdlineLogger.addHandler(cmdLineHandler);

    System.out.println("debuglogfile is:" + logFileName);
    System.out.println("userlogfile is:"  + userLogFileName);

}

public StandardLogging()
{
    try
    {
        configureLoggerLevels();
        configureHandlers();
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
}
}

And this is an example of code that I would just expect to go to my songkong-debug0-0.log file, but it is also being output to the console window:

MainWindow.logger.warning("User Dir:"+ System.getProperty("user.dir"));
MainWindow.logger.warning("Java Dir:"+ System.getProperty("java.home"));

Why would that be?

Cardstdani
  • 4,999
  • 3
  • 12
  • 31
Paul Taylor
  • 13,411
  • 42
  • 184
  • 351

1 Answers1

1

Add code to com.jthink.songkong.logging.StandardLogging to print the logger tree at the end of your configuration. This will help you troubleshoot what is happening. Since you are using a configuration class you can even make your own system property to toggle printing the logger tree if you need to in the future.

If your console output looks like the format of the CmdLineFormatter you created then code is either using that logger or a child logger that is printing to the parent handlers. Assuming you control the format of the CmdLineFormatter you can include the logger name in the output to locate the logger in question.

If the output looks like the SimpleFormatter then more likely it is the console handler that is attached to the root logger. Simply remove that handler from the root logger in your configuration class.

A more complete solution is to invoke LogManager.reset at the start of your StandardLogging class constructor. This would clear out the configuration that the JRE set prior to invoking your changes. An alternative is to set the java.util.logging.config.file to point to a null device from the command line in addition to setting your java.util.logging.config.class.

jmehrens
  • 10,580
  • 1
  • 38
  • 47
  • okay, thanks that helped I didnt realize I had some other code that later on could add some console handlers depending on OS, I have now removed this code and it is working as expected. – Paul Taylor Jul 13 '20 at 16:35