Google App Engine - 配置默认记录器以发送电子邮件

发布于 2024-10-12 04:25:21 字数 44 浏览 3 评论 0原文

在我的 GAE/J 应用程序中,如何配置默认记录器以通过电子邮件报告错误?

In my GAE/J application, how would I configure the default logger to report errors via email?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

離人涙 2024-10-19 04:25:21

SMTPHandler 已存在,但由于不满足依赖性而无法与 GAE/J 一起使用。看一下SMTPHandler的源代码并将其适配到GAE/J。

An SMTPHandler already exists, but cannot be used with GAE/J because of unsatisfied dependencies. Take a look at the source code of SMTPHandler and adapt it to GAE/J.

裂开嘴轻声笑有多痛 2024-10-19 04:25:21

包含的 MailHandler JavaMail 1.5.3 及更高版本 已内置 支持 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 存储库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 以包含正确的日志设置和电子邮件包络。以下是一个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
    [email protected]
    [email protected]
    #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

接下来创建代码来安装MailHandler 因为 LogManager 将无法看到logging-mailhandler.jar

以下是 ServletContextListener 的示例,它将在根记录器上安装 MailHandler。

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

The MailHandler included with JavaMail 1.5.3 and later have built in support for Google App Engine. Make sure you are using the most current version of JavaMail.

For GAE/J you can download the logging-mailhandler.jar and include it in your project.

<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>

Otherwise, can use the java.net Maven repository or Maven Central and pull the dependency by groupid=com.sun.mail and artifactId=logging-mailhandler.

<dependency>
    <groupId>com.sun.mail</groupId>  
    <artifactId>logging-mailhandler</artifactId>  
    <version>1.5.3</version> 
</dependency>

After the dependency is setup, then configure your logging.properties to contain the correct log settings and email envlope. Here is a sample logging.properties file:

    # 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
    [email protected]
    [email protected]
    #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

Next create code to install the MailHandler because the LogManager won't be able to see the logging-mailhandler.jar.

Here is an example of a ServletContextListener that will install the MailHandler on the root logger.

/**
 * 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());
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文