Spartacus SSR返回CSR fallback后如何记录HTTP请求耗时?
解决Spartacus Angular SSR fallback后HTTP请求耗时追踪问题
方案概述
要实现SSR超时返回CSR fallback后仍能记录应用HTTP请求耗时,核心思路是:
- 精准捕获CSR fallback的触发时机
- 通过HTTP拦截器全程追踪请求生命周期(即使SSR已返回fallback)
- 将耗时数据输出到可被监控工具(如Dynatrace)捕获的渠道
步骤1:检测CSR fallback触发状态
在Spartacus SSR的服务端逻辑中,修改server.ts标记fallback触发,并通过响应头让Dynatrace感知这一状态:
// server.ts 渲染逻辑部分 app.get('*', (req, res) => { res.render(indexHtml, { req, res, providers: [ { provide: APP_BASE_HREF, useValue: req.baseUrl }, { provide: REQUEST, useValue: req }, { provide: RESPONSE, useValue: res }, // 配置SSR超时时间(示例为5秒) { provide: NgExpressEngineDecoratorOptions, useValue: { timeout: 5000 } } ], }, (err, html) => { // 渲染超时触发err回调,返回CSR fallback if (err) { // 添加自定义响应头,供Dynatrace识别fallback请求 res.setHeader('X-Spartacus-SSR-Fallback', 'true'); // 返回CSR页面 res.sendFile(join(distFolder, 'index.html')); // 记录fallback触发日志 console.log(`[SSR Fallback] 触发于 ${req.url},时间:${new Date().toISOString()}`); } else { res.send(html); } }); });
通过X-Spartacus-SSR-Fallback响应头,你可以在Dynatrace的请求详情中直接判断该请求是否触发了fallback。
步骤2:拦截并追踪HTTP请求耗时
创建全局HTTP拦截器,捕获每个请求的开始和结束时间,即使SSR已返回fallback,拦截器依然能追踪后台运行的请求:
// request-timing.interceptor.ts import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class RequestTimingInterceptor implements HttpInterceptor { intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { const startTime = Date.now(); const { method, url } = request; return next.handle(request).pipe( tap( (event) => { if (event instanceof HttpResponse) { const duration = Date.now() - startTime; // 输出请求耗时日志,Dynatrace日志监控可自动捕获 console.log(`[SSR Request Timing] ${method} ${url} 耗时:${duration}ms`); } }, (error) => { const duration = Date.now() - startTime; console.error(`[SSR Request Timing] ${method} ${url} 失败,耗时:${duration}ms,错误:${error.message}`); } ) ); } }
在SSR模块中注册该拦截器:
// app.server.module.ts import { NgModule } from '@angular/core'; import { ServerModule, ServerTransferStateModule } from '@angular/platform-server'; import { AppModule } from './app.module'; import { AppComponent } from './app.component'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { RequestTimingInterceptor } from './request-timing.interceptor'; @NgModule({ imports: [AppModule, ServerModule, ServerTransferStateModule], bootstrap: [AppComponent], providers: [ { provide: HTTP_INTERCEPTORS, useClass: RequestTimingInterceptor, multi: true } ] }) export class AppServerModule {}
步骤3:在Dynatrace中可视化数据
- 日志捕获:确保SSR服务器已安装Dynatrace OneAgent并开启日志监控,拦截器输出的
[SSR Request Timing]前缀日志会被自动收集。 - 自定义仪表盘:在Dynatrace中创建仪表盘,通过过滤日志前缀展示所有SSR请求的耗时数据。
- fallback关联分析:以
X-Spartacus-SSR-Fallback响应头为维度,筛选触发fallback的请求,对比其与正常SSR请求的耗时差异。
额外优化建议
- 关联请求ID:在拦截器中加入请求ID或用户会话ID,方便将耗时数据与具体用户请求关联。
- 中央日志服务:若需长期存储分析数据,可将日志发送到ELK等中央日志系统,再同步到Dynatrace。
- TransferState传递数据:若要在客户端展示耗时数据,可将结果存入
TransferState,待CSR启动后读取显示(仅当SSR进程在客户端渲染前完成时有效)。
内容的提问来源于stack exchange,提问作者Krzysztof Platis
相关产品推荐
相关产品推荐

