Springcloud学习笔记38--springboot整合日志框架log4j2

1.log4j2概述

对于一个线上程序或者服务而言,重要的是要有日志输出,这样才能方便运维。而日志的输出需要有一定的规划,如日志命名、日志大小,日志分割的文件个数等。在Spring的框架下,我们可以使用log4j来进行日志的设置,高版本的SpringBoot会使用log4j2

Log4j其实可以理解为log for java,所以是java的日志框架,提供日志服务,而Log4j 2是Log4j的升级版本,性能比logback好。
日志级别优先级从低到高:ALL、DEBUG、 INFO、 WARN、 ERROR、FATAL、 OFF。一般官网建议就使用DEBUG、INFO、WARN和ERROR这四个,但是我们可以加一个ALL最低级别的来进行总日志的输出。日志的等级越高,打出的日志越少。

常用的日志框架:

  • Log4j:Apache的一个开源项目,可以控制日志信息输送的目的地是控制台、文件、GUI组件等,可以控制每一条日志的输出格式,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。虽然已经停止维护了,但目前绝大部分企业都是用的log4j。
  • LogBack:是Log4j的一个改良版本
  • Log4j2:Log4j2已经不仅仅是Log4j的一个升级版本了,它从头到尾都被重写了

log4j2 在目前JAVA中的日志框架里,异步日志的性能是最高的,没有之一。

2. log4j2的日志引入

springboot 项目结构:

 首先引入依赖,然后添加日子的配置文件,最后将配置文件引入到yml文件中生效。后就可以在项目中使用lombok的插件直接在类上注解即可使用。

2.1 pom.xml中引入依赖

web依赖中排除掉logging依赖,并且引入log4j2依赖。不只是starter-web中有logging jar包,如redis,mybatis中也有这个jar包,需要将他们也清除,否则依然会报错!

复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
复制代码

注意:在引入log4j2时,需要排除掉Logback日志框架的依赖。

log4j2一般可以通过xml,json,yaml或者properties形式文件来实现,我们这边主要介绍xml文件格式。

2.2 log4j2.xml配置路径

引入log4j2依赖后,默认在src/main/resources目录下加入log4j2.xml配置文件对日志进行配置即可,然后在application.yml中进行访问路径的配置。

示例如下:

log4j2.xml部署位置:在代码工程中的src/main/resources目录下放入配置文件。

yml配置:

复制代码
#日志配置 无特殊需求无需更改
logging:
  config:  classpath:log4j2.xml
  level:
    root: INFO
    javax.activation: info
    org.apache.catalina: INFO
    org.apache.commons.beanutils.converters: INFO
    org.apache.coyote.http11.Http11Processor: INFO
    org.apache.http: INFO
    org.apache.tomcat: INFO
    org.springframework: INFO
    com.chinamobile.cmss.bdpaas.resource.monitor: DEBUG
复制代码

2.3 log4j2.xml配置文件

部分参数说明:

  • %d 输出日志时间点的日期(一般是那一天),也可以在其后用大括号自定义格式,比如:%d{yyyy-MM-dd HH:mm:ss.SSS},输出类似:2014-11-05 23:28:22.367
  • %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL ;
  • %r 输出自应用启动到输出该log信息耗费的毫秒数 ;
  • %c 输出所属的全类名,也可以只输出类名,:%c{1} ;
  • %t 输出产生该日志的当前线程名字 ;
  • %m 输出代码中自定义的的信息;  例如 log.info("文件存储路径为:",filePath);
  • %n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n” ;
  • %X %X{name}会查询设置到MDC中的变量name的值;
  • %L 输出行号
  • ${} ${key}这样的表达式在XML中,代表引入的properties文件中key对应的一个变量值
  • %F:输出日志消息产生时所在的文件名称。

(1)%c

2.4 配置文件案例及详细说明

配置文件案例(标准2022-03-21更新):

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="600">

    <Properties>
        <!--
                <property name="LOG_HOME" value="${sys:user.home}/home/flep/logs"/>
        -->
        <property name="LOG_HOME" value="/home/test/doc/log"/>
        <!--<property name="LOG_HOME" value="D:\doc\log"/>-->
        <property name="APP_CODE" value="file_log"/>
        <property name="LOG_LEVEL_PATTERN" value="%-5p"/>
        <property name="INSTANCE_INFO_PATTERN" value="${hostName} | ${sys:user.name}"/>
        <property name="CODE_INFO_PATTERN" value="%pid:%F:%L"/>
        <property name="LOG_DATEFORMAT_PATTERN" value="yyyy-MM-dd HH:mm:ss.SSS"/>
        <property name="METRIC_LOG_DATEFORMAT_PATTERN" value="yyyy-MM-dd HH:mm:ss.SSS"/>
        <property name="APP_LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} | ${LOG_LEVEL_PATTERN} | %X{TRACE_ID}  | %t | ${CODE_INFO_PATTERN} | [%X{seq}] - %m%n"/>
        <property name="LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} | %X{TRACE_ID} | ${LOG_LEVEL_PATTERN} | ${INSTANCE_INFO_PATTERN} | FEIA | FLEP-INAPP | %t | ${CODE_INFO_PATTERN} | %m%n"/>
        <property name="ALERT_LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} $${ctx:traceId:-} | ${INSTANCE_INFO_PATTERN} | [%X{seq}] - %m%n"/>
        <property name="METRIC_LOG_PATTERN" value="%d{${METRIC_LOG_DATEFORMAT_PATTERN}}%m%n"/>
    </Properties>

    <Appenders>
        <!--控制台输出的相关配置-->
        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="%d{${LOG_DATEFORMAT_PATTERN}} | ${LOG_LEVEL_PATTERN} | %t | %c:%L | [%X{seq}] - %m%n" />
        </Console>


        <!--打印所有的info及以下的级别的信息,每次超过size,则这size大小的日志会自动存入年份-月份创建的文件夹下进行压缩存档-->
        <RollingFile name="EventLogFile" fileName="${LOG_HOME}/event.log" immediateFlush="true"
                     filePattern="${LOG_HOME}/%d{yyyyMMdd}/event.log.%i">
            <!--            <thresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>-->
            <PatternLayout>
                <Pattern>${LOG_PATTERN}</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <!--保留最近30天的日志-->
            <DefaultRolloverStrategy>
                <Delete basePath="${LOG_HOME}" maxDepth = "2">
                    <IfFileName glob = "*/event.log.*" />
                    <IfLastModified age = "30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <RollingFile name="AppLogFile" fileName="${LOG_HOME}/app.log" immediateFlush="true"
                     filePattern="${LOG_HOME}/%d{yyyyMMdd}/app.log.%i">
            <!--            <thresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>-->
            <PatternLayout>
                <Pattern>${APP_LOG_PATTERN}</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <!--保留最近30天的日志-->
            <DefaultRolloverStrategy>
                <Delete basePath="${LOG_HOME}" maxDepth = "2">
                    <IfFileName glob = "*/app.log.*" />
                    <IfLastModified age = "30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <RollingFile name="AlertLogFile" fileName="${LOG_HOME}/alert.log" immediateFlush="true"
                     filePattern="${LOG_HOME}/%d{yyyyMMdd}/alert.log.%i">
            <thresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout>
                <Pattern>${ALERT_LOG_PATTERN}</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <DefaultRolloverStrategy>
                <Delete basePath="${LOG_HOME}" maxDepth = "2">
                    <IfFileName glob = "*/alert.log.*" />
                    <IfLastModified age = "30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <RollingFile name="ErrorLogFile" fileName="${LOG_HOME}/error.log" immediateFlush="true"
                     filePattern="${LOG_HOME}/%d{yyyyMMdd}/error.log.%i">
            <thresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout>
                <Pattern>${APP_LOG_PATTERN}</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <DefaultRolloverStrategy>
                <Delete basePath="${LOG_HOME}" maxDepth = "2">
                    <IfFileName glob = "*/error.log.*" />
                    <IfLastModified age = "30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <RollingFile name="FlepMetricLogFile" fileName="${LOG_HOME}/metric.log" immediateFlush="true"
                     filePattern="${LOG_HOME}/%d{yyyyMMdd}/metric.log.%i">
            <PatternLayout>
                <Pattern>${METRIC_LOG_PATTERN}</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <DefaultRolloverStrategy>
                <Delete basePath="${LOG_HOME}" maxDepth = "2">
                    <IfFileName glob = "*/metric.log.*" />
                    <IfLastModified age = "30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>

    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console" />
            <AppenderRef ref="AppLogFile" />
            <AppenderRef ref="AlertLogFile" />
            <AppenderRef ref="ErrorLogFile" />
        </Root>
        <AsyncLogger name="io.micrometer.core.instrument.logging.LoggingMeterRegistry" level="ALL" additivity="false">
            <AppenderRef ref="FlepMetricLogFile" />
        </AsyncLogger>
        <AsyncLogger name="event" level="ALL" additivity="false">
            <AppenderRef ref="EventLogFile" />
        </AsyncLogger>

        <logger name="com.apache.ibatis" level="TRACE"/>
        <logger name="java.sql.Connection" level="DEBUG"/>
        <logger name="java.sql.Statement" level="DEBUG"/>
        <logger name="java.sql.PreparedStatement" level="DEBUG"/>
        <logger name="com.hzbank.flep.file.mapper" level="DEBUG"/>
    </Loggers>

</Configuration>
复制代码

配置参数详解:

2.4.1 Configuration标签

根节点Configuration中有两个常用的属性:status和monitorterval。如:<Configuration status="WARN" monitorInterval="30">

属性

  • status:是用于指定log4j的级别;
  • monitorterval:是用于指定log4j自动重新检测读取配置内容的间隔时间,单位为秒(s),最小值为5秒。

 2.4.2 Properties标签

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <properties>
     <property name="LOG_HOME">./service-logs</property>
  </properties>
</Configuration>

变量配置,如模板中的<property name="LOG_HOME">./service-logs</property>,我们可以配置日志的路径。后续日志存放的前缀路径即为./service-logs下。

2.4.3 Appenders标签

Appenders是输出源,用于定义日志输出的地方。
log4j2支持的输出源有很多,有控制台ConsoleAppender、文件FileAppender、AsyncAppender、RandomAccessFileAppender、RollingFileAppender、RollingRandomAccessFile 等。

(1) ConsoleAppender

控制台输出源是将日志打印到控制台上,开发的时候一般都会配置,以便调试。

  • name:指定Appender的名字。
  • target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT。
  • PatternLayout:输出格式,不设置默认为:%m%n。

(2) RollingFileAppender

RollingFileAppender 是我们以后常用的输出器,它会根据我们的条件,判断是否满足封存文件的需求,要是满足,就将文件封存,不满足就不封存。

RollingFileAppender 需要 TriggeringPolicy 来指定触发封存的条件,另外还需要 RolloverStrategy 来告诉输出器如何封存文件。

Log4j 默认给了我们几种策略。

SizeBased Triggering Policy :这一触发策略基于对log文件大小的判断。当log文件大于设定的阈值时,将触发封存动作。可设定的log文件大小的单位有bytes、KB、MB或GB。

TimeBased Triggering Policy :这个是基于时间触发。可以指定两次时间间隔,或者是按照偏移进行封存。

<1>基于大小的滚动策略

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="10"/>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>
复制代码

上述模板中,日志先写入logs/app.log中,每当文件大小达到100MB时或经过1天,按照在logs/2020-09/目录下以app-2020-09-09-1.log.gz格式对该日志进行压缩重命名并归档,并生成新的文件app.log进行日志写入。
  其中,filePattern属性的文件格式中%i就类似于一个整数计数器,受到<DefaultRolloverStrategy max="10"/>控制,要特别注意的是:当文件个数达到10个的时候会循环覆盖前面已归档的1-10个文件。若不设置该参数,默认为7。

<2>基于时间间隔的滚动策略

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>
复制代码

上述模板中,日志先写入logs/app.log中,每当文件的时间间隔到达6小时(由%d{yyyy-MM-dd-HH}决定,也可以设置成%d{yyyy-MM-dd-HH-mm},则间隔为分钟级别),触发rollover操作。
  如上配置设置好后,10点的日志开始重启服务,则从11点触发一次rollover操作,生成2020-09-09-10.log.gz对该日志进行压缩重命名并归档,并生成新的文件app.log进行日志写入;然后,每间隔6小时,则下一次是17点触发一次,生成2020-09-09-17.log.gz对该日志进行压缩重命名并归档,并生成新的文件app.log进行日志写入。

<3> 基于时间间隔和文件大小的滚动策略

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>
复制代码

上述模板中,日志先写入logs/app.log中,每当文件大小达到100MB或者当时间间隔到达6小时(由%d{yyyy-MM-dd-HH}决定),触发rollover操作,按照在logs/2020-09/目录下以app-2020-09-09-1.log.gz格式对该日志进行压缩重命名并归档,并生成新的文件app.log进行日志写入。

属性

  • name:用于指定Appender的名称;
  • fileName:用于指定日志文件的全路径;
  • filePattern:用于指定分割文件的日志全路径(命名规则)。

节点

  • PatternLayout:用于指定输出格式,不设置的话,默认为:%m%n;
  • Policies :设置日志文件切割参数;
  • SizeBasedTriggeringPolicy:Policies的子节点,用于设置基于日志文件大小触发的滚动策略,size属性用来指定每个分割的日志文件大小。
  • TimeBasedTriggeringPolicy:Policies的子节点,用于设置基于时间间隔触发的滚动策略,interval属性用于指定滚动时间间隔,默认是1小时,modulate属性是用于对interval进行偏移调节,默认为false。若为true,则第一次触发时是第一个小时触发,后续以interval间隔触发。
  • CronTriggeringPolicy:Policies的子节点,用于设置基于Cron表达式触发的滚动策略。
  • DefaultRolloverStrategy:设置默认策略设置。

2.4.4 Loggers 标签

节点

  • Root:用于指定项目的根日志,level属性表示日志输出级别,子节点AppenderRef用于指定输出到某个Appender,子节点的ref属性也就是前面的RollingFile中指定的name名称,子节点的level也是日志输出级别。
  • Logger :用于指定日志的形式,指定不同包的日志级别,level属性表示日志输出级别,name属性用来指定该Logger所适用的类或者类的全路径。子节点AppenderRef用于指定日志输出到哪个Appender,若没有指定,默认集成自Root。

下面针对配置文件进行图文说明:

 注意:user.home的属性值可以用以下方法查看,本机默认为C:\Users\14032

    public static void main(String[] args) {
        System.out.println(System.getProperty("user.home"));
    }

 2.5 在application.yml文件中引入配置文件,正式生效日志的配置

logging:
  config: classpath:log4j2-dev.xml

2.6 在项目中使用log4j2 DEMO

如果不想每次都写private final Logger logger = LoggerFactory.getLogger(XXX.class); 可以用注解@Slf4j,这个注解需要引入lombok的jar包依赖。已添加到pom中

 2.7 将指定日志打印到指定文件

        <AsyncLogger name="event" level="ALL" additivity="false">
            <AppenderRef ref="EventLogFile" />
        </AsyncLogger>

代码中:

    @PostMapping("/getLogInfo")
    public void getLogInfo(){
        org.slf4j.Logger event1 = LoggerFactory.getLogger("event");
        event1.info("hello 2022");
    }

此时,查看日志文件:

3 以日志形式定期输出监控数据

监控Spring Boot中的Tomcat性能数据;

日志Log指标包括: 线程池监控、jvm参数监控、tomcat监控

示例:

executor.completed{name=executor.sample} throughput=0.5 tasks/s // 这里LoggingMeterRegistry做了转换 count/step
executor.active{name=executor.sample} value=1 threads
executor.pool.core{name=executor.sample} value=5 threads
executor.pool.max{name=executor.sample} value=2147483647 threads
executor.pool.size{name=executor.sample} value=5 threads
executor.queue.remaining{name=executor.sample} value=2147483647 tasks
executor.queued{name=executor.sample} value=0 tasks

很多时候,如果有日志的方法去定期输出监控的数据这样已经足够我们分析了。在Spring Boot 2.x里,只需要配置一个Bean。

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
    <version>1.1.3</version>
</dependency>

使用案例:

复制代码
@Configuration
public class MetricsConfig {
    @Bean
    LoggingMeterRegistry loggingMeterRegistry() {
        //下面是单独的配置实现的参考,当需要修改配置时候可以使用
        return new LoggingMeterRegistry(new LoggingRegistryConfig() {
            @Override
            public Duration step() {
                return Duration.ofSeconds(10);//10秒输出一次
            }

            @Override
            public String get(String key) {
                return null;
            }
        }, Clock.SYSTEM);
    }
}
复制代码

日志打印结果:

复制代码
jvm.buffer.count{id=direct} value=26 buffers
jvm.buffer.count{id=mapped} value=0 buffers
jvm.buffer.memory.used{id=direct} value=632.600586 KiB
jvm.buffer.memory.used{id=mapped} value=0 B
jvm.buffer.total.capacity{id=direct} value=632.599609 KiB
jvm.buffer.total.capacity{id=mapped} value=0 B
jvm.classes.loaded{} value=12306 classes
jvm.gc.live.data.size{} value=39.339607 MiB
jvm.gc.max.data.size{} value=2.666992 GiB
jvm.memory.committed{area=nonheap,id=Compressed Class Space} value=8.539062 MiB
jvm.memory.committed{area=nonheap,id=Code Cache} value=26.8125 MiB
jvm.memory.committed{area=heap,id=PS Survivor Space} value=30 MiB
jvm.memory.committed{area=heap,id=PS Eden Space} value=416.5 MiB
jvm.memory.committed{area=heap,id=PS Old Gen} value=242 MiB
jvm.memory.committed{area=nonheap,id=Metaspace} value=66.773438 MiB
jvm.memory.max{area=heap,id=PS Survivor Space} value=30 MiB
jvm.memory.max{area=heap,id=PS Eden Space} value=1.272949 GiB
jvm.memory.max{area=heap,id=PS Old Gen} value=2.666992 GiB
jvm.memory.max{area=nonheap,id=Metaspace} value=-1 B
jvm.memory.max{area=nonheap,id=Compressed Class Space} value=1 GiB
jvm.memory.max{area=nonheap,id=Code Cache} value=240 MiB
jvm.memory.used{area=nonheap,id=Code Cache} value=26.635071 MiB
jvm.memory.used{area=heap,id=PS Survivor Space} value=25.214882 MiB
jvm.memory.used{area=heap,id=PS Eden Space} value=46.910545 MiB
jvm.memory.used{area=heap,id=PS Old Gen} value=39.34742 MiB
jvm.memory.used{area=nonheap,id=Metaspace} value=63.333778 MiB
jvm.memory.used{area=nonheap,id=Compressed Class Space} value=7.947166 MiB
jvm.threads.daemon{} value=52 threads
jvm.threads.live{} value=54 threads
jvm.threads.peak{} value=67 threads
jvm.threads.states{state=terminated} value=0 threads
jvm.threads.states{state=blocked} value=0 threads
jvm.threads.states{state=new} value=0 threads
jvm.threads.states{state=runnable} value=20 threads
jvm.threads.states{state=waiting} value=19 threads
jvm.threads.states{state=timed-waiting} value=15 threads
process.cpu.usage{} value=-1
process.start.time{} value=435900h 48m 53.344s
process.uptime{} value=56m 6.709s
system.cpu.count{} value=8
system.cpu.usage{} value=-1
tomcat.global.request.max{name=http-nio-10610} value=0.597s
tomcat.servlet.request.max{name=dispatcherServlet} value=0.567s
tomcat.sessions.active.current{} value=0 sessions
tomcat.sessions.active.max{} value=0 sessions
tomcat.threads.busy{name=http-nio-10610} value=0 threads
tomcat.threads.config.max{name=http-nio-10610} value=200 threads
tomcat.threads.current{name=http-nio-10610} value=10 threads
复制代码

 

参考文献:

https://blog.csdn.net/abu935009066/article/details/127476817---推荐

https://zhanglf.blog.csdn.net/article/details/88909106

https://blog.csdn.net/u010663021/article/details/108388817

https://www.jianshu.com/p/d13c2e50a89c

https://www.cnblogs.com/Andya/p/13641254.html --推荐

https://jaskey.github.io/blog/2019/09/23/spring-boot-tomcat-mertic/

posted @   雨后观山色  阅读(1223)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示