1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 import java.util.*;
25
26
27
28
29
30
31
32 public class ResourceChecker {
33 private static final Log LOG = LogFactory.getLog(ResourceChecker.class);
34 private String tagLine;
35
36 enum Phase {
37 INITIAL, INTERMEDIATE, END
38 }
39
40
41
42
43
44 public ResourceChecker(final String tagLine) {
45 this.tagLine = tagLine;
46 }
47
48
49
50
51 abstract static class ResourceAnalyzer {
52
53
54
55
56 public int getMax() {
57 return Integer.MAX_VALUE;
58 }
59
60
61
62
63
64 public int getMin() {
65 return Integer.MIN_VALUE;
66 }
67
68
69
70
71
72 public String getName() {
73 String className = this.getClass().getSimpleName();
74 final String extName = ResourceAnalyzer.class.getSimpleName();
75 if (className.endsWith(extName)) {
76 return className.substring(0, className.length() - extName.length());
77 } else {
78 return className;
79 }
80 }
81
82
83
84
85
86 abstract public int getVal(Phase phase);
87
88
89
90
91 public List<String> getStringsToLog() {
92 return null;
93 }
94 }
95
96 private List<ResourceAnalyzer> ras = new ArrayList<ResourceAnalyzer>();
97 private int[] initialValues;
98 private int[] endingValues;
99
100 private void fillInit() {
101 initialValues = new int[ras.size()];
102 fill(Phase.INITIAL, initialValues);
103 }
104
105 private void fillEndings() {
106 endingValues = new int[ras.size()];
107 fill(Phase.END, endingValues);
108 }
109
110 private void fill(Phase phase, int[] vals) {
111 int i = 0;
112 for (ResourceAnalyzer ra : ras) {
113 vals[i++] = ra.getVal(phase);
114 }
115 }
116
117 public void checkInit() {
118 check(initialValues);
119 }
120
121 private void checkEndings() {
122 check(endingValues);
123 }
124
125 private void check(int[] vals) {
126 int i = 0;
127 for (ResourceAnalyzer ra : ras) {
128 int cur = vals[i++];
129 if (cur < ra.getMin()) {
130 LOG.warn(ra.getName() + "=" + cur + " is inferior to " + ra.getMin());
131 }
132 if (cur > ra.getMax()) {
133 LOG.warn(ra.getName() + "=" + cur + " is superior to " + ra.getMax());
134 }
135 }
136 }
137
138 private void logInit() {
139 int i = 0;
140 StringBuilder sb = new StringBuilder();
141 for (ResourceAnalyzer ra : ras) {
142 int cur = initialValues[i++];
143
144 if (sb.length() > 0) {
145 sb.append(", ");
146 }
147
148 sb.append(ra.getName()).append("=").append(cur);
149 }
150 LOG.info("before: " + tagLine + " " + sb);
151 }
152
153 private void logEndings() {
154 assert initialValues.length == ras.size();
155 assert endingValues.length == ras.size();
156
157 int i = 0;
158 StringBuilder sb = new StringBuilder();
159 for (ResourceAnalyzer ra : ras) {
160 int curP = initialValues[i];
161 int curN = endingValues[i++];
162
163 if (sb.length() > 0) {
164 sb.append(", ");
165 }
166
167 sb.append(ra.getName()).append("=").append(curN).append(" (was ").append(curP).append(")");
168 if (curN > curP) {
169 List<String> strings = ra.getStringsToLog();
170 if (strings != null) {
171 for (String s : strings) {
172 sb.append(s);
173 }
174 }
175 sb.append(" - ").append(ra.getName()).append(" LEAK? -");
176 }
177 }
178 LOG.info("after: " + tagLine + " " + sb);
179 }
180
181
182
183
184
185
186
187 public void start() {
188 if (ras.size() == 0) {
189 LOG.info("No resource analyzer");
190 return;
191 }
192 fillInit();
193 logInit();
194 checkInit();
195 }
196
197
198
199
200
201
202
203
204 public void end() {
205 if (ras.size() == 0) {
206 LOG.info("No resource analyzer");
207 return;
208 }
209 if (initialValues == null) {
210 LOG.warn("No initial values");
211 return;
212 }
213
214 fillEndings();
215 logEndings();
216 checkEndings();
217 }
218
219
220
221
222 public void addResourceAnalyzer(ResourceAnalyzer ra) {
223 ras.add(ra);
224 }
225 }