Controller 自动化日志输出
Starter库
1.定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TraceLog {/*** 日志类型** @return*/String type() default "";
}
2.定义捕获日志接口方法
public interface ITraceLogProcess {void afterThrowing(JoinPoint pjp, Throwable ex, Long beforeTime);void afterReturning(JoinPoint pjp, Object result, Long beforeTime);void before(JoinPoint pjp);
}
3.定义捕获日志方法实现
@Slf4j
public class TraceLogProcess implements ITraceLogProcess {private static String UNKNOWN_IP = "unknown";private static String X_FORWARDED_FOR = "x-forwarded-for";@Overridepublic void afterThrowing(JoinPoint pjp, Throwable ex, Long beforeTime) {MethodSignature signature = (MethodSignature) pjp.getSignature();Method method = signature.getMethod();TraceLog traceLog = method.getAnnotation(TraceLog.class);Integer errorCode = ResultCode.UNKNOWN_CODE.getCode();String errorMsg = ResultCode.UNKNOWN_CODE.getDesc();if (ex instanceof ApiException) {errorCode = ((ApiException) ex).getResultCode();errorMsg = ex.getMessage();}HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();log.info("[Tracelog failed] Call interface[{}] from IP[{}] return error," +"URL:[{}], method name:[{}]," +"method type:[{}], expend time(ms):[{}]," +"input parameter:[{}]," +"error code:[{}], error message:[{}]",traceLog != null ? traceLog.type() : "", getIpAddr(request),request.getRequestURL().toString(), signature.getName(),request.getMethod(), System.currentTimeMillis() - beforeTime,pjp.getArgs(), errorCode, errorMsg);}@Overridepublic void afterReturning(JoinPoint pjp, Object result, Long beforeTime) {MethodSignature signature = (MethodSignature) pjp.getSignature();Method method = signature.getMethod();TraceLog traceLog = method.getAnnotation(TraceLog.class);HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();log.info("[Tracelog success]Call interface[{}] from IP[{}]," +"URL:[{}], method name:[{}]," +"method type:[{}], expend time(ms):[{}]," +"input parameter:[{}]," +"result:[{}]",traceLog != null ? traceLog.type() : "", getIpAddr(request),request.getRequestURL().toString(), signature.getName(),request.getMethod(), System.currentTimeMillis() - beforeTime,pjp.getArgs(), JSONObject.toJSONString(result));}@Overridepublic void before(JoinPoint pjp) {MethodSignature signature = (MethodSignature) pjp.getSignature();Method method = signature.getMethod();TraceLog traceLog = method.getAnnotation(TraceLog.class);HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();log.info("[Tracelog begin]Call interface[{}] from IP[{}]," +"URL:[{}], method name:[{}]," +"method type:[{}], input parameter:[{}]",traceLog != null ? traceLog.type() : "", getIpAddr(request),request.getRequestURL().toString(), signature.getName(),request.getMethod(), pjp.getArgs());}private String getIpAddr(HttpServletRequest request) {//获取代理服务器IP地址String proxyIp = request.getHeader(X_FORWARDED_FOR);//如果存在代理服务器IP地址,则从中提取客户端真实IP地址if (proxyIp != null && proxyIp.length() != 0) {String[] ips = proxyIp.split(",");for (String ip : ips) {if (!UNKNOWN_IP.equalsIgnoreCase(ip)) {return ip.trim();}}}//如果不存在代理服务器IP地址,则直接获取远程IP地址return request.getRemoteAddr();}
}
4.定义日志捕获切面
@Slf4j
@Aspect
public class TraceLogAspect {@Resource(name = "traceLogProcess")ITraceLogProcess traceLogProcess;private Long beforeTime;@AfterThrowing(throwing = "ex", value = "@annotation(uih.st.core.traceLog.TraceLog)")public void afterThrowing(JoinPoint pjp, Throwable ex) {traceLogProcess.afterThrowing(pjp, ex, beforeTime);}@AfterReturning(returning = "result", value = "@annotation(uih.st.core.traceLog.TraceLog)")public void afterReturning(JoinPoint pjp, Object result) {traceLogProcess.afterReturning(pjp, result, beforeTime);}@Before(value = "@annotation(uih.st.core.traceLog.TraceLog)")public void before(JoinPoint pjp) {this.beforeTime = System.currentTimeMillis();traceLogProcess.before(pjp);}
}
5.通过AutoConfiguration实现注入
@Configuration
@ConditionalOnWebApplication
public class TraceLogAutoConfiguration {@Bean(name = "traceLogProcess")@ConditionalOnMissingBean(name = "traceLogProcess")public ITraceLogProcess traceLogProcess() {return new TraceLogProcess();}@Beanpublic TraceLogAspect traceLogAspect() {return new TraceLogAspect();}
}
6.starter文件spring.factories新增类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=core.TraceLogAutoConfiguration
应用使用
将上述实现的starter通过依赖引用后:
@TraceLog(type = "aaaaaa")
@PostMapping("/test")
public Result<Boolean> test() {return Result.success();
}
相关文章:
Controller 自动化日志输出
Starter库 1.定义注解 Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface TraceLog {/*** 日志类型** return*/String type() default ""; }2.定义捕获日志接口方法 public interface ITraceLogProcess {void afterThr…...
css3中有哪些新属性(特性)?
在 CSS3 中引入了许多新的属性和特性,以下是其中一些主要的: Flexbox(弹性盒子布局):通过 display: flex 及其相关属性,实现灵活的布局方式,使得元素在容器中可以自动调整大小和位置。 Grid&am…...
SAP ABAP 之面向对象OO
文章目录 前言一、类的理解二、如何创建ABAP类 a.类的定义与构成 b.类的访问区域 c.特殊方法 d.类的继承 三、类中参数的使用 a.IMPORTING / EXPORTING b.CHANGING c.RETURNING d.EX…...
在VSCode中使用Vim
在VSCode中使用Vim,主要涉及到Vim插件的安装和配置。以下是在VSCode中使用Vim的详细步骤: 1. 安装Vim插件 打开VSCode:首先,启动你的VSCode编辑器。进入扩展面板:在VSCode的左侧活动栏中,点击扩展图标&am…...
鸿蒙低代码开发的局限性
在版本是DevEco Studio 3.1.1 Release,SDK是3.1.0(API9) 的基础上。 1、低代码插件没有WebView组件。 2、低代码插件没有空白的自定义组件,当前提供的所谓自定义组件,只能用列表中提供的组件来拼接新的组件。 3、使用ets代码自定义的组件&…...
Codeforces Round 952 (Div. 4) c++题解(A-H1)
开头 : 这场没打,今天vp了一下,写了A-G,然后就去吃饭了! 比赛链接 : Dashboard - Codeforces Round 952 (Div. 4) - Codeforces A 直接交换,输出即可 inline void solve(){string a , b ; cin >> a>> b ;char c a[0] ;a…...
人工智能将成为数学家的“副驾驶”
人工智能将成为数学家的“副驾驶” 数学传统上是一门独立的科学。1986年,安德鲁怀尔斯为了证明费马定理,退到书房里呆了7年。由此产生的证明往往很难让同事们理解,有些至今仍有争议。但近年来,越来越多的数学领域被严格地分解为各…...
自适应巡航控制技术规范(简化版)
自适应巡航控制技术规范(简化版) 1 系统概述2 功能需求3 性能需求4 功能激活条件5 功能抑制条件6 系统局限性1 系统概述 ACC 自适应巡航系统可自动控制纵向跟车距离,减轻驾驶员的工作量,即驾驶员无需频繁的踩制动和油门便可完成部分的驾驶任务,但责任主体仍然是驾驶员,驾…...
【AI】文心一言的使用分享
在数字化时代,人工智能(AI)技术的飞速发展正在改变我们的生活。文心一言,作为这一浪潮中的佼佼者,以其卓越的自然语言处理能力和广泛的应用场景,给我带来了前所未有的使用体验。在这篇分享中,我…...
Java学习-MyBatis学习(四)
代码下载 解决字段名与属性名不一致 ①使用别名emp_name empName解决字段名和属性名不一致 <select id"getAllEmpOld" resultType"Emp"><!--①使用别名emp_name empName解决字段名和属性名不一致-->select eid,emp_name empName,age,sex,em…...
多源最短路径算法 -- 弗洛伊德(Floyd)算法
1. 简介 Floyd算法,全名为Floyd-Warshall算法,亦称弗洛伊德算法或佛洛依德算法,是一种用于寻找给定加权图中所有顶点对之间的最短路径的算法。这种算法以1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特弗洛伊德的名字命名。 2. 核心思…...
同三维T80005EH4 H.265 4路高清HDMI编码器
同三维T80005EH4 H.265 4路高清HDMI编码器 4路HDMI输入2路3.5音频输入,第1路和第2路HDMI可支持4K30,其它支持高清1080P60 产品简介: 同三维T80005EH4 4路HDMI高清H.265编码器采用最新高效H.265高清数字视频压缩技术,具备稳定…...
焦化行业排放平台简介
在当今社会,环保事业日益受到人们的关注。焦化行业作为重要的工业领域之一,其排放问题一直是环保工作的重点。为了有效控制焦化行业的排放,实施焦化行业排放平台成为了必不可少的措施。朗观视觉小编将详细探讨焦化行业排放平台的实施范围&…...
『原型资源』Axure自带图标库不够用,第三方经典图标库来袭
今天小编为大家带来第三方经典图标库,己确认内容可用现推荐给大家。直接上手就可不用自己画哈~ 获取原型文档请与班主任联系! 先睹为快,合适再拿走不谢: 图标太多,截取部分给大家参考o(* ̄︶ ̄*…...
修改版的VectorDBBench更好用
原版本VectorDBBench的几个问题 在这里就不介绍VectorDBBench是干什么的了,上官网即可。 1.并发数设置的太少 2.测试时长30秒太长 3.连接milvus无用户和密码框,这个是最大的问题 4.修改了一下其它参数 由于很多网友发私信问一些milvus的相关技术问…...
六西格玛培训都培训哪些内容 ?
天行健六西格玛培训的内容通常涵盖多个方面,旨在帮助学员全面理解和应用六西格玛管理方法。以下是详细的培训内容概述: 一、六西格玛基础知识 引入六西格玛的概念、原理和历史,包括DMAIC(定义、测量、分析、改进、控制࿰…...
K8S环境部署Prometheus
K8S环境部署Prometheus 记录在K8S 1.18版本环境下部署Prometheus 0.5版本。 1. 下载kube-prometheus仓库 git clone https://github.com/coreos/kube-prometheus.git cd kube-prometheus笔者安装的K8S版本是1.18 ,prometheus选择配套的分支release-0.5࿱…...
在linux系统上挂载新硬盘
服务器的硬盘空间不够了,自己重新安装了一个硬盘,需要挂载,因为只是用来存放数据,所以不需要分区,直接挂载就可以 #查看当前所有硬盘 sudo fdisk -l #用于显示文件系统的磁盘空间使用情况 df -h发现一个/dev/nvme0n1 …...
1004.最大连续1的个数
给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。 示例 1: 输入:nums [1,1,1,0,0,0,1,1,1,1,0], K 2 输出:6 解释:[1,1,1,0,0,1,1,1,1,1,1] 粗体数字…...
【机器学习300问】116、什么是序列模型?序列模型能干什么?
一、序列模型是什么? 序列模型是机器学习领域中专门设计来处理具有时间顺序或序列结构数据的模型。这类模型能够理解和学习数据中的顺序依赖关系,因此非常适合诸如自然语言处理、语音识别、音乐生成、时间序列预测等任务。 看了上面的定义,似…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...
基于Uniapp的HarmonyOS 5.0体育应用开发攻略
一、技术架构设计 1.混合开发框架选型 (1)使用Uniapp 3.8版本支持ArkTS编译 (2)通过uni-harmony插件调用原生能力 (3)分层架构设计: graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...
