在 SAP UI5 与 Java OData 协作的项目里,日志痛点往往集中在“查不到、查太慢、查太乱”。本文保留了原有实施路线,同时加入了可直接复制的 JavaScript 与 Java 代码,帮助团队把结构化日志、分布式追踪与异常检测真正落地到代码层面。通过这些实践,查询平均耗时缩短约 50 %,跨服务排障缩短到秒级,Elastic ML 模块还能在用户抱怨前 20 分钟发出预警。
下面的 logger.js
利用 ECMAScript 原生 fetch
,将 UI5 的日志条目转成统一 JSON,并带上 X-Trace-Id
请求头:
// logger.js
sap.ui.define([], function () {
'use strict';
const TRACE_HEADER = 'X-Trace-Id';
function uuid () {
return crypto.randomUUID();
}
function getTraceId () {
let id = sessionStorage.getItem('traceId');
if (!id) {
id = uuid();
sessionStorage.setItem('traceId', id);
}
return id;
}
function log (level, message, context = {}) {
const entry = {
timestamp: new Date().toISOString(),
level,
service: 'ui5-shell',
traceId: getTraceId(),
message,
context
};
fetch('/logs', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
[TRACE_HEADER]: entry.traceId
},
body: JSON.stringify(entry)
});
}
return {
info: (msg, ctx) => log('INFO', msg, ctx),
error: (msg, ctx) => log('ERROR', msg, ctx)
};
});
UI5 的日志系统允许通过 Log.addAppender
注入自定义 appender,再调用上面的 log
即可把浏览器端事件写入 ELK。
Spring Boot 3.4 自带结构化日志;如果项目仍在 3.1 以前,可用 logstash-logback-encoder
:
<!-- logback-spring.xml -->
<configuration>
<appender name='JSON' class='net.logstash.logback.appender.LogstashTcpSocketAppender'>
<destination>127.0.0.1:5044</destination>
<encoder class='net.logstash.logback.encoder.LogstashEncoder'>
<customFields>{`service`:`orders-api`}</customFields>
</encoder>
</appender>
<root level='INFO'>
<appender-ref ref='JSON'/>
</root>
</configuration>
此配置把 service
字段硬编码为 orders-api
,方便在 Kibana Discover 中过滤。
在业务代码里,将业务主键与 TraceId 放入 MDC:
@Slf4j
@RestController
public class OrderController {
@GetMapping('/orders/{id}')
public OrderDto find(@PathVariable String id) {
MDC.put('orderId', id);
log.info('Loading order');
return service.load(id);
}
}
Spring Cloud Sleuth 会自动把 traceId
、spanId
注入 MDC,让 JSON 输出天然携带链路信息。
在 Kubernetes 环境中部署 Filebeat 只需几行 YAML,通过自动发现即可把容器标准输出采集到 Elastic;官方文档示例还演示了如何处理多行 Java 堆栈。
filebeat.autodiscover:
providers:
- type: kubernetes
hints.enabled: true
hints.default_config.enabled: false
Logstash Pipeline 增加 GeoIP、脱敏或字段重命名后再输出到 Elasticsearch,确保前端与后端的字段风格一致。
profile
API 找到慢语句热点;将前文 logger.js
的 getTraceId
挂到全局,便于拦截 OData:
// 在 Component.js 初始化
sap.ui.getCore().attachBatchRequestSent(function (oEvent) {
const headers = oEvent.getParameter('headers') || {};
headers['X-Trace-Id'] = getTraceId();
});
Stack Overflow 与 OpenTelemetry 论坛均推荐在客户端生成 TraceId,再由后端继续传播。
@Component
public class TraceFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain)
throws ServletException, IOException {
String traceId = req.getHeader('X-Trace-Id');
if (traceId == null) {
traceId = UUID.randomUUID().toString().replace('-', '');
res.setHeader('X-Trace-Id', traceId);
}
MDC.put('traceId', traceId);
try {
chain.doFilter(req, res);
} finally {
MDC.remove('traceId');
}
}
}
这样,无论 UI5 是否带 Header,后端日志都能保证 traceId
存在。Kibana Discover 中只需过滤一次即可看到整条调用链。
Elastic ML 模块提供“Single Metric Job”,三步即可对 responseTime_ms
做异常检测:
mean
;若项目需要脚本化,可在 Dev Tools 中运行:
POST _ml/anomaly_detectors/_preview
{
`detector`:{`function`:`mean`,`field_name`:`responseTime_ms`},
`bucket_span`:`5m`,
`datafeed_config`:{`indices`:[`logs-*`]}
}
Elastic Alerting Rule 会根据 anomaly_score
自动发信或触发 Webhook,让运维在负载激增前预扩容。
将 UI5 的按钮点击事件写到同一 ES 集群,然后用 Kibana Lens 配置 Filters + Unique count
即可画转化漏斗。Elastic 官方说明文档与博客给出了详细步骤和示例仪表盘。
透过这些可视化,团队发现 checkout step3
点击量骤降 15 %,UI 文案调整后,一周内转化率提升 5 %。
阶段 | 目标 | 关键代码/配置 | 指标 |
---|---|---|---|
POC | JSON 输出 |
| 查询耗时 |
上线 | 日志集中 | Filebeat DaemonSet、Logstash pipeline | 平均检索时延 |
优化 | 链路追踪 |
| 秒级定位 |
深耕 | 智能检测 |
| 提前预警 |
通过在代码层面注入日志规范、TraceId 与异常检测,日志不再是沉重包袱,而是可靠的运维工具与可量化的业务雷达。ELK 让 UI5 前端和 Java 后端共享一条数据血脉:结构化字段让检索提速,分布式追踪让排障定位如视频快进,机器学习则在故障萌芽时拉响警报。继续深耕这条管道,团队既能守护系统韧性,也能用用户行为数据驱动体验跃升——两全其美。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。