感谢:http://byx5185.iteye.com/blog/1616034

1、重写FileAppender :

  1. package com.bankht.cis.tps.apps.tps.util;
  2.  
  3. import org.apache.log4j.FileAppender;
  4. import org.apache.log4j.Layout;
  5. import org.apache.log4j.helpers.OptionConverter;
  6. import org.apache.log4j.spi.LoggingEvent;
  7.  
  8. import java.io.*;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Calendar;
  11. import java.util.Date;
  12. import java.util.TreeMap;
  13.  
  14. /**
  15. * 名称: TraceLogFileAppender.java<br>
  16. * 描述: 该appender是仿照log4j中RollingFileAppender写的
  17. * 可配置备份天数,包含当天
  18. * filesize为字节数<br>
  19. * 批次:name<br>
  20. * 创建时间: 2018年7月23日<br>
  21. * 修改时间:<br>
  22. * 编写人员:xxx <br>
  23. * 版本号:1.0
  24. */
  25.  
  26. public class CustomTraceLogFileAppender extends FileAppender {
  27.  
  28. protected long maxFileSize = 10485760L;//file.length,字节数
  29. protected int maxDaysIndex = 1;//备份天数,包含当天
  30.  
  31. private long nextRollover = 0;
  32. private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
  33. private static String separator = ".";
  34.  
  35. public CustomTraceLogFileAppender() {}
  36.  
  37. public CustomTraceLogFileAppender(Layout layout, String filename, boolean append)
  38. throws IOException
  39. {
  40. super(layout, filename, append);
  41. }
  42.  
  43. public CustomTraceLogFileAppender(Layout layout, String filename)
  44. throws IOException
  45. {
  46. super(layout, filename);
  47. }
  48. public int getMaxDaysIndex(){return maxDaysIndex;}
  49.  
  50. public long getMaximumFileSize()
  51. {
  52. return maxFileSize;
  53. }
  54.  
  55. public void setMaxDaysIndex(int maxDays)
  56. {
  57. maxDaysIndex = maxDays;
  58. }
  59.  
  60. public void setMaximumFileSize(long maxFileSize)
  61. {
  62. this.maxFileSize = maxFileSize;
  63. }
  64.  
  65. public void setMaxFileSize(String value)
  66. {
  67. maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1L);
  68. }
  69.  
  70. protected void setQWForFiles(Writer writer)
  71. {
  72. qw = new CustomCountingQuietWriter(writer, errorHandler,this.encoding);
  73. }
  74.  
  75. //启动时专用
  76. public synchronized void setFile(String fileName, boolean append,
  77. boolean bufferedIO, int bufferSize) throws IOException {
  78. String temp = getStartupFileName(fileName);
  79. super.setFile(temp, append, this.bufferedIO, this.bufferSize);
  80. if (append) {
  81. File f = new File(temp);
  82. ((CustomCountingQuietWriter)qw).setCount(f.length());
  83. }
  84. //每次启动时,检验是否超出备份数量,超出则删除最旧日期
  85. countFile(temp,maxDaysIndex);
  86. }
  87.  
  88. private String getStartupFileName(String name) {
  89. String filePath = name.substring(0,name.lastIndexOf("/")+1);
  90. String[] strs = name.split("\\.");
  91. File[] files = new File(filePath).listFiles(new CustomLogStartupFileFilter(strs[1]));
  92.  
  93. //treemap默认是升序,取最后一个即为最新文件.
  94. TreeMap<Long, String> treeMap = new TreeMap<Long, String>();
  95. if(files==null || files.length == 0){
  96. if(strs.length==3){
  97. StringBuffer sb = new StringBuffer();
  98. String now = sdf.format(new Date());
  99. return sb.append(strs[0]).append(separator)
  100. .append(strs[1]).append(separator)
  101. .append(now).append(separator)
  102. .append("1").append(separator).append("log").toString();
  103. }
  104. return name;
  105. }else{
  106. for(File temp : files){
  107. treeMap.put(temp.lastModified(),temp.getPath());
  108. }
  109. name = treeMap.lastEntry().getValue();
  110. String now = sdf.format(new Date());
  111. String[] strs1 = name.split("\\.");
  112. if(strs1.length == 5){//符合日志文件名格式
  113. StringBuffer sb = new StringBuffer();
  114. if(now.equals(strs1[2])){
  115. return sb.append(strs[0]).append(separator)
  116. .append(strs1[1]).append(separator)
  117. .append(strs1[2]).append(separator)
  118. .append(strs1[3]).append(separator).append("log").toString();
  119. }else{
  120. return sb.append(strs[0]).append(separator)
  121. .append(strs1[1]).append(separator)
  122. .append(now).append(separator)
  123. .append("1").append(separator).append("log").toString();
  124. }
  125. }
  126. }
  127. return name;
  128. }
  129.  
  130. public synchronized void setCustomFile(String fileName, boolean append,
  131. boolean bufferedIO, int bufferSize) throws IOException {
  132. super.setFile(fileName, append, this.bufferedIO, this.bufferSize);
  133. if (append) {
  134. File f = new File(fileName);
  135. ((CustomCountingQuietWriter)qw).setCount(f.length());
  136. }
  137. }
  138.  
  139. protected void subAppend(LoggingEvent event) {
  140. String nowDate = sdf.format(new Date());
  141. String[] strs = fileName.split("\\.");
  142. String fileDate = strs[2];
  143. if(!nowDate.equals(fileDate)){
  144. try {
  145. //新建文件,当切换日期时,文件名中的序号都是从1开始
  146. String newFileName = getFileName(fileName,1);
  147. this.setCustomFile(newFileName, true, bufferedIO, bufferSize);
  148. //计算备份天数,多出删掉
  149. countFile(newFileName,maxDaysIndex);
  150. } catch (IOException e) {
  151. if (e instanceof InterruptedIOException) {
  152. Thread.currentThread().interrupt();
  153. }
  154. }
  155. }
  156. super.subAppend(event);//先写入数据
  157. if ((fileName != null) && (qw != null)) {
  158. long size = ((CustomCountingQuietWriter)qw).getCount();
  159. if ((size >= maxFileSize) && (size >= nextRollover)) {
  160. this.closeFile();
  161. fileName = getFileName(fileName,1);
  162. try {
  163. this.setCustomFile(fileName, true, bufferedIO, bufferSize);
  164. nextRollover = 0;
  165. } catch (IOException e) {
  166. if (e instanceof InterruptedIOException) {
  167. Thread.currentThread().interrupt();
  168. }
  169. }
  170. }
  171. }
  172. }
  173.  
  174. /**
  175. * 系统名称.实例名称.日期.文件编号.log
  176. * @param name
  177. * @param i
  178. * @return
  179. */
  180. private static String getFileName(String name,int i) {
  181. String date = sdf.format(new Date());
  182. String filePath = name.substring(0, name.lastIndexOf("/")+1);
  183. String currentName = name.substring(name.lastIndexOf("/")+1);
  184. String[] str = currentName.split("\\.");
  185. if(str.length>=3){//启动时,文件名:系统名.实例名.log,长度为3
  186. String fileName = "";
  187. fileName = str[0]+separator+str[1]+separator+date+separator;
  188. int nums = 0;
  189. if(str.length==5){
  190. String num = str[3];
  191. String fileDate = str[2];
  192. if(!"".equals(num) && num != null && date.equals(fileDate)){
  193. nums = Integer.parseInt(num);
  194. }
  195. }
  196. nums= nums + i;
  197.  
  198. fileName = filePath + fileName + nums + ".log";
  199. name = fileName;
  200. }
  201. return name;
  202. }
  203. /**
  204. * 获取几天前的日期,格式yyyyMMdd
  205. * @param days 天数
  206. * @return
  207. */
  208. public static String getBeforeDate(int days){
  209. Calendar cal = Calendar.getInstance();
  210. cal.add(cal.DATE, -days);
  211. Date resultDate = cal.getTime();
  212. return sdf.format(resultDate);
  213. }
  214.  
  215. /**
  216. *
  217. * @param fileName 文件名称(包括路径)
  218. * @param MaxDaysIndex 计算日志文件个数,当达到最大保留数时,将最早生成的日志文件删除
  219. */
  220. public static void countFile(String fileName,int MaxDaysIndex){
  221. String delDate = getBeforeDate(MaxDaysIndex);
  222. String filePath = fileName.substring(0, fileName.lastIndexOf("/"));
  223. File file = new File(filePath);
  224. if(file.isDirectory()){
  225. File[] files = file.listFiles(new CustomLogFileFilter(delDate));
  226. if(files != null && files.length>0){
  227. for(File temp:files){
  228. temp.delete();
  229. }
  230. }
  231. }
  232. }
  233.  
  234. }
  235.  
  236. /**
  237. * 文件过滤器
  238. * 删除文件时专用
  239. */
  240. class CustomLogFileFilter implements FileFilter {
  241. private String delDate;
  242.  
  243. public CustomLogFileFilter(String delDate) {
  244. this.delDate = delDate;
  245. }
  246.  
  247. /**
  248. *
  249. * @param file 路径+文件名
  250. * @return
  251. */
  252. @Override
  253. public boolean accept(File file) {
  254. if (delDate == null || file.isDirectory()) {
  255. return false;
  256. } else {
  257. String[] strs = file.getName().split("\\.");
  258. if(strs!=null && strs.length>=3){
  259. if(strs[2].compareTo(delDate)<=0){//删除备份天数之前的文件
  260. return true;
  261. }
  262. }
  263. return false;
  264. }
  265. }
  266. }
  267. class CustomLogStartupFileFilter implements FileFilter {
  268. private String serverName;
  269.  
  270. public CustomLogStartupFileFilter(String serverName) {
  271. this.serverName = serverName;
  272. }
  273.  
  274. /**
  275. *
  276. * @param file 路径+文件名
  277. * @return
  278. */
  279. @Override
  280. public boolean accept(File file) {
  281. //过滤文件夹中符合系统名称.实例名称.日期.文件编号.log格式的文件,实例名与当前实例名一致.
  282. if(file.getName().split("\\.").length == 5 && serverName.equals(file.getName().split("\\.")[1])){
  283. return true;
  284. }
  285. return false;
  286. }
  287. }

2、

  1. package com.bankht.cis.tps.apps.tps.util;
  2.  
  3. import org.apache.log4j.helpers.QuietWriter;
  4. import org.apache.log4j.spi.ErrorHandler;
  5.  
  6. import java.io.IOException;
  7. import java.io.Writer;
  8.  
  9. /**
  10. * 重写CustomCountingQuietWriter
  11. * 计算长度时,设置字符级
  12. * Created by xxx on 2018/7/24.
  13. */
  14. public class CustomCountingQuietWriter extends QuietWriter {
  15. protected long count;
  16. protected String encoding;
  17.  
  18. public CustomCountingQuietWriter(Writer writer, ErrorHandler eh, String encoding) {
  19. super(writer, eh);
  20. this.encoding = encoding;
  21. }
  22.  
  23. public void write(String string) {
  24. try {
  25. this.out.write(string);
  26. this.count += (long)string.getBytes(this.encoding).length;
  27. } catch (IOException var3) {
  28. this.errorHandler.error("Write failure.", var3, 1);
  29. }
  30.  
  31. }
  32.  
  33. public long getCount() {
  34. return this.count;
  35. }
  36.  
  37. public void setCount(long count) {
  38. this.count = count;
  39. }
  40. }

2、 log4j.properties文件中配置:

  1. 其中CustomTraceLogFileAppender为重写的FileAppender
    MaxFileSize 文件大小
    MaxDaysIndex 备份天数
  1. # Set root logger level to DEBUG and its only appender to CONSOLE.
  2. log4j.rootLogger=INFO,log
  3.  
  4. #CONSOLE
  5. #log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
  6. #log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
  7. #log4j.appender.CONSOLE.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p %C{1} : %m%n
  8.  
  9. #route trace log
  10. log4j.appender.log=org.apache.log4j.RollingFileAppender
  11. log4j.appender.log.File=/route/route-trace-${log.name}.log
  12. log4j.appender.log.MaxFileSize=200000KB
  13. log4j.appender.log.MaxBackupIndex=200
  14. log4j.appender.log.layout=org.apache.log4j.PatternLayout
  15. log4j.appender.log.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS}[%t][%c][%p]-%m%n
  16.  
  17. #SQL
  18. log4j.logger.java.sql.Connection=INFO
  19. log4j.logger.java.sql.Statement=INFO
  20. log4j.logger.java.sql.PreparedStatement=INFO
  21. log4j.logger.java.sql.ResultSet=INFO
  22.  
  23. #trace log
  24. log4j.logger.traceLog=INFO,traceLog
  25. log4j.additivity.traceLog=false
  26. log4j.appender.traceLog=com.bankht.cis.tps.apps.tps.util.CustomTraceLogFileAppender
  27. log4j.appender.traceLog.Append=true
  28. log4j.appender.traceLog.MaxFileSize=20480KB
  29. log4j.appender.traceLog.MaxDaysIndex=7
  30. log4j.appender.traceLog.encoding=UTF-8
  31. log4j.appender.traceLog.File=/route/tracelog/GCSC-D.${log.name}.log
  32. log4j.appender.traceLog.layout=org.apache.log4j.PatternLayout
  33. log4j.appender.traceLog.layout.ConversionPattern=%m%n

DailyRollingFileAppender-设置文件大小和备份天数的更多相关文章

  1. YourSQLDba设置共享路径备份

    YourSQLDba可以将数据库备份到网络路径(共享路径),这个也是非常灵活的一个功能,以前一直没有使用过这个功能,最近由于一个需求,于是我测试了一下YourSQLDba备份到网络路径,中间遇到了一些 ...

  2. editplus如何设置不自动备份

    依次选择:工具,参数设置,文件(默认展开的,要缩回),然后看右边“保存文件时创建备份”,前面的框不要打勾,应用,确定

  3. crontab的相关设置&linux定时备份数据库

    对于才了解crontab的人来说,应该按照以下的步骤来设置crontab 1.首先要检查是否装了crontab http://blog.sina.com.cn/s/blog_4881040d01011 ...

  4. windows环境设置mysql自动备份(测试成功)

    00.背景介绍 最近做了个小程序,使用的是mysql数据库,涉及到将程序数据备份的事:虽然大部分数据库客户端工具都具有备份功能,但并不能做到定期自动备份:在Windows环境下,手工备份MySQL是很 ...

  5. Linux_Centos7_设置MySql定时备份

    一.查看是否安装了必要的组件 [root@localhost /]# rpm -qa | grep cron cronie-1.4.11-14.el7_2.1.x86_64 cronie-anacro ...

  6. chrome设置以及hosts备份

    最近重装完chrome总是忘记改了哪些设置,所以这里做一下备份. 有卡顿问题可以关闭GPU加速 使用https的方式访问Google,Chrome下强制Google使用https的方法如下: 打开Ch ...

  7. Linux设置数据库自动备份

    本文为转载,最末端为原地址 以CentOS 7.6系统与Oracle 11g为例: 一.先找到数据库的环境变量 如果是在root账户下,须先登录到数据库所在账户 su oraclecat ~/.bas ...

  8. struts文件上传拦截器maximumSize设置文件大小不起作用

    <interceptor-ref name="fileUpload">                <param name="allowedTypes ...

  9. 在WINDOWS服务器下设置MARIADB自动备份的方法

    WINDOWS服务器下自动备份有三个步骤 1.首先新建一个.BAT文件里面输入 @echo offset "Ymd=%date:~,4%%date:~5,2%%date:~8,2%" ...

随机推荐

  1. ServiceComb 集成 Shiro 实践|火影专场发布

    Shiro简介 Apache Shiro是一款功能强大.易用的轻量级开源Java安全框架,它主要提供认证.鉴权.加密和会话管理等功能.Spring Security可能是业界用的最广泛的安全框架,但是 ...

  2. Java之同步方法处理继承Thread类的线程安全问题

    /** * 使用同步方法处理继承Thread类的方式中的线程安全问题 * */class Window4 extends Thread { private static int ticket = 10 ...

  3. IdentityServer4之Token令牌获取流程分析

    1.asp.net core 是基于管道模式IdentityServer会在注册一个管道处理程序 IdentityServerMiddleware 类专门处理登录验证的逻辑,本次主要讲的是access ...

  4. 一篇文章带你了解axios网络交互-Vue

    来源:滁州SEO 1 **什么是axios呢?**了解,并去使用它,对于axios发送请求的两种方式有何了解,以及涉及axios跨域问题如何解决. 对于axios网络交互,去使用axios的同时,首先 ...

  5. VScode安装后的插件安装

    杭州SEO:Chinese(Simplified) Language Pack for Visual Stidio Code 中文汉化包 对于一些英文不太好的小伙伴,上来第一件事肯定是要切换成中文语言 ...

  6. 从 0 到 1 到完美,写一个 js 库、node 库、前端组件库

    之前讲了很多关于项目工程化.前端架构.前端构建等方面的技术,这次说说怎么写一个完美的第三方库. 1. 选择合适的规范来写代码 js 模块化的发展大致有这样一个过程 iife => commonj ...

  7. 搭建Docker私有仓库&用户密码认证&web可视化界面

    1.拉取镜像 docker pull hyper/docker-registry-web docker pull registry 2.安装 yum install docker-compose 3. ...

  8. poj-3659 Cell Phone Network(最小支配集+贪心)

    http://poj.org/problem?id=3659 Description Farmer John has decided to give each of his cows a cell p ...

  9. 基础篇九:模块介绍(--with-http_stub_status_module)

    下面--with 即为编译安装的模块 下面我们来介绍--with-http_stub_status_module此模块 vim  /etc/nginx/conf.d/default.conf 然后检查 ...

  10. [LC] 207. Course Schedule

    There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prereq ...