Skywalking增加登录认证和日志收集
背景:继上文Skywalking链路追踪工具基础完善一下两个小功能——登录认证和日志收集。
1.nginx方式auth_basic认证
下载httpd-tools工具生成htpasswd加密文件
yum install -y httpd-tools
htpasswd -cb nginx/htpasswd skywalking qlgya@666.
配置nginx
server {
listen port;
#auth_basic "Please enter the user name and password"; #这里是验证时的提示信息
#auth_basic_user_file /data/skywalking/nginx/htpasswd;
index index.html;
location / {
root html;
index index.html index.htm;
#auth_basic on;
auth_basic "Please enter the user name and password"; #这里是验证时的提示信息
auth_basic_user_file /data/nginx/htpasswd;
proxy_pass http://192.168.XXX.XXX:9009;
# WebSocket 穿透
#proxy_set_header Origin "";
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection "upgrade";
}
}
效果
还有一种是使用Spring Gateway增加认证暂时先不用
2.日志收集
增加依赖
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.9.0</version>
</dependency>
修改日志配置
在我们添加的依赖apm-toolkit-logback-1.x中,包含了大量适配于logback与skywalking的Appender、Encoder以及Layout实现类。下面我们需要对日志配置文件进行修改。
在微服务系统的一次请求调用链中,可能出现多个服务之间相互调用的场景(如商品服务调用订单服务,订单服务调用支付服务)。而这些服务显然处于不同的进程甚至不同的服务器,如何确定一个请求的调用链路中调用了哪些服务呢?
1. 添加链路表示traceId
skywalking使用traceId对调用链路进行标识,traceId的格式为随机字符,如果没有请求链路,则输出日志中的traceId为N/A。如果以羊肉串类比,多个羊肉被同一个棍子串起来,羊肉就类比为链路上的多个服务,棍子就类比为traceId。
修改logback.xml日志配置文件
-
在日志的输出格式定义中添加
%tid,并修改对应的Layout实现类为TraceIdPatternLogbackLayout。<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 日志输出格式 --> <property name="log.pattern" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %boldMagenta([%tid]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)"/> <!-- 控制台输出 --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> <Pattern>${log.pattern}</Pattern> </layout> </encoder> </appender> <root level="info"> <appender-ref ref="console"/> </root> </configuration> -
没有请求链路的系统日志
-
当我们向接口发送请求时
请求如下:
日志如下,从输出的日志可以看到,该请求的调用链为8012端口的商品服务调用8021端口的订单服务,8021端口的订单服务调用8032端口的支付服务,在该调用链上各个服务的traceId相同。
进入skywalking服务端的页面,我们查看该调用链路,该链路的traceId与日志中打印的traceId一致。
2. 添加链路上下文
由于traceId仅表示为随机字符,可读性较差。幸运的是,skywalking也认识到这一点,于是又引入了一个新的概念:链路上下文SW_CTX,所谓链路上下文,其实与traceId的作用相同,但他的好处是可读性强,其格式为SW_CTX:[服务名, 实例名, traceId, traceSegmentId, spanId]。
同样的,如果没有请求链路,则输出日志中的链路上下文为SW_CTX:[服务名, 实例名, N/A, N/A, -1]。
修改logback.xml日志配置文件
-
将日志的输出格式定义中表示
traceId的%tid修改为%sw_ctx即可<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 日志输出格式 --> <property name="log.pattern" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %boldMagenta([%sw_ctx]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)"/> <!-- 控制台输出 --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> <Pattern>${log.pattern}</Pattern> </layout> </encoder> </appender> <root level="info"> <appender-ref ref="console"/> </root> </configuration> -
重启项目,查看没有请求链路的系统日志
-
当我们向接口发送请求时
请求如下
日志如下,由于打印出的上下文日志包含信息量过长,只截取其部分日志。
进入skywalking服务端的页面,我们查看该调用链路,该调用链路同样是商品服务的8011端口服务调用订单服务的8022端口服务,且该调用链的traceId与日志中打印的traceId一致。
3. 异步日志
skywalking客户端还支持日志的异步打印,就是说业务代码与日志打印采用不同的线程执行,提高接口响应速度。
修改logback.xml日志配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志输出格式 -->
<property name="log.pattern"
value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %boldMagenta([%tid]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>${log.pattern}</Pattern>
</layout>
</encoder>
</appender>
<!-- 异步输出 -->
<appender name="console-async" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1024</queueSize>
<neverBlock>true</neverBlock>
<appender-ref ref="console"/>
</appender>
<root level="info">
<appender-ref ref="console-async"/>
</root>
</configuration>
四、收集链路日志
skywalking客户端通过gRpc将输出的日志发送给skywalking服务端,skywalking服务端根据traceId去分析日志,然后通过skywalking服务端页面可以查看指定调用链路中所有服务所输出的日志。
-
修改
logback.xml日志配置文件,只需要添加GRPCLogClientAppender即可<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 日志输出格式 --> <property name="log.pattern" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %boldMagenta([%tid]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)"/> <!-- 控制台输出 --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> <Pattern>${log.pattern}</Pattern> </layout> </encoder> </appender> <!-- 异步输出 --> <appender name="console-async" class="ch.qos.logback.classic.AsyncAppender"> <discardingThreshold>0</discardingThreshold> <queueSize>1024</queueSize> <neverBlock>true</neverBlock> <appender-ref ref="console"/> </appender> <!-- 使用gRpc将日志发送到skywalking服务端 --> <appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> <Pattern>${log.pattern}</Pattern> </layout> </encoder> </appender> <root level="info"> <appender-ref ref="console-async"/> <appender-ref ref="grpc-log"/> </root> </configuration> -
重启项目,并向接口发送请求
-
查看输出的日志
-
进入skywalking页面查看
-
查看该调用链路上各服务的日志,我们以商品服务的日志为例,在调用链路中电击商品服务,可查看对应的实例详情,再点击相关的日志,即可查看商品服务该实例所产生的日志列表,该列表中每一行即为代码中打印的一行日志,点击可查看该行完整的日志信息。
参考
1.使用Nginx和Spring Gateway为SkyWalking的增加登录认证功能