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