Почему мой java ведет журнал go в консоль, а также в файл - PullRequest
0 голосов
/ 13 июля 2020

Я настраиваю свое приложение для использования класса ведения журнала, а не файла logging.properties в папке jre conf, используя -Djava.util.logging.config.class=com.jthink.songkong.logging.StandardLogging

И это работает, за исключением того, что я замечаю, что информация, которая просто переход в мой файл журнала также переходит в окно консоли, это замечается при использовании --win-console с jpackage на Windows, но я думаю, что это уже происходило до того, как я использовал JPackage

Это мой класс ведения журнала:

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();
    }
}
}

И это пример кода, который, как я ожидал, внесет go в свой файл songkong-debug0-0.log, но он также вывод в окно консоли:

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

Почему это должно быть?

1 Ответ

1 голос
/ 13 июля 2020

Добавьте код в com.jthink.songkong.logging.StandardLogging , чтобы распечатать дерево регистратора в конце вашей конфигурации. Это поможет вам разобраться в происходящем. Поскольку вы используете класс конфигурации, вы даже можете создать собственное системное свойство для переключения печати дерева регистратора, если вам это понадобится в будущем.

Если вывод вашей консоли выглядит как формат CmdLineFormatter, который вы создали то код использует либо этот регистратор, либо дочерний регистратор, который печатает в родительские обработчики. Предполагая, что вы управляете форматом CmdLineFormatter, вы можете включить имя регистратора в вывод, чтобы найти рассматриваемый регистратор.

Если вывод выглядит как SimpleFormatter, то, скорее всего, это обработчик консоли, который прилагается к регистратору root. Просто удалите этот обработчик из регистратора root в вашем классе конфигурации.

Более полное решение - вызвать LogManager.reset в начале конструктора класса StandardLogging. Это очистит конфигурацию, установленную JRE перед вызовом ваших изменений. Альтернативой является установка файла java .util.logging.config.file так, чтобы он указывал на нулевое устройство из командной строки в дополнение к настройке java.util.logging.config.class.

...