OpenFeign 各种用法、 logger 日志记录

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: OpenFeign 各种用法、 logger 日志记录

<spring-cloud-openfeign.version>2.2.6.RELEASE</spring-cloud-openfeign.version>

对应的SpringBoot

<version>2.3.0.RELEASE</version>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>${spring-cloud-openfeign.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>archaius-core</artifactId>
            <groupId>com.netflix.archaius</groupId>
        </exclusion>
    </exclusions>
</dependency>

如果不在同一个 Module 中,需要添加 MapperScan

@ComponentScan(basePackages = {"com.iron"})
@SpringBootApplication
@EnableFeignClients(basePackages = {"com.iron.his"})
@MapperScan(basePackages ={"com.iron.his.mapper"} ) -- 如果两个MapperScan 就需要 classpath: 改成 classpath*
public class DefaultApplication { 
    public static void main(String[] args) {
        SpringApplication.run(VipSoftWebApplication.class, args);
    } 
}

 

日志记录

FeignConfig

package com.vipsoft.dingtalk.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfig {
    /**
     * Feign 的详细日志,配合yml使用
     *logging:
     *   level:
     *     # feign 日志以什么级别监控哪个接口
     *     com.vipsoft.ecgreport.sehedule.service: debug
     * @return
     */
    @Bean
    Logger.Level fegnLoggerLevel(){
        return Logger.Level.FULL;
    }
}

application.yml

server:
  application:
    name: VipSoft Dingtalk
  port: 8080
  servlet:
    context-path: /dingtalk
  tomcat:
    basedir: ./logs/
    background-processor-delay: 30
    redirect-context-root: true
    uri-encoding: UTF-8
    accesslog:
      enabled: true #为true时,上面的日期格式才有意义,否则就是写在一个文件里了
      buffered: true
      directory: ./logs
      file-date-format: .yyyy-MM-dd
      #pattern: '%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %D ms'
      pattern: '%t %a %m %U %s %b %D ms'
      prefix: access_log
      rename-on-rotate: false
      request-attributes-enabled: false
      rotate: true
      suffix: .log
# 因为feign调试日志是debug级别输出,springboot默认的日志级别是info,所以feign的debug日志级别就不会输出
# logging.level=debug这样配置是对所有的日志级别进行配置
# 该场景只需要对feign接口进行debug配置,所以是这样配置logging.level.com.vipsoft.dingtalk.rpc=debug
logging:
   level:
     # feign 日志以什么级别监控哪个接口
     com.vipsoft.dingtalk.rpc: debug
dingtalk:
  rebot-url: https://oapi.dingtalk.com

 

简单调用

//定义一个拦截器
public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        requestTemplate.header("AppId", "AppId");
        requestTemplate.header("AppKey", "myuser1");
        requestTemplate.header("AppSecret", "mypassword");
    }
}
//接口类
@Component
@FeignClient(name = "demo-feign",
        url = "https://www.fastmock.site/mock/e5738f58a04967320a772f1d69aa4a41/mp/",
        configuration = FeignInterceptor.class)
public interface IFeignTestService {
    @GetMapping(value = "/GetUser")
    String getUser(@RequestBody String words);
}
//调用
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FeignTests {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IFeignTestService feignTestService;
    @Test
    void searchTest() {
        String result = feignTestService.getUser("VipSoft");
        logger.info(result);
    }
}

 

OpenFeign 动态URL

//定义一个拦截器
public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        requestTemplate.header("AppId", "AppId");
        requestTemplate.header("AppKey", "myuser1");
        requestTemplate.header("AppSecret", "mypassword");
    }
}
//接口类
@Component
@FeignClient(name = "demo-feign",
        url = "url必须有值,这里随便写,但不能为空",
        configuration = FeignInterceptor.class)
public interface IFeignTestService {
    @PostMapping("/")
    String getWebsite(URI uri, @RequestBody String words); 
}
//调用
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FeignTests {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IFeignTestService feignTestService;
    @Test
    void searchTest() {
       String ss1 = feignTestService.getWebsite(new URI("https://www.fastmock.site/mock/e5738f58a04967320a772f1d69aa4a41/mp/GetUser"), "");
        logger.error(ss1);
        String ss2 = feignTestService.getWebsite(new URI("https://www.fastmock.site/mock/e5738f58a04967320a772f1d69aa4a41/mp/hospital"), "");
        logger.error(ss2);
        String ss3 = feignTestService.getWebsite(new URI("https://www.fastmock.site/mock/e5738f58a04967320a772f1d69aa4a41/mp/device"), "");
        logger.error(ss3); 
    }
}

OpenFeign  application/x-www-form-urlencoded

@Test
void queryOrderTest() { 
    MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
    param.add("msg_type", "GUOGUO_QUERY_SEND_SERVICE_DETAIL");
    param.add("logistic_provider_id", "123456"); 
    param.add("data_digest", "def");
    param.add("logistics_interface", "abc");
    String result = cainiaoService.querySendServiceDetail(param);
    logger.info(PojoUtil.pojoToJson(param));
    logger.info(result);
}
 
@Component
@FeignClient(name = "feign-cainiao", url = "${cainiao.url}")
public interface IFeignCainiaoService {
  
    /**
     * 获取三期API接口
     *
     * @param bodyParam AppId、PageIndex、PageSize
     * @return
     */
    @PostMapping(headers = {"content-type=application/x-www-form-urlencoded"})
    String querySendServiceDetail(@RequestBody MultiValueMap<String, Object> bodyParam);
}

OpenFeign 自定义配置

//接口类
@Component
@FeignClient(name = "demo-feign",
        url = "url必须有值,这里随便写,但不能为空",
        configuration = IFeignTestService.MultipartSupportConfig.class)
public interface IFeignTestService {
    //写接口内部,这样可以高内聚
    class MultipartSupportConfig {
        @Autowired
        private ObjectFactory<HttpMessageConverters> messageConverters;
        @Bean
        public Encoder feignFormEncoder() {
            return new SpringFormEncoder(new SpringEncoder(messageConverters));
        }
    }
    @PostMapping("/")
    String getWebsite(URI uri, @RequestBody String words); 
}

 


 

传 Header、URL 参数

/**
 * 发送预警信息 
 * @return
*/
@PostMapping(value = "/")
String sendMessage(@RequestHeader Map<String, Object> headerParam, @RequestBody RobotMessage param);
/**
 * 发送预警信息 
 * @return
*/
@PostMapping(value = "/robot/send")
String sendMessage(@RequestParam Map<String, Object> headerParam, @RequestBody RobotMessage param);

 

上传文件

@FeignClient(name = "vipsoft", url = "${api.url}")
public interface ICallbackFeignService {
    /**
     * 上传文件
     *
     * 注意: 使用openfeign传递参数含有文件类型时必须指定 consumes = MediaType.MULTIPART_FORM_DATA_VALUE*
     * @return
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String upload(@RequestPart("file") MultipartFile file);
}    
package com.vipsoft.web;
import com.vipsoft.web.rpc.ICallbackFeignService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
@SpringBootTest
public class AppCallbackTest {
    @Autowired
    ICallbackFeignService appCallbackFeignService;
    @Test
    void Upload() throws Exception {
        File file = new File("D:\\Users\\Desktop\\fanye.mp4");
        //这里的第一个参数值 file 是对应上面feign的文件注解中的@RequestPar中的name。一定要对应上
        MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "application/octet-stream;charset=utf-8", new FileInputStream(file));
        appCallbackFeignService.upload(multipartFile);
    }
}

 

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
5月前
|
运维 Linux Windows
[运维技术]PowerShell中实现一个最基本的日志器logger
[运维技术]PowerShell中实现一个最基本的日志器logger
79 1
|
2月前
|
Java 应用服务中间件 HSF
Java应用结构规范问题之AllLoggers接口获取异常日志的Logger实例的问题如何解决
Java应用结构规范问题之AllLoggers接口获取异常日志的Logger实例的问题如何解决
|
2月前
|
消息中间件 监控 搜索推荐
OpenFeign日志组件Logger原理与应用
该文章详细解释了如何在OpenFeign中配置并使用请求和响应的GZIP压缩功能。
|
4月前
|
监控 Linux 数据处理
深入了解Linux的logger命令:日志记录与监控
`logger`命令在Linux中用于向系统日志发送消息,便于记录系统事件和应用程序状态。它与`syslogd`配合,允许用户指定优先级、标识符和内容。简单易用,灵活适应不同日志需求。示例:`logger -p user.warning -t MYAPP &quot;A warning occurred.&quot;`。注意选择合适优先级,使用有意义的标识符,并结合其他工具如`logrotate`进行日志管理。
|
5月前
|
监控 安全 API
orhanobut/logger - 强大的Android日志打印库
orhanobut/logger - 强大的Android日志打印库
253 1
|
Java Spring
logger的日志笔记
logger的日志笔记
65 0
|
运维 Linux Windows
PowerShell中实现一个最基本的日志器logger
Powershell 是 IT 运维中绕不过去的一个语言,它不仅能在Windows中使用,同样也适用于Linux。对于运维人员来说,虽然不需要像后端开发人员一样制作日志器以记录大量的生产数据,但也同样存在记录某些运行过程的需求。
188 0
|
Python
Python 日志打印之自定义logger handler
Python 日志打印之自定义logger handler
277 0
springboot之log4j:WARN No appenders could be found for logger
springboot之log4j:WARN No appenders could be found for logger
springboot之log4j:WARN No appenders could be found for logger
|
JSON 安全 数据格式
python接口自动化(四十)- logger 日志 - 下(超详解)
日志是非常重要的,用于记录系统、软件操作事件的记录文件或文件集合,可分为事件日志和消息日志。具有处理历史数据、诊断问题的追踪以及理解系统、软件的活动等重要作用,在开发或者测试软系统过程中出现了问题,我们首先想到的就是她——logging。
228 0
python接口自动化(四十)- logger 日志 - 下(超详解)