Use reverse access with the Google App Engine (GAE)

I am working on a project that uses GAE as a backend for a mobile application. We want really good logs to be implemented in the project. I spent a lot of time reading log4j, logback-classic, logback-access, java.util.logging (JUL) and slf4j.

My conclusion is that I want to use logback access, as it has some nice features when it comes to logging HTTP-related materials (for example, logging full request data on errors, etc.).

Since GAE only supports log levels for JUL, and logback-access does not support slf4j, I thought I just needed to set up reverse access and make sure that it writes all the logs through the JUL in GAE.

Is it possible? Has anyone done this and can guide me when it comes to configuration files for log access and JUL? Can logback access be directly linked via JUL, without the need to add a custom Appender (I'm thinking of connecting to ch.qos.logback.access.jetty.RequestLogImpl, which can be added to the configuration according to the docs)? Or is Jetty's logback access configuration not applicable to GAE? Is something wrong with me?

Any advice is appreciated!

+4
source share
1 answer

We did this and stayed with the magazine for two years. In short, you will end up mixing JUL and logback settings, since your application will use logback, and Google classes will use JUL directly (and you cannot redirect JUL to logback in GAE).

Two years later, we switched to the slf4j + JUL configuration, which is simpler and the only configuration point. This is not easy though (warning: tons of code follow):

logging.properties:

.level = INFO handlers = com.acme.log.InfoHandler,com.acme.log.ErrorHandler # these should work, but they don't. See # http://code.google.com/p/googleappengine/issues/detail?id=7467 com.acme.log.InfoHandler.level=ALL com.acme.log.ErrorHandler.level=WARNING # Example of log level setup for a single class # workaround http://code.google.com/p/google-guice/issues/detail?id=488 com.google.inject.internal.util.level = WARNING 

InfoHandler.java:

 /** * Logs {@link Level#INFO} to {@link System#out}. * This class is inspired by {@link ConsoleHandler} */ public class InfoHandler extends StreamHandler { public InfoHandler() { setOutputStream(System.out); setFilter(new MaxLevelFilter(Level.WARNING)); } @Override public void publish(LogRecord record) { super.publish(record); flush(); } @Override public void close() { flush(); } } 

ErrorHandler.java:

 public class ErrorHandler extends StreamHandler { public ErrorHandler() { setOutputStream(System.err); } @Override public void publish(LogRecord record) { super.publish(record); flush(); } @Override public void close() { flush(); } } 

MaxLevel.java:

 public class MaxLevelFilter implements Filter { private final Level maxLevel; public MaxLevelFilter(Level level) { this.maxLevel = level; } @Override public boolean isLoggable(LogRecord record) { return maxLevel.intValue() > record.getLevel().intValue(); } } 

You should also apply the workaround described here in some application sink when starting the server.

+3
source

Source: https://habr.com/ru/post/1402850/


All Articles