You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spartacus SSR返回CSR fallback后如何记录HTTP请求耗时?

解决Spartacus Angular SSR fallback后HTTP请求耗时追踪问题

方案概述

要实现SSR超时返回CSR fallback后仍能记录应用HTTP请求耗时,核心思路是:

  1. 精准捕获CSR fallback的触发时机
  2. 通过HTTP拦截器全程追踪请求生命周期(即使SSR已返回fallback)
  3. 将耗时数据输出到可被监控工具(如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中可视化数据

  1. 日志捕获:确保SSR服务器已安装Dynatrace OneAgent并开启日志监控,拦截器输出的[SSR Request Timing]前缀日志会被自动收集。
  2. 自定义仪表盘:在Dynatrace中创建仪表盘,通过过滤日志前缀展示所有SSR请求的耗时数据。
  3. fallback关联分析:以X-Spartacus-SSR-Fallback响应头为维度,筛选触发fallback的请求,对比其与正常SSR请求的耗时差异。

额外优化建议

  • 关联请求ID:在拦截器中加入请求ID或用户会话ID,方便将耗时数据与具体用户请求关联。
  • 中央日志服务:若需长期存储分析数据,可将日志发送到ELK等中央日志系统,再同步到Dynatrace。
  • TransferState传递数据:若要在客户端展示耗时数据,可将结果存入TransferState,待CSR启动后读取显示(仅当SSR进程在客户端渲染前完成时有效)。

内容的提问来源于stack exchange,提问作者Krzysztof Platis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:35:26