`
wangking717
  • 浏览: 263312 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论

用LOG4J对项目进行监控,增加EMAIL日志监控

阅读更多

LOG4J用了common logging的标准接口。。。所以用LOG4J的时候得引用common logging的包哦。。

 

当然如果要在LOG4J中用EMAIL的话,得把javamail和jaf包引用进来。。。

 

OK。。原理我就不啰嗦了。。直接上代码和配置。

import org.apache.commons.logging.Log;   
  
import org.apache.commons.logging.LogFactory;   
  
public class TestLog {   
       
    private static Log log = LogFactory.getLog(TestLog.class);   
       
    public void test() {   
        log.debug("This is the debug message.");   
        log.info("This is the info message.");   
        log.warn("This is the warn message.");   
        log.error("This is the error message.");   
        log.fatal("This is the fatal message.");   
    }   
  
    public static void main(String[] args) {   
        TestLog testLog = new TestLog();   
        testLog.test();   
    }   
  
}  

 

 

配置:

log4j.rootLogger = info,stdout,RF,MAIL   
  
#There is 3 appender,you can use any of them according to you requirement.   

#Set the variable
pattern=Happened Time[%d]    Log Type[%p](%F:%L) - %m%n

#appender1[name=stdout]   log to console   
log4j.appender.stdout = org.apache.log4j.ConsoleAppender    
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout   
log4j.appender.stdout.layout.ConversionPattern =${pattern}
  
#appender2[name=RF]   log to file   
log4j.appender.RF = org.apache.log4j.RollingFileAppender    
log4j.appender.RF.File = d:/logs/pfingoopenapi2.log    
log4j.appender.RF.MaxFileSize = 10000KB    
log4j.appender.RF.MaxBackupIndex = 1  
  
log4j.appender.RF.layout=org.apache.log4j.PatternLayout   
log4j.appender.RF.layout.ConversionPattern=${pattern}   
  
  
#appender3[name=MAIL]  log to email   
log4j.appender.MAIL = com.gftech.log4j.SMTPExtAppender   
log4j.appender.MAIL.Threshold=ERROR  
log4j.appender.MAIL.BufferSize=512  
log4j.appender.MAIL.SMTPHost=smtp.qq.com   
log4j.appender.MAIL.to=wangking717@qq.com   
log4j.appender.MAIL.from=wangking717@qq.com   
#custom by myself[using auth]
log4j.appender.MAIL.SMTPAuth=true  
#custom by myself[using auth]   
log4j.appender.MAIL.SMTPUsername=wangking717  
#custom by myself[using auth]   
log4j.appender.MAIL.SMTPPassword=your password here   
log4j.appender.MAIL.Subject=Log4J Message   
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout   
log4j.appender.MAIL.layout.ConversionPattern=${pattern} 

 

 

 

因为大部分的邮件服务器都是需要认证的,而LOG4J大牛们却没有把认证加进去。。那么就只有自己来改进它吧。。

 

由于SMTPAppender的属性都是私有的,没有给我们留下继承的可能,所以我们选择直接从它的父类AppenderSkeleton来继承,然后把SMTPAppender的源代码全部COPY过来,增加如下EMAIL用户名、密码和是否需要认证的标记:

    // Define auth info   
    private String smtpUsername;   
  
    private String smtpPassword;   
  
    private String smtpAuth;  

 

 

 

在activateOptions()方法中增加验证的代码:

/* ADD auth code */  
        if (smtpAuth != null && smtpAuth.trim().equals("true")) ...{   
            props.put("mail.smtp.auth", "true");   
            authenticator = new Authenticator() ...{   
                protected PasswordAuthentication getPasswordAuthentication() ...{   
                    return new PasswordAuthentication(smtpUsername, smtpPassword);   
                }   
            };   
        }   
  
        // Session session = Session.getInstance(props, null);   
        Session session = Session.getInstance(props, authenticator);  

 

 

如果发送的日志信息涉及到中文字符,还必须设定发送内容的编码,在sendBuffer()方法如修改设置content为如下所示,把编码方式指定为GB2312格式:

part.setContent(sbuf.toString(), layout.getContentType()+";charset=GB2312");  

 

 

最后添加三个新加属性的GETTER和SETTER,全部源代码如下所示:

package com.gftech.log4j;   
  
import java.util.Date;   
import java.util.Properties;   
  
import javax.mail.Authenticator;   
import javax.mail.Message;   
import javax.mail.MessagingException;   
import javax.mail.Multipart;   
import javax.mail.PasswordAuthentication;   
import javax.mail.Session;   
import javax.mail.Transport;   
import javax.mail.internet.AddressException;   
import javax.mail.internet.InternetAddress;   
import javax.mail.internet.MimeBodyPart;   
import javax.mail.internet.MimeMessage;   
import javax.mail.internet.MimeMultipart;   
  
import org.apache.log4j.AppenderSkeleton;   
import org.apache.log4j.Level;   
import org.apache.log4j.helpers.CyclicBuffer;   
import org.apache.log4j.helpers.LogLog;   
import org.apache.log4j.helpers.OptionConverter;   
import org.apache.log4j.spi.ErrorCode;   
import org.apache.log4j.spi.LoggingEvent;   
import org.apache.log4j.spi.TriggeringEventEvaluator;   
  
/**  
 * SMTP Appender扩展,增加对邮件认证的支持  
 *   
 * @author lenovo  
 *   
 */  
public class SMTPExtAppender extends AppenderSkeleton {   
    private String to;   
  
    private String from;   
  
    private String subject;   
  
    private String smtpHost;   
  
    // define auth info   
    private String smtpUsername;   
  
    private String smtpPassword;   
  
    private String smtpAuth;   
  
    // --------------------------   
  
    private int bufferSize = 512;   
  
    private boolean locationInfo = false;   
  
    protected CyclicBuffer cb = new CyclicBuffer(bufferSize);   
  
    protected Message msg;   
  
    protected TriggeringEventEvaluator evaluator;   
  
    /**  
     * The default constructor will instantiate the appender with a  
     * {@link TriggeringEventEvaluator} that will trigger on events with level  
     * ERROR or higher.  
     */  
    public SMTPExtAppender() {   
        this(new DefaultEvaluator());   
    }   
  
    /**  
     * Use <code>evaluator</code> passed as parameter as the {@link  
     * TriggeringEventEvaluator} for this SMTPAppender.  
     */  
    public SMTPExtAppender(TriggeringEventEvaluator evaluator) {   
        this.evaluator = evaluator;   
    }   
  
    /**  
     * Activate the specified options, such as the smtp host, the recipient,  
     * from, etc.  
     */  
    public void activateOptions() {   
        Properties props = new Properties(System.getProperties());   
        Authenticator authenticator = null;   
  
        if (smtpHost != null)   
            props.put("mail.smtp.host", smtpHost);   
  
        /**//* ADD auth code */  
        if (smtpAuth != null && smtpAuth.trim().equals("true")) {   
            props.put("mail.smtp.auth", "true");   
            authenticator = new Authenticator() {   
                protected PasswordAuthentication getPasswordAuthentication() {   
                    return new PasswordAuthentication(smtpUsername,   
                            smtpPassword);   
                }   
            };   
        }   
  
        // Session session = Session.getInstance(props, null);   
        Session session = Session.getInstance(props, authenticator);   
  
        // session.setDebug(true);   
        msg = new MimeMessage(session);   
  
        try {   
            if (from != null)   
                msg.setFrom(getAddress(from));   
            else  
                msg.setFrom();   
  
            msg.setRecipients(Message.RecipientType.TO, parseAddress(to));   
            if (subject != null)   
                msg.setSubject(subject);   
        } catch (MessagingException e) {   
            LogLog.error("Could not activate SMTPAppender options.", e);   
        }   
    }   
  
    /**  
     * Perform SMTPAppender specific appending actions, mainly adding the event  
     * to a cyclic buffer and checking if the event triggers an e-mail to be  
     * sent.  
     */  
    public void append(LoggingEvent event) {   
  
        if (!checkEntryConditions()) {   
            return;   
        }   
  
        event.getThreadName();   
        event.getNDC();   
        if (locationInfo) {   
            event.getLocationInformation();   
        }   
        cb.add(event);   
        if (evaluator.isTriggeringEvent(event)) {   
            sendBuffer();   
        }   
    }   
  
    /**  
     * This method determines if there is a sense in attempting to append.  
     *   
     * <p>  
     * It checks whether there is a set output target and also if there is a set  
     * layout. If these checks fail, then the boolean value <code>false</code>  
     * is returned.  
     */  
    protected boolean checkEntryConditions() {   
        if (this.msg == null) {   
            errorHandler.error("Message object not configured.");   
            return false;   
        }   
  
        if (this.evaluator == null) {   
            errorHandler   
                    .error("No TriggeringEventEvaluator is set for appender ["  
                            + name + "].");   
            return false;   
        }   
  
        if (this.layout == null) {   
            errorHandler.error("No layout set for appender named [" + name   
                    + "].");   
            return false;   
        }   
        return true;   
    }   
  
    synchronized public void close() {   
        this.closed = true;   
    }   
  
    InternetAddress getAddress(String addressStr) {   
        try {   
            return new InternetAddress(addressStr);   
        } catch (AddressException e) {   
            errorHandler.error("Could not parse address [" + addressStr + "].",   
                    e, ErrorCode.ADDRESS_PARSE_FAILURE);   
            return null;   
        }   
    }   
  
    InternetAddress[] parseAddress(String addressStr) {   
        try {   
            return InternetAddress.parse(addressStr, true);   
        } catch (AddressException e) {   
            errorHandler.error("Could not parse address [" + addressStr + "].",   
                    e, ErrorCode.ADDRESS_PARSE_FAILURE);   
            return null;   
        }   
    }   
  
    /**  
     * Returns value of the <b>To</b> option.  
     */  
    public String getTo() {   
        return to;   
    }   
  
    /**  
     * The <code>SMTPAppender</code> requires a  
     * {@link org.apache.log4j.Layout layout}.  
     */  
    public boolean requiresLayout() {   
        return true;   
    }   
  
    /**  
     * Send the contents of the cyclic buffer as an e-mail message.  
     */  
    protected void sendBuffer() {   
  
        // Note: this code already owns the monitor for this   
        // appender. This frees us from needing to synchronize on 'cb'.   
        try {   
            MimeBodyPart part = new MimeBodyPart();   
  
            StringBuffer sbuf = new StringBuffer();   
            String t = layout.getHeader();   
            if (t != null)   
                sbuf.append(t);   
            int len = cb.length();   
            for (int i = 0; i < len; i++) {   
                // sbuf.append(MimeUtility.encodeText(layout.format(cb.get())));   
                LoggingEvent event = cb.get();   
                sbuf.append(layout.format(event));   
                if (layout.ignoresThrowable()) {   
                    String[] s = event.getThrowableStrRep();   
                    if (s != null) {   
                        for (int j = 0; j < s.length; j++) {   
                            sbuf.append(s[j]);   
                        }   
                    }   
                }   
            }   
            t = layout.getFooter();   
            if (t != null)   
                sbuf.append(t);   
            part.setContent(sbuf.toString(), layout.getContentType()   
                    + ";charset=GB2312");   
  
            Multipart mp = new MimeMultipart();   
            mp.addBodyPart(part);   
            msg.setContent(mp);   
            msg.setSentDate(new Date());   
            Transport.send(msg);   
        } catch (Exception e) {   
            LogLog.error("Error occured while sending e-mail notification.", e);   
        }   
    }   
  
    /**  
     * Returns value of the <b>EvaluatorClass</b> option.  
     */  
    public String getEvaluatorClass() {   
        return evaluator == null ? null : evaluator.getClass().getName();   
    }   
  
    /**  
     * Returns value of the <b>From</b> option.  
     */  
    public String getFrom() {   
        return from;   
    }   
  
    /**  
     * Returns value of the <b>Subject</b> option.  
     */  
    public String getSubject() {   
        return subject;   
    }   
  
    /**  
     * The <b>From</b> option takes a string value which should be a e-mail  
     * address of the sender.  
     */  
    public void setFrom(String from) {   
        this.from = from;   
    }   
  
    /**  
     * The <b>Subject</b> option takes a string value which should be a the  
     * subject of the e-mail message.  
     */  
    public void setSubject(String subject) {   
        this.subject = subject;   
    }   
  
    /**  
     * The <b>BufferSize</b> option takes a positive integer representing the  
     * maximum number of logging events to collect in a cyclic buffer. When the  
     * <code>BufferSize</code> is reached, oldest events are deleted as new  
     * events are added to the buffer. By default the size of the cyclic buffer  
     * is 512 events.  
     */  
    public void setBufferSize(int bufferSize) {   
        this.bufferSize = bufferSize;   
        cb.resize(bufferSize);   
    }   
  
    /**  
     * The <b>SMTPHost</b> option takes a string value which should be a the  
     * host name of the SMTP server that will send the e-mail message.  
     */  
    public void setSMTPHost(String smtpHost) {   
        this.smtpHost = smtpHost;   
    }   
  
    /**  
     * Returns value of the <b>SMTPHost</b> option.  
     */  
    public String getSMTPHost() {   
        return smtpHost;   
    }   
  
  
    /**  
     * The <b>To</b> option takes a string value which should be a comma  
     * separated list of e-mail address of the recipients.  
     */  
    public void setTo(String to) {   
        this.to = to;   
    }   
  
  
    /**  
     * Returns value of the <b>BufferSize</b> option.  
     */  
    public int getBufferSize() {   
        return bufferSize;   
    }   
  
  
    /**  
     * The <b>EvaluatorClass</b> option takes a string value representing the  
     * name of the class implementing the {@link TriggeringEventEvaluator}  
     * interface. A corresponding object will be instantiated and assigned as  
     * the triggering event evaluator for the SMTPAppender.  
     */  
    public void setEvaluatorClass(String value) {   
        evaluator = (TriggeringEventEvaluator) OptionConverter   
                .instantiateByClassName(value, TriggeringEventEvaluator.class,   
                        evaluator);   
    }   
  
  
    /**  
     * The <b>LocationInfo</b> option takes a boolean value. By default, it is  
     * set to false which means there will be no effort to extract the location  
     * information related to the event. As a result, the layout that formats  
     * the events as they are sent out in an e-mail is likely to place the wrong  
     * location information (if present in the format).  
     *   
     * <p>  
     * Location information extraction is comparatively very slow and should be  
     * avoided unless performance is not a concern.  
     */  
    public void setLocationInfo(boolean locationInfo) {   
        this.locationInfo = locationInfo;   
    }   
  
  
    /**  
     * Returns value of the <b>LocationInfo</b> option.  
     */  
    public boolean getLocationInfo() {   
        return locationInfo;   
    }   
  
    public String getSMTPAuth() {   
        return smtpAuth;   
    }   
  
  
    /**  
     * 设置是否进行SMTP认证。  
     */  
    public void setSMTPAuth(String smtpAuth) {   
        this.smtpAuth = smtpAuth;   
    }   
  
  
    /**  
     * Returns value of the <b>SMTPPassword</b> option.  
     *   
     * @return <b>SMTPPassword</b>  
     */  
    public String getSMTPPassword() {   
        return smtpPassword;   
    }   
  
  
    /**  
     * 设置访问SMTP服务器的密码。  
     */  
    public void setSMTPPassword(String smtpPassword) {   
        this.smtpPassword = smtpPassword;   
    }   
  
  
    /**  
     * Returns value of the <b>SMTPUsername</b> option.  
     *   
     * @return <b>SMTPUsername</b>  
     */  
    public String getSMTPUsername() {   
        return smtpUsername;   
    }   
  
  
    /**  
     * 设置访问SMTP服务器的用户名。  
     */  
    public void setSMTPUsername(String smtpUsername) {   
        this.smtpUsername = smtpUsername;   
    }   
  
}   
  
class DefaultEvaluator implements TriggeringEventEvaluator {   
  
    /**  
     * Is this <code>event</code> the e-mail triggering event?  
     *   
     * <p>  
     * This method returns <code>true</code>, if the event level has ERROR  
     * level or higher. Otherwise it returns <code>false</code>.  
     */  
    public boolean isTriggeringEvent(LoggingEvent event) {   
        return event.getLevel().isGreaterOrEqual(Level.ERROR);   
    }   
}  

 

 

 

分享到:
评论

相关推荐

    Spring项目中怎么配置log4j

    在Spring项目中配置log4j是一项基础且重要的工作,它能帮助我们记录应用程序的运行日志,便于调试、排查问题和性能分析。Log4j是一个广泛使用的Java日志框架,提供灵活的日志记录功能。接下来,我们将详细讲解如何在...

    log4j 发送邮件

    2. **Log4j配置**:要使用Log4j发送邮件,首先需要在项目的配置文件(通常是`log4j.properties`或`log4j.xml`)中添加适当的配置,包括设置SMTP服务器信息、发件人和收件人地址,以及触发发送邮件的日志级别。...

    javaweb配置Log4j发送日志邮件------全面

    Log4j是一个广泛使用的日志记录框架,它提供了灵活的日志配置和丰富的功能。本教程将详细介绍如何配置Log4j来实现日志信息通过电子邮件发送,以便于及时获取系统异常或关键事件的通知。 首先,我们需要理解Log4j的...

    log4j 不同级别 不同文件 发送邮件配置

    Log4j是一款广泛使用的...在实际项目中,可能还需要结合业务需求进行调整,例如,增加过滤器以控制特定类的日志级别,或者使用更复杂的布局模式。总之,理解和掌握log4j的配置,对于优化Java应用的日志管理至关重要。

    apache-log4j-2.6.2.jar包

    Log4j 2的主要目的是提供高效、灵活且强大的日志记录解决方案,它允许开发者和系统管理员对应用程序的运行时行为进行详细监控,从而帮助调试、性能优化以及安全事件追踪。 在Apache Log4j 2.6.2中,主要包含以下几...

    log4j-java

    **日志框架Log4j详解** Log4j是Java领域广泛应用的一个开源日志记录工具,由Apache软件基金会开发。它的核心功能在于提供了一种灵活且高效的方式来记录应用程序运行过程中的事件,这对于调试、性能监控、故障排查...

    log4j 发送邮件配置实例

    Log4j是一个广泛使用的Java日志框架,它允许开发者在程序中插入日志语句,以便跟踪错误、调试信息和其他重要事件。当我们遇到严重错误(如`error`级别)时,能够实时收到通知至关重要。在本实例中,我们将探讨如何...

    log4j发送邮件log4j1.2.16.jar、mail.jar、activation.jar

    在IT行业中,日志记录是系统管理和故障排查的重要环节,而Log4j是Java平台上的一个广泛应用的日志组件。本文将深入探讨Log4j发送邮件的功能,以及涉及到的log4j-1.2.16.jar、mail.jar和activation.jar这三个关键文件...

    使用Log4net发送日志邮件实例

    在"使用Log4net发送日志邮件实例"中,我们将探讨如何利用Log4net的功能,将日志信息通过电子邮件发送,以便于实时监控和快速响应潜在的问题。 首先,你需要在项目中引用Log4net库。这可以通过NuGet包管理器完成,...

    Web 式样书,Log4J,发送Email

    本实战项目旨在帮助开发者掌握Web应用程序的实现,包括使用MVC设计模式、数据源(DataSource)、数据传输对象(DTO)、数据访问对象(DAO)、电子邮件发送以及日志管理工具Log4J的配置。此外,还将涉及文件上传功能...

    基于python实现的linux后台日志监控小项目

    在IT行业中,Linux系统的日志监控是运维工作中不可或缺的一部分,它可以帮助我们实时了解系统运行状态、排查问题以及预测潜在故障。Python作为一种强大的编程语言,因其简洁的语法和丰富的库资源,常被用于开发各种...

    TestLog4j2Mail

    【标题】"TestLog4j2Mail" 涉及的知识点主要集中在日志管理和电子邮件通信上,核心是使用Log4j框架将日志信息发送到电子邮件。Log4j是Apache提供的一款开源日志记录工具,它允许程序员灵活地控制日志信息的输出级别...

    log4 net用法总结(TXT格式)

    log4net 是一个基于 .NET 的日志记录工具,其灵感来源于 Java 平台下的 log4j,并且由 Apache 软件基金会维护。log4net 可以帮助开发者记录程序运行时的日志信息,这对于调试代码、追踪错误以及监控应用程序的行为都...

    log4perl - log4j for Perl-开源

    `log4perl` 是一个专门为 Perl 语言设计的日志记录框架,灵感来源于 Java 平台上的著名日志库 `log4j`。它的核心目标是提供灵活、高效且可扩展的日志处理能力,使得开发者能够方便地控制应用程序中的日志输出,从而...

    log_monitor:监控日志

    日志监控器监视Web服务器的日志。 并通过电子邮件,Webpost,文件或控制台发出警报。安装添加gem "log-monitor" 到Gemfile。用法作为RAILS插件创建config / log-monitor.yml monitor: target: /tmp/log/development....

    Laravel开发-laravel-email-database-log

    总结来说,"Laravel开发-laravel-email-database-log"项目提供了记录Laravel邮件发送到数据库的能力,增强了日志管理的灵活性和可分析性。通过自定义日志驱动和数据库存储,开发者可以更好地监控和分析邮件发送行为...

    Laravel开发-activitylog

    在Laravel项目中使用activitylog,首先需要通过Composer进行安装: ```bash composer require spatie/laravel-activitylog ``` 然后在`config/app.php`中注册服务提供者和门面: ```php // 在providers数组中添加...

    Laravel开发-laravel-mysql-email-log

    在“Laravel-mysql-email-log”项目中,开发者实现了一个功能,它允许我们把日志保存到 MySQL 数据库,并且当日志达到指定级别时,通过电子邮件发送警报。 ### 1. 配置数据库存储 首先,我们需要配置 Laravel 的...

Global site tag (gtag.js) - Google Analytics