1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.master;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.hadoop.conf.Configuration;
25 import org.apache.hadoop.fs.FileStatus;
26 import org.apache.hadoop.fs.FileSystem;
27 import org.apache.hadoop.fs.Path;
28 import org.apache.hadoop.hbase.Chore;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.RemoteExceptionHandler;
31 import org.apache.hadoop.hbase.regionserver.wal.HLog;
32
33 import java.io.IOException;
34 import java.util.LinkedList;
35 import java.util.List;
36 import java.util.concurrent.atomic.AtomicBoolean;
37
38
39
40
41
42
43 public class LogsCleaner extends Chore {
44
45 static final Log LOG = LogFactory.getLog(LogsCleaner.class.getName());
46
47
48
49 private final int maxDeletedLogs;
50 private final FileSystem fs;
51 private final Path oldLogDir;
52 private List<LogCleanerDelegate> logCleanersChain;
53 private final Configuration conf;
54
55
56
57
58
59
60
61
62
63 public LogsCleaner(final int p, final AtomicBoolean s,
64 Configuration conf, FileSystem fs,
65 Path oldLogDir) {
66 super("LogsCleaner", p, s);
67
68 this.maxDeletedLogs =
69 conf.getInt("hbase.master.logcleaner.maxdeletedlogs", 20);
70 this.fs = fs;
71 this.oldLogDir = oldLogDir;
72 this.conf = conf;
73 this.logCleanersChain = new LinkedList<LogCleanerDelegate>();
74
75 initLogCleanersChain();
76 }
77
78
79
80
81
82
83 private void initLogCleanersChain() {
84 String[] logCleaners = conf.getStrings("hbase.master.logcleaner.plugins");
85 if (logCleaners != null) {
86 for (String className : logCleaners) {
87 LogCleanerDelegate logCleaner = newLogCleaner(className, conf);
88 addLogCleaner(logCleaner);
89 }
90 }
91 }
92
93
94
95
96
97
98
99
100 public static LogCleanerDelegate newLogCleaner(String className, Configuration conf) {
101 try {
102 Class c = Class.forName(className);
103 LogCleanerDelegate cleaner = (LogCleanerDelegate) c.newInstance();
104 cleaner.setConf(conf);
105 return cleaner;
106 } catch(Exception e) {
107 LOG.warn("Can NOT create LogCleanerDelegate: " + className, e);
108
109 return null;
110 }
111 }
112
113
114
115
116
117
118 public void addLogCleaner(LogCleanerDelegate logCleaner) {
119 if (logCleaner != null && !logCleanersChain.contains(logCleaner)) {
120 logCleanersChain.add(logCleaner);
121 LOG.debug("Add log cleaner in chain: " + logCleaner.getClass().getName());
122 }
123 }
124
125 @Override
126 protected void chore() {
127 try {
128 FileStatus[] files = this.fs.listStatus(this.oldLogDir);
129 int nbDeletedLog = 0;
130 FILE: for (FileStatus file : files) {
131 Path filePath = file.getPath();
132 if (HLog.validateHLogFilename(filePath.getName())) {
133 for (LogCleanerDelegate logCleaner : logCleanersChain) {
134 if (!logCleaner.isLogDeletable(filePath) ) {
135
136 continue FILE;
137 }
138 }
139
140 this.fs.delete(filePath, true);
141 nbDeletedLog++;
142 } else {
143 LOG.warn("Found a wrongly formated file: "
144 + file.getPath().getName());
145 this.fs.delete(filePath, true);
146 nbDeletedLog++;
147 }
148 if (nbDeletedLog >= maxDeletedLogs) {
149 break;
150 }
151 }
152 } catch (IOException e) {
153 e = RemoteExceptionHandler.checkIOException(e);
154 LOG.warn("Error while cleaning the logs", e);
155 }
156 }
157 }