SpringBoot自主监控,获取服务信息、JVM、CPU、内存、磁盘、堆、线程、GC等

这篇具有很好参考价值的文章主要介绍了SpringBoot自主监控,获取服务信息、JVM、CPU、内存、磁盘、堆、线程、GC等。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 简介

  在日常开发中一些关键的业务服务,期望在高并发状态下可以正常工作,或在异常情况时可以记录当时的性能信息,所以就需要进行监控。常见的监控例如:Prometheus可以实现这个需求,如果需要更加简单方便的自主监控能力,可以引入本博客中的方案。

2. 相关博客

  Promtail+Loki+Grafana搭建轻量级日志管理平台SpringBoot 2.x + Prometheus + Grafana 实现应用监控

3. 示例代码

  • 创建项目springboot监控jvm,jvm,spring boot,java,mybatis,spring
  • 修改pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.c3stones</groupId>
    <artifactId>spring-boot-monitor-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.8.12</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.24</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 配置定时巡检预警阈值
      在resources下新建配置文件application.yml。
# 预警配置
monitor:
  warn:
    enabled: true
    cpu:
      stage1: 85
      stage2: 95
    memory:
      stage1: 85
      stage2: 95
    disk:
      stage1: 85
      stage2: 95
  • 创建预警配置
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 预警配置
 *
 * @author  CL
 */
@Getter
@Component
public class WarnConfig {

    /**
     * 预警开关
     */
    @Value("${monitor.warn.enabled:true}")
    private Boolean enabled;

    /**
     * CPU - 阶段1
     */
    @Value("${monitor.warn.cpu.stage1:85}")
    private Double cpuStage1;

    /**
     * CPU - 阶段2
     */
    @Value("${monitor.warn.cpu.stage2:95}")
    private Double cpuStage2;

    /**
     * 内存 - 阶段1
     */
    @Value("${monitor.warn.memory.stage1:85}")
    private Double memoryStage1;

    /**
     * 内存 - 阶段2
     */
    @Value("${monitor.warn.memory.stage2:95}")
    private Double memoryStage2;

    /**
     * 磁盘 - 阶段1
     */
    @Value("${monitor.warn.disk.stage1:85}")
    private Double diskStage1;

    /**
     * 磁盘 - 阶段2
     */
    @Value("${monitor.warn.disk.stage2:95}")
    private Double diskStage2;

}
  • 创建预警状态枚举
import cn.hutool.core.util.NumberUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Objects;

/**
 * 预警状态枚举类
 *
 * @author  CL
 */
@Getter
@AllArgsConstructor
public enum WarnSateEnum {

    /**
     * 正常
     */
    GREEN(1),

    /**
     * 警告
     */
    YELLOW(2),

    /**
     * 紧急
     */
    RED(3),
    ;

    private final int value;

    /**
     * 根据值获取枚举
     *
     * @param value 值
     * @return {@link WarnSateEnum}
     */
    public static WarnSateEnum findByValue(Integer value) {
        if (Objects.nonNull(value)) {
            for (WarnSateEnum warnState : values()) {
                if (NumberUtil.equals(warnState.getValue(), value)) {
                    return warnState;
                }
            }
        }
        return GREEN;
    }

    /**
     * 获取高优先级
     *
     * @param warnSateEnum 预警状态
     * @return
     */
    public WarnSateEnum max(WarnSateEnum warnSateEnum) {
        if (Objects.nonNull(warnSateEnum)) {
            return findByValue(Math.max(this.value, warnSateEnum.value));
        }
        return this;
    }

}
  • 创建字节转文本工具类
/**
 * 字节转换工具类
 *
 * @author CL
 */
public class ByteUtil {

    private static final int UNIT = 1024;

    /**
     * 格式化字节大小
     *
     * @param byteSize 字节大小
     * @return {@link String}
     */
    public static String formatByteSize(long byteSize) {

        if (byteSize <= -1) {
            return String.valueOf(byteSize);
        }

        double size = 1.0 * byteSize;

        String type;
        if ((int) Math.floor(size / UNIT) <= 0) { // 不足1KB
            type = "B";
            return format(size, type);
        }

        size = size / UNIT;
        if ((int) Math.floor(size / UNIT) <= 0) { // 不足1MB
            type = "KB";
            return format(size, type);
        }

        size = size / UNIT;
        if ((int) Math.floor(size / UNIT) <= 0) { // 不足1GB
            type = "MB";
            return format(size, type);
        }

        size = size / UNIT;
        if ((int) Math.floor(size / UNIT) <= 0) { // 不足1TB
            type = "GB";
            return format(size, type);
        }

        size = size / UNIT;
        if ((int) Math.floor(size / UNIT) <= 0) { // 不足1PB
            type = "TB";
            return format(size, type);
        }

        size = size / UNIT;
        if ((int) Math.floor(size / UNIT) <= 0) {
            type = "PB";
            return format(size, type);
        }
        return ">PB";
    }

    /**
     * 格式化字节大小为指定单位
     *
     * @param size 字节大小
     * @param type 单位类型
     * @return {@link String}
     */
    private static String format(double size, String type) {
        int precision;

        if (size * 100 % 10 > 0) {
            precision = 2;
        } else if (size * 10 % 10 > 0) {
            precision = 1;
        } else {
            precision = 0;
        }

        String formatStr = "%." + precision + "f";

        if ("KB".equals(type)) {
            return String.format(formatStr, (size)) + "KB";
        } else if ("MB".equals(type)) {
            return String.format(formatStr, (size)) + "MB";
        } else if ("GB".equals(type)) {
            return String.format(formatStr, (size)) + "GB";
        } else if ("TB".equals(type)) {
            return String.format(formatStr, (size)) + "TB";
        } else if ("PB".equals(type)) {
            return String.format(formatStr, (size)) + "PB";
        }
        return String.format(formatStr, (size)) + "B";
    }

}
  • 创建打印格式类
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 打印布局
 *
 * @author CL
 */
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Layout {

    // 横线和竖线
    private final static String H_LINE = "-";
    private final static String V_LINE = "┊";

    /**
     * 大标题
     */
    private String headline;

    /**
     * 数据
     */
    private ArrayList<Object> objs;

    /**
     * 自定义构造方法
     *
     * @param headline 大标题
     * @param objs     数据
     */
    private Layout(String headline, Object... objs) {
        this.headline = headline;
        this.objs = CollUtil.toList(objs);
    }

    /**
     * 自定义静态构造方法
     *
     * @param headline 大标题
     * @param objs     数据
     * @return {@link Layout}
     */
    public static Layout of(String headline, Object... objs) {
        return new Layout(headline, objs);
    }

    /**
     * 重写toString方法
     *
     * @return {@link String}
     */
    @Override
    public String toString() {
        StringJoiner sj = new StringJoiner(StrUtil.LF);
        if (Objects.nonNull(headline)) {
            sj.add(headline + StrUtil.COLON);
            sj.add(StrUtil.EMPTY);
        }
        objs.forEach(obj -> sj.add(obj.toString()));
        sj.add(StrUtil.EMPTY);
        return sj.toString();
    }


    /**
     * 表格
     */
    @Getter
    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public static class Table {

        /**
         * 标题
         */
        private String title;

        /**
         * 行
         */
        private ArrayList<Row> rows;

        /**
         * 自定义构造方法
         *
         * @param title 标题
         * @param rows  行
         */
        private Table(String title, Row... rows) {
            this.title = title;
            this.rows = CollUtil.toList(rows);
        }

        /**
         * 自定义静态构造方法
         *
         * @param title 标题
         * @param rows  行
         * @return {@link Table}
         */
        public static Table of(String title, Row... rows) {
            return new Table(title, rows);
        }

        /**
         * 自定义静态构造方法
         *
         * @param rows 行
         * @return {@link Table}
         */
        public static Table of(Row... rows) {
            return new Table(null, rows);
        }

        /**
         * 重写ToString方法
         *
         * @return {@link String}
         */
        @Override
        public String toString() {
            int maxKeyLength = rows.stream().map(Row::getKey).map(StrUtil::length).max(Comparator.comparing(Integer::valueOf)).orElse(1) + 5;
            int maxValueLength = rows.stream().map(Row::getValues).flatMap(Collection::stream).map(StrUtil::toStringOrNull).map(StrUtil::length).max(Comparator.comparing(Integer::valueOf)).orElse(1) + 5;
            int totalLength = maxKeyLength + maxValueLength + 3;
            // 分割行
            String spit = StrUtil.SPACE + IntStream.range(0, totalLength).mapToObj(i -> H_LINE).collect(Collectors.joining()) + StrUtil.SPACE;
            StringJoiner sj = new StringJoiner(StrUtil.LF);
            if (Objects.nonNull(title)) {
                sj.add(spit);
                sj.add(V_LINE + StrUtil.padAfter(title, totalLength, StrUtil.SPACE) + V_LINE);
            }
            sj.add(spit);
            rows.forEach(row -> sj.add(row.toString(maxKeyLength, maxValueLength)));
            sj.add(spit);
            return sj.toString();
        }

    }

    /**
     * 行
     */
    @Getter
    @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
    public static class Row {

        /**
         * 键
         */
        private final String key;

        /**
         * 跨行
         */
        private final int rowspan;

        /**
         * 值
         */
        private final ArrayList<Object> values;

        /**
         * 自定义静态构造方法
         *
         * @param key   键
         * @param value 值
         * @return {@link Row}
         */
        public static Row of(String key, Object value) {
            return of(key, 1, value);
        }

        /**
         * 自定义静态构造方法
         *
         * @param key     键
         * @param rowspan 跨行
         * @param value   值
         * @return {@link Row}
         */
        public static Row of(String key, int rowspan, Object value) {
            return new Row(key, Math.max(rowspan, 1), value instanceof List ? new ArrayList<>(((List<?>) value)) : CollUtil.toList(value));
        }

        /**
         * 重写ToString方法
         *
         * @param maxKeyLength   最大的键长度
         * @param maxValueLength 最大的值长度
         * @return {@link String}
         */
        public String toString(int maxKeyLength, int maxValueLength) {
            StringJoiner sj = new StringJoiner(StrUtil.LF);
            IntStream.range(0, rowspan).forEach(i -> sj.add(
                    V_LINE + StrUtil.SPACE +
                            String.format("%-" + Math.max(maxKeyLength, 1) + "s", i == 0 ? key : StrUtil.SPACE) +
                            V_LINE + StrUtil.SPACE +
                            String.format("%-" + Math.max(maxValueLength, 1) + "s", values.get(i)) +
                            V_LINE));
            return sj.toString();
        }

    }

}
  • 创建监控信息BO
import com.c3stones.monitor.print.Layout;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 服务器信息
 *
 * @author CL
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Server {

    /**
     * 主机名
     */
    private String hostName;

    /**
     * 操作系统名称
     */
    private String osName;

    /**
     * 操作系统版本
     */
    private String osVersion;

    /**
     * 系统架构
     */
    private String arch;

    /**
     * 本地IP
     */
    private String localIp;

    @Override
    public String toString() {
        return Layout.Table.of(
                Layout.Row.of("HostName", hostName),
                Layout.Row.of("OS", osName + "/" + osVersion),
                Layout.Row.of("Arch", arch),
                Layout.Row.of("LocalIp", localIp)
        ).toString();
    }

}
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import com.c3stones.monitor.print.Layout;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;

import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;

/**
 * JVM信息
 *
 * @author CL
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Jvm {

    /**
     * 虚拟机名称
     */
    private String vmName;

    /**
     * JDK版本
     */
    private String jdkVersion;

    /**
     * JavaHome
     */
    private String javaHome;

    /**
     * 进程号
     */
    private String pid;

    /**
     * 启动时间
     */
    private LocalDateTime startTime;

    /**
     * 运行时长
     */
    private long runtime;

    /**
     * 启动餐参数
     */
    private List<String> startParameters;

    @Override
    public String toString() {
        return Layout.Table.of(
                Layout.Row.of("VM Name", vmName),
                Layout.Row.of("JDK Version", jdkVersion),
                Layout.Row.of("Java Home", javaHome),
                Layout.Row.of("PID", pid),
                Layout.Row.of("StartTime", NORM_DATETIME_FORMATTER.format(startTime)),
                Layout.Row.of("RunTime", DateUtil.formatBetween(runtime, BetweenFormatter.Level.SECOND)
                        .replaceAll(BetweenFormatter.Level.SECOND.getName(), "s")
                        .replaceAll(BetweenFormatter.Level.MINUTE.getName(), "m")
                        .replaceAll(BetweenFormatter.Level.HOUR.getName(), "h")
                        .replaceAll(BetweenFormatter.Level.DAY.getName(), "d")),
                Layout.Row.of("Start Parameters", startParameters.size(), startParameters)
        ).toString();
    }

}
import cn.hutool.core.util.NumberUtil;
import com.c3stones.monitor.print.Layout;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * CPU信息
 *
 * @author  CL
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Cpu {

    /**
     * 可用处理器数
     */
    private int availableProcssors;

    /**
     * 系统CPU使用率
     */
    private BigDecimal systemCpuUsage;

    /**
     * 当前进程CPU使用率
     */
    private BigDecimal processCpuUsage;

    @Override
    public String toString() {
        return Layout.Table.of(
                Layout.Row.of("Available Processors", availableProcssors),
                Layout.Row.of("System CPU Usage", NumberUtil.mul(systemCpuUsage, 100).setScale(2, RoundingMode.HALF_UP) + "%"),
                Layout.Row.of("Process CPU Usage", NumberUtil.mul(processCpuUsage, 100).setScale(2, RoundingMode.HALF_UP) + "%")
        ).toString();
    }

}
import cn.hutool.core.util.NumberUtil;
import com.c3stones.monitor.print.Layout;
import com.c3stones.monitor.utils.ByteUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 内存信息
 *
 * @author CL
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Memory {

    /**
     * 总物理内存
     */
    private long totalPhysicalMemory;

    /**
     * 空闲物理内存
     */
    private long freePhysicalMemory;

    /**
     * 已使用物理内存
     */
    private long usedPhysicalMemory;

    /**
     * 物理内存使用率
     */
    private BigDecimal physicalMemoryUsage;

    /**
     * 总内存
     */
    private long totalMemory;

    /**
     * 空闲内存
     */
    private long freeMemory;

    /**
     * 已用内存
     */
    private long usedMemory;

    /**
     * 最大内存
     */
    private long maxMemory;

    /**
     * 最大可用内存
     */
    private long maxUseMemory;

    /**
     * 内存使用率
     */
    private BigDecimal memoryUsage;

    @Override
    public String toString() {
        return Layout.Table.of(
                Layout.Row.of("Total Physical Memory", ByteUtil.formatByteSize(totalPhysicalMemory)),
                Layout.Row.of("Free Physical Memory", ByteUtil.formatByteSize(freePhysicalMemory)),
                Layout.Row.of("Used Physical Memory", ByteUtil.formatByteSize(usedPhysicalMemory)),
                Layout.Row.of("Physical Memory Usage", NumberUtil.mul(physicalMemoryUsage, 100).setScale(2, RoundingMode.HALF_UP) + "%"),
                Layout.Row.of("Total Memory", ByteUtil.formatByteSize(totalMemory)),
                Layout.Row.of("Free Memory", ByteUtil.formatByteSize(freeMemory)),
                Layout.Row.of("Used Memory", ByteUtil.formatByteSize(usedMemory)),
                Layout.Row.of("Max Memory", ByteUtil.formatByteSize(maxMemory)),
                Layout.Row.of("Max Use Memory", ByteUtil.formatByteSize(maxUseMemory)),
                Layout.Row.of("Memory Usage", NumberUtil.mul(memoryUsage, 100).setScale(2, RoundingMode.HALF_UP) + "%")
        ).toString();
    }

}
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.c3stones.monitor.print.Layout;
import com.c3stones.monitor.utils.ByteUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 磁盘信息
 *
 * @author CL
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Disk {

    /**
     * 盘符
     */
    private List<Drive> devices;

    @Override
    public String toString() {
        return Opt.ofNullable(devices).orElse(ListUtil.empty()).stream().map(Drive::toString).collect(Collectors.joining(StrUtil.LF));
    }

    /**
     * 盘符
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Drive {

        /**
         * 盘符名称
         */
        private String name;

        /**
         * 总大小
         */
        private long totalSpace;

        /**
         * 空闲大小
         */
        private long freeSpace;

        /**
         * 已用大小
         */
        private long usedSpace;

        /**
         * 盘符使用率
         */
        private BigDecimal driveUsage;

        @Override
        public String toString() {
            return Layout.Table.of(name,
                    Layout.Row.of("Total Space", ByteUtil.formatByteSize(totalSpace)),
                    Layout.Row.of("Free Space", ByteUtil.formatByteSize(freeSpace)),
                    Layout.Row.of("Used Space", ByteUtil.formatByteSize(usedSpace)),
                    Layout.Row.of("Drive Space", NumberUtil.mul(driveUsage, 100).setScale(2, RoundingMode.HALF_UP) + "%")
            ).toString();
        }
    }

}
import com.c3stones.monitor.print.Layout;
import com.c3stones.monitor.utils.ByteUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 堆/非堆信息
 *
 * @author CL
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Heap {

    /**
     * 堆初始化大小
     */
    private long heapInit;

    /**
     * 堆最大大小
     */
    private long heapMaxMemory;

    /**
     * 堆已用大小
     */
    private long heapUsedMemory;

    /**
     * 堆空闲大小
     */
    private long heapFreeMemory;

    /**
     * 非堆初始化大小
     */
    private long nonHeapInit;

    /**
     * 非堆最大大小
     */
    private long nonHeapMaxMemory;

    /**
     * 非堆已用大小
     */
    private long nonHeapUsedMemory;

    /**
     * 非堆空闲大小
     */
    private long nonHeapFreeMemory;

    @Override
    public String toString() {
        return Layout.Table.of(
                Layout.Row.of("Heap Init Size", ByteUtil.formatByteSize(heapInit)),
                Layout.Row.of("Heap Max Size", ByteUtil.formatByteSize(heapMaxMemory)),
                Layout.Row.of("Heap Used Size", ByteUtil.formatByteSize(heapUsedMemory)),
                Layout.Row.of("Heap Free Size", ByteUtil.formatByteSize(heapFreeMemory)),
                Layout.Row.of("NonHeap Init Size", ByteUtil.formatByteSize(nonHeapInit)),
                Layout.Row.of("NonHeap Max Size", ByteUtil.formatByteSize(nonHeapMaxMemory)),
                Layout.Row.of("NonHeap Used Size", ByteUtil.formatByteSize(nonHeapUsedMemory)),
                Layout.Row.of("NonHeap Free Size", ByteUtil.formatByteSize(nonHeapFreeMemory))
        ).toString();
    }

}
import com.c3stones.monitor.print.Layout;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 线程信息
 *
 * @author CL
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Thread {

    /**
     * 活动线程数
     */
    private int threadCount;

    /**
     * 峰值活动线程数
     */
    private int peakThreadCount;

    /**
     * 守护线程数
     */
    private int daemonThreadCount;

    /**
     * 非守护线程数
     */
    private int nonDaemonThreadCount;

    /**
     * 总线程数
     */
    private long totalStartedThreadCount;

    @Override
    public String toString() {
        return Layout.Table.of(
                Layout.Row.of("Active Thread Count", threadCount),
                Layout.Row.of("Active Peak Thread Count", peakThreadCount),
                Layout.Row.of("Daemon Thread Count", daemonThreadCount),
                Layout.Row.of("NonDaemon Thread Count", nonDaemonThreadCount),
                Layout.Row.of("Total Thread Count", totalStartedThreadCount)
        ).toString();
    }
    
}
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
import com.c3stones.monitor.print.Layout;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 垃圾回收信息
 *
 * @author CL
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Gc {

    /**
     * GC收集器
     */
    private List<GcCollector> collectors;

    @Override
    public String toString() {
        return Opt.ofNullable(collectors).orElse(ListUtil.empty()).stream().map(Gc.GcCollector::toString).collect(Collectors.joining(StrUtil.LF));
    }

    /**
     * GC收集器
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class GcCollector {

        /**
         * 收集器名称
         */
        private String name;

        /**
         * 收集总数
         */
        private long count;

        /**
         * 收集耗时
         */
        private long time;

        @Override
        public String toString() {
            return Layout.Table.of(name,
                    Layout.Row.of("Count", count),
                    Layout.Row.of("Time", DateUtil.formatBetween(time, BetweenFormatter.Level.MILLISECOND)
                            .replaceAll(BetweenFormatter.Level.MILLISECOND.getName(), "ms")
                            .replaceAll(BetweenFormatter.Level.SECOND.getName(), "s")
                            .replaceAll(BetweenFormatter.Level.MINUTE.getName(), "m")
                            .replaceAll(BetweenFormatter.Level.HOUR.getName(), "h")
                            .replaceAll(BetweenFormatter.Level.DAY.getName(), "d"))
            ).toString();
        }

    }

}
  • 创建监控Controller
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.text.CharPool;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.qax.ngsoc.indicator.common.config.GlobalConfigs;
import com.qax.ngsoc.indicator.monitor.bo.Thread;
import com.qax.ngsoc.indicator.monitor.bo.*;
import com.qax.ngsoc.indicator.monitor.config.WarnConfig;
import com.qax.ngsoc.indicator.monitor.config.WarnSateEnum;
import com.qax.ngsoc.indicator.monitor.print.Layout;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import java.io.File;
import java.lang.management.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 监控 Controller
 *
 * @author caolei02
 */
@Slf4j
@EnableScheduling
public abstract class MonitorBaseController {

    @Resource
    protected GlobalConfigs globalConfigs;

    /**
     * 巡检
     */
    @Scheduled(cron = "0 0/10 * * * ?")
    public void patrol() {
        // 发现预警
        warn();
    }

    /**
     * 预警
     *
     * @return {@link WarnSateEnum}
     */
    @GetMapping("/warn")
    public WarnSateEnum warn() {
        WarnConfig warnConfig = globalConfigs.getMonitorWarn();
        // 不开启,则返回空
        if (Objects.isNull(warnConfig) || BooleanUtil.isFalse(warnConfig.getEnabled())) return null;

        WarnSateEnum result = WarnSateEnum.GREEN;

        // 判断CPU
        Cpu cpu = cpu();
        if (NumberUtil.sub(cpu.getSystemCpuUsage().doubleValue() * 100, warnConfig.getCpuStage2().doubleValue()) >= 0 ||
                NumberUtil.sub(cpu.getProcessCpuUsage().doubleValue() * 100, warnConfig.getCpuStage2().doubleValue()) >= 0) {
            result = result.max(WarnSateEnum.RED);
            log.warn("Monitoring capability detection cpu warning!!!" + StrUtil.LF + cpu);
        } else if (NumberUtil.sub(cpu.getSystemCpuUsage().doubleValue() * 100, warnConfig.getCpuStage1().doubleValue()) >= 0 ||
                NumberUtil.sub(cpu.getProcessCpuUsage().doubleValue() * 100, warnConfig.getCpuStage1().doubleValue()) >= 0) {
            result = result.max(WarnSateEnum.YELLOW);
            log.warn("Monitoring capability detection cpu warning!!!" + StrUtil.LF + cpu);
        }

        // 判断内存
        Memory memory = memory();
        if (NumberUtil.sub(memory.getPhysicalMemoryUsage().doubleValue() * 100, warnConfig.getMemoryStage2().doubleValue()) >= 0 ||
                NumberUtil.sub(memory.getMemoryUsage().doubleValue() * 100, warnConfig.getMemoryStage2().doubleValue()) >= 0) {
            result = result.max(WarnSateEnum.RED);
            log.warn("Monitoring capability detection memory warning!!!" + StrUtil.LF + memory);
        } else if (NumberUtil.sub(memory.getPhysicalMemoryUsage().doubleValue() * 100, warnConfig.getMemoryStage1().doubleValue()) >= 0 ||
                NumberUtil.sub(memory.getMemoryUsage().doubleValue() * 100, warnConfig.getMemoryStage1().doubleValue()) >= 0) {
            result = result.max(WarnSateEnum.YELLOW);
            log.warn("Monitoring capability detection memory warning!!!" + StrUtil.LF + memory);
        }

        // 判断磁盘
        Disk disk = disk();
        double diskTotalUsage = Opt.ofNullable(disk.getDevices().stream().map(Disk.Drive::getDriveUsage)
                        .mapToDouble(BigDecimal::doubleValue).average()).map(OptionalDouble::getAsDouble)
                .orElse(BigInteger.ZERO.doubleValue());
        if (NumberUtil.sub(diskTotalUsage * 100, warnConfig.getDiskStage2().doubleValue()) >= 0) {
            result = result.max(WarnSateEnum.RED);
            log.warn("Monitoring capability detection disk warning!!!" + StrUtil.LF + disk);
        } else if (NumberUtil.sub(diskTotalUsage * 100, warnConfig.getDiskStage1().doubleValue()) >= 0) {
            result = result.max(WarnSateEnum.YELLOW);
            log.warn("Monitoring capability detection disk warning!!!" + StrUtil.LF + disk);
        }

        return result;
    }

    /**
     * 打印
     *
     * @return {@link String}
     */
    @GetMapping({"", "/print"})
    public String print(String cmd) {
        boolean isAll = StrUtil.equalsIgnoreCase("all", cmd);

        Map<String, Function<Void, Object>> items = new LinkedHashMap<>();
        items.put("Work State", unused -> work());
        items.put("Kafka", unused -> kafka());
        items.put("Server Info", unused -> server());
        items.put("JVM", unused -> jvm());
        items.put("CPU", unused -> cpu());
        items.put("Memory", unused -> memory());
        items.put("Disk", unused -> disk());
        items.put("Heap/NonHeap", unused -> heap());
        items.put("Thread", unused -> thread());
        items.put("ThreadPool", unused -> threadPool());
        items.put("GC", unused -> gc());

        Stream<Layout> streams = items.entrySet().stream()
                .filter(entry -> isAll ? Boolean.TRUE : StrUtil.containsAnyIgnoreCase(entry.getKey(),
                        Opt.ofBlankAble(cmd).orElse("CPU&Memory&ThreadPool").split(Objects.toString(CharPool.AMP))))
                .map(entry -> Layout.of(entry.getKey(), entry.getValue().apply(null)));

        String tip = !isAll ? "Tip: Set parameters [cmd=all] will return more information."
                + StrUtil.LF + StrUtil.LF : StrUtil.EMPTY;
        return tip + streams.map(Layout::toString).collect(Collectors.joining(StrUtil.LF));
    }

    /**
     * 工作状态
     *
     * @return {@link Work}
     */
    protected abstract Work work();

    /**
     * KAFKA信息
     *
     * @return {@link Kafka}
     */
    protected abstract Kafka kafka();

    /**
     * 服务器信息
     *
     * @return {@link Server}
     */
    @SneakyThrows
    protected Server server() {
        InetAddress inetAddress = InetAddress.getLocalHost();
        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
        return Server.builder()
                .hostName(inetAddress.getHostName())
                .osName(operatingSystemMXBean.getName())
                .osVersion(operatingSystemMXBean.getVersion())
                .arch(operatingSystemMXBean.getArch())
                .localIp(inetAddress.getHostAddress())
                .build();
    }

    /**
     * Java虚拟机信息
     *
     * @return {@link Jvm}
     */
    protected Jvm jvm() {
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        Map<String, String> systemProperties = runtimeMXBean.getSystemProperties();
        return Jvm.builder()
                .vmName(runtimeMXBean.getVmName())
                .jdkVersion(systemProperties.get("java.runtime.version"))
                .javaHome(systemProperties.get("java.home"))
                .pid(systemProperties.get("PID"))
                .startTime(LocalDateTimeUtil.of(runtimeMXBean.getStartTime()))
                .runtime(runtimeMXBean.getUptime())
                .startParameters(runtimeMXBean.getInputArguments())
                .build();
    }

    /**
     * CPU
     *
     * @return {@link Cpu}
     */
    protected Cpu cpu() {
        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
        JSONObject operatingSystemJson = JSONObject.parseObject(JSONObject.toJSONString(operatingSystemMXBean));
        return Cpu.builder()
                .availableProcssors(operatingSystemMXBean.getAvailableProcessors())
                .systemCpuUsage(operatingSystemJson.getBigDecimal("systemCpuLoad"))
                .processCpuUsage(operatingSystemJson.getBigDecimal("processCpuLoad"))
                .build();
    }

    /**
     * 内存
     *
     * @return {@link Memory}
     */
    protected Memory memory() {
        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
        JSONObject operatingSystemJson = JSONObject.parseObject(JSONObject.toJSONString(operatingSystemMXBean));
        long totalPhysicalMemory = operatingSystemJson.getLongValue("totalPhysicalMemorySize");
        long freePhysicalMemory = operatingSystemJson.getLongValue("freePhysicalMemorySize");
        long usedPhysicalMemory = totalPhysicalMemory - freePhysicalMemory;
        Runtime runtime = Runtime.getRuntime();
        return Memory.builder()
                .totalPhysicalMemory(totalPhysicalMemory)
                .freePhysicalMemory(freePhysicalMemory)
                .usedPhysicalMemory(usedPhysicalMemory)
                .physicalMemoryUsage(NumberUtil.toBigDecimal(NumberUtil.div(usedPhysicalMemory, totalPhysicalMemory)))
                .totalMemory(runtime.totalMemory())
                .freeMemory(runtime.freeMemory())
                .usedMemory(runtime.totalMemory() - runtime.freeMemory()).maxMemory(runtime.maxMemory())
                .maxUseMemory(runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory())
                .memoryUsage(NumberUtil.toBigDecimal(NumberUtil.div(runtime.totalMemory() - runtime.freeMemory(), runtime.totalMemory())))
                .build();
    }

    /**
     * 磁盘信息
     *
     * @return {@link Disk}
     */
    protected Disk disk() {
        List<Disk.Drive> drives = Stream.of(File.listRoots()).map(file -> Disk.Drive.builder()
                .name(file.toString())
                .totalSpace(file.getTotalSpace())
                .freeSpace(file.getFreeSpace())
                .usedSpace(file.getTotalSpace() - file.getFreeSpace())
                .driveUsage(NumberUtil.toBigDecimal(NumberUtil.div(file.getTotalSpace() - file.getFreeSpace(), file.getTotalSpace())))
                .build()
        ).collect(Collectors.toList());
        return new Disk(drives);
    }

    /**
     * 堆/非堆
     *
     * @return {@link StringBuilder}
     */
    protected Heap heap() {
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
        MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
        return Heap.builder()
                .heapInit(heapMemoryUsage.getInit())
                .heapMaxMemory(heapMemoryUsage.getMax())
                .heapUsedMemory(heapMemoryUsage.getUsed())
                .heapFreeMemory(heapMemoryUsage.getMax() - heapMemoryUsage.getUsed())
                .nonHeapInit(nonHeapMemoryUsage.getInit())
                .nonHeapMaxMemory(nonHeapMemoryUsage.getMax())
                .nonHeapUsedMemory(nonHeapMemoryUsage.getUsed())
                .nonHeapFreeMemory(nonHeapMemoryUsage.getMax() - nonHeapMemoryUsage.getUsed())
                .build();
    }

    /**
     * 线程信息
     *
     * @return {@link Thread}
     */
    protected Thread thread() {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        return Thread.builder()
                .threadCount(threadMXBean.getThreadCount())
                .peakThreadCount(threadMXBean.getPeakThreadCount())
                .daemonThreadCount(threadMXBean.getDaemonThreadCount())
                .nonDaemonThreadCount(threadMXBean.getThreadCount() - threadMXBean.getDaemonThreadCount())
                .totalStartedThreadCount(threadMXBean.getTotalStartedThreadCount())
                .build();
    }

    /**
     * 线程池
     *
     * @return {@link ThreadPool}
     */
    protected abstract ThreadPool threadPool();

    /**
     * 垃圾回收信息
     *
     * @return {@link Gc}
     */
    private Gc gc() {
        List<Gc.GcCollector> collectors = ManagementFactory.getGarbageCollectorMXBeans().stream().map(garbageCollectorMXBean -> Gc.GcCollector.builder()
                        .name(garbageCollectorMXBean.getName())
                        .count(garbageCollectorMXBean.getCollectionCount())
                        .time(garbageCollectorMXBean.getCollectionTime())
                        .build()).sorted(Comparator.comparing(Gc.GcCollector::getCount).reversed())
                .collect(Collectors.toList());
        return Gc.builder().collectors(collectors).build();
    }

}
  • 创建启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 启动类
 *
 * @author CL
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

4. 测试

  • 测试全部监控信息
curl http://127.0.0.1:8080/monitor/print

  接口响应:

Server Info:

 ------------------------------------
┊ HostName     ┊ c3sontes-pc         ┊
┊ OS           ┊ Windows 10/10.0     ┊
┊ Arch         ┊ amd64               ┊
┊ LocalIp      ┊ 127.0.0.1           ┊
 ------------------------------------

JVM:

 --------------------------------------------------------------
┊ VM Name              ┊ Java HotSpot(TM) 64-Bit Server VM     ┊
┊ JDK Version          ┊ 1.8.0_102-b14                         ┊
┊ Java Home            ┊ C:\Java\jdk1.8.0_102\jre              ┊
┊ PID                  ┊ 29128                                 ┊
┊ StartTime            ┊ 2023-03-09 21:14:42                   ┊
┊ RunTime              ┊ 1m8s                                  ┊
┊ Start Parameters     ┊     -Xms1g                            ┊
┊                      ┊ -Xmx2g                                ┊
┊                      ┊ -Xss512k                              ┊
┊                      ┊ -XX:MetaspaceSize=128m                ┊
┊                      ┊ -XX:MaxMetaspaceSize=256m             ┊
┊                      ┊ -Dfile.encoding=UTF-8                 ┊
 --------------------------------------------------------------

CPU:

 ---------------------------------------
┊ Available Processors     ┊ 8          ┊
┊ System CPU Usage         ┊ 54.10%     ┊
┊ Process CPU Usage        ┊ 12.63%     ┊
 ---------------------------------------

Memory:

 ------------------------------------------
┊ Total Physical Memory     ┊ 15.76GB      ┊
┊ Free Physical Memory      ┊ 2.22GB       ┊
┊ Used Physical Memory      ┊ 13.53GB      ┊
┊ Physical Memory Usage     ┊ 85.89%       ┊
┊ Total Memory              ┊ 258.5MB      ┊
┊ Free Memory               ┊ 241.64MB     ┊
┊ Used Memory               ┊ 16.86MB      ┊
┊ Max Memory                ┊ 3.50GB       ┊
┊ Max Use Memory            ┊ 3.49GB       ┊
┊ Memory Usage              ┊ 6.52%        ┊
 ------------------------------------------

Disk:

 --------------------------------
┊C:\                             ┊
 --------------------------------
┊ Total Space     ┊ 150.00GB     ┊
┊ Free Space      ┊ 53.59GB      ┊
┊ Used Space      ┊ 96.41GB      ┊
┊ Drive Space     ┊ 64.27%       ┊
 --------------------------------
 --------------------------------
┊D:\                             ┊
 --------------------------------
┊ Total Space     ┊ 326.52GB     ┊
┊ Free Space      ┊ 263.06GB     ┊
┊ Used Space      ┊ 63.46GB      ┊
┊ Drive Space     ┊ 19.43%       ┊
 --------------------------------

Heap/NonHeap:

 ---------------------------------------
┊ Heap Init Size        ┊ 254MB         ┊
┊ Heap Max Size         ┊ 3.50GB        ┊
┊ Heap Used Size        ┊ 16.86MB       ┊
┊ Heap Free Size        ┊ 3.49GB        ┊
┊ NonHeap Init Size     ┊ 2.44MB        ┊
┊ NonHeap Max Size      ┊ -1            ┊
┊ NonHeap Used Size     ┊ 43.12MB       ┊
┊ NonHeap Free Size     ┊ -45210705     ┊
 ---------------------------------------

Thread:

 ---------------------------------------
┊ Active Thread Count          ┊ 22     ┊
┊ Active Peak Thread Count     ┊ 25     ┊
┊ Daemon Thread Count          ┊ 18     ┊
┊ NonDaemon Thread Count       ┊ 4      ┊
┊ Total Thread Count           ┊ 38     ┊
 ---------------------------------------

GC:

 ----------------------- 
┊PS Scavenge            ┊
 ----------------------- 
┊ Count     ┊ 5         ┊
┊ Time      ┊ 240ms     ┊
 ----------------------- 
 ----------------------- 
┊PS MarkSweep           ┊
 ----------------------- 
┊ Count     ┊ 2         ┊
┊ Time      ┊ 266ms     ┊
 ----------------------- 
 
  • 测试单个监控信息
curl http://127.0.0.1:8080/monitor/print?cmd=memory

  接口响应:

Tip: Set parameters [cmd=all] will return more information.

Memory:

 ------------------------------------------ 
┊ Total Physical Memory     ┊ 15.76GB      ┊
┊ Free Physical Memory      ┊ 2.85GB       ┊
┊ Used Physical Memory      ┊ 12.91GB      ┊
┊ Physical Memory Usage     ┊ 81.93%       ┊
┊ Total Memory              ┊ 249MB        ┊
┊ Free Memory               ┊ 226.00MB     ┊
┊ Used Memory               ┊ 23.00MB      ┊
┊ Max Memory                ┊ 3.50GB       ┊
┊ Max Use Memory            ┊ 3.48GB       ┊
┊ Memory Usage              ┊ 9.24%        ┊
 ------------------------------------------ 
  • 测试默认监控信息
curl http://127.0.0.1:8080/monitor/print

  接口响应:

Tip: Set parameters [cmd=all] will return more information.

CPU:

 --------------------------------------- 
┊ Available Processors     ┊ 8          ┊
┊ System CPU Usage         ┊ 67.12%     ┊
┊ Process CPU Usage        ┊ 0.07%      ┊
 --------------------------------------- 

Memory:

 ------------------------------------------ 
┊ Total Physical Memory     ┊ 15.76GB      ┊
┊ Free Physical Memory      ┊ 3.15GB       ┊
┊ Used Physical Memory      ┊ 12.61GB      ┊
┊ Physical Memory Usage     ┊ 80.00%       ┊
┊ Total Memory              ┊ 249MB        ┊
┊ Free Memory               ┊ 218.76MB     ┊
┊ Used Memory               ┊ 30.24MB      ┊
┊ Max Memory                ┊ 3.50GB       ┊
┊ Max Use Memory            ┊ 3.47GB       ┊
┊ Memory Usage              ┊ 12.14%       ┊
 ------------------------------------------ 

GC:

 ----------------------- 
┊PS Scavenge            ┊
 ----------------------- 
┊ Count     ┊ 5         ┊
┊ Time      ┊ 240ms     ┊
 ----------------------- 
 ----------------------- 
┊PS MarkSweep           ┊
 ----------------------- 
┊ Count     ┊ 2         ┊
┊ Time      ┊ 266ms     ┊
 ----------------------- 
 
  • 测试主动预警
curl http://127.0.0.1:8080/monitor/warn

  接口响应:

"YELLOW"

  日志打印:

2023-03-09 21:10:50.110  WARN 97132 --- [nio-8080-exec-2] com.c3stones.monitor.MonitorController   : Monitoring capability detection memory warning!!!
 ------------------------------------------ 
┊ Total Physical Memory     ┊ 15.76GB      ┊
┊ Free Physical Memory      ┊ 2.23GB       ┊
┊ Used Physical Memory      ┊ 13.53GB      ┊
┊ Physical Memory Usage     ┊ 85.84%       ┊
┊ Total Memory              ┊ 258.5MB      ┊
┊ Free Memory               ┊ 228.27MB     ┊
┊ Used Memory               ┊ 30.23MB      ┊
┊ Max Memory                ┊ 3.50GB       ┊
┊ Max Use Memory            ┊ 3.47GB       ┊
┊ Memory Usage              ┊ 11.70%       ┊
 ------------------------------------------

5. 项目地址

  spring-boot-monitor-demo文章来源地址https://www.toymoban.com/news/detail-550086.html

到了这里,关于SpringBoot自主监控,获取服务信息、JVM、CPU、内存、磁盘、堆、线程、GC等的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java线上故障排查(CPU、磁盘、内存、网络、GC)+JVM性能调优监控工具+JVM常用参数和命令

    根据服务部署和项目架构,从如下几个方面排查: (1)运用服务器:排查内存,cpu,请求数等; (2)文件图片服务器:排查内存,cpu,请求数等; (3)计时器服务器:排查内存,cpu,请求数等; (4)redis服务器:排查内存,cpu,连接数等; (5)db服务器:排查内存,cpu,连接数

    2024年02月07日
    浏览(67)
  • 【C#】获取电脑CPU、内存、屏幕、磁盘等信息

    通过WMI类来获取电脑各种信息,参考文章:WMI_04_常见的WMI类的属性_wmi scsilogicalunit_fantongl的博客-CSDN博客 自己整理了获取电脑CPU、内存、屏幕、磁盘等信息的代码 可以获取下面这些信息: ComputerCheck Info: System Info:Windows 10 Enterprise, Enterprise, X64, Microsoft Windows 10.0.18363  CPU Info:

    2024年02月13日
    浏览(49)
  • linux服务器监控之内存、cpu、网络、磁盘

    一、服务器实时内存监控 1、Linux帮助命令 man:Linux下的函数手册命令,可以查看所有命令的使用方法 ls:  ls -al: ll: 2、实时监控命令 top:   能够实时监控系统的运行状态,并且可以按照cpu及内存等进行排序。            语法:top -hv|-bcHiOSs -d secs -n max -u|U user -p pid(s) -o file

    2024年02月09日
    浏览(67)
  • 获取linuxIP、内存、cpu、磁盘IO等信息的Shell脚本及其讲解

    grep是一个在Unix和Unix-like系统上使用的命令行工具,用于在文本文件中搜索匹配指定模式的行。它的名字来自于\\\"global regular expression print\\\"(全局正则表达式打印)的缩写。grep的基本用法是通过指定一个正则表达式模式和一个文件名(或者从标准输入读取数据),来查找和打印

    2024年04月27日
    浏览(33)
  • Shell开发实践:服务器的磁盘、CPU、内存的占用监控

    🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论⭐收藏 CPU、内存和磁盘是计算机中重要且相互依赖

    2024年02月10日
    浏览(58)
  • Python 获取windows下硬件数据信息(CPU,内存,英特尔、英伟达、AMD显卡使用率及详细信息)

    前言:最近一直在做关于显卡数据采集的调研工作,也在github上看到了一些三方库比如Python和golang的psutil, python: gpustart,再或者通过wmi或者windowsApi等底层接口 但是都只能获取到显卡的名称以及厂家信息等 无法真正意义上获取到显卡占用率等数据 在或者只能获取到英伟达的显卡

    2024年02月16日
    浏览(58)
  • Apache JMeter 3.1压力测试监控服务器数据(cpu、内存、磁盘io等)

    监控服务器CPU、内存、磁盘、网络等相关资源需要使用3.1版本并使用以下插件 客户端:JMeterPlugins-Standard和JMeterPlugins-Extras 服务端:ServerAgent 官网链接:https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-3.1.zip 解压安装包,进入 bin 目录,点击 jmeter.bat 启动 Jmeter 1.1 添加线程组 线

    2024年01月18日
    浏览(53)
  • prometheus使用node_exporter监控Linux主机CPU、内存、磁盘、服务运行状况

    目录 1.node_exporter简介 2.部署node_exporter 2.1.安装node_exporter 2.2.编写system启动脚本 3.prometheus监控Linux主机 3.1.修改配置文件增加主机节点 3.2.主机添加成功 4.监控Linux主机CPU、内存、磁盘使用率 4.1.监控CPU使用率 4.1.1.获取空闲CPU监控数据 4.1.2.获取5分钟内的监控数据 4.1.3.获取5分钟

    2024年04月16日
    浏览(45)
  • Linux:查看服务器信息,CPU、内存、系统版本、内核版本等

    还是最近工作的总结,在做一些性能验证,这就需要要根据服务器的配置综合考虑来做进一步的结论论证,废话不多说 第一种方式 第二种方式 个人偏推崇第一种方式吧,能够更明显的看到版本和一些详细信息 第一种方式 这个命令适用于所有的Linux发行版,包括Redhat、SuSE、

    2024年01月19日
    浏览(81)
  • 【经验案例】Springboot微服务搭建JVM监控(Springboot + Prometheus + Grafana)

    由于项目之前在生产环境出现过OOM的问题,并且没有及时发现,导致生产环境出现了在一定时间内不可用的情况,故决定搭建JVM监控对微服务24小时监听,以便于出现问题能够及时通知相关人员进行服务降级或解决问题。 经过可行性分析,得到目前较为适合的微服务监控为

    2024年02月06日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包