From 27dd1a7a4034bf8943cc1203b02ee8355a177bd3 Mon Sep 17 00:00:00 2001 From: fuliqi <fuliqi@qq.com> Date: 星期五, 08 三月 2024 11:30:14 +0800 Subject: [PATCH] 日志、接口耗时、防重复提交 --- ycl-server/src/main/java/com/ycl/filter/RepeatedlyRequestWrapper.java | 77 +++++++ ycl-server/src/main/java/com/ycl/interceptor/RepeatSubmitInterceptor.java | 56 +++++ ycl-server/src/main/resources/application.yml | 1 /dev/null | 129 ------------ ycl-server/src/main/resources/logback.xml | 93 +++++++++ ycl-server/src/main/java/com/ycl/config/FilterConfig.java | 29 ++ ycl-server/src/main/java/com/ycl/interceptor/impl/SameUrlDataInterceptor.java | 111 +++++++++++ ycl-server/src/main/java/com/ycl/aop/TimeAspect.java | 29 ++ ycl-server/src/main/java/com/ycl/filter/RepeatableFilter.java | 48 ++++ 9 files changed, 443 insertions(+), 130 deletions(-) diff --git a/ycl-server/src/main/java/com/ycl/aop/TimeAspect.java b/ycl-server/src/main/java/com/ycl/aop/TimeAspect.java new file mode 100644 index 0000000..5b9d8e4 --- /dev/null +++ b/ycl-server/src/main/java/com/ycl/aop/TimeAspect.java @@ -0,0 +1,29 @@ +package com.ycl.aop; + +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +@Aspect +@Component +@Slf4j +public class TimeAspect { + + // 瀹氫箟鍒囩偣Pointcut + @Pointcut("execution(public * com.ycl..*.*Controller.*(..))") + public void excudeService() { + } + + @Around("excudeService()") + public Object doAround(ProceedingJoinPoint pjp) throws Throwable { + long start=System.currentTimeMillis(); + Object result = pjp.proceed(); + long end=System.currentTimeMillis(); + log.debug("鎺ュ彛鎬昏鑰楁椂:{}ms",end-start); + return result; + } +} diff --git a/ycl-server/src/main/java/com/ycl/config/FilterConfig.java b/ycl-server/src/main/java/com/ycl/config/FilterConfig.java new file mode 100644 index 0000000..2f5a4dd --- /dev/null +++ b/ycl-server/src/main/java/com/ycl/config/FilterConfig.java @@ -0,0 +1,29 @@ +package com.ycl.config; + +import com.ycl.filter.RepeatableFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Filter閰嶇疆 + * + * @author ruoyi + */ +@Configuration +public class FilterConfig +{ + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + public FilterRegistrationBean someFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(new RepeatableFilter()); + registration.addUrlPatterns("/*"); + registration.setName("repeatableFilter"); + registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); + return registration; + } + +} diff --git a/ycl-server/src/main/java/com/ycl/filter/RepeatableFilter.java b/ycl-server/src/main/java/com/ycl/filter/RepeatableFilter.java new file mode 100644 index 0000000..dd1f5e9 --- /dev/null +++ b/ycl-server/src/main/java/com/ycl/filter/RepeatableFilter.java @@ -0,0 +1,48 @@ +package com.ycl.filter; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.http.MediaType; +import utils.StringUtils; + +import java.io.IOException; + +/** + * Repeatable 杩囨护鍣� + * + * @author ruoyi + */ +public class RepeatableFilter implements Filter +{ + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + ServletRequest requestWrapper = null; + if (request instanceof HttpServletRequest + && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) + { + requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); + } + if (null == requestWrapper) + { + chain.doFilter(request, response); + } + else + { + chain.doFilter(requestWrapper, response); + } + } + + @Override + public void destroy() + { + + } +} diff --git a/ycl-server/src/main/java/com/ycl/filter/RepeatedlyRequestWrapper.java b/ycl-server/src/main/java/com/ycl/filter/RepeatedlyRequestWrapper.java new file mode 100644 index 0000000..d1995bf --- /dev/null +++ b/ycl-server/src/main/java/com/ycl/filter/RepeatedlyRequestWrapper.java @@ -0,0 +1,77 @@ +package com.ycl.filter; + +import com.ycl.utils.http.HttpHelper; +import constant.Constants; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * 鏋勫缓鍙噸澶嶈鍙杋nputStream鐨剅equest + * + * @author ruoyi + */ +public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper +{ + private final byte[] body; + + public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException + { + super(request); + request.setCharacterEncoding(Constants.UTF8); + response.setCharacterEncoding(Constants.UTF8); + + body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8); + } + + @Override + public BufferedReader getReader() throws IOException + { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() + { + @Override + public int read() throws IOException + { + return bais.read(); + } + + @Override + public int available() throws IOException + { + return body.length; + } + + @Override + public boolean isFinished() + { + return false; + } + + @Override + public boolean isReady() + { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) + { + + } + }; + } +} diff --git a/ycl-server/src/main/java/com/ycl/interceptor/RepeatSubmitInterceptor.java b/ycl-server/src/main/java/com/ycl/interceptor/RepeatSubmitInterceptor.java new file mode 100644 index 0000000..0cb7905 --- /dev/null +++ b/ycl-server/src/main/java/com/ycl/interceptor/RepeatSubmitInterceptor.java @@ -0,0 +1,56 @@ +package com.ycl.interceptor; + +import annotation.RepeatSubmit; +import com.alibaba.fastjson2.JSON; +import com.ycl.system.AjaxResult; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import utils.ServletUtils; + +import java.lang.reflect.Method; + +/** + * 闃叉閲嶅鎻愪氦鎷︽埅鍣� + * + * @author ruoyi + */ +@Component +public abstract class RepeatSubmitInterceptor implements HandlerInterceptor +{ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception + { + if (handler instanceof HandlerMethod) + { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); + if (annotation != null) + { + if (this.isRepeatSubmit(request, annotation)) + { + AjaxResult ajaxResult = AjaxResult.error(annotation.message()); + ServletUtils.renderString(response, JSON.toJSONString(ajaxResult)); + return false; + } + } + return true; + } + else + { + return true; + } + } + + /** + * 楠岃瘉鏄惁閲嶅鎻愪氦鐢卞瓙绫诲疄鐜板叿浣撶殑闃查噸澶嶆彁浜ょ殑瑙勫垯 + * + * @param request + * @return + * @throws Exception + */ + public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation); +} diff --git a/ycl-server/src/main/java/com/ycl/interceptor/impl/SameUrlDataInterceptor.java b/ycl-server/src/main/java/com/ycl/interceptor/impl/SameUrlDataInterceptor.java new file mode 100644 index 0000000..21010ad --- /dev/null +++ b/ycl-server/src/main/java/com/ycl/interceptor/impl/SameUrlDataInterceptor.java @@ -0,0 +1,111 @@ +package com.ycl.interceptor.impl; + +import annotation.RepeatSubmit; +import com.alibaba.fastjson2.JSON; +import com.ycl.filter.RepeatedlyRequestWrapper; +import com.ycl.interceptor.RepeatSubmitInterceptor; +import com.ycl.utils.http.HttpHelper; +import com.ycl.utils.redis.RedisCache; +import constant.CacheConstants; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import utils.StringUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 鍒ゆ柇璇锋眰url鍜屾暟鎹槸鍚﹀拰涓婁竴娆$浉鍚岋紝 + * 濡傛灉鍜屼笂娆$浉鍚岋紝鍒欐槸閲嶅鎻愪氦琛ㄥ崟銆� 鏈夋晥鏃堕棿涓�10绉掑唴銆� + * + * @author ruoyi + */ +@Component +public class SameUrlDataInterceptor extends RepeatSubmitInterceptor +{ + public final String REPEAT_PARAMS = "repeatParams"; + + public final String REPEAT_TIME = "repeatTime"; + + // 浠ょ墝鑷畾涔夋爣璇� + @Value("${token.header}") + private String header; + + @Autowired + private RedisCache redisCache; + + @SuppressWarnings("unchecked") + @Override + public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) + { + String nowParams = ""; + if (request instanceof RepeatedlyRequestWrapper) + { + RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; + nowParams = HttpHelper.getBodyString(repeatedlyRequest); + } + + // body鍙傛暟涓虹┖锛岃幏鍙朠arameter鐨勬暟鎹� + if (StringUtils.isEmpty(nowParams)) + { + nowParams = JSON.toJSONString(request.getParameterMap()); + } + Map<String, Object> nowDataMap = new HashMap<String, Object>(); + nowDataMap.put(REPEAT_PARAMS, nowParams); + nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); + + // 璇锋眰鍦板潃锛堜綔涓哄瓨鏀綾ache鐨刱ey鍊硷級 + String url = request.getRequestURI(); + + // 鍞竴鍊硷紙娌℃湁娑堟伅澶村垯浣跨敤璇锋眰鍦板潃锛� + String submitKey = StringUtils.trimToEmpty(request.getHeader(header)); + + // 鍞竴鏍囪瘑锛堟寚瀹歬ey + url + 娑堟伅澶达級 + String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; + + Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); + if (sessionObj != null) + { + Map<String, Object> sessionMap = (Map<String, Object>) sessionObj; + if (sessionMap.containsKey(url)) + { + Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url); + if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) + { + return true; + } + } + } + Map<String, Object> cacheMap = new HashMap<String, Object>(); + cacheMap.put(url, nowDataMap); + redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS); + return false; + } + + /** + * 鍒ゆ柇鍙傛暟鏄惁鐩稿悓 + */ + private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap) + { + String nowParams = (String) nowMap.get(REPEAT_PARAMS); + String preParams = (String) preMap.get(REPEAT_PARAMS); + return nowParams.equals(preParams); + } + + /** + * 鍒ゆ柇涓ゆ闂撮殧鏃堕棿 + */ + private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap, int interval) + { + long time1 = (Long) nowMap.get(REPEAT_TIME); + long time2 = (Long) preMap.get(REPEAT_TIME); + if ((time1 - time2) < interval) + { + return true; + } + return false; + } +} diff --git a/ycl-server/src/main/resources/application.yml b/ycl-server/src/main/resources/application.yml index 7b858c4..d08e1c8 100644 --- a/ycl-server/src/main/resources/application.yml +++ b/ycl-server/src/main/resources/application.yml @@ -69,7 +69,6 @@ level: org.springframework: warn com.ycl : debug - config: classpath:logback-plus.xml # security閰嶇疆 security: diff --git a/ycl-server/src/main/resources/logback-plus.xml b/ycl-server/src/main/resources/logback-plus.xml deleted file mode 100644 index cf804e0..0000000 --- a/ycl-server/src/main/resources/logback-plus.xml +++ /dev/null @@ -1,129 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<configuration> - <property name="log.path" value="./logs"/> - <property name="console.log.pattern" - value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/> - <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/> - - <!-- 鎺у埗鍙拌緭鍑� --> - <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> - <encoder> - <pattern>${console.log.pattern}</pattern> - <charset>utf-8</charset> - </encoder> - </appender> - - <!-- 鎺у埗鍙拌緭鍑� --> - <appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${log.path}/sys-console.log</file> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� --> - <fileNamePattern>${log.path}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern> - <!-- 鏃ュ織鏈�澶� 1澶� --> - <maxHistory>1</maxHistory> - </rollingPolicy> - <encoder> - <pattern>${log.pattern}</pattern> - <charset>utf-8</charset> - </encoder> - <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> - <!-- 杩囨护鐨勭骇鍒� --> - <level>INFO</level> - </filter> - </appender> - - <!-- 绯荤粺鏃ュ織杈撳嚭 --> - <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${log.path}/sys-info.log</file> - <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� --> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� --> - <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> - <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� --> - <maxHistory>60</maxHistory> - </rollingPolicy> - <encoder> - <pattern>${log.pattern}</pattern> - </encoder> - <filter class="ch.qos.logback.classic.filter.LevelFilter"> - <!-- 杩囨护鐨勭骇鍒� --> - <level>INFO</level> - <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� --> - <onMatch>ACCEPT</onMatch> - <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� --> - <onMismatch>DENY</onMismatch> - </filter> - </appender> - - <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${log.path}/sys-error.log</file> - <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� --> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� --> - <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern> - <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� --> - <maxHistory>60</maxHistory> - </rollingPolicy> - <encoder> - <pattern>${log.pattern}</pattern> - </encoder> - <filter class="ch.qos.logback.classic.filter.LevelFilter"> - <!-- 杩囨护鐨勭骇鍒� --> - <level>ERROR</level> - <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� --> - <onMatch>ACCEPT</onMatch> - <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� --> - <onMismatch>DENY</onMismatch> - </filter> - </appender> - - <!-- info寮傛杈撳嚭 --> - <appender name="async_info" class="ch.qos.logback.classic.AsyncAppender"> - <!-- 涓嶄涪澶辨棩蹇�.榛樿鐨�,濡傛灉闃熷垪鐨�80%宸叉弧,鍒欎細涓㈠純TRACT銆丏EBUG銆両NFO绾у埆鐨勬棩蹇� --> - <discardingThreshold>0</discardingThreshold> - <!-- 鏇存敼榛樿鐨勯槦鍒楃殑娣卞害,璇ュ�间細褰卞搷鎬ц兘.榛樿鍊间负256 --> - <queueSize>512</queueSize> - <!-- 娣诲姞闄勫姞鐨刟ppender,鏈�澶氬彧鑳芥坊鍔犱竴涓� --> - <appender-ref ref="file_info"/> - </appender> - - <!-- error寮傛杈撳嚭 --> - <appender name="async_error" class="ch.qos.logback.classic.AsyncAppender"> - <!-- 涓嶄涪澶辨棩蹇�.榛樿鐨�,濡傛灉闃熷垪鐨�80%宸叉弧,鍒欎細涓㈠純TRACT銆丏EBUG銆両NFO绾у埆鐨勬棩蹇� --> - <discardingThreshold>0</discardingThreshold> - <!-- 鏇存敼榛樿鐨勯槦鍒楃殑娣卞害,璇ュ�间細褰卞搷鎬ц兘.榛樿鍊间负256 --> - <queueSize>512</queueSize> - <!-- 娣诲姞闄勫姞鐨刟ppender,鏈�澶氬彧鑳芥坊鍔犱竴涓� --> - <appender-ref ref="file_error"/> - </appender> - - <!-- 鏁村悎 skywalking 鎺у埗鍙拌緭鍑� tid --> - <!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">--> - <!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">--> - <!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">--> - <!-- <pattern>[%tid] ${console.log.pattern}</pattern>--> - <!-- </layout>--> - <!-- <charset>utf-8</charset>--> - <!-- </encoder>--> - <!-- </appender>--> - - <!-- 鏁村悎 skywalking 鎺ㄩ�侀噰闆嗘棩蹇� --> - <!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">--> - <!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">--> - <!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">--> - <!-- <pattern>[%tid] ${console.log.pattern}</pattern>--> - <!-- </layout>--> - <!-- <charset>utf-8</charset>--> - <!-- </encoder>--> - <!-- </appender>--> - - <!--绯荤粺鎿嶄綔鏃ュ織--> - <root level="info"> - <appender-ref ref="console" /> - <appender-ref ref="async_info" /> - <appender-ref ref="async_error" /> - <appender-ref ref="file_console" /> - <!-- <appender-ref ref="sky_log"/>--> - </root> - -</configuration> diff --git a/ycl-server/src/main/resources/logback.xml b/ycl-server/src/main/resources/logback.xml new file mode 100644 index 0000000..77d7d62 --- /dev/null +++ b/ycl-server/src/main/resources/logback.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <!-- 鏃ュ織瀛樻斁璺緞 --> + <property name="log.path" value="./logs" /> + <!-- 鏃ュ織杈撳嚭鏍煎紡 --> + <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /> + + <!-- 鎺у埗鍙拌緭鍑� --> + <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + </appender> + + <!-- 绯荤粺鏃ュ織杈撳嚭 --> + <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.path}/sys-info.log</file> + <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� --> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� --> + <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> + <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� --> + <maxHistory>60</maxHistory> + </rollingPolicy> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <!-- 杩囨护鐨勭骇鍒� --> + <level>INFO</level> + <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� --> + <onMatch>ACCEPT</onMatch> + <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� --> + <onMismatch>DENY</onMismatch> + </filter> + </appender> + + <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.path}/sys-error.log</file> + <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� --> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� --> + <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern> + <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� --> + <maxHistory>60</maxHistory> + </rollingPolicy> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <!-- 杩囨护鐨勭骇鍒� --> + <level>ERROR</level> + <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� --> + <onMatch>ACCEPT</onMatch> + <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� --> + <onMismatch>DENY</onMismatch> + </filter> + </appender> + + <!-- 鐢ㄦ埛璁块棶鏃ュ織杈撳嚭 --> + <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.path}/sys-user.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <!-- 鎸夊ぉ鍥炴粴 daily --> + <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern> + <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� --> + <maxHistory>60</maxHistory> + </rollingPolicy> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + </appender> + + <!-- 绯荤粺妯″潡鏃ュ織绾у埆鎺у埗 --> + <logger name="com.ycl" level="info" /> + <!-- Spring鏃ュ織绾у埆鎺у埗 --> + <logger name="org.springframework" level="warn" /> + + <root level="info"> + <appender-ref ref="console" /> + </root> + + <!--绯荤粺鎿嶄綔鏃ュ織--> + <root level="info"> + <appender-ref ref="file_info" /> + <appender-ref ref="file_error" /> + </root> + + <!--绯荤粺鐢ㄦ埛鎿嶄綔鏃ュ織--> + <logger name="sys-user" level="info"> + <appender-ref ref="sys-user"/> + </logger> +</configuration> \ No newline at end of file -- Gitblit v1.8.0