首页 > 其他分享 >第3方接口交互-日志方案

第3方接口交互-日志方案

时间:2023-01-31 16:15:21浏览次数:49  
标签:interLog demo req 接口 private org import 日志 交互

1. 打印log日志
2. 异步记录到日志表中
日志表
CREATE TABLE `d_interaction_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增长id',
  `client_code` varchar(20) NOT NULL COMMENT '系统标识',
  `direction` char(1) NOT NULL COMMENT '数据流向:出(S)/入(R)',
  `key_code` varchar(50) DEFAULT NULL COMMENT '业务主键/applycd',
  `serialnumber` varchar(50) DEFAULT NULL COMMENT '流水号',
  `interface_name` varchar(200) DEFAULT NULL COMMENT '接口名称',
  `remotehost` varchar(200) DEFAULT NULL COMMENT '访问主机地址',
  `input_params` mediumtext COMMENT '入参',
  `output_params` mediumtext COMMENT '出参',
  `request_time` datetime DEFAULT NULL COMMENT '开始请求时间',
  `response_time` datetime DEFAULT NULL COMMENT '收到响应时间',
  `time_length` int(11) DEFAULT NULL COMMENT '耗时:ms',
  `result` int(11) DEFAULT NULL COMMENT '调用结果:1,成功;0,失败',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注,发生错误时放入异常信息',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `IDX_KEYCODE` (`key_code`),
  KEY `IDX_SERNUM` (`serialnumber`)
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8 AVG_ROW_LENGTH=613 COMMENT='与外部业务系统交互日志'
日志 bean
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Date;


@TableName("d_interaction_log")
@Getter
@Setter
public class InteractionLog implements Serializable {
	private static final long serialVersionUID = 1L;

	/** 自增长id */
	@TableId(type = IdType.AUTO)
 	private Integer id;
	/** 系统标识 */
 	private String clientCode;
	/** 数据流向:出(S)/入(R) */
 	private String direction;
	/** 业务主键/applycd */
 	private String keyCode;
	/** 流水号 */
 	private String serialnumber;
	/** 接口名称 */
 	private String interfaceName;
	/** 访问主机地址 */
 	private String remotehost;
	/** 入参 */
 	private String inputParams;
	/** 出参 */
 	private String outputParams;
	/** 开始请求时间 */
 	private Date requestTime;
	/** 收到响应时间 */
 	private Date responseTime;
	/** 耗时:ms */
 	private Integer timeLength;
	/** 调用结果:1,成功;0,失败 */
 	private Integer result;
	/** 备注,发生错误时放入异常信息 */
 	private String remark;
	/** 创建时间 */
 	private Date createTime;
};
import org.demo.model.entity.InteractionLog;
import org.cango.midbase.mybatis.CangoBaseMapper;

public interface InteractionLogMapper extends CangoBaseMapper<InteractionLog> {

}
public interface AsyncService {
    /**
     * 异步保存日志
     * @param interLog
     */
    void saveInterLog(InteractionLog interLog);
}


@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {
    @Autowired
    private InteractionLogMapper interLogMapper;

    @Override
    @Async("asyncServiceExecutor")
    public void saveInterLog(InteractionLog interLog) {
        interLogMapper.insert(interLog);
    }
}
异步线程池
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
@Slf4j
public class ThreadPoolTaskExecutorConfig {

    @Bean
    public Executor asyncServiceExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(20);
        //配置最大线程数
        executor.setMaxPoolSize(50);
        //空闲时间
        executor.setKeepAliveSeconds(60);
        //配置队列大小
        executor.setQueueCapacity(5000);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix("thread-");
        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }
}
package org.demo.service.invoke.paycenter.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.cango.base.exception.CangoBusinessException;
import org.demo.config.cache.LocalMapCache;
import org.demo.enums.PayCenterPayChannelEnum;
import org.demo.integration.ChargeBackPaymentRes;
import org.demo.integration.GetQrPayResultResponseModel;
import org.demo.integration.QrResponseModel;
import org.demo.model.dto.req.GetChargeBackResultReq;
import org.demo.model.dto.req.PayReq;
import org.demo.model.dto.req.paycenter.InsPayOrderReq;
import org.demo.model.dto.req.paycenter.PayOrderQueryReq;
import org.demo.model.dto.req.paycenter.QuotationRes;
import org.demo.model.dto.req.paycenter.TradeRefundReq;
import org.demo.model.dto.res.PayRes;
import org.demo.model.entity.CWorkOrderPayment;
import org.demo.model.entity.InteractionLog;
import org.demo.model.entity.quotation.QuotationEntity;
import org.demo.service.invoke.paycenter.PayCenterService;
import org.demo.service.system.AsyncService;
import org.demo.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 支付中心交互
 */
@Service
@Slf4j
public class PayCenterServiceImpl implements PayCenterService {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private AsyncService asyncService;

    @Override
    public ChargeBackPaymentRes queryResult(GetChargeBackResultReq req) {
        AssertsUtil.assertsNull(req.getApplyId(), "applyId不能为空");
        AssertsUtil.assertsNull(req.getClientId(), "clientId不能为空");

        Date start = Calendar.getInstance().getTime();
        JSONObject param = new JSONObject();
        String responseBody = "";
        String remark = null;
        Integer result = 1;

        // 退款结果查询 url
        final String url = "http://xxx.yyy";
        try {
            // 加解密密钥
            final String slatKey = "xxxxx";
            // 签名
            req.setSign(AESUtil.sign(req, slatKey));

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity entity = new HttpEntity(req, headers);

            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
            responseBody = responseEntity.getBody();
            JSONObject st = JSONObject.parseObject(responseBody);
            final String resultCode = st.getString("resultCode");
            final String resultMsg = st.getString("resultMsg");
            JSONObject obj = st.getJSONObject("obj");
            if (!"0000".equals(resultCode)) {
                throw new CangoBusinessException("0004", new Object[]{resultMsg});
            }
            if (obj == null) {
                throw new CangoBusinessException("0004", new Object[]{"接口未返回信息"});
            }
            return JSONObject.parseObject(obj.toJSONString(), ChargeBackPaymentRes.class);
        } catch (Exception e) {
            log.error("【退款结果查询】失败,入参:{}", req, e);
            remark = e.getMessage();
            result = 0;
            throw new CangoBusinessException("0004", new Object[]{"退款结果查询失败:" + remark});
        } finally {
            log.info("【退款结果查询】入参:{}, 出参:{}, 入参明文:{}", param, responseBody, req);

            // 异步写入日志
            InteractionLog interLog = new InteractionLog();
            // 系统标识
            interLog.setClientCode(TARGET_CLIENT_CODE);
            // 数据流向:出(S)/入(R)
            interLog.setDirection("S");
            // 业务主键
            interLog.setKeyCode(req.getApplyId());
            // 流水号
            interLog.setSerialnumber(req.getApplyId());
            // 接口名称
            interLog.setInterfaceName(url);
            // 入参
            interLog.setInputParams(req.toString());
            // 出参
            interLog.setOutputParams(responseBody);
            // 开始请求时间
            interLog.setRequestTime(start);
            Date end = Calendar.getInstance().getTime();
            // 收到响应时间
            interLog.setResponseTime(end);
            int tl = (int) (end.getTime() - start.getTime());
            // 耗时:ms
            interLog.setTimeLength(tl);
            interLog.setRemotehost(CommonUtil.getHost(url));
            // 备注
            if (null != remark && remark.length() > 500) {
                remark = remark.substring(0, 499);
            }
            interLog.setRemark(remark);
            // 调用结果
            interLog.setResult(result);
            interLog.setCreateTime(new Date());
            asyncService.saveInterLog(interLog);
        }
    }
}

标签:interLog,demo,req,接口,private,org,import,日志,交互
From: https://www.cnblogs.com/lovedaodao/p/17079460.html

相关文章

  • 【转载】 spring 利用注解类添加日志到mysql
    一、前言我们写完一个项目,运维时,如果出现了bug,我们需要查看控制台的日志,但是那个日志无关方法太多,查找不是很方便,还有就是一个项目上线之后,我们需要记录谁操作了那些功能,......
  • springboot 统一日志记录 - AOP日志
    参考学习:https://www.bilibili.com/video/BV1bf4y187KX/三步:1.使用日志注解。2.编写日志注解类。3.编写日志注解类的AOP实现。1.在需要记日志处,使用自定义的注解。pac......
  • Java(9)类/对象/接口
    一.Java是面向对象的编程语言,对象就是面向对象程序设计的核心。所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种......
  • drf前戏 web应用模式 api接口 postman下载安装以及基本使用
    今日内容概要web应用模式djangoweb框架专门用来写web项目之前所学习的写的bbs项目图书管理项目使用的是前后端混合开发在真正的项目中应该是前后端分开来处理......
  • 密封类和密封接口sealed和permits关键字
    1.sealed和permits类和接口上可以添加sealed关键字,用来限定自己可以派生出哪些子类.换句话说,就是控制哪些子类可以继承或者实现自己,不允许其他类派生.sealedclassB......
  • 【悲伤的Debug日志】Windows Anaconda 运行报错 ImportError: DLL load failed while
    今天在Windows10上安装Anaconda(Anaconda|AnacondaDistribution)。首次安装选择了“在所有用户上安装”,发现进入下一步时无法勾选“将Anaconda加入PATH环境变......
  • api接口规范/测试/DRF
    Web应用模式1.前后端不分离客户端看到的内容和所有页面效果都是有一个服务器提供的。后端代码和前端代码都是一起返回的前后端分离把前端页面效果前端的代码单独分离......
  • web应用模式、api接口、postman下载
    web应用模式#djangoweb框架,专门用来写web项目#bbs项目,图书管理系统,用的是前后端混合开发-后端人员,写后端,也要写【模板语法】---》xx.html的python代码-全栈开发-......
  • 温习日志-10
    温习日志——2023年1月30日下午学习内容简单数组方法通过arr.slice(开始截断索引,截断后一位索引)返回的是截断后的新数组如果slice中不放任何参数就是类似于浅拷贝......
  • drf基础:1、web应用模式、API接口、接口测试工具
    drf入门一、web应用模式​ web的应用模式共分为两种,前后端不分离、前后端分离1、前后端混合​ 之前所写的bbs项目就是前后端不分离,后端人员在开发过程中使用模板语法......