概述
SpringBoot整合ELK单指将SpringBoot日志推送至Logstash以及使用教程。
日志流程
项目输出Log日志 --> TCP推送Logstash --> Logstash接收日志处理 --> 输出到Elasticsearch中 --> Kibana图形化展示
流程图如下:
Logstash配置
TCP方式
input {
# TCP输入,Json格式编码UTF-8
tcp {
port => 9400
codec => json {
charset => "UTF-8"
}
}
stdin{}
}
filter {
}
output {
elasticsearch {
action => "index"
# 这里是es的地址,多个es要写成数组的形式
hosts => "elasticsearch-server:9200"
# 用于kibana过滤,可以填项目名称,按日期生成索引
index => "vosp-log-%{+YYYY-MM-dd}"
# es用户名
user => vosp
# es密码
password => vosp123
# 超时时间
timeout => 300
}
}
SpringBoot+Log4j2
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions><!-- 去掉springboot默认配置 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <!-- 引入log4j2依赖 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
编写SpringBoot启动以及配置类
新建配置类,
import org.slf4j.MDC;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.GenericApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
/**
* @Author HuangKang
* @Date 2021/4/22 下午5:44
* @Summarize Log4j2启动配置文件事件监听器
* SpringApplication application = new SpringApplication(VospApiApplication.class);
* Set<ApplicationListener<?>> ls = application.getListeners();
* Log4j2PropertiesEventListener eventListener = new Log4j2PropertiesEventListener();
* application.addListeners(eventListener);
* application.run(args);
* 启动类启动注册监听器
*/
public class Log4j2PropertiesEventListener implements GenericApplicationListener {
public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 10;
private static Class<?>[] EVENT_TYPES = {ApplicationStartingEvent.class, ApplicationEnvironmentPreparedEvent.class,
ApplicationPreparedEvent.class, ContextClosedEvent.class, ApplicationFailedEvent.class};
private static Class<?>[] SOURCE_TYPES = {SpringApplication.class, ApplicationContext.class};
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
ConfigurableEnvironment envi = ((ApplicationEnvironmentPreparedEvent) event).getEnvironment();
MutablePropertySources mps = envi.getPropertySources();
// 获取配置文件配置源,注意版本不同SpringBoot可能配置源名称不一样,可以DEBUG查看名称
PropertySource<?> ps = mps.get("configurationProperties");
// 设置log4j2日志收集logstash地址
if (ps != null && ps.containsProperty("log4j2.logstash.address")) {
Object address = ps.getProperty("log4j2.logstash.address");
if (address != null && !address.toString().trim().isEmpty()) {
MDC.put("log4j2.logstash.address", address.toString());
}
}
// 设置log4j2日志收集logstash端口号
if (ps != null && ps.containsProperty("log4j2.logstash.port")) {
Object port = ps.getProperty("log4j2.logstash.port");
if (port != null && !port.toString().trim().isEmpty()) {
MDC.put("log4j2.logstash.port", port.toString());
}
}
// 设置log4j2日志收集logstash日志格式化表达式
if (ps != null && ps.containsProperty("log4j2.logstash.pattern")) {
Object pattern = ps.getProperty("log4j2.logstash.pattern");
if (pattern != null && !pattern.toString().trim().isEmpty()) {
// 获取项目名
String appName = ps.getProperty("spring.application.name").toString();
// 获取项目名
String profile = ps.getProperty("spring.profiles.active").toString();
MDC.put("log4j2.logstash.pattern", pattern.toString().replace("${spring.application.name}", appName).replace("${spring.profiles.active}",profile));
}
}
}
}
@Override
public int getOrder() {
return DEFAULT_ORDER;
}
@Override
public boolean supportsEventType(ResolvableType resolvableType) {
return isAssignableFrom(resolvableType.getRawClass(), EVENT_TYPES);
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
return isAssignableFrom(sourceType, SOURCE_TYPES);
}
private boolean isAssignableFrom(Class<?> type, Class<?>... supportedTypes) {
if (type != null) {
for (Class<?> supportedType : supportedTypes) {
if (supportedType.isAssignableFrom(type)) {
return true;
}
}
}
return false;
}
}
修改SpringBoot启动类,添加监听器
public static void main(String[] args) {
SpringApplication application = new SpringApplication(BootK8sApplication.class);
// 添加Log4j2配置文件监听
Log4j2PropertiesEventListener eventListener = new Log4j2PropertiesEventListener();
application.addListeners(eventListener);
application.run(args);
}
编写配置文件
在Yaml中写入如下参数
spring:
application:
# 项目名称启动时传入Log4j2作为app名称
name: test-k8s
logging:
# Log4j2配置文件xml地址
config: classpath:log4j2-spring.xml
log4j2:
logstash:
# 自定义配置Logstash地址
address: 124.71.9.101
# 自定义配置Logstash端口号
port: 9400
# 自定义Json消息
# {
# "app": "${spring.application.name}", 当前项目名称
# "class": "%c", 类全限定名称
# "method": "%M", 输出日志方法
# "traceId": "%X{traceId}", traceId跟踪
# "level": "%level", 日志级别
# "message": "[%thread] [%c:%L] --- %replace{%msg}{\"}{\\\"}\" 消息内容体,将"替换为转义,防止日志中输出Json导致解析异常
# "profile":"${spring.profiles.active}" 当前启动环境
# }
# Json写入至ELK中属性
pattern: "{\"app\":\"${spring.application.name}\", \"profile\":\"${spring.profiles.active}\", \"class\":\"%c\",\"method\":\"%M\",\"traceId\":\"%X{traceId}\",\"level\": \"%level\", \"message\": \"[%thread] [%c:%L] --- %replace{%msg}{\\\"}{\\\\\\\"}\\\"}%n"
编写Log4j2-XML文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="info" monitorInterval="30">
<properties>
<!--日志路径-->
<property name="log.path">./logs</property>
<!--日志打印格式-->
<property name="pattern">%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5level] [%X{traceId}] [%t] [%C{1.}] %msg%n</property>
<!--SpringBoot读取的配置地址,端口以及日志格式-->
<Property name="logstashAddress">${ctx:log4j2.logstash.address}</Property>
<Property name="logstashPort">${ctx:log4j2.logstash.port}</Property>
<Property name="logstashPattern">${ctx:log4j2.logstash.pattern}</Property>
</properties>
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<console name="console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout>
<!-- 控制台彩色日志格式 -->
<Pattern>%style{%d{yyyy-MM-dd HH:mm:ss,SSS}}{bright,white} %highlight{%-5level} %style{[%X{traceId}]}{cyan} [%style{%t}{bright,blue}] [%style{%C{1.}}{bright,yellow}:%L] %msg%n%style{%throwable}{red}</Pattern>
<!-- 控制台统一日志格式 -->
<!-- <Pattern>${pattern}</Pattern>-->
</PatternLayout>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</console>
<RollingFile name="infoLog" immediateFlush="true" fileName="${sys:log.path}/info.log"
filePattern="${sys:log.path}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.zip">
<Filters>
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="warnLog" immediateFlush="true" fileName="${sys:log.path}/warn.log"
filePattern="${sys:log.path}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.zip">
<Filters>
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="errorLog" immediateFlush="true" fileName="${sys:log.path}/error.log"
filePattern="${sys:log.path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.zip">
<Filters>
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<Pattern>${pattern}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<!-- Socket TCP方式推送日志到Logstash中,只推送INFO以及以上级别日志 -->
<Socket>
<name>logstash</name>
<protocol>TCP</protocol>
<port>${logstashPort}</port>
<host>${logstashAddress}</host>
<PatternLayout pattern="${logstashPattern}"/>
<reconnectionDelay>5000</reconnectionDelay>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Socket>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
<loggers>
<!--过滤掉无用的debug信息-->
<logger name="org.springframework" level="INFO"/>
<logger name="org.mybatis" level="INFO"/>
<logger name="cn.binarywang" level="ERROR"/>
<!--指定了logger就使用logger,没有指定就使用root-->
<logger name="com.botpy.vosp.client" level="debug" additivity="false">
<appender-ref ref="console"/>
<appender-ref ref="infoLog"/>
<appender-ref ref="warnLog"/>
<appender-ref ref="errorLog"/>
</logger>
<logger name="logstashLog" level="info" additivity="false">
<appender-ref ref="logstash"/>
</logger>
<root level="debug">
<appender-ref ref="console"/>
<appender-ref ref="infoLog"/>
<appender-ref ref="warnLog"/>
<appender-ref ref="errorLog"/>
<appender-ref ref="logstash" />
</root>
</loggers>
</configuration>
新增traceId拦截器
新建拦截器
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
/**
* @Author HuangKang
* @Date 2021/4/23 下午2:23
* @Summarize 请求TraceId拦截器
*/
@Component
public class RequestTraceIdInterceptor implements HandlerInterceptor {
/**
* 日志TRACE_ID名称常量
*/
private static final String LOG_TRACE_ID_NAME = "traceId";
/**
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
MDC.put(LOG_TRACE_ID_NAME, UUID.randomUUID().toString().replace("-",""));
return true;
}
}
新增Mvc配置拦截器
package com.kang.test.k8s.config;
import com.kang.test.k8s.interceptor.RequestTraceIdInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Author HuangKang
* @Date 2021/4/23 下午4:00
* @Summarize 自定义WebMvc配置
*/
@Configuration
public class CustomWebMvcConfig implements WebMvcConfigurer {
final RequestTraceIdInterceptor requestTraceIdInterceptor;
@Autowired
public CustomWebMvcConfig(RequestTraceIdInterceptor requestTraceIdInterceptor) {
this.requestTraceIdInterceptor = requestTraceIdInterceptor;
}
/**
* 添加拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 添加TraceId拦截器
registry.addInterceptor(requestTraceIdInterceptor);
}
}
使用方式,新建Controller测试功能
@RequestMapping("/")
public Map index() throws UnknownHostException {
Map<String, Object> map = new HashMap<>();
InetAddress localHost = InetAddress.getLocalHost();
String hostName = localHost.getHostName();
String hostAddress = localHost.getHostAddress();
map.put("主机名",hostName);
map.put("主机地址",hostAddress);
log.info("测试日志");
return map;
}
调用接口后打印如下日志
可以查看到INFO [3d9e051ceafe4e59bce8aa6ac2972fda] 成功打印traceId
2021-04-23 16:21:13,929 INFO [3d9e051ceafe4e59bce8aa6ac2972fda] [http-nio-8080-exec-1] [c.k.t.k.c.TestK8sController:37] 测试日志
SpringBoot+Logback
引入依赖
引入依赖正常即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.1</version>
</dependency>
编写配置文件
spring:
application:
# 项目名称启动时传入,写入ELK通过app名称进行隔离
name: test-k8s
profiles:
# 启动环境,ELK隔离通过profile属性隔离dev以及prod
active: log
server:
port: 8080
logging:
# 日志文件地址
config: classpath:logback-spring.xml
# 配置Logstash地址
logstash:
address: 124.71.9.101:9400
编写XML文件
新建XML文件,重点观察ELK Json属性,可以自定义拓展,新建logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--从配置文件读取配置路径,并且添加默认值-->
<!--日志全局设置-->
<springProperty scope="context" name="log.charset" source="log.charset" defaultValue="UTF-8"/>
<springProperty scope="context" name="log.pattern" source="log.pattern"
defaultValue="%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5level] [%X{traceId}] [%t] [%C{1.}] %msg%n"/>
<!--INFO日志设置-->
<springProperty scope="context" name="info.path" source="log.info.path" defaultValue="logs/info"/>
<springProperty scope="context" name="info.history" source="log.info.history" defaultValue="10"/>
<springProperty scope="context" name="info.maxsize" source="log.info.maxsize" defaultValue="1GB"/>
<springProperty scope="context" name="info.filesize" source="log.info.filesize" defaultValue="10MB"/>
<springProperty scope="context" name="info.pattern" source="log.info.pattern"
defaultValue="%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n"/>
<!--ERROR日志设置-->
<springProperty scope="context" name="error.path" source="log.error.path" defaultValue="logs/error"/>
<springProperty scope="context" name="error.history" source="log.error.history" defaultValue="10"/>
<springProperty scope="context" name="error.maxsize" source="log.error.maxsize" defaultValue="1GB"/>
<springProperty scope="context" name="error.filesize" source="log.error.filesize" defaultValue="10MB"/>
<springProperty scope="context" name="error.pattern" source="log.error.pattern"
defaultValue="%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n"/>
<!--从SpringBoot配置文件读取项目名,环境,以及logstash地址-->
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<springProperty scope="context" name="springProfile" source="spring.profiles.active"/>
<springProperty scope="context" name="logstashAddress" source="logging.logstash.address"/>
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 定义彩色日志格式模板 -->
<!--控制台日志打印格式-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>${log.pattern}</pattern>
<charset>${log.charset}</charset>
</encoder>
</appender>
<!--INFO日志打印-->
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高, 所以我们使用下面的策略,可以避免输出 Error 的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--过滤 Error-->
<level>ERROR</level>
<!--匹配到就禁止-->
<onMatch>DENY</onMatch>
<!--没有匹配到就允许-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天的日志改名为今天的日期。即,<File> 的日志都是当天的。-->
<!--<File>logs/info.spring-boot-demo-logback.log</File>-->
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${info.path}/info_%d{yyyy-MM-dd}.part_%i.log</FileNamePattern>
<!--只保留最近10天的日志-->
<maxHistory>${info.history}</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<totalSizeCap>${info.maxsize}</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 -->
<maxFileSize>${info.filesize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!--<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">-->
<!--<maxFileSize>1KB</maxFileSize>-->
<!--</triggeringPolicy>-->
<encoder>
<pattern>${info.pattern}</pattern>
<charset>${log.charset}</charset> <!-- 此处设置字符集 -->
</encoder>
</appender>
<!--ERROR日志打印-->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天的日志改名为今天的日期。即,<File> 的日志都是当天的。-->
<!--<File>logs/error.spring-boot-demo-logback.log</File>-->
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${error.path}/error_%d{yyyy-MM-dd}.part_%i.log</FileNamePattern>
<!--只保留最近90天的日志-->
<maxHistory>${error.history}</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<totalSizeCap>${error.maxsize}</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 -->
<maxFileSize>${error.filesize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>${error.pattern}</pattern>
<charset>${log.charset}</charset> <!-- 此处设置字符集 -->
</encoder>
</appender>
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${logstashAddress}</destination>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
<!--设置项目-->
"app": "${springAppName:-}",
<!--设置环境-->
"profile": "${springProfile:-}",
<!--设置等级-->
"level": "%level",
<!--设置traceId-->
"traceId": "%X{traceId}",
<!--设置类名-->
"class": "%c",
<!--设置方法名-->
"method": "%M",
<!--设置消息-->
"message": "[%thread] [%X{traceId}] [%logger{35}:%L] --- %msg"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE_INFO"/>
<appender-ref ref="FILE_ERROR"/>
<appender-ref ref="logstash"/>
</root>
</configuration>
新增traceId拦截器
参考上方Log4j2一样
Kibana使用
修改时间显示格式化
打开菜单 --> 打开Stack Management --> 找到Kibana --> 选择高级设置 --> 修改日期格式
新建日志视图
打开菜单 --> 打开Stack Management --> 找到Kibana --> 选择索引模式 --> 点击创建索引模式
点击创建编辑如下输入日志表达式,匹配格式,匹配日志索引,点击下一步
选择时间字段,TCP方式Logstash推送日志后会自动生成,选择日志即可,点击创建索引模式
使用日志视图
打开菜单 --> 打开Discover --> 点击进入
打开菜单 --> 打开Discover --> 点击下拉框选择创建的索引匹配器,即可打开日志视图
日志筛选
点击添加筛选,选择运算符是 (等于),设置日志级别即可过滤
查看指定信息
点击Message,点击添加Message,就只查看Message的信息
点击点击后查看的结果如下
新增日志视图图表分析
打开菜单 --> 打开Dashboard --> 点击创建 --> 点击创建面板 --> 创建Lens选择自己的图表以及需要统计展示的日志字段即可
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。