ElasticsearchRestTemplate DSL日志打印

ElasticsearchRestTemplate DSL日志打印

    • 痛点
    • 解决方案
      • 打印基础文档查询信息
      • 打印最终DML语句

痛点

在使用 ElasticsearchRestTemplate 进行数据操作时,经常遇到的一个问题是线上问题排查困难。具体来说,在线上环境中,当出现问题时,我们往往无法直接获取到实际执行的 DSL(Domain Specific Language)语句。这导致我们在排查问题时面临以下几个主要挑战:

  • 缺乏可追溯性:当线上系统出现性能问题或数据不一致的问题时,我们需要能够回溯到具体的查询或更新操作。然而,由于 ElasticsearchRestTemplate 默认并不会记录实际执行的 DSL 语句,我们很难确定问题的具体原因。
  • 难以重现问题:在开发和测试环境中,我们通常会模拟各种场景来测试系统的健壮性和性能。但在生产环境中,由于数据量大且复杂,很多问题只有在实际运行时才会暴露出来。
  • 调试难度增加:当系统出现异常或错误时,我们需要能够快速定位问题并修复。如果无法获取到实际执行的 DSL 语句,我们就无法准确判断问题的原因。
  • 维护成本高:在长期维护过程中,系统可能会经历多次迭代和升级。如果没有记录实际执行的 DSL 语句,每次修改或优化查询逻辑时都需要重新验证其正确性和性能。
  • 性能优化困难:在优化过程中,我们需要能够分析每个查询的实际执行情况,从而找出性能瓶颈并进行针对性的优化。如果没有记录实际执行的 DSL 语句,我们就无法准确评估每个查询的性能表现,从而导致优化效果不佳。

解决方案

为了应对上述痛点,我们需要在使用 ElasticsearchRestTemplate 时打印实际执行的 DSL 日志。

打印基础文档查询信息

经查询发现有人提出打印queryBuilder.build().getQuery()的方法。然而,发现只会显示基础文档查询信息,而不包括过滤、聚合等内容。这并非我们所需的最终DML语句。

log.info("DML:{}", queryBuilder.build().getQuery());

在这里插入图片描述

打印最终DML语句

通过Debug我们发现 SearchRequest 中的source属性,正是我们想要的最终DML语句。
在这里插入图片描述
SearchRequest 需要通过 RequestFactory 获取,虽然 ElasticsearchRestTemplate 提供了getRequestFactory() 方法获取RequestFactory,但RequestFactory是个私有类,无法编译运行。好在java留了后门,提供了强大的反射机制。于是,对于elasticsearchRestTemplate.search()方法编写了如下切面:

/*** Description: ElasticsearchRestTemplate 切面** @author YanAn* @date 2024/9/20 10:52*/
@Slf4j
@Aspect
@Component
public class ElasticsearchRestTemplateAspect {@Resourceprivate ElasticsearchRestTemplate elasticsearchRestTemplate;/*** AbstractElasticsearchTemplate#search(org.springframework.data.elasticsearch.core.query.Query, java.lang.Class) 前置通知** @param joinPoint*/@Before("execution(* org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate.search(org.springframework.data.elasticsearch.core.query.Query, java.lang.Class))")public void beforeSearch(JoinPoint joinPoint) {try {Object[] args = joinPoint.getArgs();if (args != null && args.length == 2) {Query query = (Query) args[0];Class<?> clazz = (Class<?>) args[1];IndexCoordinates index = elasticsearchRestTemplate.getIndexCoordinatesFor(clazz);Method searchRequest = Class.forName("org.springframework.data.elasticsearch.core.RequestFactory").getMethod("searchRequest", Query.class, Class.class, IndexCoordinates.class);searchRequest.setAccessible(true);Object result = searchRequest.invoke(elasticsearchRestTemplate.getRequestFactory(), query, clazz, index);if (result instanceof SearchRequest) {SearchSourceBuilder source = ((SearchRequest) result).source();log.info("DSL: {}", source.toString());}} else {log.info("DSL打印失败");}} catch (Exception e) {log.warn("DSL打印失败", e);}}
}

效果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1541026.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vue项目中——如何用echarts实现动态水球图

有时候UI的脑洞真的很大&#xff0c;总是设计出一些稀奇古怪的图形&#xff0c;但又不得不佩服他们的审美&#xff0c;确实还挺好看的。今天给大家介绍echarts如何实现动态水球图。如图所示&#xff1a; 实现步骤 一、引入 在vue页面中引入echarts&#xff0c;如未安装需要先…

Java面试篇基础部分-Synchronized关键字详解

Synchronized关键字用于对Java对象、方法、代码块等提供线程安全操作。Synchronized属于独占式的悲观锁机制,同时也是可重入锁。我们在使用Synchronized关键字的时候,可以保证同一时刻只有一个线程对该对象进行访问;也就是说它在同一个JVM中是线程安全的。   Java中的每个…

Golang | Leetcode Golang题解之第420题强密码检验器

题目&#xff1a; 题解&#xff1a; func strongPasswordChecker(password string) int {hasLower, hasUpper, hasDigit : 0, 0, 0for _, ch : range password {if unicode.IsLower(ch) {hasLower 1} else if unicode.IsUpper(ch) {hasUpper 1} else if unicode.IsDigit(ch)…

TLC/TK Adv学习笔记1 - Py版本+美化

Python下重点 tkinter.ttk 模块自 Tk 8.5 开始引入&#xff0c;它提供了对 Tk 风格的部件集的访问。 它还带来了一些额外好处包括在 X11 下的反锯齿字体渲染和透明化窗口&#xff08;需要有 X11 上的混合窗口管理器&#xff09;。 tkinter.ttk 的基本设计思路&#xff0c;就是…

【Python】探索 Errbot:多功能聊天机器人框架

不是旅行治愈了你&#xff0c;是你在路上放过了自己。 在当今的数字化时代&#xff0c;聊天机器人已成为企业与客户互动、提升工作效率和增加乐趣的重要工具。Errbot是一个高度可扩展的聊天机器人框架&#xff0c;它允许开发者使用Python轻松创建和定制机器人。本文将介绍Errb…

乐观锁、悲观锁及死锁

乐观锁、悲观锁 1.概念 悲观锁(悲观锁定)&#xff1a;具有强烈的独占和排他特性。在整个执行过程中&#xff0c;将处于锁定状态。悲观锁在持有数据的时候总会把资源或者数据锁住&#xff0c;这样其他线程想要请求这个资源的时候就会阻塞&#xff0c;直到等到悲观锁把资源释放为…

如何基于Flink CDC与OceanBase构建实时数仓,实现简化链路,高效排查

本文作者&#xff1a;阿里云Flink SQL负责人&#xff0c;伍翀&#xff0c;Apache Flink PMC Member & Committer 众多数据领域的专业人士都很熟悉Apache Flink&#xff0c;它作为流式计算引擎&#xff0c;流批一体&#xff0c;其核心在于其强大的分布式流数据处理能力&…

DHCP协议原理(网络协议)

DHCP简介 定义 DHCP&#xff08;动态主机配置协议&#xff09;是一种网络管理协议&#xff0c;能够自动为局域网中的每台计算机分配IP地址及其他网络配置参数&#xff0c;包括子网掩码、默认网关和DNS服务器等。这一机制极大简化了网络管理&#xff0c;尤其在大型局域网中&am…

李沐 过拟合和欠拟合【动手学深度学习v2】

模型容量 模型容量的影响 估计模型容量 难以在不同的种类算法之间比较&#xff0c;例如树模型和神经网络 给定一个模型种类&#xff0c;将有两个主要因素&#xff1a; 参数的个数参数值的选择范围 VC维 线性分类器的VC维 VC维的用处 数据复杂度 多个重要因素&#xff1a; 样…

信息安全数学基础(20)中国剩余定理

前言 信息安全数学基础中的中国剩余定理&#xff08;Chinese Remainder Theorem&#xff0c;简称CRT&#xff09;&#xff0c;又称孙子定理&#xff0c;是数论中一个重要的定理&#xff0c;主要用于求解一次同余式组。 一、背景与起源 中国剩余定理最早见于我国南北朝时期的数学…

鸿蒙小技巧

1.子调用父的方法 子组件 父组件 2.使用emitter实现孙子传爷 孙子组件 import emitter from ohos.events.emitter;let event: emitter.InnerEvent {eventId: 1,priority: emitter.EventPriority.HIGH};let eventData: emitter.EventData {data: {"state": true,…

R语言APSIM模型进阶应用与参数优化、批量模拟实践技术

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

帧率和丢帧分析实践

一、识别丢帧 1、使用AppAnalyzer检测性能问题 首先使用AppAnalyzer工具进行性能问题检测&#xff0c;AppAnalyzer是DevEco Studio中提供的检测评分工具&#xff0c;用于测试并评价HarmonyOS应用或元服务的质量&#xff0c;能快速提供评估结果和改进建议&#xff0c;当前支持的…

Visual Studio 引入外部静态库与动态库

Windows Visual Studio 引入外部静态库与动态库 1.前言 在C开发中不可避免地要在自己的项目中引入外部库&#xff08;OpenGL、OpenCV、OCC等&#xff09;&#xff0c;使用这些库都需要在项目中配置相应的属性才能正常开发编译。 2.引入 引入外部库主要引入三种文件&#xf…

C语言 | Leetcode C语言题解之第420题强密码检验器

题目&#xff1a; 题解&#xff1a; #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))int strongPasswordChecker(char * password) {int n strlen(password);bool has_lower false, has_upper false, has_digit false;for …

高质量的翻译:应用程序可用性和成功的关键

在日益全球化的应用市场中&#xff0c;开发一款优秀的产品只是成功的一半。另一半&#xff1f;确保你的用户&#xff0c;无论他们在哪里或说什么语言&#xff0c;都能无缝理解和使用它。这就是高质量翻译的用武之地——不是事后的想法&#xff0c;而是应用程序可用性和最终成功…

攻防世界---->ReverseMe-120

做题学习笔记。 前言&#xff1a;目前遇见的reverse都是&#xff0c;已知密文&#xff0c;去求解明文flag&#xff1b; 此题逆着来&#xff0c;通过明文&#xff0c;去求解密文flag。 base加密的识别&#xff0c;还算容易。 那么&#xff0c;base解码的识别呢&#xff1f; 攻…

Java调用数据库 笔记06 (修改篇)

1.创建Java的普通class类 2.加载驱动 Class.forName("com.mysql.jdbc.Driver"); 3.驱动管理类调用方法进行连接&#xff0c;得到连接对象 DriverManager.getConnection(url, user, password); 其中设置参数&#xff1a; static final String url "jdbc:my…

聊天组件 Vue3-beautiful-chat 插槽

前言 Vue3-beautiful-chat 组件有四个插槽可以定制 一、user-avatar(头像) 首先是头像插槽,我们可以直接在 <beautiful-chat></beautiful-chat> 中间使用; 作用: 我们可以在用户头像上添加自定义样式,比如添加节日边框、可以使用首字母作为头像。。。 …

《使用 LangChain 进行大模型应用开发》学习笔记(五)

前言 本文是 Harrison Chase &#xff08;LangChain 创建者&#xff09;和吴恩达&#xff08;Andrew Ng&#xff09;的视频课程《LangChain for LLM Application Development》&#xff08;使用 LangChain 进行大模型应用开发&#xff09;的学习笔记。由于原课程为全英文视频课…