在我的GAE / J应用程序中,如何配置默认记录器以通过电子邮件报告错误?
答案 0 :(得分:1)
SMTPHandler已经存在,但由于不满意的依赖关系,无法与GAE / J一起使用。查看SMTPHandler的源代码并将其调整为GAE / J.
答案 1 :(得分:0)
MailHandler中包含的JavaMail 1.5.3 and later已内置support for Google App Engine。确保您使用的是最新版本的JavaMail。
对于GAE / J,您可以下载logging-mailhandler.jar并将其包含在您的项目中。
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>logging-mailhandler</artifactId>
<version>1.5.3</version>
<scope>system</scope>
<systemPath>FILE_PATH_TO/logging-mailhandler.jar</systemPath>
</dependency>
否则,可以使用java.net Maven repository或Maven Central并通过groupid = com.sun.mail和artifactId = logging-mailhandler拉取依赖关系。
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>logging-mailhandler</artifactId>
<version>1.5.3</version>
</dependency>
设置依赖项后,将logging.properties配置为包含正确的日志设置和电子邮件envlope。以下是logging.properties文件示例:
# A default java.util.logging configuration.
# (All App Engine logging is through java.util.logging by default).
#
# To use this configuration, copy it into your application's WEB-INF
# folder and add the following to your appengine-web.xml:
#
# <system-properties>
# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
# </system-properties>
#
# Set the default logging level for all loggers to INFO
.level = INFO
java.util.logging.MemoryHandler.level=ALL
java.util.logging.MemoryHandler.push=WARNING
#com.sun.mail.util.logging.CompactFormatter.format=%1$tc %2$s%n%4$s: %5$s%6$s%n
#com.sun.mail.util.logging.MailHandler.formatter=com.sun.mail.util.logging.CompactFormatter
com.sun.mail.util.logging.MailHandler.level=WARNING
com.sun.mail.util.logging.MailHandler.mail.from=me@example.com
com.sun.mail.util.logging.MailHandler.mail.to=me@example.com
#com.sun.mail.util.logging.MailHandler.pushLevel=OFF
#com.sun.mail.util.logging.MailHandler.subject=com.sun.mail.util.logging.CollectorFormatter
com.sun.mail.util.logging.MailHandler.verify=limited
下一步create code to install the MailHandler,因为LogManager won't be able to see the logging-mailhandler.jar。
以下是将在根记录器上安装MailHandler的ServletContextListener示例。
/**
* Modify web.xml to include
* <listener>
* <description>Install MailHandler on root logger.</description>
* <listener-class>PACKAGE_NAME_FOR.MailHandlerConfig</listener-class>
* </listener>
*/
import com.sun.mail.util.logging.*;
import static com.google.appengine.api.ThreadManager.backgroundThreadFactory;
import java.util.Arrays;
import static java.util.concurrent.Executors.newScheduledThreadPool;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.MemoryHandler;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MailHandlerConfig implements ServletContextListener, Runnable {
private static final String LOGGER_NAME = "";
private static final Logger logger = Logger.getLogger(LOGGER_NAME);
private volatile ScheduledExecutorService ses;
private volatile Future<?> task;
private volatile Handler handler;
@Override
public void contextInitialized(ServletContextEvent sce) {
MailHandler mh = new MailHandler();
mh.setSubject(defaultSubject());
handler = mh;
try {
handler = new MemoryHandler(mh, mh.getCapacity(), mh.getPushLevel());
ses = newScheduledThreadPool(1, backgroundThreadFactory());
task = ses.scheduleAtFixedRate(this, 30L, 30L, TimeUnit.MINUTES);
} catch (RuntimeException | LinkageError re) {
logger.log(Level.WARNING, "Unable to create push thread.", re);
Level lvl = mh.getLevel();
if (lvl.intValue() < mh.getPushLevel().intValue()) {
mh.setPushLevel(lvl);
handler = mh;
logger.log(Level.WARNING, "Forcing push level to {0}.", lvl);
}
}
logger.addHandler(handler);
logger.log(Level.INFO, "Application initialized. {0}",
Arrays.toString(logger.getHandlers()));
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//Never called under GAE.
try {
Future<?> f = task;
if (f != null) {
f.cancel(false);
}
} catch (RuntimeException ignore) {
}
try {
ScheduledExecutorService e = this.ses;
if (e != null) {
e.shutdown();
}
} catch (RuntimeException ignore) {
}
try {
Handler h = handler;
if (h != null) {
h.close();
logger.removeHandler(h);
}
} catch (RuntimeException ignore) {
}
run();
}
@Override
public void run() {
for (Handler h : logger.getHandlers()) {
try {
if (h instanceof MemoryHandler) {
((MemoryHandler) h).push();
}
h.flush();
} catch (RuntimeException ignore) {
}
}
}
private static Formatter defaultSubject() {
return new CollectorFormatter(
"{0}{1}{2}{4,choice,-1#|0#|0<... {4,number,integer} more}",
new CompactFormatter("%7$#.160s"),
new SeverityComparator());
}
}