文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

log4j如何控制日志输出文件名称

2023-06-22 05:59

关注

小编给大家分享一下log4j如何控制日志输出文件名称,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

log4j控制日志输出文件名称

1. 第一种方式

在类对象中用如下方式定义logger变量

private static Logger logger = Logger.getLogger("lemmaXml");

这样通过名称的方式获取logger,需要在log4j.properties文件中定义一个名称为lemmaXml的appender,配置如下:

log4j.logger.lemmaXml=INFO,lemmaXmllog4j.appender.lemmaXml=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.lemmaXml.Threshold=DEBUGlog4j.appender.lemmaXml.File=${catalina.home}/logs/lemmaXml.loglog4j.appender.lemmaXml.layout=org.apache.log4j.PatternLayoutlog4j.appender.lemmaXml.layout.ConversionPattern=%5p %d{yyyy-MM-dd HH:mm:ss} %m %n

上述配置说明,名称为lemmaXml的appender,是每天形成一个日志文件,日志文件的名称为

${catalina.home}/logs/lemmaXml.log

日志的格式为

%5p %d{yyyy-MM-dd HH:mm:ss} %m %n

2. 第二种方式(这种方式亲测正确)

在类对象中用如下方式定义logger变量

import org.apache.log4j.Logger;private static Logger logger = Logger.getLogger(ExportLemmaManagerService.class);

即,通过类的参数来获取logger变量,此时必然也需要在log4j.properties文件有关于该对象日志文件的输出配置,当然这里的配置不是针对每个类专门配置,而是针对一个路径整体配置,即,你可以配置某个目录下的所有类方式的输出文件的文件名称,如下

log4j.rootLogger=info,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Threshold=DEBUGlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n  log4j.logger.com.soso.baike.service=DEBUG,ServiceLoglog4j.appender.ServiceLog=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.ServiceLog.Threshold=DEBUGlog4j.appender.ServiceLog.File=${catalina.home}/logs/service.loglog4j.appender.ServiceLog.MaxBackupIndex=10log4j.appender.ServiceLog.layout=org.apache.log4j.PatternLayoutlog4j.appender.ServiceLog.layout.ConversionPattern=%5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n

上述配置了目录com.soso.baike.service下的输出文件方式,上述ExportLemmaManagerService类就是在该包下,所以用该包下的类方式来定义logger的话,输出的文件就都在service.log文件中,每天生成一个新的日志文件。

如何随心所欲地自定义log4j输出格式

在某种情况下,我们需要在不影响原有代码的基础上自定义log4j的输出格式。

例如这样的需求,硬性规定了项目的日志格式为:

日期 日志等级 ClassName:line - [版本号] [请求ip地址] [项目应用名称] [服务接口模块] [模块方法] [业务参数1] [业务参数2] [业务参数3] 日志详细内容(必须为json格式)

示例:

2018-05-10 14:04:50,972 INFO ViolationService:51 - [v1.0.0] [192.168.137.47] [merchant-service.cx580.com] [OrderController] [messageList] [null] [] [] {"body":"订单状态消息列表resp:{\"code\":1000,\"msg\":\"成功\"}"}

其中:

以上是我遇到的场景,这时在不影响原有项目代码的基础上,我们做出日志格式的调整,使用如下方案:

通过log4j的占位替换符%X{}配合MDC格式化日志,使用AOP切面在请求线程开始处填充替换符变量

继承log4j的具体appender类,重写subAppend方法,修改日志输出的内容格式。

此时log4j文件如下

log4j.rootCategory=INFO, stdout, file, errorfile#log4j.category.com.cx=DEBUGlog4j.logger.error=errorfile log4j.appender.stdout=com.test.common.GrayLogConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L%X{log_version}%X{log_ip}%X{log_item}%X{log_module}%X{log_method}%X{log_req_params} %m%n log4j.appender.file=com.test.common.GrayLogDailyRollingFileAppenderlog4j.appender.file.file=${log.dir}/${spring.application.name}.loglog4j.appender.file.DatePattern='.'yyyy-MM-ddlog4j.appender.file.layout=org.apache.log4j.PatternLayoutlog4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L%X{log_version}%X{log_ip}%X{log_item}%X{log_module}%X{log_method}%X{log_req_params} %m%n log4j.appender.errorfile=com.test.common.GrayLogDailyRollingFileAppenderlog4j.appender.errorfile.file=${log.dir}/${spring.application.name}_error.loglog4j.appender.errorfile.DatePattern='.'yyyy-MM-ddlog4j.appender.errorfile.Threshold = ERRORlog4j.appender.errorfile.layout=org.apache.log4j.PatternLayoutlog4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L%X{log_version}%X{log_ip}%X{log_item}%X{log_module}%X{log_method}%X{log_req_params} %m%n

在log4j.properties文件,我们做了两个变动,一个是添加了%X{value}的变量,另一个则是将原本的DailyRollingFileAppender修改成了com.test.common.GrayLogConsoleAppender。

处理log4j的变量,对代码进行controller切面,在一个http请求java的入口中放入线程变量,该线程变量在当次http请求生命周期内生效。

切面代码如下:

@Around("execution(public * com.test.controller..*.*(..))")    public Object aroundController(ProceedingJoinPoint joinPoint) {        ServletRequestAttributes attributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();        HttpServletRequest request =attributes.getRequest();        String execIp = request.getHeader("X-Real-IP");        if(StringUtils.isBlank(execIp)){            execIp=request.getRemoteAddr();        }        String execClass= joinPoint.getTarget().getClass().getSimpleName();        String execMethod = joinPoint.getSignature().getName();        Map<String,String[]> map = request.getParameterMap();        List<String> paramsList = new ArrayList<>();        for(Map.Entry<String,String []> m : map.entrySet()){            String [] value = m.getValue();            paramsList.add( m.getKey() + "=" + StringUtils.join(value,","));        }         String execParams = "[" + StringUtils.join(paramsList,"&") + "] [] []";        MDC.put("log_version"," - [V1.0.0]");        MDC.put("log_item"," [violation-mini]");        MDC.put("log_module"," [" + execClass + "]");        MDC.put("log_method"," [" + execMethod+ "]");        MDC.put("log_req_params"," " + execParams);        MDC.put("log_ip"," [" + execIp+ "]");        Object result= null;        try {            result = joinPoint.proceed();        } catch (Throwable throwable) {            LOGGER.error("方法异常:",throwable);        }        return result;    }

至此,格式中的MDC变量都已被放入成功。

下一步,将原本的日志内容套上json外套。

新建GrayLogConsoleAppender类继承具体的appender类

代码如下:

package com.test.common; import net.sf.json.JSONObject;import org.apache.commons.lang.StringUtils;import org.apache.log4j.ConsoleAppender;import org.apache.log4j.spi.LoggingEvent;import org.apache.log4j.spi.ThrowableInformation; import java.lang.reflect.Field; public class GrayLogConsoleAppender extends ConsoleAppender {    @Override    protected void subAppend(LoggingEvent event) {        try {            Class<LoggingEvent> clazz = LoggingEvent.class;            Field filed = clazz.getDeclaredField("throwableInfo");            filed.setAccessible(true);            Object exception = filed.get(event);            JSONObject json = new JSONObject();            if(exception != null){                if(exception instanceof ThrowableInformation){                    ThrowableInformation throwableInformation = (ThrowableInformation) exception;                    String [] details = throwableInformation.getThrowableStrRep();                    String error_msg = StringUtils.join(details,"\r\n");                    json.put("exception",error_msg);                }            }            filed.set(event,null);            boolean flag = false;            Field filed1 = clazz.getDeclaredField("message");            filed1.setAccessible(true);            Object message = filed1.get(event);            if (message instanceof String) {                String msg = (String) message;                if (message != null) {                    flag = true;                }                json.put("body", msg);                filed1.set(event, json.toString());            }            if(!flag){                Field filed2 = clazz.getDeclaredField("renderedMessage");                filed2.setAccessible(true);                Object message2 = filed2.get(event);                if (message2 instanceof String) {                    String msg = (String) message2;                    json.put("body", msg);                    filed2.set(event, json.toString());                }            }        } catch (Exception e) {            e.printStackTrace();        }        super.subAppend(event);    }}

至此,已为日志内容套上json外套,并且当有异常日志时,将异常的堆栈信息放入json的exception中输出出来,不打印堆栈信息。

最终结果:

2018-06-09 00:48:31,849 INFO LogAspect:65 - [V1.0.0] [223.88.53.135] [violation-mini] [TestController] [queryList] [appName=abc&authType=test&avatar=&nickName=&token=asdfasdfadsfasdf&userId=asdfasdfasdfasdf&userType=aaaaa] [] [] {"body":"结果为:ResponseResult{code='0', msg='null', errormsg='查询成功', data={}, successFlag=false}"}

以上是“log4j如何控制日志输出文件名称”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯