<?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配置推荐的更多相关文章

  1. 转:spring boot log4j2配置(使用log4j2.yml文件)---YAML 语言教程

    转:spring boot log4j2配置(使用log4j2.yml文件) - CSDN博客http://blog.csdn.net/ClementAD/article/details/514988 ...

  2. log4j2配置ThresholdFilter,让info文件记录error日志

    日志级别: 是按严重(重要)程度来分的(如下6种): ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < ...

  3. Log4j2配置之Appender详解

    Log4j2配置之Appender详解 Appender负责将日志事件传递到其目标.每个Appender都必须实现Appender接口.大多数Appender将扩展AbstractAppender,它 ...

  4. 简单快捷好用的vim配置和终端配置推荐

    vim 配置实用spf13-vim,安装方便简单快捷,极力推荐. 另外oh-my-zsh 终端配置很好,与之搭配使用效果更佳. 安装都很简单,一个脚本搞定, 都是在gitHub上开源的,自行搜索,这里 ...

  5. Log4j2 - 配置

    官方文档:http://logging.apache.org/log4j/2.x/index.html 1 概述 Log4j2的配置包含四种方式,其中3种都是在程序中直接调用Log4j2的方法进行配置 ...

  6. log4j2配置详解

    1.    log4j2需要两个jar   log4j-api-2.x.x.jar    log4j-core-2.x.x.jar  .log4j和log4j2有很大的区别,jar包不要应错. 2. ...

  7. 【Log4j2 配置详解】log4j2的资源文件具体怎么配置

    可以先附上一个log4j2的资源文件详细内容,对照着看 ### set log levels ### log4j.rootLogger = INFO , C , D , E ### console # ...

  8. Log4j2 配置笔记(Eclipse+maven+SpringMVC)

    Log4j2相关介绍可以百度看下,这里只注重配置Log4j2 能够马上跑起来: 1.pom.xml文件中添加Log4j2的相关Maven配置信息 <!-- log4j2 --> <d ...

  9. Spring Boot初探之log4j2配置

    一.背景 下面讲在使用Spring Boot搭建微服务框架时如何配置log4j2,通过log4j2输出系统中日志信息. 二.添加log4j2的配置文件 在项目的src/main/rescources目 ...

随机推荐

  1. npm下载指定版本的插件

    eg:下载boostrap版本为3.3.7 npm install --save-dev bootstrap@3.3.7 备注:--save则将依赖的组件添加到package.json文件下 --sa ...

  2. Mybatis select、insert、update、delete 增删改查操作

    MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索.MyBatis 可以使用简单的XML ...

  3. Linux平台Oracle 12.1.0.2 单实例安装部署

    主题:Linux平台Oracle 12.1.0.2 单实例安装部署 环境:RHEL 6.5 + Oracle 12.1.0.2 需求:安装部署OEM 13.2需要Oracle 12.1.0.2版本作为 ...

  4. PHP json_encode/json_decode与serialize/unserializ性能测

    PHP里面,有时候出于实际需求考虑,需要将某些信息以数组的方式进行存储,甚至有时候介于数组.字符串两者之间,很难确定是数组还是字符串,如果最终还需要将这些信息存储到文件系统中,而且要保证正确无误的存储 ...

  5. Boot-col-sm布局

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. C# mongodb中内嵌文档数组条件查询

    样例数据: {      "_id" : "1064621564857",      "cNo" : "1064621564857 ...

  7. org.joda.time.DateTime 日期格式

    最近一直在使用Java,偶尔一次遇到日期(util)的格式转换,心里还是规矩的写着记忆里面的代码,但是在自己测试的时候发现不正确,具体看了下代码,发现这里使用jota的方式编写,顺道查了一下,做了笔记 ...

  8. python 爬起点目录

    #目标:书名,简介,作者,字数 #首先确定源代码的列表 import urllib.request import re from bs4 import BeautifulSoup import ran ...

  9. 缓存 Memached

    https://github.com/enyim/EnyimMemcached http://www.newasp.net/soft/63735.html#downloaded/ http://blo ...

  10. MySQL超时配置

    connect_timeout:连接响应超时时间.服务器端在这个时间内如未连接成功,则会返回连接失败. wait_timeout:连接空闲超时时间.与服务器端无交互状态的连接,直到被服务器端强制关闭而 ...