com.alibaba.otter
diff --git a/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/CanalAdapterApplication.java b/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/CanalAdapterApplication.java
index 2e3501dd..990af7fa 100644
--- a/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/CanalAdapterApplication.java
+++ b/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/CanalAdapterApplication.java
@@ -13,6 +13,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
*/
@SpringBootApplication(exclude= { DataSourceAutoConfiguration.class})
public class CanalAdapterApplication {
+
public static void main(String[] args) {
// 支持rocketmq client 配置日志路径
System.setProperty("rocketmq.client.logUseSlf4j","true");
diff --git a/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/prometheus/CanalAdapterExports.java b/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/prometheus/CanalAdapterExports.java
new file mode 100644
index 00000000..7dd100bc
--- /dev/null
+++ b/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/prometheus/CanalAdapterExports.java
@@ -0,0 +1,33 @@
+package com.alibaba.otter.canal.adapter.launcher.prometheus;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author sunxien
+ * @date 2025/5/19
+ * @since 1.0.0-SNAPSHOT
+ */
+public class CanalAdapterExports {
+
+ private static final Logger logger = LoggerFactory.getLogger(CanalAdapterExports.class);
+
+ private CanalAdapterExports() {
+ }
+
+ private static class SingletonHolder {
+ private static final CanalAdapterExports SINGLETON = new CanalAdapterExports();
+ }
+
+ public static CanalAdapterExports instance() {
+ return SingletonHolder.SINGLETON;
+ }
+
+ public void initialize() {
+ // TODO
+ }
+
+ public void terminate() {
+ // TODO
+ }
+}
diff --git a/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/prometheus/PrometheusService.java b/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/prometheus/PrometheusService.java
new file mode 100644
index 00000000..76fcf8c8
--- /dev/null
+++ b/client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/prometheus/PrometheusService.java
@@ -0,0 +1,98 @@
+package com.alibaba.otter.canal.adapter.launcher.prometheus;
+
+import io.prometheus.client.exporter.HTTPServer;
+import io.prometheus.client.hotspot.DefaultExports;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+/**
+ * @author sunxien
+ * @date 2025/5/19
+ * @since 1.0.0-SNAPSHOT
+ */
+@Component
+public class PrometheusService implements InitializingBean, DisposableBean {
+
+ private static final Logger logger = LoggerFactory.getLogger(PrometheusService.class);
+
+ private final CanalAdapterExports adapterExports;
+ private volatile boolean running = false;
+
+ /**
+ *
+ * Canal Server admin port: 11112
+ * Canal Server tcp port: 11111
+ * Canal Adapter metric port: 11113
+ *
+ */
+ private int port = 11113;
+ private HTTPServer httpServer;
+
+ private PrometheusService() {
+ this.adapterExports = CanalAdapterExports.instance();
+ }
+
+ private static class SingletonHolder {
+ private static final PrometheusService SINGLETON = new PrometheusService();
+ }
+
+ public static PrometheusService getInstance() {
+ return SingletonHolder.SINGLETON;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ PrometheusService.getInstance().initialize();
+ }
+
+ @Override
+ public void destroy() throws Exception {
+ PrometheusService.getInstance().terminate();
+ }
+
+ public void initialize() {
+ try {
+ logger.info("Starting prometheus HTTPServer on port {}....", port);
+ // TODO 2.Https?
+ httpServer = new HTTPServer(port);
+ logger.info("Start prometheus HTTPServer on port {} success", port);
+ } catch (IOException e) {
+ logger.error("Unable to start prometheus HTTPServer on port {}.", port, e);
+ return;
+ }
+ try {
+ // JVM exports
+ DefaultExports.initialize();
+ // adapterExports.initialize();
+ this.running = true;
+ } catch (Throwable t) {
+ logger.error("Unable to initialize adapter exports. (Register the default Hotspot collectors)", t);
+ }
+ }
+
+ public void terminate() {
+ try {
+ this.running = false;
+ adapterExports.terminate();
+ if (httpServer != null) {
+ httpServer.stop();
+ logger.info("Stop prometheus HTTPServer on port {} success", port);
+ }
+ } catch (Throwable t) {
+ logger.error("Something happened while terminating prometheus HTTPServer.", t);
+ }
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+ public void setServerPort(int port) {
+ this.port = port;
+ }
+}