Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7b08df9

Browse files
test metrics health check
1 parent f2d12f3 commit 7b08df9

File tree

8 files changed

+380
-92
lines changed

8 files changed

+380
-92
lines changed

‎java-metrics-demo/lombok.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lombok.log.fieldname=logger

‎java-metrics-demo/pom.xml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
</plugin>
2121
</plugins>
2222
</build>
23+
2324
<dependencies>
2425
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
2526
<dependency>
2627
<groupId>org.slf4j</groupId>
2728
<artifactId>slf4j-api</artifactId>
2829
<version>1.7.7</version>
2930
</dependency>
31+
3032
<dependency>
3133
<groupId>ch.qos.logback</groupId>
3234
<artifactId>logback-classic</artifactId>
@@ -47,6 +49,20 @@
4749
<scope>provided</scope>
4850
</dependency>
4951

52+
<!-- https://mvnrepository.com/artifact/io.dropwizard.metrics/metrics-healthchecks -->
53+
<dependency>
54+
<groupId>io.dropwizard.metrics</groupId>
55+
<artifactId>metrics-healthchecks</artifactId>
56+
<version>4.1.0</version>
57+
</dependency>
58+
59+
<!-- https://mvnrepository.com/artifact/io.dropwizard.metrics/metrics-healthchecks -->
60+
<dependency>
61+
<groupId>io.dropwizard.metrics</groupId>
62+
<artifactId>metrics-core</artifactId>
63+
<version>4.1.0</version>
64+
</dependency>
65+
5066
<!-- test -->
5167
<dependency>
5268
<groupId>junit</groupId>
@@ -55,6 +71,4 @@
5571
<scope>test</scope>
5672
</dependency>
5773
</dependencies>
58-
59-
6074
</project>
Lines changed: 5 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
import java.math.BigDecimal;
2-
import java.util.ArrayList;
3-
import java.util.List;
4-
import java.util.Map;
5-
import java.util.Random;
6-
import java.util.UUID;
7-
import java.util.concurrent.CountDownLatch;
8-
import java.util.concurrent.TimeUnit;
9-
import java.util.stream.LongStream;
1+
import health.HealthCheckMain;
102
import lombok.extern.slf4j.Slf4j;
11-
import metrics1.DoubleSupplier;
12-
import metrics1.JvmMemoryMetrics1;
13-
import metrics1.MetricRegistry1;
14-
import metrics1.MetricSet1;
15-
import metrics1.SystemMetrics1;
3+
import metrics1.Metrics1Main;
164

175
/**
186
* @author zacconding
@@ -22,80 +10,9 @@
2210
@Slf4j
2311
public class Main {
2412

25-
public static void main(String[] args) throws InterruptedException {
26-
CountDownLatch countDownLatch = new CountDownLatch(1);
27-
final SystemMetrics1 systemMetrics1 = new SystemMetrics1();
28-
final JvmMemoryMetrics1 jvmMemoryMetrics1 = new JvmMemoryMetrics1();
29-
Thread t = new Thread(() -> {
30-
try {
31-
while (!Thread.currentThread().isInterrupted()) {
32-
MetricRegistry1 registry1 = new MetricRegistry1();
33-
//systemMetrics1.start(registry1);
34-
jvmMemoryMetrics1.start(registry1);
13+
public static void main(String[] args) throws Exception {
14+
// Metrics1Main.run();
3515

36-
registry1.getMetricSets().entrySet().forEach(entry -> {
37-
MetricSet1 set = entry.getValue();
38-
Map<String, DoubleSupplier> samples = set.getSamples();
39-
System.out.println("--------------------------------------");
40-
samples.entrySet().forEach(sampleEntry -> {
41-
log.info("{} >> {}", sampleEntry.getKey(), new BigDecimal(sampleEntry.getValue().get()).toPlainString());
42-
});
43-
// double memoryFree = samples.get("system.memory.actual.free").get();
44-
// double memoryTotal = samples.get("system.memory.total").get();
45-
// double memoryUsage = 1.0D - (memoryFree / memoryTotal);
46-
// log.info("memory usage : {}", new BigDecimal(memoryUsage).toPlainString());
47-
System.out.println("--------------------------------------");
48-
});
49-
TimeUnit.SECONDS.sleep(5L);
50-
}
51-
} catch (InterruptedException e) {
52-
Thread.currentThread().interrupt();
53-
} catch (Exception e) {
54-
log.error("Exception occur", e);
55-
}
56-
});
57-
t.setDaemon(true);
58-
t.start();
59-
60-
Thread useMemory = new Thread(() -> {
61-
try {
62-
for (int i = 0; i < 2; i++) {
63-
log.info("## use memory");
64-
Main.useMemory(100000);
65-
TimeUnit.SECONDS.sleep(5L);
66-
}
67-
68-
log.info("## free memory");
69-
70-
Main.freeMemory();
71-
} catch (InterruptedException e) {
72-
Thread.currentThread().interrupt();
73-
} catch (Exception e) {
74-
log.error("Exception occur", e);
75-
}
76-
});
77-
useMemory.setDaemon(true);
78-
useMemory.start();
79-
80-
countDownLatch.await();
81-
}
82-
83-
static List<String> uuids;
84-
85-
static void useMemory(long repeat) {
86-
if (uuids == null) {
87-
uuids = new ArrayList<>();
88-
}
89-
90-
LongStream.range(0L, repeat).forEach(i -> {
91-
uuids.add(UUID.randomUUID().toString());
92-
});
93-
}
94-
95-
static void freeMemory() {
96-
uuids = null;
97-
//System.runFinalization();
98-
System.gc();
99-
System.runFinalization();
16+
HealthCheckMain.run();
10017
}
10118
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package health;
2+
3+
import java.util.List;
4+
import java.util.concurrent.TimeUnit;
5+
import java.util.stream.Collectors;
6+
import lombok.extern.slf4j.Slf4j;
7+
8+
/**
9+
* @GitHub : https://github.com/zacscoding
10+
*/
11+
@Slf4j
12+
public class HealthCheckMain {
13+
14+
public static void run() throws Exception {
15+
HealthChecker.INSTANCE.start();
16+
17+
for (int i = 1; i < 4; i++) {
18+
String nodeName = "node0" + i;
19+
HealthChecker.INSTANCE.register(nodeName, StubHealthCheck.newInstance(nodeName));
20+
}
21+
22+
Thread displayThread = new Thread(() -> {
23+
try {
24+
while (!Thread.currentThread().isInterrupted()) {
25+
List<String> healthyNodes = HealthChecker.INSTANCE.getHealthyNodes();
26+
List<String> unhealthyNodes = HealthChecker.INSTANCE.getUnhealthyNodes();
27+
28+
StringBuilder builder = new StringBuilder()
29+
.append("\n======================================================\n")
30+
.append("## Display health status\n")
31+
.append("> Healthy\n")
32+
.append(
33+
healthyNodes.stream().collect(Collectors.joining(" "))
34+
)
35+
.append("\n")
36+
.append("> Unhealthy\n")
37+
.append(
38+
unhealthyNodes.stream().collect(Collectors.joining(" "))
39+
);
40+
logger.info(builder.toString());
41+
TimeUnit.SECONDS.sleep(2L);
42+
}
43+
} catch (Exception e) {
44+
logger.warn("Exception occur while display health status");
45+
}
46+
});
47+
displayThread.setDaemon(true);
48+
displayThread.start();
49+
50+
TimeUnit.SECONDS.sleep(15);
51+
}
52+
53+
/*
54+
Output
55+
00:58:10.850 [pool-1-thread-1] INFO health.StubHealthCheck - [StubHealthCheck] Health check node01 -> Unhealthy
56+
00:58:10.865 [pool-1-thread-1] INFO health.StubHealthCheck - [StubHealthCheck] Health check node02 -> Unhealthy
57+
00:58:10.865 [pool-1-thread-1] INFO health.StubHealthCheck - [StubHealthCheck] Health check node03 -> Healthy
58+
00:58:11.908 [Thread-1] INFO health.HealthCheckMain -
59+
======================================================
60+
## Display health status
61+
> Healthy
62+
node03
63+
> Unhealthy
64+
node01 node02
65+
00:58:13.849 [pool-1-thread-1] INFO health.StubHealthCheck - [StubHealthCheck] Health check node01 -> Healthy
66+
00:58:13.849 [pool-1-thread-1] INFO health.StubHealthCheck - [StubHealthCheck] Health check node02 -> Unhealthy
67+
00:58:13.850 [pool-1-thread-1] INFO health.StubHealthCheck - [StubHealthCheck] Health check node03 -> Unhealthy
68+
00:58:13.850 [pool-1-thread-1] INFO health.HealthChecker - ## Name : node01's health status is changed. Unhealthy -> Healthy
69+
00:58:13.850 [pool-1-thread-1] INFO health.HealthChecker - ## Name : node03's health status is changed. Healthy -> Unhealthy
70+
00:58:13.909 [Thread-1] INFO health.HealthCheckMain -
71+
======================================================
72+
## Display health status
73+
> Healthy
74+
node01
75+
> Unhealthy
76+
node02 node03
77+
*/
78+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package health;
2+
3+
import com.codahale.metrics.health.HealthCheck;
4+
import com.codahale.metrics.health.HealthCheck.Result;
5+
import com.codahale.metrics.health.HealthCheckRegistry;
6+
import java.util.ArrayList;
7+
import java.util.HashMap;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.Map.Entry;
11+
import java.util.SortedMap;
12+
import java.util.concurrent.Executors;
13+
import java.util.concurrent.ScheduledExecutorService;
14+
import java.util.concurrent.TimeUnit;
15+
import java.util.concurrent.locks.ReentrantReadWriteLock;
16+
import java.util.function.Predicate;
17+
import lombok.extern.slf4j.Slf4j;
18+
19+
/**
20+
* @GitHub : https://github.com/zacscoding
21+
*/
22+
@Slf4j
23+
public class HealthChecker implements Runnable {
24+
25+
public static HealthChecker INSTANCE = new HealthChecker();
26+
27+
private ScheduledExecutorService scheduledExecutor;
28+
private ReentrantReadWriteLock lock;
29+
private HealthCheckRegistry healthChecks;
30+
private Map<String, Result> healthStatusMap;
31+
32+
private HealthChecker() {
33+
this.lock = new ReentrantReadWriteLock();
34+
this.healthChecks = new HealthCheckRegistry();
35+
this.healthStatusMap = new HashMap<>();
36+
}
37+
38+
/**
39+
* Start health checker
40+
*/
41+
public void start() {
42+
if (isRunning()) {
43+
logger.warn("Already health check scheduler is running");
44+
return;
45+
}
46+
47+
scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
48+
scheduledExecutor.scheduleAtFixedRate(this, 3000L, 3000L, TimeUnit.MILLISECONDS);
49+
50+
Runtime.getRuntime().addShutdownHook(new Thread(() -> HealthChecker.this.stop()));
51+
}
52+
53+
/**
54+
* Stop health checker and unregister all
55+
*/
56+
public void stop() {
57+
if (scheduledExecutor == null) {
58+
return;
59+
}
60+
61+
scheduledExecutor.shutdown();
62+
63+
for (String name : healthChecks.getNames()) {
64+
unregister(name);
65+
}
66+
67+
healthStatusMap.clear();
68+
69+
try {
70+
scheduledExecutor.awaitTermination(3000, TimeUnit.MILLISECONDS);
71+
} catch (InterruptedException e) {
72+
}
73+
}
74+
75+
/**
76+
* Check whether health checker is running or not
77+
*/
78+
public boolean isRunning() {
79+
return (scheduledExecutor != null)
80+
&& (!scheduledExecutor.isShutdown())
81+
&& (!scheduledExecutor.isTerminated());
82+
}
83+
84+
/**
85+
* Register health check
86+
*/
87+
public void register(String name, HealthCheck healthCheck) {
88+
healthChecks.register(name, healthCheck);
89+
}
90+
91+
/**
92+
* Unregister health check
93+
*/
94+
public void unregister(String name) {
95+
healthChecks.unregister(name);
96+
}
97+
98+
public List<String> getHealthyNodes() {
99+
return getNodesByStatus(result -> result.isHealthy());
100+
}
101+
102+
public List<String> getUnhealthyNodes() {
103+
return getNodesByStatus(result -> !result.isHealthy());
104+
}
105+
106+
private List<String> getNodesByStatus(Predicate<Result> sortedPredicate) {
107+
try {
108+
lock.readLock().lock();
109+
List<String> nodes = new ArrayList<>();
110+
for (Entry<String, Result> entry : healthStatusMap.entrySet()) {
111+
if (sortedPredicate.test(entry.getValue())) {
112+
nodes.add(entry.getKey());
113+
}
114+
}
115+
116+
return nodes;
117+
} finally {
118+
lock.readLock().unlock();
119+
}
120+
}
121+
122+
@Override
123+
public void run() {
124+
SortedMap<String, Result> results = healthChecks.runHealthChecks();
125+
try {
126+
lock.writeLock().lock();
127+
128+
for (Entry<String, Result> entry : results.entrySet()) {
129+
String name = entry.getKey();
130+
Result result = entry.getValue();
131+
Result prevResult = healthStatusMap.put(name, result);
132+
133+
if (prevResult != null && (result.isHealthy() != prevResult.isHealthy())) {
134+
logger.info("## Name : {}'s health status is changed. {} -> {}"
135+
, name
136+
, prevResult.isHealthy() ? "Healthy" : "Unhealthy"
137+
, result.isHealthy() ? "Healthy" : "Unhealthy"
138+
);
139+
}
140+
}
141+
} finally {
142+
lock.writeLock().unlock();
143+
}
144+
}
145+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /