├── src └── main │ ├── resources │ └── META-INF │ │ └── MANIFEST.MF │ └── java │ └── com │ └── dtstack │ └── catcher │ ├── monitor │ ├── service │ │ ├── RuntimeService.java │ │ ├── ThreadService.java │ │ ├── LogService.java │ │ └── MertricService.java │ ├── RuntimeMonitor.java │ ├── log │ │ ├── LogMonitor.java │ │ └── LogFilter.java │ ├── GCMonitor.java │ ├── ProcessMonitor.java │ ├── metric │ │ ├── GaugeMonitor.java │ │ └── CounterMonitor.java │ ├── ThreadMonitor.java │ ├── OsMonitor.java │ └── MemMonitor.java │ ├── info │ ├── GC.java │ ├── RunTime.java │ └── Memory.java │ ├── common │ ├── bean │ │ ├── MetricType.java │ │ ├── Metric.java │ │ ├── MetricFamily.java │ │ └── ThreadBean.java │ └── utils │ │ ├── constants │ │ └── SystemProperty.java │ │ ├── TimeUtils.java │ │ └── PathUtils.java │ └── network │ ├── handler │ ├── RuntimeHandler.java │ ├── ThreadHandler.java │ ├── LogHandler.java │ ├── AbstractHandler.java │ └── MetricHandler.java │ └── NetServer.java ├── .gitignore ├── assembly.xml ├── README.md ├── pom.xml └── LICENSE.md /src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Premain-Class: com.dtstack.catcher.Catcher 3 | Can-Redefine-Classes: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .sincedb 2 | target 3 | .idea/ 4 | .idea/* 5 | /.idea/* 6 | *.pyc 7 | *.swp 8 | .DS_Store 9 | /target 10 | target 11 | .class 12 | .project 13 | .classpath 14 | *.eclipse.* 15 | *.iml 16 | *.log.* 17 | *.log 18 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/service/RuntimeService.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor.service; 2 | 3 | import com.dtstack.catcher.info.RunTime; 4 | import com.dtstack.catcher.monitor.RuntimeMonitor; 5 | 6 | public class RuntimeService { 7 | 8 | public RunTime collect() { 9 | return RuntimeMonitor.get(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/service/ThreadService.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor.service; 2 | 3 | import java.util.List; 4 | 5 | import com.dtstack.catcher.common.bean.ThreadBean; 6 | import com.dtstack.catcher.monitor.ThreadMonitor; 7 | 8 | public class ThreadService { 9 | 10 | public List collect() { 11 | return ThreadMonitor.get(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/service/LogService.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor.service; 2 | 3 | import java.util.List; 4 | 5 | import com.dtstack.catcher.monitor.log.LogMonitor; 6 | 7 | public class LogService { 8 | 9 | public List collectErrorLog() { 10 | return LogMonitor.errorLog(); 11 | } 12 | 13 | public List collectRecentLog() { 14 | return LogMonitor.recentLog(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/info/GC.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.info; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class GC { 7 | 8 | private Full full = new Full(); 9 | private Young young = new Young(); 10 | 11 | @Data 12 | public static class Full { 13 | private long count; 14 | private long time; 15 | } 16 | 17 | @Data 18 | public static class Young { 19 | private long count; 20 | private long time; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/common/bean/MetricType.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.common.bean; 2 | 3 | public enum MetricType { 4 | COUNTER("counter"), GAUGE("gauge"), SUMMARY("summary"), HISTOGRAM("histogram"), UNTYPED("untyped"); 5 | 6 | private String name; 7 | 8 | public String getName() { 9 | return name; 10 | } 11 | 12 | public void setName(String name) { 13 | this.name = name; 14 | } 15 | 16 | MetricType(String name) { 17 | this.name = name; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/common/utils/constants/SystemProperty.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.common.utils.constants; 2 | 3 | public class SystemProperty { 4 | 5 | public static final String OS_NAME = System.getProperty("os.name"); 6 | public static final boolean LINUX = OS_NAME.startsWith("Linux"); 7 | public static final boolean WINDOWS = OS_NAME.startsWith("Windows"); 8 | public static final boolean SUN_OS = OS_NAME.startsWith("SunOS"); 9 | public static final boolean MAC_OS_X = OS_NAME.startsWith("Mac OS X"); 10 | public static final boolean FREE_BSD = OS_NAME.startsWith("FreeBSD"); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/common/bean/Metric.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.common.bean; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Data; 6 | 7 | @Data 8 | public class Metric { 9 | 10 | private String name; 11 | private List labelNames; 12 | private List labelValues; 13 | private String value; 14 | private long timestamp; 15 | 16 | public Metric(String name, List labelNames, List labelValues, String value) { 17 | this.name = name; 18 | this.labelNames = labelNames; 19 | this.labelValues = labelValues; 20 | this.value = value; 21 | this.timestamp = System.currentTimeMillis(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /assembly.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | jar 7 | 8 | with-dependencies 9 | false 10 | 11 | 12 | / 13 | true 14 | true 15 | runtime 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/info/RunTime.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.info; 2 | 3 | import java.lang.management.ManagementFactory; 4 | import java.lang.management.RuntimeMXBean; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import lombok.Data; 9 | 10 | @Data 11 | public class RunTime { 12 | 13 | private String name; 14 | private String bootClassPath; 15 | private List inputArguments; 16 | private String libraryPath; 17 | private Map systemProperties; 18 | 19 | public static void main(String[] args) { 20 | RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); 21 | System.out.println(runtimeMXBean.getName()); 22 | System.out.println(runtimeMXBean.getBootClassPath()); 23 | System.out.println(runtimeMXBean.getInputArguments()); 24 | System.out.println(runtimeMXBean.getLibraryPath()); 25 | System.out.println(runtimeMXBean.getSystemProperties()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/common/utils/TimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.common.utils; 2 | 3 | import java.sql.Timestamp; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | import java.util.TimeZone; 7 | 8 | public class TimeUtils { 9 | 10 | private static SimpleDateFormat utc; 11 | private static SimpleDateFormat local; 12 | 13 | static { 14 | utc = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 15 | utc.setTimeZone(TimeZone.getTimeZone("GMT")); 16 | local = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 17 | } 18 | 19 | public static String utc(Date date) { 20 | return utc.format(date); 21 | } 22 | 23 | public static String utc(long timestamp) { 24 | return utc.format(new Timestamp(timestamp)); 25 | } 26 | 27 | public static String local(Date date) { 28 | return local.format(date); 29 | } 30 | 31 | public static String local(long timestamp) { 32 | return local.format(new Timestamp(timestamp)); 33 | } 34 | 35 | public static void main(String[] args) { 36 | System.out.println(TimeUtils.local(System.currentTimeMillis())); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/network/handler/RuntimeHandler.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.network.handler; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStreamWriter; 6 | import com.alibaba.fastjson.JSON; 7 | import com.dtstack.catcher.info.RunTime; 8 | import com.dtstack.catcher.monitor.service.RuntimeService; 9 | import com.sun.net.httpserver.HttpExchange; 10 | 11 | public class RuntimeHandler extends AbstractHandler { 12 | 13 | private RuntimeService runtimeService; 14 | 15 | public RuntimeHandler(RuntimeService runtimeService) { 16 | this.runtimeService = runtimeService; 17 | } 18 | 19 | @Override 20 | public void handle(HttpExchange t) throws IOException { 21 | 22 | ByteArrayOutputStream response = this.response.get(); 23 | response.reset(); 24 | OutputStreamWriter osw = new OutputStreamWriter(response); 25 | write(osw, runtimeService.collect()); 26 | osw.flush(); 27 | osw.close(); 28 | response.flush(); 29 | response.close(); 30 | 31 | flush(t, response); 32 | } 33 | 34 | public void write(OutputStreamWriter osw, RunTime source) throws IOException { 35 | osw.write(JSON.toJSONString(source)); 36 | } 37 | 38 | 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/network/handler/ThreadHandler.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.network.handler; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStreamWriter; 6 | import java.util.List; 7 | 8 | import com.dtstack.catcher.common.bean.ThreadBean; 9 | import com.dtstack.catcher.monitor.service.ThreadService; 10 | import com.sun.net.httpserver.HttpExchange; 11 | 12 | public class ThreadHandler extends AbstractHandler { 13 | 14 | private ThreadService threadService; 15 | 16 | public ThreadHandler(ThreadService threadService) { 17 | this.threadService = threadService; 18 | } 19 | 20 | @Override 21 | public void handle(HttpExchange t) throws IOException { 22 | 23 | ByteArrayOutputStream response = this.response.get(); 24 | response.reset(); 25 | OutputStreamWriter osw = new OutputStreamWriter(response); 26 | write(osw, threadService.collect()); 27 | osw.flush(); 28 | osw.close(); 29 | response.flush(); 30 | response.close(); 31 | 32 | flush(t, response); 33 | } 34 | 35 | public void write(OutputStreamWriter osw, List source) throws IOException { 36 | for (ThreadBean s : source) { 37 | osw.write(s.format()); 38 | osw.write('\n'); 39 | } 40 | } 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/RuntimeMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor; 2 | 3 | import java.lang.management.ManagementFactory; 4 | import java.lang.management.RuntimeMXBean; 5 | 6 | import com.dtstack.catcher.info.RunTime; 7 | 8 | public class RuntimeMonitor { 9 | 10 | private static RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); 11 | 12 | public static RunTime get() { 13 | RunTime rt = new RunTime(); 14 | 15 | try { 16 | rt.setBootClassPath(runtimeMXBean.getBootClassPath()); 17 | rt.setName(runtimeMXBean.getName()); 18 | rt.setInputArguments(runtimeMXBean.getInputArguments()); 19 | rt.setBootClassPath(runtimeMXBean.getLibraryPath()); 20 | rt.setSystemProperties(runtimeMXBean.getSystemProperties()); 21 | } catch (Exception e) { 22 | e.printStackTrace(); 23 | } 24 | 25 | return rt; 26 | } 27 | 28 | public static void main(String[] args) { 29 | RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); 30 | // System.out.println(runtimeMXBean.getName()); 31 | // System.out.println(runtimeMXBean.getBootClassPath()); 32 | // System.out.println(runtimeMXBean.getInputArguments()); 33 | // System.out.println(runtimeMXBean.getLibraryPath()); 34 | // System.out.println(runtimeMXBean.getSystemProperties()); 35 | System.out.println(System.getProperty("os.name")); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/log/LogMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor.log; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.concurrent.BlockingQueue; 6 | import java.util.concurrent.LinkedBlockingQueue; 7 | 8 | public class LogMonitor { 9 | private static final int queueCapacity = 10; 10 | private static BlockingQueue recentLogQueue = new LinkedBlockingQueue<>(queueCapacity); 11 | private static BlockingQueue errorLogQueue = new LinkedBlockingQueue<>(queueCapacity); 12 | 13 | public static void pushToErrorLogQueue(String message) { 14 | pushToQueue(message, errorLogQueue); 15 | } 16 | 17 | public static void pushToRecentLogQueue(String message) { 18 | pushToQueue(message, recentLogQueue); 19 | } 20 | 21 | public static void pushToQueue(String message, BlockingQueue queue) { 22 | if (queue.remainingCapacity() < 1) { 23 | queue.poll(); 24 | } 25 | queue.offer(message); 26 | } 27 | 28 | public static List recentLog() { 29 | return listQueueData(recentLogQueue); 30 | } 31 | 32 | public static List errorLog() { 33 | return listQueueData(errorLogQueue); 34 | } 35 | 36 | public static List listQueueData(BlockingQueue queue) { 37 | String[] data = new String[queue.size()]; 38 | queue.toArray(data); 39 | return Arrays.asList(data); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 概述 2 | java性能采集工具。可采集进程内的内存(堆、非堆、直接)、cpu、句柄数、gc、日志(logback日志,分级别采集),也支持采集自定义指标,并提供http方式访问数据。 3 | 4 | ## http服务 5 | - /runtime:运行时参数 6 | - /metrics:prometheus采集数据 7 | - /threads:线程堆栈 8 | - /logs/recent:最近日志 9 | - /logs/error:最近错误日志 10 | 11 | ## 接入方式 12 | #### 引入包 13 | ``` 14 | 15 | com.dtstack 16 | catcher 17 | 0.0.1-SNAPSHOT 18 | 19 | ``` 20 | 21 | #### 启动服务 22 | ``` 23 | String address = "localhost:19222";//自定义端口ip 24 | NetServer server = new NetServer(address); 25 | server.start(); 26 | ``` 27 | 28 | #### 关闭服务 29 | ``` 30 | server.stop(); 31 | ``` 32 | 33 | #### 如果需要采集日志,logback.xml的appender中加入LogFilter 34 | ``` 35 | 36 | 37 | 38 | 39 | ${LOG_CHARSET} 40 | ${LOG_PATTERN} 41 | 42 | 43 | ``` 44 | 45 | #### 如果需要采集自定义指标,目前支持prometheus的counter方式和gauge方式 46 | (1)counter方式 47 | ``` 48 | CounterMonitor.increase(String name, String labelNames, String labelValues, long delta); 49 | ``` 50 | (2)gauge方式 51 | ``` 52 | GaugeMonitor.set(String name, String labelNames, String labelValues, long value); 53 | ``` 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/common/bean/MetricFamily.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.common.bean; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import lombok.Data; 7 | 8 | @Data 9 | public class MetricFamily { 10 | 11 | private String name; 12 | private String help; 13 | private MetricType type; 14 | private List metrics = new ArrayList(); 15 | 16 | public MetricFamily(String name, String help) { 17 | this.name = name; 18 | this.help = help; 19 | } 20 | 21 | public void addMetric(Metric metric) { 22 | metrics.add(metric); 23 | } 24 | 25 | public void addMetric(String name, List labelNames, List labelValues, String value) { 26 | Metric metric = new Metric(name, labelNames, labelValues, value); 27 | metrics.add(metric); 28 | } 29 | 30 | public void addMetric(String name, String value) { 31 | Metric metric = new Metric(name, new ArrayList(), new ArrayList(), value); 32 | metrics.add(metric); 33 | } 34 | 35 | public static class Gauge extends MetricFamily { 36 | 37 | public Gauge(String name, String help) { 38 | super(name, help); 39 | setType(MetricType.GAUGE); 40 | } 41 | 42 | } 43 | 44 | public static class Counter extends MetricFamily { 45 | 46 | public Counter(String name, String help) { 47 | super(name, help); 48 | setType(MetricType.COUNTER); 49 | } 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/network/handler/LogHandler.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.network.handler; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStreamWriter; 6 | import java.util.List; 7 | 8 | import com.dtstack.catcher.monitor.service.LogService; 9 | import com.sun.net.httpserver.HttpExchange; 10 | 11 | public class LogHandler extends AbstractHandler { 12 | 13 | private LogService logService; 14 | 15 | public LogHandler(LogService logService) { 16 | this.logService = logService; 17 | } 18 | 19 | @Override 20 | public void handle(HttpExchange t) throws IOException { 21 | 22 | ByteArrayOutputStream response = this.response.get(); 23 | response.reset(); 24 | OutputStreamWriter osw = new OutputStreamWriter(response); 25 | List logs = null; 26 | if(t.getRequestURI().getPath().equals("/logs/recent")) { 27 | logs = logService.collectRecentLog(); 28 | } else { 29 | logs = logService.collectErrorLog(); 30 | } 31 | write(osw, logs); 32 | osw.flush(); 33 | osw.close(); 34 | response.flush(); 35 | response.close(); 36 | 37 | flush(t, response); 38 | } 39 | 40 | public void write(OutputStreamWriter osw, List source) throws IOException { 41 | if(source == null) { 42 | return; 43 | } 44 | for(String s : source) { 45 | osw.write(s); 46 | osw.write('\n'); 47 | } 48 | 49 | } 50 | 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/common/utils/PathUtils.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.common.utils; 2 | 3 | import java.net.URI; 4 | import java.nio.file.FileSystem; 5 | import java.nio.file.FileSystems; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | 9 | public final class PathUtils { 10 | private PathUtils() {} 11 | 12 | static final FileSystem ACTUAL_DEFAULT = FileSystems.getDefault(); 13 | 14 | static volatile FileSystem DEFAULT = ACTUAL_DEFAULT; 15 | 16 | public static Path get(String first, String... more) { 17 | return DEFAULT.getPath(first, more); 18 | } 19 | 20 | public static Path get(URI uri) { 21 | if (uri.getScheme().equalsIgnoreCase("file")) { 22 | return DEFAULT.provider().getPath(uri); 23 | } else { 24 | return Paths.get(uri); 25 | } 26 | } 27 | 28 | public static Path get(Path[] roots, String path) { 29 | for (Path root : roots) { 30 | Path normalizedRoot = root.normalize(); 31 | Path normalizedPath = normalizedRoot.resolve(path).normalize(); 32 | if(normalizedPath.startsWith(normalizedRoot)) { 33 | return normalizedPath; 34 | } 35 | } 36 | return null; 37 | } 38 | 39 | public static Path get(Path[] roots, URI uri) { 40 | return get(roots, PathUtils.get(uri).normalize().toString()); 41 | } 42 | 43 | public static FileSystem getDefaultFileSystem() { 44 | return DEFAULT; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/network/handler/AbstractHandler.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.network.handler; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.net.HttpURLConnection; 6 | import java.util.List; 7 | import java.util.zip.GZIPOutputStream; 8 | import com.sun.net.httpserver.HttpExchange; 9 | import com.sun.net.httpserver.HttpHandler; 10 | 11 | public abstract class AbstractHandler implements HttpHandler { 12 | 13 | public void flush(HttpExchange t, ByteArrayOutputStream response) throws IOException { 14 | t.getResponseHeaders().set("Content-Type", "text/plain; version=0.0.4; charset=utf-8"); 15 | t.getResponseHeaders().set("Content-Length", String.valueOf(response.size())); 16 | if (shouldUseCompression(t)) { 17 | t.getResponseHeaders().set("Content-Encoding", "gzip"); 18 | t.sendResponseHeaders(HttpURLConnection.HTTP_OK, 0); 19 | final GZIPOutputStream os = new GZIPOutputStream(t.getResponseBody()); 20 | response.writeTo(os); 21 | os.finish(); 22 | } else { 23 | t.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.size()); 24 | response.writeTo(t.getResponseBody()); 25 | } 26 | t.close(); 27 | } 28 | 29 | protected final LocalByteArray response = new LocalByteArray(); 30 | 31 | protected static boolean shouldUseCompression(HttpExchange exchange) { 32 | List encodingHeaders = exchange.getRequestHeaders().get("Accept-Encoding"); 33 | if (encodingHeaders == null) 34 | return false; 35 | 36 | for (String encodingHeader : encodingHeaders) { 37 | String[] encodings = encodingHeader.split(","); 38 | for (String encoding : encodings) { 39 | if (encoding.trim().toLowerCase().equals("gzip")) { 40 | return true; 41 | } 42 | } 43 | } 44 | return false; 45 | } 46 | 47 | public static class LocalByteArray extends ThreadLocal { 48 | protected ByteArrayOutputStream initialValue() { 49 | return new ByteArrayOutputStream(1 << 20); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/info/Memory.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.info; 2 | 3 | import lombok.Data; 4 | 5 | 6 | @Data 7 | public class Memory { 8 | 9 | private Heap heap = new Heap(); 10 | private HeapEdenSpace heapEdenSpace = new HeapEdenSpace(); 11 | private HeapOldGen heapOldGen = new HeapOldGen(); 12 | private HeapSurvivorSpace heapSurvivorSpace = new HeapSurvivorSpace(); 13 | private Metaspace metaspace = new Metaspace(); 14 | private CodeCache codeCache = new CodeCache(); 15 | private CompressedClassSpace compressedClassSpace = new CompressedClassSpace(); 16 | private Direct direct = new Direct(); 17 | private NonHeap nonHeap = new NonHeap(); 18 | 19 | @Data 20 | public static class Heap { 21 | private long init; 22 | private long used; 23 | private long committed; 24 | private long max; 25 | } 26 | 27 | @Data 28 | public static class NonHeap { 29 | private long init; 30 | private long used; 31 | private long committed; 32 | private long max; 33 | } 34 | 35 | @Data 36 | public static class Metaspace { 37 | private long init; 38 | private long used; 39 | private long committed; 40 | private long max; 41 | } 42 | 43 | @Data 44 | public static class HeapOldGen { 45 | private long init; 46 | private long used; 47 | private long committed; 48 | private long max; 49 | } 50 | 51 | @Data 52 | public static class HeapEdenSpace { 53 | private long init; 54 | private long used; 55 | private long committed; 56 | private long max; 57 | } 58 | 59 | @Data 60 | public static class CodeCache { 61 | private long init; 62 | private long used; 63 | private long committed; 64 | private long max; 65 | } 66 | 67 | @Data 68 | public static class CompressedClassSpace { 69 | private long init; 70 | private long used; 71 | private long committed; 72 | private long max; 73 | } 74 | 75 | @Data 76 | public static class HeapSurvivorSpace { 77 | private long init; 78 | private long used; 79 | private long committed; 80 | private long max; 81 | } 82 | 83 | @Data 84 | public static class Direct { 85 | private long used; 86 | private long max; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.dtstack 5 | catcher 6 | 0.0.1-SNAPSHOT 7 | catcher 8 | 9 | 10 | 11 | org.projectlombok 12 | lombok 13 | 1.16.6 14 | 15 | 16 | ch.qos.logback 17 | logback-classic 18 | 1.1.7 19 | 20 | 21 | com.google.guava 22 | guava 23 | 25.1-jre 24 | 25 | 26 | com.alibaba 27 | fastjson 28 | 1.2.47 29 | 30 | 31 | 32 | jar 33 | 34 | 35 | catcher 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-assembly-plugin 40 | 41 | 42 | true 43 | 44 | src/main/resources/META-INF/MANIFEST.MF 45 | 46 | 47 | 48 | 49 | 50 | 51 | assembly.xml 52 | 53 | 54 | 55 | 56 | package 57 | 58 | single 59 | 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-jar-plugin 66 | 2.3.2 67 | 68 | 69 | true 70 | 71 | src/main/resources/META-INF/MANIFEST.MF 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | org.apache.maven.plugins 81 | maven-compiler-plugin 82 | 83 | 1.8 84 | 1.8 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/log/LogFilter.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor.log; 2 | 3 | import com.dtstack.catcher.common.utils.TimeUtils; 4 | import com.dtstack.catcher.monitor.metric.CounterMonitor; 5 | import ch.qos.logback.classic.Level; 6 | import ch.qos.logback.classic.spi.ILoggingEvent; 7 | import ch.qos.logback.classic.spi.StackTraceElementProxy; 8 | import ch.qos.logback.core.filter.Filter; 9 | import ch.qos.logback.core.spi.FilterReply; 10 | 11 | public class LogFilter extends Filter { 12 | 13 | public void increaseLineCount() { 14 | CounterMonitor.increase("logback", "type", "total_line"); 15 | } 16 | 17 | public void increaseBytesCount(String message) { 18 | CounterMonitor.increase("logback", "type", "total_bytes", message.getBytes().length); 19 | } 20 | 21 | public void increaseLevelLineCount(Level level) { 22 | CounterMonitor.increase("logback_level", "type", level.levelStr); 23 | } 24 | 25 | public void increaseErrorLineCount(String exceptionClass) { 26 | CounterMonitor.increase("logback_error", "class", exceptionClass); 27 | } 28 | 29 | public StringBuilder formatLog(ILoggingEvent event) { 30 | 31 | StringBuilder logBuilder = new StringBuilder(""); 32 | logBuilder.append(TimeUtils.local(event.getTimeStamp())).append(" ").append(event.getLevel()) 33 | .append(" ").append(event.getFormattedMessage()); 34 | 35 | if (Level.ERROR.equals(event.getLevel()) && event.getThrowableProxy() != null) { 36 | 37 | logBuilder.append(" ").append(event.getThrowableProxy().getClassName()).append(" ") 38 | .append(event.getThrowableProxy().getMessage()); 39 | 40 | if (event.getThrowableProxy().getStackTraceElementProxyArray() != null) { 41 | for (StackTraceElementProxy p : event.getThrowableProxy().getStackTraceElementProxyArray()) { 42 | logBuilder.append("\n ").append(p.getStackTraceElement().getClassName()); 43 | } 44 | } 45 | 46 | } 47 | 48 | return logBuilder; 49 | } 50 | 51 | @Override 52 | public FilterReply decide(ILoggingEvent event) { 53 | try { 54 | increaseLineCount(); 55 | 56 | increaseLevelLineCount(event.getLevel()); 57 | 58 | if (Level.ERROR.equals(event.getLevel())) { 59 | String className = event.getThrowableProxy() == null ? "null" 60 | : event.getThrowableProxy().getClassName(); 61 | 62 | increaseErrorLineCount(className); 63 | } 64 | 65 | 66 | StringBuilder logBuilder = formatLog(event); 67 | 68 | if(Level.ERROR.equals(event.getLevel())) { 69 | LogMonitor.pushToErrorLogQueue(logBuilder.toString()); 70 | } 71 | 72 | LogMonitor.pushToRecentLogQueue(logBuilder.toString()); 73 | 74 | increaseBytesCount(logBuilder.toString()); 75 | 76 | } catch (Throwable e) { 77 | e.printStackTrace(); 78 | } 79 | 80 | return FilterReply.ACCEPT; 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/network/handler/MetricHandler.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.network.handler; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStreamWriter; 6 | import java.io.Writer; 7 | import java.util.List; 8 | import com.dtstack.catcher.common.bean.Metric; 9 | import com.dtstack.catcher.common.bean.MetricFamily; 10 | import com.dtstack.catcher.monitor.service.MertricService; 11 | import com.sun.net.httpserver.HttpExchange; 12 | 13 | public class MetricHandler extends AbstractHandler { 14 | 15 | private MertricService mertricService; 16 | 17 | public MetricHandler(MertricService mertricService) { 18 | this.mertricService = mertricService; 19 | } 20 | 21 | @Override 22 | public void handle(HttpExchange t) { 23 | 24 | try { 25 | ByteArrayOutputStream response = this.response.get(); 26 | response.reset(); 27 | OutputStreamWriter osw = new OutputStreamWriter(response); 28 | write(osw, mertricService.collect()); 29 | osw.flush(); 30 | osw.close(); 31 | response.flush(); 32 | response.close(); 33 | 34 | flush(t, response); 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | 39 | 40 | } 41 | 42 | public static void write(Writer writer, List mfs) throws IOException { 43 | 44 | for (MetricFamily metricFamily : mfs) { 45 | 46 | writer.write("# HELP "); 47 | writer.write(metricFamily.getName()); 48 | writer.write(' '); 49 | writeEscapedHelp(writer, metricFamily.getHelp()); 50 | writer.write('\n'); 51 | 52 | writer.write("# TYPE "); 53 | writer.write(metricFamily.getName()); 54 | writer.write(' '); 55 | writer.write(metricFamily.getType().getName()); 56 | writer.write('\n'); 57 | 58 | for (Metric metric : metricFamily.getMetrics()) { 59 | writer.write(metric.getName()); 60 | if (metric.getLabelNames().size() > 0) { 61 | writer.write('{'); 62 | for (int i = 0; i < metric.getLabelNames().size(); ++i) { 63 | writer.write(metric.getLabelNames().get(i)); 64 | writer.write("=\""); 65 | writeEscapedLabelValue(writer, metric.getLabelValues().get(i)); 66 | writer.write("\","); 67 | } 68 | writer.write('}'); 69 | } 70 | writer.write(' '); 71 | writer.write(metric.getValue()); 72 | if (metric.getTimestamp() > 0) { 73 | writer.write(' '); 74 | writer.write(String.valueOf(metric.getTimestamp())); 75 | } 76 | writer.write('\n'); 77 | } 78 | } 79 | } 80 | 81 | private static void writeEscapedHelp(Writer writer, String s) throws IOException { 82 | for (int i = 0; i < s.length(); i++) { 83 | char c = s.charAt(i); 84 | switch (c) { 85 | case '\\': 86 | writer.append("\\\\"); 87 | break; 88 | case '\n': 89 | writer.append("\\n"); 90 | break; 91 | default: 92 | writer.append(c); 93 | } 94 | } 95 | } 96 | 97 | private static void writeEscapedLabelValue(Writer writer, String s) throws IOException { 98 | for (int i = 0; i < s.length(); i++) { 99 | char c = s.charAt(i); 100 | switch (c) { 101 | case '\\': 102 | writer.append("\\\\"); 103 | break; 104 | case '\"': 105 | writer.append("\\\""); 106 | break; 107 | case '\n': 108 | writer.append("\\n"); 109 | break; 110 | default: 111 | writer.append(c); 112 | } 113 | } 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/network/NetServer.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.network; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.util.concurrent.ExecutorService; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.ThreadFactory; 8 | import java.util.concurrent.atomic.AtomicInteger; 9 | 10 | import com.dtstack.catcher.monitor.service.LogService; 11 | import com.dtstack.catcher.monitor.service.MertricService; 12 | import com.dtstack.catcher.monitor.service.RuntimeService; 13 | import com.dtstack.catcher.monitor.service.ThreadService; 14 | import com.dtstack.catcher.network.handler.LogHandler; 15 | import com.dtstack.catcher.network.handler.MetricHandler; 16 | import com.dtstack.catcher.network.handler.RuntimeHandler; 17 | import com.dtstack.catcher.network.handler.ThreadHandler; 18 | import com.sun.net.httpserver.HttpServer; 19 | 20 | public class NetServer { 21 | 22 | protected final ExecutorService executorService; 23 | protected final HttpServer server; 24 | 25 | private MertricService mertricService = new MertricService(); 26 | private LogService logService = new LogService(); 27 | private ThreadService threadService = new ThreadService(); 28 | private RuntimeService runtimeService = new RuntimeService(); 29 | 30 | public NetServer(String address) throws IOException { 31 | String[] addrs = address.split(":"); 32 | server = HttpServer.create(new InetSocketAddress(addrs[0], Integer.valueOf(addrs[1])), 3); 33 | MetricHandler mHandler = new MetricHandler(mertricService); 34 | LogHandler logHandler = new LogHandler(logService); 35 | ThreadHandler threadHandler = new ThreadHandler(threadService); 36 | RuntimeHandler runtimeHandler = new RuntimeHandler(runtimeService); 37 | 38 | server.createContext("/", mHandler); 39 | server.createContext("/metrics", mHandler); 40 | server.createContext("/logs", logHandler); 41 | server.createContext("/threads", threadHandler); 42 | server.createContext("/runtime", runtimeHandler); 43 | 44 | executorService = Executors.newFixedThreadPool(5, new NamedThreadFactory("netserver", true)); 45 | server.setExecutor(executorService); 46 | } 47 | 48 | public void start() { 49 | server.start(); 50 | } 51 | 52 | public void stop() { 53 | server.stop(0); 54 | } 55 | 56 | static class NamedThreadFactory implements ThreadFactory { 57 | 58 | private static final AtomicInteger poolNumber = new AtomicInteger(1); 59 | 60 | final AtomicInteger threadNumber = new AtomicInteger(1); 61 | final ThreadGroup group; 62 | final String namePrefix; 63 | final boolean isDaemon; 64 | 65 | public NamedThreadFactory() { 66 | this("pool"); 67 | } 68 | 69 | public NamedThreadFactory(String name) { 70 | this(name, false); 71 | } 72 | 73 | public NamedThreadFactory(String preffix, boolean daemon) { 74 | SecurityManager s = System.getSecurityManager(); 75 | group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); 76 | namePrefix = preffix + "-" + poolNumber.getAndIncrement() + "-thread-"; 77 | isDaemon = daemon; 78 | } 79 | 80 | public Thread newThread(Runnable r) { 81 | Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); 82 | t.setDaemon(isDaemon); 83 | if (t.getPriority() != Thread.NORM_PRIORITY) { 84 | t.setPriority(Thread.NORM_PRIORITY); 85 | } 86 | return t; 87 | } 88 | } 89 | 90 | public static void main(String[] args) throws IOException { 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/GCMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor; 2 | 3 | import java.lang.management.GarbageCollectorMXBean; 4 | import java.lang.management.ManagementFactory; 5 | import java.util.List; 6 | 7 | import com.dtstack.catcher.info.GC; 8 | 9 | public class GCMonitor { 10 | 11 | private static GarbageCollectorMXBean fullGC; 12 | private static GarbageCollectorMXBean youngGC; 13 | 14 | static { 15 | try { 16 | init(); 17 | } catch (Exception e) { 18 | e.printStackTrace(); 19 | } 20 | } 21 | 22 | public static void init() { 23 | List list = ManagementFactory.getGarbageCollectorMXBeans(); 24 | for (GarbageCollectorMXBean item : list) { 25 | if ("ConcurrentMarkSweep".equals(item.getName()) || "MarkSweepCompact".equals(item.getName()) 26 | || "PS MarkSweep".equals(item.getName()) || "G1 Old Generation".equals(item.getName()) 27 | || "Garbage collection optimized for short pausetimes Old Collector".equals(item.getName()) 28 | || "Garbage collection optimized for throughput Old Collector".equals(item.getName()) 29 | || "Garbage collection optimized for deterministic pausetimes Old Collector" 30 | .equals(item.getName())) { 31 | fullGC = item; 32 | } else if ("ParNew".equals(item.getName()) || "Copy".equals(item.getName()) 33 | || "PS Scavenge".equals(item.getName()) || "G1 Young Generation".equals(item.getName()) 34 | || "Garbage collection optimized for short pausetimes Young Collector".equals(item.getName()) 35 | || "Garbage collection optimized for throughput Young Collector".equals(item.getName()) 36 | || "Garbage collection optimized for deterministic pausetimes Young Collector" 37 | .equals(item.getName())) { 38 | youngGC = item; 39 | } 40 | } 41 | } 42 | 43 | public static GC get() { 44 | GC gc = new GC(); 45 | try { 46 | gc.getFull().setCount(fullGC.getCollectionCount()); 47 | gc.getFull().setTime(fullGC.getCollectionTime()); 48 | gc.getYoung().setCount(youngGC.getCollectionCount()); 49 | gc.getYoung().setTime(youngGC.getCollectionTime()); 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | } 53 | 54 | return gc; 55 | } 56 | 57 | public static void main(String[] args) { 58 | List list = ManagementFactory.getGarbageCollectorMXBeans(); 59 | for (GarbageCollectorMXBean item : list) { 60 | if ("ConcurrentMarkSweep".equals(item.getName()) // 61 | || "MarkSweepCompact".equals(item.getName()) // 62 | || "PS MarkSweep".equals(item.getName()) // 63 | || "G1 Old Generation".equals(item.getName()) // 64 | || "Garbage collection optimized for short pausetimes Old Collector".equals(item.getName()) // 65 | || "Garbage collection optimized for throughput Old Collector".equals(item.getName()) // 66 | || "Garbage collection optimized for deterministic pausetimes Old Collector".equals(item.getName()) // 67 | ) { 68 | fullGC = item; 69 | } else if ("ParNew".equals(item.getName()) // 70 | || "Copy".equals(item.getName()) // 71 | || "PS Scavenge".equals(item.getName()) // 72 | || "G1 Young Generation".equals(item.getName()) // 73 | || "Garbage collection optimized for short pausetimes Young Collector".equals(item.getName()) // 74 | || "Garbage collection optimized for throughput Young Collector".equals(item.getName()) // 75 | || "Garbage collection optimized for deterministic pausetimes Young Collector" 76 | .equals(item.getName()) // 77 | ) { 78 | youngGC = item; 79 | } 80 | } 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/ProcessMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor; 2 | 3 | import java.lang.management.ManagementFactory; 4 | import java.lang.management.OperatingSystemMXBean; 5 | import java.lang.reflect.Method; 6 | 7 | public class ProcessMonitor { 8 | 9 | private static final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean(); 10 | 11 | private static final Method getMaxFileDescriptorCountField; 12 | private static final Method getOpenFileDescriptorCountField; 13 | private static final Method getProcessCpuLoad; 14 | private static final Method getProcessCpuTime; 15 | private static final Method getCommittedVirtualMemorySize; 16 | 17 | static { 18 | getMaxFileDescriptorCountField = getUnixMethod("getMaxFileDescriptorCount"); 19 | getOpenFileDescriptorCountField = getUnixMethod("getOpenFileDescriptorCount"); 20 | getProcessCpuLoad = getMethod("getProcessCpuLoad"); 21 | getProcessCpuTime = getMethod("getProcessCpuTime"); 22 | getCommittedVirtualMemorySize = getMethod("getCommittedVirtualMemorySize"); 23 | } 24 | 25 | private static Method getUnixMethod(String methodName) { 26 | try { 27 | return Class.forName("com.sun.management.UnixOperatingSystemMXBean").getMethod(methodName); 28 | } catch (Exception t) { 29 | // not available 30 | return null; 31 | } 32 | } 33 | 34 | private static Method getMethod(String methodName) { 35 | try { 36 | return Class.forName("com.sun.management.OperatingSystemMXBean").getMethod(methodName); 37 | } catch (Exception t) { 38 | // not available 39 | return null; 40 | } 41 | } 42 | 43 | public static long getMaxFileDescriptorCount() { 44 | if (getMaxFileDescriptorCountField == null) { 45 | return -1; 46 | } 47 | try { 48 | return (Long) getMaxFileDescriptorCountField.invoke(osMxBean); 49 | } catch (Exception t) { 50 | return -1; 51 | } 52 | } 53 | 54 | public static long getOpenFileDescriptorCount() { 55 | if (getOpenFileDescriptorCountField == null) { 56 | return -1; 57 | } 58 | try { 59 | return (Long) getOpenFileDescriptorCountField.invoke(osMxBean); 60 | } catch (Exception t) { 61 | return -1; 62 | } 63 | } 64 | 65 | public static long getProcessCpuTotalTime() { 66 | if (getProcessCpuTime != null) { 67 | try { 68 | long time = (long) getProcessCpuTime.invoke(osMxBean); 69 | if (time >= 0) { 70 | return (time / 1_000_000L); 71 | } 72 | } catch (Exception t) { 73 | return -1; 74 | } 75 | } 76 | return -1; 77 | } 78 | 79 | /** 80 | * Returns the process CPU usage in percent 81 | */ 82 | public static short getProcessCpuPercent() { 83 | return getLoadAndScaleToPercent(getProcessCpuLoad, osMxBean); 84 | } 85 | 86 | public static long getTotalVirtualMemorySize() { 87 | if (getCommittedVirtualMemorySize != null) { 88 | try { 89 | long virtual = (long) getCommittedVirtualMemorySize.invoke(osMxBean); 90 | if (virtual >= 0) { 91 | return virtual; 92 | } 93 | } catch (Exception t) { 94 | return -1; 95 | } 96 | } 97 | return -1; 98 | } 99 | 100 | public static short getLoadAndScaleToPercent(Method method, OperatingSystemMXBean osMxBean) { 101 | if (method != null) { 102 | try { 103 | double load = (double) method.invoke(osMxBean); 104 | if (load >= 0) { 105 | return (short) (load * 100); 106 | } 107 | } catch (Exception e) { 108 | return -1; 109 | } 110 | } 111 | return -1; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/metric/GaugeMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor.metric; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | import java.util.concurrent.atomic.AtomicLong; 9 | 10 | import com.dtstack.catcher.common.bean.MetricFamily; 11 | 12 | public class GaugeMonitor { 13 | 14 | private static Map> cache = new ConcurrentHashMap<>(); 15 | private static Map>> gaugePool = new ConcurrentHashMap<>(); 16 | 17 | public static List getListFormat(String source) { 18 | if (source == null) { 19 | source = ""; 20 | } 21 | 22 | if (!cache.containsKey(source)) { 23 | List target = Arrays.asList(source.split(",")); 24 | 25 | cache.put(source, target); 26 | } 27 | 28 | return cache.get(source); 29 | } 30 | 31 | public static List getAllMetricFamily() { 32 | List list = new ArrayList<>(); 33 | for (Map.Entry>> entry : gaugePool.entrySet()) { 34 | if (entry.getValue() == null) { 35 | continue; 36 | } 37 | 38 | list.add(getMetricFamily(entry.getKey())); 39 | } 40 | 41 | return list; 42 | } 43 | 44 | public static MetricFamily getMetricFamily(String name) { 45 | MetricFamily counter = new MetricFamily.Gauge(name, ""); 46 | 47 | Map> values = gaugePool.get(name); 48 | if (values == null) { 49 | return counter; 50 | } 51 | 52 | for (Map.Entry> labelNameEntry : values.entrySet()) { 53 | String labelName = labelNameEntry.getKey(); 54 | if (labelNameEntry.getValue() == null) { 55 | continue; 56 | } 57 | 58 | for (Map.Entry labelValueEntry : labelNameEntry.getValue().entrySet()) { 59 | String labelValue = labelValueEntry.getKey(); 60 | 61 | List labelNameList = getListFormat(labelName); 62 | List labelValueList = getListFormat(labelValue); 63 | 64 | counter.addMetric(name, labelNameList, labelValueList, 65 | String.valueOf(labelValueEntry.getValue().get())); 66 | } 67 | } 68 | return counter; 69 | } 70 | 71 | public static void set(String name, long value) { 72 | set(name, "", "", value); 73 | } 74 | 75 | public static void set(String name, String labelNames, String labelValues, long value) { 76 | try { 77 | if (!gaugePool.containsKey(name)) { 78 | synchronized (GaugeMonitor.class) { 79 | if (!gaugePool.containsKey(name)) { 80 | gaugePool.put(name, new ConcurrentHashMap>()); 81 | } 82 | } 83 | } 84 | 85 | if (!gaugePool.get(name).containsKey(labelNames)) { 86 | synchronized (GaugeMonitor.class) { 87 | if (!gaugePool.get(name).containsKey(labelNames)) { 88 | gaugePool.get(name).put(labelNames, new ConcurrentHashMap()); 89 | 90 | } 91 | } 92 | } 93 | 94 | if (!gaugePool.get(name).get(labelNames).containsKey(labelValues)) { 95 | synchronized (GaugeMonitor.class) { 96 | if (!gaugePool.get(name).get(labelNames).containsKey(labelValues)) { 97 | gaugePool.get(name).get(labelNames).put(labelValues, new AtomicLong(0)); 98 | } 99 | 100 | } 101 | } 102 | 103 | gaugePool.get(name).get(labelNames).get(labelValues).set(value); 104 | } catch (Exception e) { 105 | System.out.println("input=" + name+labelNames+labelValues+value + " gaugePool="+gaugePool); 106 | e.printStackTrace(); 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/ThreadMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor; 2 | 3 | import java.lang.management.ManagementFactory; 4 | import java.lang.management.ThreadInfo; 5 | import java.lang.management.ThreadMXBean; 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.Comparator; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | import com.dtstack.catcher.common.bean.ThreadBean; 13 | 14 | public class ThreadMonitor { 15 | 16 | private static long interval = 1000l; 17 | 18 | private static ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); 19 | 20 | static { 21 | try { 22 | threadMXBean.setThreadContentionMonitoringEnabled(true); 23 | } catch (Exception e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | 28 | public static List get() { 29 | 30 | List threadList = new ArrayList<>(); 31 | 32 | try { 33 | 34 | Map threadInfos = new HashMap<>(); 35 | for (long id : threadMXBean.getAllThreadIds()) { 36 | long cpuTime = threadMXBean.getThreadCpuTime(id) / 1000000; 37 | ThreadInfo info = threadMXBean.getThreadInfo(id); 38 | threadInfos.put(id, new ThreadBean(cpuTime, info)); 39 | } 40 | 41 | Thread.sleep(interval); 42 | 43 | for (long id : threadMXBean.getAllThreadIds()) { 44 | long cpuTime = threadMXBean.getThreadCpuTime(id) / 1000000; 45 | ThreadInfo info = threadMXBean.getThreadInfo(id, 100); 46 | threadInfos.get(id).setDelta(cpuTime, info); 47 | } 48 | 49 | threadList.addAll(threadInfos.values()); 50 | 51 | Collections.sort(threadList, new Comparator() { 52 | 53 | @Override 54 | public int compare(ThreadBean o1, ThreadBean o2) { 55 | long score1 = 100 * o1.getCpuTime() + 50 * o1.getBlockedTime(); 56 | long score2 = 100 * o2.getCpuTime() + 50 * o2.getBlockedTime(); 57 | 58 | if (score1 >= score2) { 59 | return -1; 60 | } else { 61 | return 1; 62 | } 63 | } 64 | }); 65 | } catch (Exception e) { 66 | e.printStackTrace(); 67 | } 68 | 69 | return threadList; 70 | } 71 | 72 | public static void main(String[] args) throws InterruptedException { 73 | ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); 74 | Map threadInfos = new HashMap<>(); 75 | for (long id : threadMXBean.getAllThreadIds()) { 76 | long cpuTime = threadMXBean.getThreadCpuTime(id); 77 | ThreadInfo info = threadMXBean.getThreadInfo(id); 78 | threadInfos.put(id, new ThreadBean(cpuTime, info)); 79 | } 80 | System.out.println(threadInfos); 81 | Thread.sleep(1000l); 82 | for (long id : threadMXBean.getAllThreadIds()) { 83 | long cpuTime = threadMXBean.getThreadCpuTime(id); 84 | ThreadInfo info = threadMXBean.getThreadInfo(id); 85 | threadInfos.get(id).setDelta(cpuTime, info); 86 | } 87 | System.out.println("dd:" + threadInfos); 88 | 89 | List threadList = new ArrayList<>(threadInfos.values()); 90 | Collections.sort(threadList, new Comparator() { 91 | 92 | @Override 93 | public int compare(ThreadBean o1, ThreadBean o2) { 94 | long score1 = 100 * o1.getCpuTime() + 50 * o1.getBlockedTime(); 95 | long score2 = 100 * o2.getCpuTime() + 50 * o2.getBlockedTime(); 96 | 97 | if (score1 >= score2) { 98 | return -1; 99 | } else { 100 | return 1; 101 | } 102 | } 103 | }); 104 | 105 | for (ThreadBean b : threadList) { 106 | System.out.println(b.getInfo().getThreadName() + ":" + b.getCpuTime() + ":" + b.getBlockedTime() + ":" 107 | + b.getWaitedTime()); 108 | 109 | } 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/metric/CounterMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor.metric; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | import java.util.concurrent.atomic.AtomicLong; 9 | 10 | import com.dtstack.catcher.common.bean.MetricFamily; 11 | 12 | public class CounterMonitor { 13 | 14 | private static Map> cache = new ConcurrentHashMap<>(); 15 | private static Map>> counterPool = new ConcurrentHashMap<>(); 16 | 17 | public static List getListFormat(String source) { 18 | if (source == null) { 19 | source = ""; 20 | } 21 | 22 | if (!cache.containsKey(source)) { 23 | List target = Arrays.asList(source.split(",")); 24 | 25 | cache.put(source, target); 26 | } 27 | 28 | return cache.get(source); 29 | } 30 | 31 | public static List getAllMetricFamily() { 32 | List list = new ArrayList<>(); 33 | for (Map.Entry>> entry : counterPool.entrySet()) { 34 | if (entry.getValue() == null) { 35 | continue; 36 | } 37 | 38 | list.add(getMetricFamily(entry.getKey())); 39 | } 40 | 41 | return list; 42 | } 43 | 44 | public static MetricFamily getMetricFamily(String name) { 45 | MetricFamily counter = new MetricFamily.Counter(name, ""); 46 | 47 | Map> values = counterPool.get(name); 48 | if (values == null) { 49 | return counter; 50 | } 51 | 52 | for (Map.Entry> labelNameEntry : values.entrySet()) { 53 | String labelName = labelNameEntry.getKey(); 54 | if (labelNameEntry.getValue() == null) { 55 | continue; 56 | } 57 | 58 | for (Map.Entry labelValueEntry : labelNameEntry.getValue().entrySet()) { 59 | String labelValue = labelValueEntry.getKey(); 60 | 61 | List labelNameList = getListFormat(labelName); 62 | List labelValueList = getListFormat(labelValue); 63 | 64 | counter.addMetric(name, labelNameList, labelValueList, 65 | String.valueOf(labelValueEntry.getValue().get())); 66 | } 67 | } 68 | return counter; 69 | } 70 | 71 | public static void increase(String name, String labelNames, String labelValues) { 72 | increase(name, labelNames, labelValues, 1); 73 | } 74 | 75 | public static void increase(String name) { 76 | increase(name, "", ""); 77 | } 78 | 79 | public static void increase(String name, long delta) { 80 | increase(name, "", "", delta); 81 | } 82 | 83 | public static void increase(String name, String labelNames, String labelValues, long delta) { 84 | try { 85 | if (!counterPool.containsKey(name)) { 86 | synchronized (CounterMonitor.class) { 87 | if (!counterPool.containsKey(name)) { 88 | counterPool.put(name, new ConcurrentHashMap>()); 89 | } 90 | } 91 | } 92 | 93 | if (!counterPool.get(name).containsKey(labelNames)) { 94 | synchronized (CounterMonitor.class) { 95 | if (!counterPool.get(name).containsKey(labelNames)) { 96 | counterPool.get(name).put(labelNames, new ConcurrentHashMap()); 97 | } 98 | } 99 | } 100 | 101 | if (!counterPool.get(name).get(labelNames).containsKey(labelValues)) { 102 | synchronized (CounterMonitor.class) { 103 | if (!counterPool.get(name).get(labelNames).containsKey(labelValues)) { 104 | counterPool.get(name).get(labelNames).put(labelValues, new AtomicLong(0)); 105 | } 106 | } 107 | } 108 | 109 | counterPool.get(name).get(labelNames).get(labelValues).addAndGet(delta); 110 | } catch (Exception e) { 111 | System.out.println("input=" + name+labelNames+labelValues+delta + " counterPool=" + counterPool); 112 | e.printStackTrace(); 113 | } 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/common/bean/ThreadBean.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.common.bean; 2 | 3 | import java.lang.management.LockInfo; 4 | import java.lang.management.MonitorInfo; 5 | import java.lang.management.ThreadInfo; 6 | 7 | import lombok.Data; 8 | 9 | @Data 10 | public class ThreadBean { 11 | private long cpuTime; 12 | private long blockedTime; 13 | private long waitedTime; 14 | private ThreadInfo info; 15 | 16 | private boolean hasDelta = false; 17 | 18 | public ThreadBean(long cpuTime, ThreadInfo info) { 19 | this.cpuTime = cpuTime; 20 | this.blockedTime = info.getBlockedTime(); 21 | this.waitedTime = info.getWaitedTime(); 22 | this.info = info; 23 | } 24 | 25 | public void setDelta(long cpuTime, ThreadInfo info) { 26 | if(hasDelta == true) { 27 | return; 28 | } 29 | 30 | this.cpuTime = cpuTime - this.cpuTime; 31 | this.blockedTime = info.getBlockedTime() - this.blockedTime; 32 | this.waitedTime = info.getWaitedTime() - this.waitedTime; 33 | this.info = info; 34 | this.hasDelta = true; 35 | } 36 | 37 | public String format() { 38 | return getInfo().getThreadName() + "\n- usage:" + getCpuTime() + "ms blocked:" + getBlockedTime() + "ms waited:" 39 | + getWaitedTime() + "ms\n- " + info; 40 | } 41 | 42 | public String string(ThreadInfo info) { 43 | StringBuilder sb = new StringBuilder("\"" + info.getThreadName() + "\"" + 44 | " Id=" + info.getThreadId() + " " + 45 | info.getThreadState()); 46 | if (info.getLockName() != null) { 47 | sb.append(" on " + info.getLockName()); 48 | } 49 | if (info.getLockOwnerName() != null) { 50 | sb.append(" owned by \"" + info.getLockOwnerName() + 51 | "\" Id=" + info.getLockOwnerId()); 52 | } 53 | if (info.isSuspended()) { 54 | sb.append(" (suspended)"); 55 | } 56 | if (info.isInNative()) { 57 | sb.append(" (in native)"); 58 | } 59 | sb.append('\n'); 60 | int i = 0; 61 | 62 | for (; i < info.getStackTrace().length && i < 8; i++) { 63 | StackTraceElement ste = info.getStackTrace()[i]; 64 | sb.append("\tat " + ste.toString()); 65 | sb.append('\n'); 66 | if (i == 0 && info.getLockInfo() != null) { 67 | Thread.State ts = info.getThreadState(); 68 | switch (ts) { 69 | case BLOCKED: 70 | sb.append("\t- blocked on " + info.getLockInfo()); 71 | sb.append('\n'); 72 | break; 73 | case WAITING: 74 | sb.append("\t- waiting on " + info.getLockInfo()); 75 | sb.append('\n'); 76 | break; 77 | case TIMED_WAITING: 78 | sb.append("\t- waiting on " + info.getLockInfo()); 79 | sb.append('\n'); 80 | break; 81 | default: 82 | } 83 | } 84 | 85 | for (MonitorInfo mi : info.getLockedMonitors()) { 86 | if (mi.getLockedStackDepth() == i) { 87 | sb.append("\t- locked " + mi); 88 | sb.append('\n'); 89 | } 90 | } 91 | } 92 | if (i < info.getStackTrace().length) { 93 | sb.append("\t..."); 94 | sb.append('\n'); 95 | } 96 | 97 | LockInfo[] locks = info.getLockedSynchronizers(); 98 | if (locks.length > 0) { 99 | sb.append("\n\tNumber of locked synchronizers = " + locks.length); 100 | sb.append('\n'); 101 | for (LockInfo li : locks) { 102 | sb.append("\t- " + li); 103 | sb.append('\n'); 104 | } 105 | } 106 | sb.append('\n'); 107 | return sb.toString(); 108 | } 109 | 110 | 111 | } -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/OsMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor; 2 | 3 | import java.io.IOException; 4 | import java.lang.management.ManagementFactory; 5 | import java.lang.management.OperatingSystemMXBean; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | import java.nio.file.Files; 9 | import java.nio.file.Path; 10 | import java.util.List; 11 | 12 | import com.dtstack.catcher.common.utils.PathUtils; 13 | import com.dtstack.catcher.common.utils.constants.SystemProperty; 14 | 15 | public class OsMonitor { 16 | 17 | private static final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean(); 18 | 19 | private static final Method getFreePhysicalMemorySize; 20 | private static final Method getTotalPhysicalMemorySize; 21 | private static final Method getFreeSwapSpaceSize; 22 | private static final Method getTotalSwapSpaceSize; 23 | private static final Method getSystemLoadAverage; 24 | private static final Method getSystemCpuLoad; 25 | 26 | static { 27 | getFreePhysicalMemorySize = getMethod("getFreePhysicalMemorySize"); 28 | getTotalPhysicalMemorySize = getMethod("getTotalPhysicalMemorySize"); 29 | getFreeSwapSpaceSize = getMethod("getFreeSwapSpaceSize"); 30 | getTotalSwapSpaceSize = getMethod("getTotalSwapSpaceSize"); 31 | getSystemLoadAverage = getMethod("getSystemLoadAverage"); 32 | getSystemCpuLoad = getMethod("getSystemCpuLoad"); 33 | } 34 | 35 | public static long getFreePhysicalMemorySize() { 36 | if (getFreePhysicalMemorySize == null) { 37 | return -1; 38 | } 39 | try { 40 | return (long) getFreePhysicalMemorySize.invoke(osMxBean); 41 | } catch (Exception e) { 42 | return -1; 43 | } 44 | } 45 | 46 | public static long getFreeSwapSpaceSize() { 47 | if (getFreeSwapSpaceSize == null) { 48 | return -1; 49 | } 50 | try { 51 | return (long) getFreeSwapSpaceSize.invoke(osMxBean); 52 | } catch (Exception e) { 53 | return -1; 54 | } 55 | } 56 | 57 | public static long getTotalSwapSpaceSize() { 58 | if (getTotalSwapSpaceSize == null) { 59 | return -1; 60 | } 61 | try { 62 | return (long) getTotalSwapSpaceSize.invoke(osMxBean); 63 | } catch (Exception e) { 64 | return -1; 65 | } 66 | } 67 | 68 | final static double[] getSystemLoadAverage() { 69 | if (SystemProperty.WINDOWS) { 70 | return null; 71 | } else if (SystemProperty.LINUX) { 72 | try { 73 | final String procLoadAvg = readProcLoadavg(); 74 | assert procLoadAvg.matches("(\\d+\\.\\d+\\s+){3}\\d+/\\d+\\s+\\d+"); 75 | final String[] fields = procLoadAvg.split("\\s+"); 76 | return new double[]{Double.parseDouble(fields[0]), Double.parseDouble(fields[1]), Double.parseDouble(fields[2])}; 77 | } catch (final IOException e) { 78 | 79 | return null; 80 | } 81 | } else { 82 | if (getSystemLoadAverage == null) { 83 | return null; 84 | } 85 | try { 86 | final double oneMinuteLoadAverage = (double) getSystemLoadAverage.invoke(osMxBean); 87 | return new double[]{oneMinuteLoadAverage >= 0 ? oneMinuteLoadAverage : -1, -1, -1}; 88 | } catch (IllegalAccessException | InvocationTargetException e) { 89 | return null; 90 | } 91 | } 92 | } 93 | 94 | 95 | 96 | public static long getTotalPhysicalMemorySize() { 97 | if (getTotalPhysicalMemorySize == null) { 98 | return -1; 99 | } 100 | try { 101 | return (long) getTotalPhysicalMemorySize.invoke(osMxBean); 102 | } catch (Exception e) { 103 | return -1; 104 | } 105 | } 106 | 107 | 108 | private static Method getMethod(String methodName) { 109 | try { 110 | return Class.forName("com.sun.management.OperatingSystemMXBean").getMethod(methodName); 111 | } catch (Exception e) { 112 | // not available 113 | return null; 114 | } 115 | } 116 | 117 | public static String readProcLoadavg() throws IOException { 118 | 119 | return readSingleLine(PathUtils.get("/proc/loadavg")); 120 | } 121 | 122 | private static String readSingleLine(final Path path) throws IOException { 123 | final List lines = Files.readAllLines(path); 124 | assert lines != null && lines.size() == 1; 125 | return lines.get(0); 126 | } 127 | 128 | public static short getSystemCpuPercent() { 129 | return getLoadAndScaleToPercent(getSystemCpuLoad, osMxBean); 130 | } 131 | 132 | private static short getLoadAndScaleToPercent(Method method, OperatingSystemMXBean osMxBean) { 133 | if (method != null) { 134 | try { 135 | double load = (double) method.invoke(osMxBean); 136 | if (load >= 0) { 137 | return (short) (load * 100); 138 | } 139 | } catch (Exception e) { 140 | return -1; 141 | } 142 | } 143 | return -1; 144 | } 145 | 146 | public static void main(String[] args) { 147 | System.out.println(OsMonitor.getFreePhysicalMemorySize()); 148 | System.out.println(OsMonitor.getTotalPhysicalMemorySize()); 149 | System.out.println(OsMonitor.getFreeSwapSpaceSize()); 150 | System.out.println(OsMonitor.getTotalSwapSpaceSize()); 151 | System.out.println(OsMonitor.getSystemCpuPercent()); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/MemMonitor.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor; 2 | 3 | import java.lang.management.ManagementFactory; 4 | import java.lang.management.MemoryMXBean; 5 | import java.lang.management.MemoryPoolMXBean; 6 | import java.lang.management.MemoryUsage; 7 | import java.nio.ByteBuffer; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import com.dtstack.catcher.info.Memory; 11 | 12 | public class MemMonitor { 13 | 14 | private static MemoryPoolMXBean metaSpaceMxBean = null; 15 | private static MemoryPoolMXBean oldGenMxBean = null; 16 | private static MemoryPoolMXBean edenSpaceMxBean = null; 17 | private static MemoryPoolMXBean pSSurvivorSpaceMxBean = null; 18 | private static MemoryPoolMXBean codeCache = null; 19 | private static MemoryPoolMXBean compressedClassSpace = null; 20 | 21 | private static MemoryMXBean memoryMXBean = null; 22 | 23 | static { 24 | try { 25 | init(); 26 | } catch (Exception e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | 31 | public static void init() { 32 | 33 | memoryMXBean = ManagementFactory.getMemoryMXBean(); 34 | 35 | List list = ManagementFactory.getMemoryPoolMXBeans(); 36 | for (MemoryPoolMXBean item : list) { 37 | if ("CMS Perm Gen".equals(item.getName()) || "Perm Gen".equals(item.getName()) 38 | || "PS Perm Gen".equals(item.getName()) || "G1 Perm Gen".equals(item.getName()) 39 | || "Metaspace".equals(item.getName())) { 40 | metaSpaceMxBean = item; 41 | } else if ("CMS Old Gen".equals(item.getName()) || "Tenured Gen".equals(item.getName()) 42 | || "PS Old Gen".equals(item.getName()) || "G1 Old Gen".equals(item.getName())) { 43 | oldGenMxBean = item; 44 | } else if ("Par Eden Space".equals(item.getName()) || "Eden Space".equals(item.getName()) 45 | || "PS Eden Space".equals(item.getName()) || "G1 Eden Space".equals(item.getName())) { 46 | edenSpaceMxBean = item; 47 | } else if ("Par Survivor Space".equals(item.getName()) || "Survivor Space".equals(item.getName()) 48 | || "PS Survivor Space".equals(item.getName()) || "G1 Survivor Space".equals(item.getName())) { 49 | pSSurvivorSpaceMxBean = item; 50 | } else if ("Code Cache".equals(item.getName())) { 51 | codeCache = item; 52 | } else if ("Compressed Class Space".equals(item.getName())) { 53 | compressedClassSpace = item; 54 | } 55 | } 56 | } 57 | 58 | public static Memory get() { 59 | Memory memory = new Memory(); 60 | 61 | try { 62 | 63 | MemoryUsage heapMemUsage = memoryMXBean.getHeapMemoryUsage(); 64 | memory.getHeap().setCommitted(heapMemUsage.getCommitted()); 65 | memory.getHeap().setUsed(heapMemUsage.getUsed()); 66 | memory.getHeap().setMax(heapMemUsage.getMax()); 67 | memory.getHeap().setInit(heapMemUsage.getInit()); 68 | 69 | MemoryUsage nonHeapMemUsage = memoryMXBean.getNonHeapMemoryUsage(); 70 | memory.getNonHeap().setCommitted(nonHeapMemUsage.getCommitted()); 71 | memory.getNonHeap().setInit(nonHeapMemUsage.getInit()); 72 | memory.getNonHeap().setUsed(nonHeapMemUsage.getUsed()); 73 | memory.getNonHeap().setMax(nonHeapMemUsage.getMax()); 74 | 75 | try { 76 | Class vmClass = Class.forName("sun.misc.VM"); 77 | long directMemoryMax = (Long) vmClass.getMethod("maxDirectMemory").invoke(null); 78 | memory.getDirect().setMax(directMemoryMax); 79 | 80 | // 仅仅统计到ByteBuffer.allocateDirect()方式分配的内存 81 | long directUsed = sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getMemoryUsed(); 82 | memory.getDirect().setUsed(directUsed); 83 | // Class vmClass = Class.forName("sun.misc.VM"); 84 | } catch (Exception t) { 85 | t.printStackTrace(); 86 | } 87 | 88 | if(edenSpaceMxBean != null) { 89 | memory.getHeapEdenSpace().setCommitted(edenSpaceMxBean.getUsage().getCommitted()); 90 | memory.getHeapEdenSpace().setInit(edenSpaceMxBean.getUsage().getInit()); 91 | memory.getHeapEdenSpace().setUsed(edenSpaceMxBean.getUsage().getUsed()); 92 | memory.getHeapEdenSpace().setMax(edenSpaceMxBean.getUsage().getMax()); 93 | } 94 | 95 | if(oldGenMxBean != null) { 96 | memory.getHeapOldGen().setCommitted(oldGenMxBean.getUsage().getCommitted()); 97 | memory.getHeapOldGen().setInit(oldGenMxBean.getUsage().getInit()); 98 | memory.getHeapOldGen().setUsed(oldGenMxBean.getUsage().getUsed()); 99 | memory.getHeapOldGen().setMax(oldGenMxBean.getUsage().getMax()); 100 | } 101 | 102 | if(metaSpaceMxBean != null) { 103 | memory.getMetaspace().setCommitted(metaSpaceMxBean.getUsage().getCommitted()); 104 | memory.getMetaspace().setInit(metaSpaceMxBean.getUsage().getInit()); 105 | memory.getMetaspace().setMax(metaSpaceMxBean.getUsage().getMax()); 106 | memory.getMetaspace().setUsed(metaSpaceMxBean.getUsage().getUsed()); 107 | } 108 | 109 | if(pSSurvivorSpaceMxBean != null) { 110 | memory.getHeapSurvivorSpace().setCommitted(pSSurvivorSpaceMxBean.getUsage().getCommitted()); 111 | memory.getHeapSurvivorSpace().setInit(pSSurvivorSpaceMxBean.getUsage().getInit()); 112 | memory.getHeapSurvivorSpace().setMax(pSSurvivorSpaceMxBean.getUsage().getMax()); 113 | memory.getHeapSurvivorSpace().setUsed(pSSurvivorSpaceMxBean.getUsage().getUsed()); 114 | } 115 | 116 | if(codeCache != null) { 117 | memory.getCodeCache().setCommitted(codeCache.getUsage().getCommitted()); 118 | memory.getCodeCache().setInit(codeCache.getUsage().getInit()); 119 | memory.getCodeCache().setMax(codeCache.getUsage().getMax()); 120 | memory.getCodeCache().setUsed(codeCache.getUsage().getUsed()); 121 | } 122 | 123 | if(compressedClassSpace != null) { 124 | memory.getCompressedClassSpace().setCommitted(compressedClassSpace.getUsage().getCommitted()); 125 | memory.getCompressedClassSpace().setInit(compressedClassSpace.getUsage().getInit()); 126 | memory.getCompressedClassSpace().setMax(compressedClassSpace.getUsage().getMax()); 127 | memory.getCompressedClassSpace().setUsed(compressedClassSpace.getUsage().getUsed()); 128 | } 129 | 130 | } catch (Exception e) { 131 | e.printStackTrace(); 132 | } 133 | 134 | return memory; 135 | } 136 | 137 | public static void main(String[] args) { 138 | 139 | Memory fmem = MemMonitor.get(); 140 | ByteBuffer b = ByteBuffer.allocateDirect(1000); 141 | List l = new ArrayList(); 142 | for (int i = 0; i < 10000; i++) { 143 | // l.add("333"+ System.currentTimeMillis()); 144 | } 145 | Memory smem = MemMonitor.get(); 146 | System.out.println(smem.getDirect().getUsed()); 147 | System.out.println(smem.getHeap().getUsed() - fmem.getHeap().getUsed()); 148 | 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/com/dtstack/catcher/monitor/service/MertricService.java: -------------------------------------------------------------------------------- 1 | package com.dtstack.catcher.monitor.service; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.dtstack.catcher.common.bean.MetricFamily; 7 | import com.dtstack.catcher.info.GC; 8 | import com.dtstack.catcher.info.Memory; 9 | import com.dtstack.catcher.monitor.GCMonitor; 10 | import com.dtstack.catcher.monitor.MemMonitor; 11 | import com.dtstack.catcher.monitor.ProcessMonitor; 12 | import com.dtstack.catcher.monitor.metric.CounterMonitor; 13 | import com.dtstack.catcher.monitor.metric.GaugeMonitor; 14 | import com.google.common.collect.Lists; 15 | 16 | public class MertricService { 17 | 18 | private List metricFamily = new ArrayList<>(); 19 | 20 | public List collect() { 21 | 22 | metricFamily.clear(); 23 | 24 | metricFamily.add(getGCMetricFamily()); 25 | metricFamily.add(getMemoryMetricFamily()); 26 | metricFamily.addAll(getProcessMetricFamily()); 27 | 28 | List gaugeList = getGaugeMetricFamily(); 29 | if(gaugeList.size() > 0) { 30 | metricFamily.addAll(gaugeList); 31 | } 32 | 33 | List counterList = getCounterMetricFamily(); 34 | if(counterList.size() > 0) { 35 | metricFamily.addAll(counterList); 36 | } 37 | 38 | 39 | return metricFamily; 40 | } 41 | 42 | public List getProcessMetricFamily() { 43 | List list = new ArrayList<>(); 44 | 45 | MetricFamily fdMetricFamily = new MetricFamily.Gauge("process_fd", "process fd"); 46 | fdMetricFamily.addMetric("process_fd", Lists.newArrayList("stat"), Lists.newArrayList("max"), String.valueOf(ProcessMonitor.getMaxFileDescriptorCount())); 47 | fdMetricFamily.addMetric("process_fd", Lists.newArrayList("stat"), Lists.newArrayList("used"), String.valueOf(ProcessMonitor.getOpenFileDescriptorCount())); 48 | 49 | MetricFamily cpuPercentMetricFamily = new MetricFamily.Gauge("process_cpu_percent", "process cpu percent"); 50 | cpuPercentMetricFamily.addMetric("process_cpu_percent", String.valueOf(ProcessMonitor.getProcessCpuPercent())); 51 | 52 | MetricFamily cpuTimeMetricFamily = new MetricFamily.Counter("process_cpu_time", "process cpu time"); 53 | cpuTimeMetricFamily.addMetric("process_cpu_time", String.valueOf(ProcessMonitor.getProcessCpuTotalTime())); 54 | 55 | list.add(cpuTimeMetricFamily); 56 | list.add(cpuPercentMetricFamily); 57 | list.add(fdMetricFamily); 58 | 59 | return list; 60 | } 61 | 62 | public List getGaugeMetricFamily() { 63 | return GaugeMonitor.getAllMetricFamily(); 64 | } 65 | 66 | public List getCounterMetricFamily() { 67 | return CounterMonitor.getAllMetricFamily(); 68 | } 69 | 70 | public MetricFamily getGCMetricFamily() { 71 | MetricFamily metricFamily = new MetricFamily.Counter("jvm_gc", "jvm gc"); 72 | GC gc = GCMonitor.get(); 73 | 74 | metricFamily.addMetric("jvm_gc", Lists.newArrayList("type","stat"), Lists.newArrayList("full","time"), String.valueOf(gc.getFull().getTime())); 75 | metricFamily.addMetric("jvm_gc", Lists.newArrayList("type","stat"), Lists.newArrayList("full","count"), String.valueOf(gc.getFull().getCount())); 76 | metricFamily.addMetric("jvm_gc", Lists.newArrayList("type","stat"), Lists.newArrayList("young","time"), String.valueOf(gc.getYoung().getTime())); 77 | metricFamily.addMetric("jvm_gc", Lists.newArrayList("type","stat"), Lists.newArrayList("young","count"), String.valueOf(gc.getYoung().getCount())); 78 | 79 | return metricFamily; 80 | } 81 | 82 | public MetricFamily getMemoryMetricFamily() { 83 | MetricFamily metricFamily = new MetricFamily.Gauge("jvm_memory", "jvm memory"); 84 | Memory mem = MemMonitor.get(); 85 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heap","init"), String.valueOf(mem.getHeap().getInit())); 86 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heap","commited"), String.valueOf(mem.getHeap().getCommitted())); 87 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heap","max"), String.valueOf(mem.getHeap().getMax())); 88 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heap","used"), String.valueOf(mem.getHeap().getUsed())); 89 | 90 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("nonheap","init"), String.valueOf(mem.getNonHeap().getInit())); 91 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("nonheap","commited"), String.valueOf(mem.getNonHeap().getCommitted())); 92 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("nonheap","max"), String.valueOf(mem.getNonHeap().getMax())); 93 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("nonheap","used"), String.valueOf(mem.getNonHeap().getUsed())); 94 | 95 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("codecache","init"), String.valueOf(mem.getCodeCache().getInit())); 96 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("codecache","commited"), String.valueOf(mem.getCodeCache().getCommitted())); 97 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("codecache","max"), String.valueOf(mem.getCodeCache().getMax())); 98 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("codecache","used"), String.valueOf(mem.getCodeCache().getUsed())); 99 | 100 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("compressedclassspace","init"), String.valueOf(mem.getCompressedClassSpace().getInit())); 101 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("compressedclassspace","commited"), String.valueOf(mem.getCompressedClassSpace().getCommitted())); 102 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("compressedclassspace","max"), String.valueOf(mem.getCompressedClassSpace().getMax())); 103 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("compressedclassspace","used"), String.valueOf(mem.getCompressedClassSpace().getUsed())); 104 | 105 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapedenspace","init"), String.valueOf(mem.getHeapEdenSpace().getInit())); 106 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapedenspace","commited"), String.valueOf(mem.getHeapEdenSpace().getCommitted())); 107 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapedenspace","max"), String.valueOf(mem.getHeapEdenSpace().getMax())); 108 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapedenspace","used"), String.valueOf(mem.getHeapEdenSpace().getUsed())); 109 | 110 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapoldgen","init"), String.valueOf(mem.getHeapOldGen().getInit())); 111 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapoldgen","commited"), String.valueOf(mem.getHeapOldGen().getCommitted())); 112 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapoldgen","max"), String.valueOf(mem.getHeapOldGen().getMax())); 113 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapoldgen","used"), String.valueOf(mem.getHeapOldGen().getUsed())); 114 | 115 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapsurvivorspace","init"), String.valueOf(mem.getHeapSurvivorSpace().getInit())); 116 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapsurvivorspace","commited"), String.valueOf(mem.getHeapSurvivorSpace().getCommitted())); 117 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapsurvivorspace","max"), String.valueOf(mem.getHeapSurvivorSpace().getMax())); 118 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("heapsurvivorspace","used"), String.valueOf(mem.getHeapSurvivorSpace().getUsed())); 119 | 120 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("metaspace","init"), String.valueOf(mem.getMetaspace().getInit())); 121 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("metaspace","commited"), String.valueOf(mem.getMetaspace().getCommitted())); 122 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("metaspace","max"), String.valueOf(mem.getMetaspace().getMax())); 123 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("metaspace","used"), String.valueOf(mem.getMetaspace().getUsed())); 124 | 125 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("direct","max"), String.valueOf(mem.getDirect().getMax())); 126 | metricFamily.addMetric("jvm_memory", Lists.newArrayList("type","stat"), Lists.newArrayList("direct","used"), String.valueOf(mem.getDirect().getUsed())); 127 | 128 | return metricFamily; 129 | } 130 | 131 | 132 | 133 | } 134 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | --------------------------------------------------------------------------------