简体   繁体   English

使用Spring Application配置日志

[英]configuring log with Spring Application

I have developed a spring application, I want to configure it with apache log4j, have downloaded it and put the jar in project's class path. 我开发了一个spring应用程序,我想用apache log4j配置它,下载它并将jar放在项目的类路径中。 Below is my log4j.Properties file. 下面是我的log4j.Properties文件。

# Root logger option
log4j.rootLogger=INFO, file
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C\:\\loging.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

And below is my main spring application class. 以下是我的主要春季应用程序类。

import org.apache.log4j.Logger;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class DrawingClass {

    public static void main(String args[])
    {
        //without dependency injection 
        /*Triangle t1 = new Triangle();
        t1.draw();*/


        //with dependency injection     
        BeanFactory factory = new XmlBeanFactory(new FileSystemResource("Spring.xml"));
        Triangle t1 =(Triangle) factory.getBean("triangle");
        t1.draw();
    }
}

Please advise if I want to put the log.info in my above main class what modifications I need to do in my main class and also please advise what modifications I need to done to call log4j in my main class? 请告诉我是否要将log.info放在我上面的主类中我需要在主类中进行哪些修改,还请告知我在主类中调用log4j需要做些什么修改?

come up with this solution and it works ..the edited log4j.properties file is 提出这个解决方案,它的工作原理..编辑的log4j.properties文件是

### direct messages to file or.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=C:/logs/s.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1} - %m%n
log4j.appender.file.append=true

### set log levels - for more verbose logging change 'info' to 'debug' ##
log4j.rootCategory=ALL, file
log4j.logger.Demo=\=debug
log4j.logger.org.eclipse=debug

and the way to callit from main class is 从主类叫callit的方法是

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class DrawingClass {
     /* Get actual class name to be printed on */
    static final Logger log = Logger.getLogger(DrawingClass.class);
    public static void main(String args[])
    {PropertyConfigurator.configure("log4j.properties");
        //without dependency injection 
        /*Triangle t1 = new Triangle();
        t1.draw();*/

         log.info("Before execution");
        //with dependency injection     
        BeanFactory factory = new XmlBeanFactory(new FileSystemResource("Spring.xml"));
        Triangle t1 =(Triangle) factory.getBean("triangle");
        log.info("Hello this is an info message");
        t1.draw();
         log.info("after object execution");
    }
}

If there is any other better way then please advise . 如果还有其他更好的方法,请告知。

For using logging in my project I made such things: 为了在我的项目中使用日志记录,我做了以下事情

1) Defined special annotation that should mark fields where logger should be injected: 1)定义的特殊注释应标记应注入记录器的字段:

@Retention(RUNTIME)  
@Target(FIELD)  
@Documented  
public @interface InjectLogger {  
}  

2) Then created special BeanPostProcessor for injected logger into annotated field: 2)然后创建特殊的BeanPostProcessor,用于将注入的记录器注入注释字段:

@Component(value="loggerInjector")
public class LoggerInjector implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {

        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(final Object bean, String beanName)
            throws BeansException {
        ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {  
            public void doWith(Field field) throws IllegalArgumentException,  
            IllegalAccessException {  
                // make the field accessible if defined private  
                ReflectionUtils.makeAccessible(field);  
                if (field.getAnnotation(InjectLogger.class) != null) {  
                    Logger log = LoggerFactory.getLogger(bean.getClass()); 
                    field.set(bean, log);  
                }  
            }  
        });  
        return bean;  
    }  

}

3) After this in necessary bean mark property where logger should be injected by @InjectLogger annotation and use this logger in your code. 3)在必要的bean标记属性之后,应该通过@InjectLogger注释注入logger并在代码中使用此记录器。

    @InjectLogger
    private Logger logger;

public void doSomething(...) {
     try{
     ...
     } catch (Exception e) {
        logger.error("bla bla bla", e);
     }
}

In my project I use slf4j with log4j as concrete implementation. 在我的项目中,我使用slf4j和log4j作为具体实现。 But with log4j it will be similar. 但是使用log4j它会是类似的。

Also you need to know that by default all Spring libs using common-logging. 此外,您需要知道默认情况下所有使用common-logging的Spring库。 And if you want that Spring libs write their log to your file you should use special additionla lib. 如果你想让Spring libs将他们的日志写入你的文件,你应该使用特殊的addla lib。 You can get them, as I remember, from appache site. 我记得你可以从appache网站获取它们。 For slf4j such lib is named jcl-over-slf4j-1.6.4.jar. 对于slf4j,这样的lib被命名为jcl-over-slf4j-1.6.4.jar。

EDIT 2: 编辑2:

Also in spring the good practise is to use AOP for logging. 同样在春天,良好的做法是使用AOP进行记录。 Here is an example of simplified Aspect: 以下是简化方面的示例:

@Component
@Aspect
@Order(value=2)
public class LoggingAspect {

    @Around("execution(* com.blablabla.server..*.*(..))")
    public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable{
        final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName());
        Object retVal = null;

        try {
            StringBuffer startMessageStringBuffer = new StringBuffer();

            startMessageStringBuffer.append("Start method ");
            startMessageStringBuffer.append(joinPoint.getSignature().getName());
            startMessageStringBuffer.append("(");

            Object[] args = joinPoint.getArgs();
            for (int i = 0; i < args.length; i++) {
                startMessageStringBuffer.append(args[i]).append(",");
            }
            if (args.length > 0) {
                startMessageStringBuffer.deleteCharAt(startMessageStringBuffer.length() - 1);
            }

            startMessageStringBuffer.append(")");

            logger.trace(startMessageStringBuffer.toString());

            StopWatch stopWatch = new StopWatch();
            stopWatch.start();

            retVal = joinPoint.proceed();

            stopWatch.stop();

            StringBuffer endMessageStringBuffer = new StringBuffer();
            endMessageStringBuffer.append("Finish method ");
            endMessageStringBuffer.append(joinPoint.getSignature().getName());
            endMessageStringBuffer.append("(..); execution time: ");
            endMessageStringBuffer.append(stopWatch.getTotalTimeMillis());
            endMessageStringBuffer.append(" ms;");

            logger.trace(endMessageStringBuffer.toString());
        } catch (Throwable ex) {
            StringBuffer errorMessageStringBuffer = new StringBuffer();

             // Create error message 
             logger.error(errorMessageStringBuffer.toString(), e)

            throw ex;
        }

        return retVal;
    }
}

Can you try adding this line to your class - 你能尝试在你的班级添加这一行 -

public class DrawingClass {

   static final Logger log = Logger.getLogger(DrawingClass.class);

public static void main(String args[])
{
    //without dependency injection 
    /*Triangle t1 = new Triangle();
    t1.draw();*/

    log.info("Before execution");
    //with dependency injection     
    BeanFactory factory = new XmlBeanFactory(new FileSystemResource("Spring.xml"));
    Triangle t1 =(Triangle) factory.getBean("triangle");
    t1.draw();
}
 }

Now let me know if anything gets added to the log. 现在让我知道是否有任何东西被添加到日志中。

This link might help you - http://www.dzone.com/tutorials/java/log4j/sample-log4j-properties-file-configuration-1.html 此链接可能对您有所帮助 - http://www.dzone.com/tutorials/java/log4j/sample-log4j-properties-file-configuration-1.html

 # LOG4J configuration log4j.rootLogger= DEBUG, INFO, Appender1, Appender2 log4j.appender.Appender1=org.apache.log4j.ConsoleAppender log4j.appender.Appender1.layout=org.apache.log4j.PatternLayout log4j.appender.Appender1.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n log4j.appender.Appender2=org.apache.log4j.FileAppender log4j.appender.Appender2.File=D:/Project Log/Demo/demo.log log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout log4j.appender.Appender2.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n 

Write this code in log4j.properties which is in Resources folder of src folder. 将此代码写入log4j.properties,该文件位于src文件夹的Resources文件夹中。

 <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> 
Write this above code in porm.xml file or download jar for this dependency. 将以上代码写在porm.xml文件中或下载jar以获取此依赖关系。

 <context:property-placeholder location="classpath:log4j.properties" /> 

write this above code between and in your spring-config.xml 在spring-config.xml之间和之间写下以上代码

 package com.apmc.controller; import org.apache.log4j.Logger; import java.text.DateFormat; import java.util.Date; import com.apmc.Generic.RandomGenerator;//This my own made class So You need to create //RandomGenerator for use it @Controller public class StateController { private static Logger logger = Logger.getLogger(StateController.class); DateFormat df = new SimpleDateFormat("ddMMyyHHmmss"); Date dateobj = new Date(); int randNum = RandomGenerator.randInt(1000, 9999); String successMsg = "", errorMsg = ""; @Autowired StateService stateService; List<State> newList = new ArrayList(); @RequestMapping(value = "/Admin/admin/NewState_form") public ModelAndView stateForm(@ModelAttribute State state) { try { logger.info("\\n stateForm Started \\n errorcode : "+errorcode); newList = stateService.loadAll(); logger.info("\\n stateForm Completed"); errorMsg = ""; } catch (Exception e) { errorcode = ""+df.format(dateobj)+randNum; errorMsg = " New State Form Error \\n Please contact Admin and errorcode:" +errorcode; successMsg = ""; logger.error("error code for stateForm in StateController" +df.format(dateobj)+" errorcode: "+errorcode); } return new ModelAndView("state").addObject("editState", new State()) .addObject("errorMsg", errorMsg) .addObject("showStateList",newList) .addObject("successMsg", successMsg); } } 

Above example for how to use log in Controller or any Java Class Here I made for error Tracking create error code show for commmunicate with error using RandomGenerator.java write as below given 以上示例了解如何使用登录控制器或任何Java类这里我为错误跟踪创建错误代码显示为使用RandomGenerator.java的commmunicate错误写如下给出

 package com.apmc.Generic; import java.util.Random; public class RandomGenerator { /** * Returns a pseudo-random number between min and max, inclusive. * The difference between min and max can be at most * <code>Integer.MAX_VALUE - 1</code>. * * @param min Minimum value * @param max Maximum value. Must be greater than min. * @return Integer between min and max, inclusive. * @see java.util.Random#nextInt(int) */ public static int randInt(int min, int max) { // NOTE: Usually this should be a field rather than a method // variable so that it is not re-seeded every call. Random rand = new Random(); // nextInt is normally exclusive of the top value, // so add 1 to make it inclusive int randomNum = rand.nextInt((max - min) + 1) + min; return randomNum; } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM