Skip to content

Commit 924e4f5

Browse files
committed
feat: add instrumentation MBean
Signed-off-by: Marcos Tischer Vallim <tischer@gmail.com>
1 parent 2c6ddee commit 924e4f5

6 files changed

Lines changed: 203 additions & 17 deletions

File tree

amazon-sns-java-messaging-lib-template/src/main/java/com/amazon/sns/messaging/lib/core/AmazonSnsThreadPoolExecutor.java

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,50 +22,56 @@
2222
import java.util.concurrent.TimeUnit;
2323
import java.util.concurrent.atomic.AtomicInteger;
2424

25-
public class AmazonSnsThreadPoolExecutor extends ThreadPoolExecutor {
25+
import com.amazon.sns.messaging.lib.concurrent.ThreadFactoryProvider;
2626

27+
public class AmazonSnsThreadPoolExecutor extends ThreadPoolExecutor {
28+
2729
private final AtomicInteger activeTaskCount = new AtomicInteger();
28-
30+
2931
private final AtomicInteger failedTaskCount = new AtomicInteger();
30-
32+
3133
private final AtomicInteger succeededTaskCount = new AtomicInteger();
32-
34+
3335
public AmazonSnsThreadPoolExecutor(final int maximumPoolSize) {
34-
super(0, maximumPoolSize, 60, TimeUnit.SECONDS, new SynchronousQueue<>(), new BlockingSubmissionPolicy(30000));
36+
super(0, maximumPoolSize, 60, TimeUnit.SECONDS, new SynchronousQueue<>(), ThreadFactoryProvider.getThreadFactory(), new BlockingSubmissionPolicy(30000));
3537
}
36-
38+
3739
public int getActiveTaskCount() {
38-
return activeTaskCount.get();
40+
return this.activeTaskCount.get();
3941
}
40-
42+
4143
public int getFailedTaskCount() {
42-
return failedTaskCount.get();
44+
return this.failedTaskCount.get();
4345
}
44-
46+
4547
public int getSucceededTaskCount() {
46-
return succeededTaskCount.get();
48+
return this.succeededTaskCount.get();
4749
}
48-
50+
51+
public int getQueueSize() {
52+
return getQueue().size();
53+
}
54+
4955
@Override
5056
protected void beforeExecute(final Thread thread, final Runnable runnable) {
5157
try {
5258
super.beforeExecute(thread, runnable);
5359
} finally {
54-
activeTaskCount.incrementAndGet();
60+
this.activeTaskCount.incrementAndGet();
5561
}
5662
}
57-
63+
5864
@Override
5965
protected void afterExecute(final Runnable runnable, final Throwable throwable) {
6066
try {
6167
super.afterExecute(runnable, throwable);
6268
} finally {
6369
if (Objects.nonNull(throwable)) {
64-
failedTaskCount.incrementAndGet();
70+
this.failedTaskCount.incrementAndGet();
6571
} else {
66-
succeededTaskCount.incrementAndGet();
72+
this.succeededTaskCount.incrementAndGet();
6773
}
68-
activeTaskCount.decrementAndGet();
74+
this.activeTaskCount.decrementAndGet();
6975
}
7076
}
7177

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.amazon.sns.messaging.lib.instrument;
18+
19+
import com.amazon.sns.messaging.lib.core.AmazonSnsThreadPoolExecutor;
20+
21+
import lombok.RequiredArgsConstructor;
22+
23+
@RequiredArgsConstructor
24+
public class AmazonSnsThreadPoolExecutorJmx implements AmazonSnsThreadPoolExecutorJmxMBean {
25+
26+
private final AmazonSnsThreadPoolExecutor amazonSnsThreadPoolExecutor;
27+
28+
@Override
29+
public int getActiveTaskCount() {
30+
return this.amazonSnsThreadPoolExecutor.getActiveTaskCount();
31+
}
32+
33+
@Override
34+
public int getFailedTaskCount() {
35+
return this.amazonSnsThreadPoolExecutor.getFailedTaskCount();
36+
}
37+
38+
@Override
39+
public int getSucceededTaskCount() {
40+
return this.amazonSnsThreadPoolExecutor.getSucceededTaskCount();
41+
}
42+
43+
@Override
44+
public int getQueueSize() {
45+
return this.amazonSnsThreadPoolExecutor.getQueueSize();
46+
}
47+
48+
@Override
49+
public int getPoolSize() {
50+
return this.amazonSnsThreadPoolExecutor.getPoolSize();
51+
}
52+
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.amazon.sns.messaging.lib.instrument;
18+
19+
public interface AmazonSnsThreadPoolExecutorJmxMBean {
20+
21+
int getActiveTaskCount();
22+
23+
int getFailedTaskCount();
24+
25+
int getSucceededTaskCount();
26+
27+
int getQueueSize();
28+
29+
int getPoolSize();
30+
31+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.amazon.sns.messaging.lib.instrument;
2+
3+
import java.lang.management.ManagementFactory;
4+
5+
import javax.management.MBeanServer;
6+
import javax.management.ObjectName;
7+
8+
import lombok.AccessLevel;
9+
import lombok.NoArgsConstructor;
10+
import lombok.SneakyThrows;
11+
12+
@NoArgsConstructor(access = AccessLevel.PRIVATE)
13+
public final class MBeanRegistrar {
14+
15+
private static final MBeanServer BEAN_SERVER = ManagementFactory.getPlatformMBeanServer();
16+
17+
@SneakyThrows
18+
public static void registerMBean(final Object mbean, final String name) {
19+
final ObjectName objectName = new ObjectName(name);
20+
21+
if (!MBeanRegistrar.BEAN_SERVER.isRegistered(objectName)) {
22+
MBeanRegistrar.BEAN_SERVER.registerMBean(mbean, objectName);
23+
}
24+
25+
}
26+
27+
@SneakyThrows
28+
public static void unregisterMBean(final String name) {
29+
final ObjectName objectName = new ObjectName(name);
30+
31+
if (MBeanRegistrar.BEAN_SERVER.isRegistered(objectName)) {
32+
MBeanRegistrar.BEAN_SERVER.unregisterMBean(objectName);
33+
}
34+
35+
}
36+
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.amazon.sns.messaging.lib.instrument;
2+
3+
import com.amazon.sns.messaging.lib.concurrent.RingBufferBlockingQueue;
4+
5+
import lombok.RequiredArgsConstructor;
6+
7+
@RequiredArgsConstructor
8+
public class RingBufferBlockingQueueJmx implements RingBufferBlockingQueueJmxMBean {
9+
10+
private final RingBufferBlockingQueue<?> ringBufferBlockingQueue;
11+
12+
@Override
13+
public int capacity() {
14+
return this.ringBufferBlockingQueue.capacity();
15+
}
16+
17+
@Override
18+
public int size() {
19+
return this.ringBufferBlockingQueue.size();
20+
}
21+
22+
@Override
23+
public boolean isEmpty() {
24+
return this.ringBufferBlockingQueue.isEmpty();
25+
}
26+
27+
@Override
28+
public boolean isFull() {
29+
return this.ringBufferBlockingQueue.isFull();
30+
}
31+
32+
@Override
33+
public long writeSequence() {
34+
return this.ringBufferBlockingQueue.writeSequence();
35+
}
36+
37+
@Override
38+
public long readSequence() {
39+
return this.ringBufferBlockingQueue.readSequence();
40+
}
41+
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.amazon.sns.messaging.lib.instrument;
2+
3+
public interface RingBufferBlockingQueueJmxMBean {
4+
5+
int capacity();
6+
7+
int size();
8+
9+
boolean isEmpty();
10+
11+
boolean isFull();
12+
13+
long writeSequence();
14+
15+
long readSequence();
16+
17+
}

0 commit comments

Comments
 (0)