feign如何开启日志及分析

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: feign如何开启日志及分析

1、首先需要设置属性logging.level.包名:debug。为什么要打开这个属性呢?

因为feign的logger实现类Slf4jLogger在调用log方法时,会判断是否开启了debug。

protectedvoidlog(StringconfigKey, Stringformat, Object... args) {
// Not using SLF4J's support for parameterized messages (even though it would be more efficient)// because it would// require the incoming message formats to be SLF4J-specific.if (logger.isDebugEnabled()) {
logger.debug(String.format(methodTag(configKey) +format, args));
    }
}

2、feign的日志级别

feign的日志级别包含下面几个

  • NONE:不输出日志
  • BASIC:输出请求方法及url,响应的状态码及响应时间
  • HEADERS:输出请求和响应的头信息
  • FULL:输出请求和响应的请求头,消息体及元数据

在发送请求时,会判断feign的日志级别,如果级别大于等于HEADERS,则输出请求头,如果级别大于等于FULL,则输出消息体。

protectedvoidlogRequest(StringconfigKey, LevellogLevel, Requestrequest) {
log(configKey, "---> %s %s HTTP/1.1", request.httpMethod().name(), request.url());
if (logLevel.ordinal() >=Level.HEADERS.ordinal()) {
for (Stringfield : request.headers().keySet()) {
for (Stringvalue : valuesOrEmpty(request.headers(), field)) {
log(configKey, "%s: %s", field, value);
        }
      }
intbodyLength=0;
if (request.body() !=null) {
bodyLength=request.length();
if (logLevel.ordinal() >=Level.FULL.ordinal()) {
StringbodyText=request.charset() !=null?newString(request.body(), request.charset())
                  : null;
log(configKey, ""); // CRLFlog(configKey, "%s", bodyText!=null?bodyText : "Binary data");
        }
      }
log(configKey, "---> END HTTP (%s-byte body)", bodyLength);
    }
}

在feign处理响应时,AsyncResponseHandler处理响应时判断日志级别输出日志,请求头或者消息体。

protectedResponselogAndRebufferResponse(StringconfigKey,
LevellogLevel,
Responseresponse,
longelapsedTime)
throwsIOException {
Stringreason=response.reason() !=null&&logLevel.compareTo(Level.NONE) >0?" "+response.reason()
            : "";
intstatus=response.status();
log(configKey, "<--- HTTP/1.1 %s%s (%sms)", status, reason, elapsedTime);
if (logLevel.ordinal() >=Level.HEADERS.ordinal()) {
for (Stringfield : response.headers().keySet()) {
for (Stringvalue : valuesOrEmpty(response.headers(), field)) {
log(configKey, "%s: %s", field, value);
        }
      }
intbodyLength=0;
if (response.body() !=null&&!(status==204||status==205)) {
// HTTP 204 No Content "...response MUST NOT include a message-body"// HTTP 205 Reset Content "...response MUST NOT include an entity"if (logLevel.ordinal() >=Level.FULL.ordinal()) {
log(configKey, ""); // CRLF        }
byte[] bodyData=Util.toByteArray(response.body().asInputStream());
bodyLength=bodyData.length;
if (logLevel.ordinal() >=Level.FULL.ordinal() &&bodyLength>0) {
log(configKey, "%s", decodeOrDefault(bodyData, UTF_8, "Binary data"));
        }
log(configKey, "<--- END HTTP (%s-byte body)", bodyLength);
returnresponse.toBuilder().body(bodyData).build();
      } else {
log(configKey, "<--- END HTTP (%s-byte body)", bodyLength);
      }
    }
returnresponse;
}

3、如何设置日志级别的方式

3.1 通过属性配置

即feign.client.{contextId}.loggerLeve=BASIC、HEADERS或者FULL

可以发现在配置feign时,先是使用Configuration来配置,然后使用属性中的默认配置,最后使用属性中contextId对应的配置

protectedvoidconfigureFeign(FeignContextcontext, Feign.Builderbuilder) {
FeignClientPropertiesproperties=applicationContext            .getBean(FeignClientProperties.class);
FeignClientConfigurerfeignClientConfigurer=getOptional(context,
FeignClientConfigurer.class);
setInheritParentContext(feignClientConfigurer.inheritParentConfiguration());
if (properties!=null&&inheritParentContext) {
if (properties.isDefaultToProperties()) {
configureUsingConfiguration(context, builder);
configureUsingProperties(
properties.getConfig().get(properties.getDefaultConfig()),
builder);
configureUsingProperties(properties.getConfig().get(contextId), builder);
        }
else {
configureUsingProperties(
properties.getConfig().get(properties.getDefaultConfig()),
builder);
configureUsingProperties(properties.getConfig().get(contextId), builder);
configureUsingConfiguration(context, builder);
        }
    }
else {
configureUsingConfiguration(context, builder);
    }
}

3.2 @Configuration配置

@ConfigurationpublicclassFeignClientConfig {
@BeanLogger.LevelfeignLoggerLevel() {
returnLogger.Level.FULL;
    }
}

此时是通过父子BeanFactory中查找Logger.Level,因为在子BeanFactory中没有,实际上是在父BeanFactory查找得到Logger.Level。

3.3 @FeignClient注解中的configuration来指定配置类。

此时是通过在子BeanFactory中查找得到Logger.Level。

配置的优先级为从高到低

配置文件中的contextId对应的属性->配置文件中的default对应的属性->FeignClient注解通过configuration指定的配置类->全局配置

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1天前
|
缓存 监控 算法
分析慢日志文件来优化 PHP 脚本的性能
分析慢日志文件来优化 PHP 脚本的性能
|
1月前
|
SQL 监控 关系型数据库
使用 pt-query-digest 工具分析 MySQL 慢日志
【8月更文挑战第5天】使用 pt-query-digest 工具分析 MySQL 慢日志
33 3
使用 pt-query-digest 工具分析 MySQL 慢日志
|
28天前
|
存储 分布式计算 大数据
【Flume的大数据之旅】探索Flume如何成为大数据分析的得力助手,从日志收集到实时处理一网打尽!
【8月更文挑战第24天】Apache Flume是一款高效可靠的数据收集系统,专为Hadoop环境设计。它能在数据产生端与分析/存储端间搭建桥梁,适用于日志收集、数据集成、实时处理及数据备份等多种场景。通过监控不同来源的日志文件并将数据标准化后传输至Hadoop等平台,Flume支持了性能监控、数据分析等多种需求。此外,它还能与Apache Storm或Flink等实时处理框架集成,实现数据的即时分析。下面展示了一个简单的Flume配置示例,说明如何将日志数据导入HDFS进行存储。总之,Flume凭借其灵活性和强大的集成能力,在大数据处理流程中占据了重要地位。
33 3
|
29天前
|
应用服务中间件 Linux nginx
在Linux中,如何统计ip访问情况?分析 nginx 访问日志?如何找出访问页面数量在前十位的ip?
在Linux中,如何统计ip访问情况?分析 nginx 访问日志?如何找出访问页面数量在前十位的ip?
|
1月前
|
监控 安全 关系型数据库
在Linux中,什么是系统日志和应用程序日志?如何分析它们?
在Linux中,什么是系统日志和应用程序日志?如何分析它们?
|
22天前
|
存储 消息中间件 监控
Java日志详解:日志级别,优先级、配置文件、常见日志管理系统ELK、日志收集分析
Java日志详解:日志级别,优先级、配置文件、常见日志管理系统、日志收集分析。日志级别从小到大的关系(优先级从低到高): ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF 低级别的会输出高级别的信息,高级别的不会输出低级别的信息
|
24天前
|
算法 关系型数据库 程序员
第一周算法设计与分析:A : log2(N)
这篇文章介绍了解决算法问题"输入一个数N,输出log2N(向下取整)"的三种编程思路,包括使用对数函数和幂函数的转换方法,以及避免浮点数精度问题的整数逼近方法。
|
2月前
|
消息中间件 Kubernetes Kafka
日志采集/分析
日志采集/分析
51 7
|
1月前
|
存储 数据可视化 Linux
在Linux中,如何使用ELK进行日志管理和分析?
在Linux中,如何使用ELK进行日志管理和分析?
|
1月前
|
存储 监控 数据可视化
在Linux中,有哪些日志管理和分析工具?
在Linux中,有哪些日志管理和分析工具?