Java 如何使用Log4J SMTPAppender动态更改电子邮件主题?

Java 如何使用Log4J SMTPAppender动态更改电子邮件主题?,java,log4j,Java,Log4j,我使用上述log4j属性文件发送 我发电子邮件的时候 log4j.appender.ERROREMAIL=org.apache.log4j.net.SMTPAppender log4j.appender.ERROREMAIL.SMTPHost=www.company.com log4j.appender.ERROREMAIL.Threshold=ERROR log4j.appender.ERROREMAIL.To=email.address1@company.com,email.address2

我使用上述log4j属性文件发送 我发电子邮件的时候

log4j.appender.ERROREMAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.ERROREMAIL.SMTPHost=www.company.com
log4j.appender.ERROREMAIL.Threshold=ERROR
log4j.appender.ERROREMAIL.To=email.address1@company.com,email.address2@company.com,email.address3@company.com
log4j.appender.ERROREMAIL.From=some.emailaddress.com
log4j.appender.ERROREMAIL.Subject=messagesubject1
我如何才能使其动态化,以便 消息主题可以根据计算机名称(env name)动态更改

例如:

我想根据机器名动态使用主题1、2和3

任何帮助都将不胜感激。
谢谢

我可以想出两种解决方案:

1) 编写自己的记录器,使用SMTPAppender并通过编程设置属性

2) 使用将动态值放入代码中。您可以使用%X从log4j.xml中的MDC获取值

例:
log4j.appender.ERROREMAIL.Subject=%X{key}

您应该只需要使用hostname变量,例如:

log4j.appender.ERROREMAIL.Subject=messagesubject1, messagesubject2, messagesubject3

根据您的paritcular配置和操作系统,您可能需要使用-Dhostname='machinename'或-Dhostname=$HOST将此变量提供给statrup的JVM。在下面的代码段中,我读取了log4j.properties文件,将属性log4j.appender.ERROREMAIL.Subject设置为emailRecipients,并重置log4j配置。可以在应用程序开始时完成,只需正确设置emailRecepients字符串

log4j.appender.ERROREMAIL.Subject=${hostname} 

设置用户名或over ENV变量的步骤

    Properties props = new Properties();
    try {
         InputStream configStream = Thread.class.getResourceAsStream("/log4j.properties");
         if (configStream == null) {
             throw new RuntimeException();
         }
         props.load(configStream);
         configStream.close();
    } catch(Throwable e) {
        System.out.println("Error: Cannot load log4j configuration file ");
    }

    props.setProperty("log4j.appender.ERROREMAIL.Subject", emailRecipients);

    LogManager.resetConfiguration();
    PropertyConfigurator.configure(props);
///////////////////////////////////////////////////////////////////////////
//初始日志记录配置
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//SMTAppender属性的动态配置
///////////////////////////////////////////////////////////////////////////
包es.foo.test;
导入java.util.Enumeration;
导入java.util.Properties;
导入org.apache.log4j.Appender;
导入org.apache.log4j.Logger;
导入org.apache.log4j.net.SMTPAppender;
公共类testsMTAppender{
专用静态记录器smtp=Logger.getLogger(“smtp.Logger”);
私有静态布尔ini_标志=false;
私有静态最终属性propiedades=新属性();
静止的{
试试{
propiedades.load(TestSMTPAppender.class.getClassLoader().getResourceAsStream(“mydomainUtiles.properties”);
}捕获(异常ioe){
System.err.println(“从'mydomainUtiles.properties'创建属性时出错:“+ioe.getMessage());
}
}   
私有静态void initializeLogger(){
字符串SMTPHost=propiedades.getProperty(“主机”);
字符串SMTPUsername=propiedades.getProperty(“用户”);
字符串From=propiedades.getProperty(“发送方”);
枚举eappenders=smtp.getAllAppenders();
while(eappenders.hasMoreElements()){
Appender Appender=(Appender)eappenders.nextElement();
if(SMT附件的附件实例){
if(SMTPHost!=null){
((SMTPAppender)appender.setSMTPHost(SMTPHost);
}
if(SMTPUsername!=null){
((SMTPAppender)appender.setsmtppusername(SMTPUsername);
}
if(From!=null){
((SMTPAppender)appender).setFrom(From);
}
//在此处放置其他属性,如主题
((SMTPAppender)appender).激活选项();
}           
}
}
公共静态记录器getSMTPLogger(){
如果(!ini_标志){
initializeLogger();
ini_标志=真;
}
返回TestSMTPAppender.smtp;
}   
}
///////////////////////////////////////////////////////////////////////////
//试验
///////////////////////////////////////////////////////////////////////////
包es.foo.test;
导入java.util.Enumeration;
导入org.apache.log4j.Appender;
导入org.apache.log4j.Logger;
导入org.apache.log4j.net.SMTPAppender;
公开课考试{
私有静态记录器smtp=TestSMTPAppender.getSMTPLogger();
公共静态void main(字符串[]args){
smtp.trace(“message1”);
smtp.debug(“message2”);
smtp.info(“message3”);
smtp.warn(“message4”);
smtp.error(“message5”);
}
}

如果我们正在读取属性并添加主题抛出java代码,我们将遇到并发请求问题


如果第一个用户在发送邮件之前修改了主题并执行了一些其他操作。同时,第二个用户添加了不同的主题。第一个用户也可以获取第二个用户的主题

我正在研究你的第一项建议。我可以改变主题,但我如何设置信息。我的印象是,当你调用logger.error(“这是我的错误”)时,消息内容中会出现字符串“这是我的错误”!经过一些思考,解决方案2会更容易,因为您不必编写任何代码。您的应用程序是Web应用程序还是独立应用程序?代码中动态生成的消息如何?我想捕获它。有办法吗。
    Properties props = new Properties();
    try {
         InputStream configStream = Thread.class.getResourceAsStream("/log4j.properties");
         if (configStream == null) {
             throw new RuntimeException();
         }
         props.load(configStream);
         configStream.close();
    } catch(Throwable e) {
        System.out.println("Error: Cannot load log4j configuration file ");
    }

    props.setProperty("log4j.appender.ERROREMAIL.Subject", emailRecipients);

    LogManager.resetConfiguration();
    PropertyConfigurator.configure(props);
log4j.appender.smtp.Subject=SYNC PROJECTS (${user.name}) Error Log ...
///////////////////////////////////////////////////////////////////////////
// Initial Logging configuration
///////////////////////////////////////////////////////////////////////////

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>


    <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d{dd MMM yyyy HH:mm:ss} %5p %c{1} - %m%n"/>
      </layout>
   </appender>


    <!-- BufferSize almacena un buffer de mensajes. Un evento de tipo error o 
    superior provoca el envio del correo junto con el resto de mensajes en el buffer (si los hay) -->
    <appender name="emailAppender"  class="org.apache.log4j.net.SMTPAppender">  

        <param name="BufferSize"    value="40"/> 
        <param name="SMTPHost"      value="conectores.mydomain.es" />  
        <param name="SMTPUsername"  value="weblogic" />           
        <param name="From"          value="no.reply@mydomain.es" />  
        <param name="To"            value="foo.bar@externos-mydomain.es" />  
        <param name="Subject"       value="Notificación de la aplicación" />  

        <layout class="org.apache.log4j.PatternLayout">  
            <param name="ConversionPattern" value="%n%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%l] %n%m%n" />  
        </layout>  
    </appender>  

    <!-- Las trazas de nivel trace o superior las mete en el buffer, el resto las desecha -->
    <logger name="smtp.logger">  
        <level value="debug"/>
        <appender-ref ref="emailAppender" />  
    </logger>   

    <root>
        <priority value="debug"/>
        <appender-ref ref="consoleAppender"/>
    </root>

</log4j:configuration>

///////////////////////////////////////////////////////////////////////////
// Dynamic configuration of SMTAppender attributes
///////////////////////////////////////////////////////////////////////////

package es.foo.test;

import java.util.Enumeration;

import java.util.Properties;

import org.apache.log4j.Appender;
import org.apache.log4j.Logger;
import org.apache.log4j.net.SMTPAppender;

public class TestSMTPAppender {

    private static Logger smtp = Logger.getLogger("smtp.logger");
    private static boolean ini_flag = false;    
    private static final Properties propiedades = new Properties(); 
    static {
        try {           
            propiedades.load(TestSMTPAppender.class.getClassLoader().getResourceAsStream("mydomainUtiles.properties"));
        } catch (Exception ioe) {
            System.err.println("error while creating properties from 'mydomainUtiles.properties': " + ioe.getMessage());    
        }
    }   

    private static void initializeLogger(){ 

        String SMTPHost = propiedades.getProperty("host");
        String SMTPUsername = propiedades.getProperty("user");
        String From = propiedades.getProperty("sender");

        Enumeration eappenders = smtp.getAllAppenders();
        while(eappenders.hasMoreElements()){
            Appender appender = (Appender) eappenders.nextElement();
            if(appender instanceof SMTPAppender){

                if(SMTPHost != null){
                    ((SMTPAppender)appender).setSMTPHost(SMTPHost);
                }

                if(SMTPUsername != null){
                    ((SMTPAppender)appender).setSMTPUsername(SMTPUsername);
                }

                if(From != null){
                    ((SMTPAppender)appender).setFrom(From);
                }

                // Place here other attributes, like Subject

                ((SMTPAppender)appender).activateOptions();
            }           
        }
    }

    public static Logger getSMTPLogger(){
        if(!ini_flag){
            initializeLogger();
            ini_flag = true;        
        }
        return TestSMTPAppender.smtp;
    }   

}

///////////////////////////////////////////////////////////////////////////
// TEST
///////////////////////////////////////////////////////////////////////////

package es.foo.test;

import java.util.Enumeration;

import org.apache.log4j.Appender;
import org.apache.log4j.Logger;
import org.apache.log4j.net.SMTPAppender;

public class Test {

    private static Logger smtp = TestSMTPAppender.getSMTPLogger();

    public static void main(String[] args) {

        smtp.trace("message1");
        smtp.debug("message2");
        smtp.info("message3");
        smtp.warn("message4");
        smtp.error("message5");

    }
}