Spring Bootlog and monitor

LearningSpring Boot logconfiguration and monitormechanism, includingLogback, Actuator and Prometheusetc.tool using

1. Spring Bootlogconfiguration

Spring Boot默认usingSLF4Jserving aslog门面, Logbackserving aslogimplementation.

1.1 log级别

log级别 from low to high 依次 for :

  • TRACE: 最详细 loginformation
  • DEBUG: debuginformation
  • INFO: 一般information
  • WARN: warninginformation
  • ERROR: errorinformation

1.2 basiclogconfiguration

in application.propertiesinconfigurationlog级别:

# 根log级别
logging.level.root=INFO
# specificpackage log级别
logging.level.com.example=DEBUG
# specificclass log级别
logging.level.org.springframework.web=WARN
logging.level.org.hibernate=ERROR

1.3 log输出格式

configurationlog输出格式:

# 控制台输出格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
# file输出格式
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n

1.4 logfileconfiguration

configurationlogfile:

# logfilepath
logging.file.name=logs/myapp.log
# logfile big  small 限制
logging.logback.rollingpolicy.max-file-size=10MB
# 保留 logfile数量
logging.logback.rollingpolicy.max-history=7

1.5 自定义Logbackconfiguration

in src/main/resourcesTable of Contents under creationlogback-spring.xmlfile, 自定义Logbackconfiguration:

<configuration>
    <!-- application名称 -->
    <property name="APP_NAME" value="myapp" />
    
    <!-- logfilepath -->
    <property name="LOG_PATH" value="logs" />
    
    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    
    <!-- file输出 (INFO级别)  -->
    <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${APP_NAME}_info_%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <maxHistory>7</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
    </appender>
    
    <!-- file输出 (ERROR级别)  -->
    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${APP_NAME}_error_%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <maxHistory>7</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
    </appender>
    
    <!-- 根logconfiguration -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE_INFO" />
        <appender-ref ref="FILE_ERROR" />
    </root>
    
    <!-- specificpackage logconfiguration -->
    <logger name="com.example" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE_INFO" />
        <appender-ref ref="FILE_ERROR" />
    </logger>
</configuration>

2. Spring Boot Actuator

Spring Boot Actuatorproviding了一系列produce级functions, such ashealthycheck, 指标monitoretc..

2.1 添加Actuator依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2.2 configurationActuator

in application.propertiesinconfigurationActuator:

# 暴露所 has 端点
management.endpoints.web.exposure.include=*
# 暴露healthycheck详细information
management.endpoint.health.show-details=always
# 设置端点 before 缀
management.endpoints.web.base-path=/actuator

2.3 常用Actuator端点

  • /actuator/health: healthycheck
  • /actuator/info: applicationinformation
  • /actuator/metrics: application指标
  • /actuator/env: environmentvariable
  • /actuator/configprops: configurationproperty
  • /actuator/loggers: logconfiguration
  • /actuator/beans: Spring Beaninformation
  • /actuator/mappings: requestmap
  • /actuator/threaddump: thread转储
  • /actuator/heapdump: 堆转储

2.4 自定义healthycheck

creation自定义healthycheckcomponent:

@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        // check自定义healthystatus
        boolean isHealthy = checkCustomHealth();
        
        if (isHealthy) {
            return Health.up()
                    .withDetail("custom", "service正常")
                    .withDetail("timestamp", System.currentTimeMillis())
                    .build();
        } else {
            return Health.down()
                    .withDetail("custom", "serviceexception")
                    .withDetail("timestamp", System.currentTimeMillis())
                    .build();
        }
    }
    
    private boolean checkCustomHealth() {
        // implementation自定义healthycheck逻辑
        return true;
    }
}

2.5 自定义Infoinformation

in application.propertiesinconfiguration自定义Infoinformation:

info.app.name=My Application
info.app.version=1.0.0
info.app.description=Spring Boot Actuator Demo
info.build.artifact=@project.artifactId@
info.build.version=@project.version@

3. Prometheus and Grafanamonitor

Prometheus用于收集指标, Grafana用于visualization指标.

3.1 添加Micrometer依赖

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

3.2 configurationPrometheus

configurationPrometheus收集Spring Boot指标:

# configurationMicrometer
management.metrics.export.prometheus.enabled=true
# configurationapplication名称 (用于Prometheustag) 
spring.application.name=myapp

3.3 installationPrometheus

  1. from Prometheus官网 under 载Prometheus
  2. 解压并creationprometheus.ymlconfigurationfile:
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'spring-boot'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['localhost:8080']

启动Prometheus:

./prometheus --config.file=prometheus.yml

访问http://localhost:9090查看Prometheus界面.

3.4 installationGrafana

  1. from Grafana官网 under 载Grafana
  2. 启动Grafana:
# Linux
sudo systemctl start grafana-server

# Windows
启动grafana-server.exe

访问http://localhost:3000 (默认user名/password: admin/admin) .

3.5 configurationGrafanadatasources

  1. loginGrafana after , 点击"Configuration" -> "Data Sources"
  2. 点击"Add data source", 选择"Prometheus"
  3. 设置URL for http://localhost:9090, 点击"Save & Test"

3.6 importGrafana仪表板

  1. 点击"Create" -> "Import"
  2. 输入仪表板ID (such as10280, Spring Boot 2.x 官方仪表板)
  3. 选择Prometheusdatasources, 点击"Import"

4. log收集 and analysis

for 于distributedsystem, 我们需要集in收集 and analysislog.

4.1 ELK Stack

ELK StackincludingElasticsearch, Logstash and Kibana:

  • Elasticsearch: distributed搜index擎, 用于store and indexlog
  • Logstash: log收集 and processingtool
  • Kibana: logvisualizationtool

4.2 usingFilebeat收集log

Filebeat is a 轻量级 log收集tool:

# installationFilebeat
sudo apt-get install filebeat

# configurationFilebeat (/etc/filebeat/filebeat.yml) 
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /path/to/logs/*.log

output.elasticsearch:
  hosts: ["localhost:9200"]

setup.kibana:
  host: "localhost:5601"

# 启动Filebeat
sudo systemctl start filebeat

4.3 usingLogstashprocessinglog

configurationLogstashprocessinglog:

# configurationLogstash (logstash.conf) 
input {
  beats {
    port => 5044
  }
}

filter {
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} \[%{DATA:thread}\] %{LOGLEVEL:level} %{DATA:logger} - %{GREEDYDATA:message}" }
  }
  date {
    match => [ "timestamp", "yyyy-MM-dd HH:mm:ss.SSS" ]
    target => "@timestamp"
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "myapp-logs-%{+YYYY.MM.dd}"
  }
  stdout {
    codec => rubydebug
  }
}

5. distributed追踪

distributed追踪用于跟踪request in distributedsystemin 流转.

5.1 添加Sleuth and Zipkin依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

5.2 configurationSleuth and Zipkin

in application.propertiesinconfiguration:

# configuration采样率 (1.0表示100%采样) 
spring.sleuth.sampler.rate=1.0
# Zipkinserver地址
spring.zipkin.base-url=http://localhost:9411/

5.3 启动Zipkin

# usingDocker启动Zipkin
docker run -d -p 9411:9411 openzipkin/zipkin

访问http://localhost:9411查看Zipkin界面.

6. monitorbest practices

6.1 选择合适 monitor指标

  • Basics设施指标: CPU, memory, disk, networketc.
  • application指标: request数, response时间, error率etc.
  • 业务指标: 订单数, user数, 销售额etc.

6.2 设置合理 告警规则

根据指标设置合理 告警阈值, such as:

  • CPUusing率超过80%持续5分钟
  • memoryusing率超过90%持续10分钟
  • error率超过5%持续1分钟
  • requestresponse时间超过2秒持续5分钟

6.3 定期analysismonitordata

定期analysismonitordata, 找出system瓶颈 and optimization点.

6.4 monitordata持久化

将monitordata持久化 to datalibrary, 用于趋势analysis and 容量planning.

6.5 security考虑

  • 限制Actuator端点 访问
  • for monitorsystem添加authentication and authorization
  • encryptionmonitordata 传输

7. logbest practices

7.1 log级别usingprinciples

  • TRACE/DEBUG: 仅 in Development and debug时using
  • INFO: 记录 important 业务operation and systemevent
  • WARN: 记录可能导致issues circumstances
  • ERROR: 记录error and exception

7.2 log in 容best practices

  • log in 容应package含足够 on under 文information
  • 避免记录敏感information (such aspassword, Tokenetc.)
  • usingstructure化log, 便于analysis and 搜索
  • 统一log格式, 便于集in收集 and analysis

7.3 logperformance考虑

  • 避免 in 循环in记录 big 量log
  • using条件log, such aslogger.isDebugEnabled()
  • 合理设置log级别, 避免记录过 many 无用log
  • usingasynchronouslog, improvingapplicationperformance

7.4 asynchronouslogconfiguration

in Logbackinconfigurationasynchronouslog:

<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
    <discardingThreshold>0</discardingThreshold>
    <queueSize>512</queueSize>
    <appender-ref ref="FILE_INFO" />
</appender>