-
Notifications
You must be signed in to change notification settings - Fork 512
/
MethodMetricsHistogram.java
164 lines (143 loc) · 6.04 KB
/
MethodMetricsHistogram.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package cn.myperf4j.core;
import cn.myperf4j.base.MethodTag;
import cn.myperf4j.base.config.ProfilingConfig;
import cn.myperf4j.base.metric.MethodMetrics;
import cn.myperf4j.base.util.Logger;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* Created by LinShunkang on 2019/07/23
*/
public final class MethodMetricsHistogram {
private static final ConcurrentMap<Integer, MethodMetricsInfo> METHOD_MAP = new ConcurrentHashMap<>(1024 * 8);
private MethodMetricsHistogram() {
//empty
}
public static void recordMetrics(MethodMetrics metrics) {
recordMetrics0(metrics.getMethodTagId(),
metrics.getTP95(),
metrics.getTP99(),
metrics.getTP999(),
metrics.getTP9999());
}
public static void recordNoneMetrics(int methodTagId) {
recordMetrics0(methodTagId, -1, -1, -1, -1);
}
private static void recordMetrics0(int methodTagId, int tp95, int tp99, int tp999, int tp9999) {
final MethodMetricsInfo methodMetricsInfo = METHOD_MAP.get(methodTagId);
if (methodMetricsInfo != null) {
methodMetricsInfo.add(tp95, tp99, tp999, tp9999);
return;
}
METHOD_MAP.put(methodTagId, new MethodMetricsInfo(tp95, tp99, tp999, tp9999));
}
public static void buildSysGenProfilingFile() {
final long startMills = System.currentTimeMillis();
final String filePath = ProfilingConfig.basicConfig().sysProfilingParamsFile();
final String tempFilePath = filePath + "_tmp";
final File tempFile = new File(tempFilePath);
try (BufferedWriter fileWriter = new BufferedWriter(new FileWriter(tempFile, false), 8 * 1024)) {
fileWriter.write("#This is a file automatically generated by MyPerf4J, please do not edit!\n");
final List<Integer> neverInvokedMethods = new ArrayList<>(128);
final MethodTagMaintainer tagMaintainer = MethodTagMaintainer.getInstance();
for (Map.Entry<Integer, MethodMetricsInfo> entry : METHOD_MAP.entrySet()) {
final Integer methodId = entry.getKey();
final MethodMetricsInfo info = entry.getValue();
if (info.getCount() <= 0) {
neverInvokedMethods.add(methodId);
continue;
}
final int mostTimeThreshold = calMostTimeThreshold(info);
writeProfilingInfo(tagMaintainer, fileWriter, methodId, mostTimeThreshold);
}
fileWriter.flush();
if (!neverInvokedMethods.isEmpty()) {
fileWriter.write("#The following methods have never been invoked!\n");
for (int i = 0; i < neverInvokedMethods.size(); i++) {
final Integer methodId = neverInvokedMethods.get(i);
writeProfilingInfo(tagMaintainer, fileWriter, methodId, 128);
}
fileWriter.flush();
}
final File destFile = new File(filePath);
final boolean rename = tempFile.renameTo(destFile) && destFile.setReadOnly();
Logger.debug("MethodMetricsHistogram.buildSysGenProfilingFile(): rename " + tempFile.getName()
+ " to " + destFile.getName() + " " + (rename ? "success" : "fail"));
} catch (Exception e) {
Logger.error("MethodMetricsHistogram.buildSysGenProfilingFile()", e);
} finally {
Logger.debug("MethodMetricsHistogram.buildSysGenProfilingFile() finished, cost="
+ (System.currentTimeMillis() - startMills) + "ms");
}
}
private static void writeProfilingInfo(MethodTagMaintainer tagMaintainer,
BufferedWriter fileWriter,
Integer methodId,
int mostTimeThreshold) throws IOException {
final MethodTag methodTag = tagMaintainer.getMethodTag(methodId);
if (methodTag == null) {
Logger.warn("MethodMetricsHistogram.writeProfilingInfo(): methodId=" + methodId + ", methodTag is null");
return;
}
fileWriter.write(methodTag.getFullDesc());
fileWriter.write('=');
fileWriter.write(mostTimeThreshold + ":" + calOutThresholdCount(mostTimeThreshold));
fileWriter.newLine();
}
private static int calMostTimeThreshold(MethodMetricsInfo info) {
final int count = info.getCount();
final long tp9999Avg = info.getTp9999Sum() / count;
if (tp9999Avg <= 64) {
return 64;
} else if (tp9999Avg <= 128) {
return 128;
} else if (tp9999Avg <= 256) {
return 256;
}
final long tp999Avg = info.getTp999Sum() / count;
if (tp999Avg <= 128) {
return 128;
} else if (tp999Avg <= 256) {
return 256;
} else if (tp999Avg <= 512) {
return 512;
}
final long tp99Avg = info.getTp99Sum() / count;
if (tp99Avg <= 256) {
return 256;
} else if (tp99Avg <= 512) {
return 512;
} else if (tp99Avg <= 1024) {
return 1024;
}
final long tp95Avg = info.getTp95Sum() / count;
if (tp95Avg <= 512) {
return 512;
} else if (tp95Avg <= 1024) {
return 1024;
} else if (tp95Avg <= 1536) {
return 1536;
}
return 2048;
}
private static int calOutThresholdCount(int mostTimeThreshold) {
if (mostTimeThreshold <= 256) {
return 64;
} else if (mostTimeThreshold <= 512) {
return 128;
} else if (mostTimeThreshold <= 1024) {
return 256;
} else if (mostTimeThreshold <= 1536) {
return 512;
} else {
return 1024;
}
}
}