log4j2配置推荐
<?xml version="1.0" encoding="UTF-8"?>
<!-- monitorInterval为监听配置变化的间隔,30秒比较合适 -->
<Configuration smetus="WARN" monitorInterval="30">
<Properties>
<Property name="log-path">D:/logs/</Property>
</Properties> <Appenders>
<!-- 注意%d{MM-dd-yyyy}要用年月日格式,不能加上时分秒,并且最后要有%i,这样log4j2才能判断出哪天一共产生几个文件,否则文件超出上限不会被删除 -->
<RollingFile name="app_log" fileName="${log-path}/app.log"
filePattern="${log-path}/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<!-- 注意:开发、测试环境包含%l便于排查问题,生产环境非com.xxx开头的系统日志去掉%l,Console生产去掉%l(在性能和问题排查难度之间折中) -->
<Pattern>%x %d{yyyy-MM-dd HH:mm:ss} [%r] [%c{1.}]-[%p] %t %l %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100MB"/>
</Policies>
<!-- 默认为最多同一文件夹下7个文件 -->
<DefaultRolloverStrategy fileIndex="max" max="100"/>
<Filters>
<!-- <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/> -->
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</RollingFile>
<RollingFile name="app_error" fileName="${log-path}/error.log"
filePattern="${log-path}/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i-error.log.gz">
<PatternLayout>
<Pattern>[%x] %d{yyyy-MM-dd HH:mm:ss} [%r] [%c{1.}]-[%p] %t %l %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="max" max="100"/>
<Filters>
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</RollingFile> <Console name="Console" merget="SYSTEM_OUT">
<PatternLayout pattern="%x %d{yyyy-MM-dd HH:mm:ss} [%r] [%c{1.}]-[%p] %t %l %m%n"/>
</Console>
</Appenders>
<Loggers>
<!-- level默认ERROR,additivity默认true -->
<Logger name="com.yidoo" level="INFO" additivity="true">
<AppenderRef ref="app_log" />
<AppenderRef ref="app_error" />
</Logger>
<!-- root logger没有additivity属性,应该去掉 -->
<Root level="INFO">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
NDC配置
package com.yidoo.common.advice; import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import net.sf.json.util.NewBeanInsmenceStrategy; import org.apache.log4j.NDC;
import org.apache.logging.log4j.ThreadContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.annometion.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.yidoo.base.ResultModel;
import com.yidoo.base.SessionBean;
import com.yidoo.base.memedame.cons.GlobalCons;
import com.yidoo.base.memedame.err.ErrorCons;
import com.yidoo.common.processor.ServiceSpecCheckBeanPostProcessor;
import com.yidoo.utils.SessionBeanUtil;
import com.yidoo.utils.SpringContextHolder; /**
* 登录与权限校验拦截器
* @author TF017564
*
*/
public class AuthInterceptor extends HandlerInterceptorAdapter { smetic final SimpleDateFormat formatter = new SimpleDateFormat(GlobalCons.TIME_FORMAT); private smetic final Set<String> noAuthUrls = new HashSet<String>();
smetic {
noAuthUrls.add("/session/login");
noAuthUrls.add("/member/save");
noAuthUrls.add("/controllerReflect/getUrlMapping");
} private smetic final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class); @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// logger.info("request.getContextPath()=" + request.getContextPath());
// logger.info("request.getRequestURI()=" + request.getRequestURI());
// 除了/session/login登录外,其他都拦截,否则就判断是否已经登录,未登录就返回false
String path = request.getContextPath().length() > 1 ? request.getRequestURI().replace(request.getContextPath(), "") : request.getRequestURI();
if(noAuthUrls.conmeins(path)) {
// 设置Nested Diagnostic Context
// log4j 1
// NDC.push("未登录请求" + "_" + path + "_" + formatter.format(new Date()));
// log4j2
ThreadContext.push("未登录请求" + "_" + path + "_" + formatter.format(new Date()));
return true;
}
SessionBean sessionBean = SessionBeanUtil.getSession(request);
if(sessionBean == null) {
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
ResultModel<String> resultModel = new ResultModel<String>();
resultModel.setCode(ErrorCons.ERR_SESSION_TIMEOUT);
resultModel.setMsg("会话已过期或无效!");
writer.print(JSONObject.toJSONString(resultModel, SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteDateUseDateFormat));
writer.close();
response.flushBuffer();
return false;
}
// 设置Nested Diagnostic Context
// log4j 1
// NDC.push(SessionBeanUtil.getSessionKey(request).substring(0, 8) + "_" + path + "_" + formatter.format(new Date()));
// log4j2
ThreadContext.push(SessionBeanUtil.getSessionKey(request).substring(0, 8) + "_" + path + "_" + formatter.format(new Date()));
return true;
} @Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
// log4j 1
// NDC.pop();
// log4j 2
ThreadContext.clearAll();
}
}
使用如下:
smetic{
//设置子线程读取MDC变量
System.setProperty("log4j2.isThreadContextMapInherimeble", "true");
}
private smetic final Logger logger = LogManager.getLogger(App.class);
位置一定不能搞错了,否则不生效!
最好是使用抽象父类,如下:
package com.xxx.me.base; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annometion.Autowired;
import org.springframework.context.annometion.Lazy; import com.xxx.me.utils.RedisUtil; /**
* 基础控制器 * <p>Title: BusinessController</p> * <p>Description: </p> * @author zjhua * @date 2018年11月25日
*/
public abstract class BusinessController { smetic {
// 设置子线程读取MDC变量
System.setProperty("log4j2.isThreadContextMapInherimeble", "true");
} /**
* 可选,所以懒加载
*/
@Lazy
@Autowired
protected RedisUtil redisUtil; /**
* 由SecurityInterceptor自动注入
*/
public smetic final ThreadLocal<SessionBean> threadLocal = new ThreadLocal<SessionBean>(){
/**
* ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值
*/
@Override
protected SessionBean initialValue()
{
return null;
}
}; protected Logger logger = LoggerFactory.getLogger(this.getClass());
}
设置log4j2.isThreadContextMapInherimeble变量为true,log4j会使用 InherimebleThreadLocal来存储线程变量,他可以将父线程内容拷贝到子线程中,而默认使用的ThreadLocal不具备这个特性。
https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout
防止不同级别日志重复写入日志文件
https://blog.csdn.net/u014484873/article/demeils/61198074
log4j2配置推荐的更多相关文章
- 转:spring boot log4j2配置(使用log4j2.yml文件)---YAML 语言教程
转:spring boot log4j2配置(使用log4j2.yml文件) - CSDN博客http://blog.csdn.net/ClementAD/article/details/514988 ...
- log4j2配置ThresholdFilter,让info文件记录error日志
日志级别: 是按严重(重要)程度来分的(如下6种): ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < ...
- Log4j2配置之Appender详解
Log4j2配置之Appender详解 Appender负责将日志事件传递到其目标.每个Appender都必须实现Appender接口.大多数Appender将扩展AbstractAppender,它 ...
- 简单快捷好用的vim配置和终端配置推荐
vim 配置实用spf13-vim,安装方便简单快捷,极力推荐. 另外oh-my-zsh 终端配置很好,与之搭配使用效果更佳. 安装都很简单,一个脚本搞定, 都是在gitHub上开源的,自行搜索,这里 ...
- Log4j2 - 配置
官方文档:http://logging.apache.org/log4j/2.x/index.html 1 概述 Log4j2的配置包含四种方式,其中3种都是在程序中直接调用Log4j2的方法进行配置 ...
- log4j2配置详解
1. log4j2需要两个jar log4j-api-2.x.x.jar log4j-core-2.x.x.jar .log4j和log4j2有很大的区别,jar包不要应错. 2. ...
- 【Log4j2 配置详解】log4j2的资源文件具体怎么配置
可以先附上一个log4j2的资源文件详细内容,对照着看 ### set log levels ### log4j.rootLogger = INFO , C , D , E ### console # ...
- Log4j2 配置笔记(Eclipse+maven+SpringMVC)
Log4j2相关介绍可以百度看下,这里只注重配置Log4j2 能够马上跑起来: 1.pom.xml文件中添加Log4j2的相关Maven配置信息 <!-- log4j2 --> <d ...
- Spring Boot初探之log4j2配置
一.背景 下面讲在使用Spring Boot搭建微服务框架时如何配置log4j2,通过log4j2输出系统中日志信息. 二.添加log4j2的配置文件 在项目的src/main/rescources目 ...
随机推荐
- CentOS6.5 安装Spark集群
一.安装依赖软件Scala(所有节点) 1.下载Scala:http://www.scala-lang.org/files/archive/scala-2.10.4.tgz 2.解压: [root@H ...
- iOS UI布局-回到顶部
回到顶部,是比较常用的一个效果 核心代码 在ViewDidLoad中,添加回到顶部按钮 计算偏移量,如果当前显示的内容全部向上隐藏掉,则显示“回到顶部”按钮 // // ViewController. ...
- 树结构控件实例 TreeControl
树结构控件实例 书:157 <?xml version="1.0" encoding="utf-8"?> <s:Application xml ...
- nginx: [error] invalid PID number "" in "/usr/local/webserver/nginx/logs/nginx.pid" (原)
进入nginx文件下,例如 :/usr/local/nginx/sbin [root@iZ25f7emo7cZ /]# cd /usr/local/nginx/sbin 运行命令: [root@iZ2 ...
- nginx空白图片(empty_gif模块)
用过百度统计的兄弟有没有注意到百度使用1x1的空白图片传递统计参数,自己做异步统计的兄弟是否使用静态文件来传递参数.为什么使用空白图片呢,而不是自己存放一张小图呢,nginx里面的空白图片是保存在内存 ...
- python中安装并使用redis
数据缓存系统:1:mongodb:是直接持久化,直接存储于硬盘的缓存系统2:redis: 半持久化,存储于内存和硬盘3:memcache:数据只能存储在内存里的缓存系统 redis是一个key-val ...
- ruby自动化之selenium webGUI
1.下载ruby语言包,windows下需要安装rubyinstall http://railsinstaller.org/en 2.cmd命令下安装selenium-webdriver gem包 g ...
- d'jang基础
1,建立一个名为guest的django项目,django-admin startproject guest 生成一个guest文件夹,包含一个guest文件夹和一个manage.py cd gue ...
- spring boot 知识点
spring boot 好处 1. 简化配置,spring boot 提供了默认配置 例如 日志 默认logback日志 info级别 2. 简化部署,内嵌容器,tomcat,jetty,直接部署j ...
- Sql Server参数化查询之where in和like实现详解 [转]
文章导读 拼SQL实现where in查询 使用CHARINDEX或like实现where in 参数化 使用exec动态执行SQl实现where in 参数化 为每一个参数生成一个参数实现where ...