1

I'm actually adding java logging (can't use other framework) to my project. I build my app on a .war, and deployed it over Weblogic, the logger is working with my logging.properties config, except for the formatter i don't know why the app is ignoring it.

This is my class where i prepare the logger;

public class CtgLogger {
private static final String LOAD_ERROR = "Properties could not be loaded.";

private static final Map<String, Level> LEVEL_MAP;
private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
static {

    final InputStream inputStream = CtgLogger.class.getResourceAsStream("/logging.properties");
    try {
        LogManager.getLogManager().readConfiguration(inputStream);
    } catch (Exception e) {
        Logger.getAnonymousLogger().severe(LOAD_ERROR);
        Logger.getAnonymousLogger().severe(e.getMessage());
    }
    // and I add the LEVEL_MAP to the logger...

And this is my properties...

handlers = java.util.logging.FileHandler
java.util.logging.FileHandler.pattern=logsfolder/CTGLOG_%g.log
java.util.logging.FileHandler.level=ALL
java.util.logging.FileHandler.limit=3000
java.util.logging.FileHandler.count=6
#java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
#If I use the SimpleFormatter, apps goes well with it format. 
java.util.logging.FileHandler.formatter = com.package.my.log.JsonCustomFormatter
#If I use my custom formatter, the weblogic works with a XMLFormatter (default)

I know the .properties is working, because logger is working with the pattern, limit and count I setted.

PD: If i run my app with JUnit, logs are working with my custom formatter, but do not at weblogic! Don't know why!

2 Answers2

0

Weblogic is going to have multiple class loaders. The standard LogManager can only see classes loaded via the system class loader. Check the Server Log for errors related to not finding your custom class. If that is the case, you have to move your formatter to the system classloader. Otherwise you have have to use code to install your formatter from your web app which is running in a child classloader.

There are also bugs in the LogManager.readConfiguration and alternative methods to use in JDK9 and later.

jmehrens
  • 10,580
  • 1
  • 38
  • 47
  • I have a problem, don't know if u can help me, if i add the formatter from code, when i redeploy my app, like the handler is not close, it makes multiple logs. (It is an API REST, and i don't know if opening and closing the handler at each call is a good method) – Nicolas Villacorta Nov 08 '19 at 12:15
  • Do you have any idea how can i move my custom formatter to the system classloader? – Nicolas Villacorta Nov 11 '19 at 19:21
  • @NicolasVillacorta [Follow advise in #3 and maintain your logger settings via preDistroy and postConstruct](https://stackoverflow.com/questions/58711944/best-way-for-closing-filehandler-on-rest-apis). You don't have to change classloaders then. – jmehrens Nov 12 '19 at 18:40
  • I solved my problem changing the java logging for log4j2. Anyway i selected your answer because it was really usefull to help me understand how the LogManager works with weblogic :) – Nicolas Villacorta Nov 13 '19 at 13:30
0

Using Eclipse and java standard logger may be painful. I found something to produce similar output to Log4J:

"%d{HH:mm:ss,SSS} %-5p %m (%F:%L) in %t%n" in Log4J : you can click on reference and you are there log was issued

21:36:37,9 INFO process model event Digpro2021a/digpro.Digpro(Digpro.java:358) in processModelEvent
21:36:37,9 INFO start polling Digpro2021a/digpro.Digpro(Digpro.java:398) in processEventAutoreload
21:36:37,9 INFO reload now Digpro2021a/digpro.Digpro(Digpro.java:370) in processModelEvent


public class Digpro {

    protected static final Logger L = Logger.getLogger("Digpro");
//logger conf
  static {
    L.setLevel(Level.FINE);
    Handler handler = Logger.getLogger("").getHandlers()[0];
    handler.setLevel(Level.FINE); // Default console handler
    handler.setFormatter(new Formatter() {
        @Override
        public String format(LogRecord r) {
            Date d = new Date(r.getMillis());
            String srcClassLong = r.getSourceClassName();
            String[] aClass = srcClassLong.split("\\$")[0].split("\\.");
            String srcClass = aClass[aClass.length - 1];
            StackTraceElement elem = (new Throwable()).getStackTrace()[7];
            int line = elem.getLineNumber();
            String modulName = elem.getModuleName();
            return String.format("%tH:%tM:%tS,%tl %.7s %s %s/%s(%s.java:%d) in %s\n", d, d, d, d, // 
                    r.getLevel(), r.getMessage(), // LEVEL and message
                    modulName, srcClassLong, srcClass, line, r.getSourceMethodName()); //ref to click on
        }
    });
  }
...
  public static class TestDigpro extends Digpro {
    //TESTING: 

    @Test
    public void testLogFormat() {
        L.info("poll info");
        L.fine("got fine");
    }
  }
}

produses:

21:51:20,9 INFO poll info Digpro2021a/digpro.Digpro$TestDigpro(Digpro.java:723) in testLogFormat
21:51:20,9 FINE got fine Digpro2021a/digpro.Digpro$TestDigpro(Digpro.java:724) in testLogFormat