【问题标题】:How to log the time of http requests in Spartacus SSR, even after the SSR timeout如何在 Spartacus SSR 中记录 http 请求的时间,即使在 SSR 超时之后
【发布时间】:2022-12-16 03:40:36
【问题描述】:
如何记录在 Spartacus Angular SSR 应用程序中发出的 http 请求的时间,即使在 SSR 超时(将 CSR 回退发送给客户端)之后?
语境:
在像dynatrace这样的监控工具中,您可以看到一个瀑布图,显示了呈现请求的持续时间,还包括呈现的应用程序对外部服务(例如 OCC)进行的 http 调用。但是,当 Spartacus SSR 返回 CSR 回退(由于 SSR 请求超时)时,dynatrace 停止显示呈现的应用程序正在进行的 http 调用。需要强调的是,即使在 ExpressJS 服务器发送 CSR 回退后,Angular SSR 应用程序仍会在后台呈现,并且仍然可以进行 http 调用。当这些 http 调用花费的时间太长时,最好能够调试哪些 http 调用花费了这么长时间。
【问题讨论】:
标签:
angular
spartacus-storefront
dynatrace
【解决方案1】:
出于调试目的,您可以提供一个 Angular HttpInteceptor 来记录 Angular 应用发出的每个 http 请求的时间。顺便提一句。它还可以指示响应是否已由 ExpressJS 引擎发送到客户端(例如,由于 SSR 请求超时)。
请参阅示例实现:
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Inject, InjectionToken, Optional } from '@angular/core';
import { RESPONSE } from '@nguniversal/express-engine/tokens';
import { Response } from 'express';
export class LoggingInterceptor implements HttpInterceptor {
constructor(@Optional() @Inject(RESPONSE) private response: Response) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const started = Date.now();
return next.handle(request).pipe(
tap(
_event => {
console.log(
`Request for ${request.urlWithParams} took ${Date.now() - started} ms. ` +
`Was ExpressJS Response already sent?: ${this.response?.headersSent}`
);
},
_error => {
console.log(
`Request for ${request.urlWithParams} failed after ${Date.now() - started} ms. ` +
`Was ExpressJS Response already sent?: ${this.response?.headersSent}`
);
}
)
);
}
}
解释:
- 我们从
@nguniversal/express-engine/tokens注入RESPONSEInjectionToken@
-
RESPONSE 对象具有来自 ExpressJS 的 Response 类型。介意者写信:import {Response} from 'express'。否则会隐式使用Node.js的全局类型Response,这是不正确的
- 我们用
@Optional()装饰器注入RESPONSE,因为它在浏览器中不可用,但仅在 SSR 中可用
- 我们查找属性
this.response.headersSent,它指示 ExpressJS 是否已经向客户端发送了响应。更多请看docs of ExpressJS Response.headersSent
注意:如果你还想在 SSR 中 console.log 当前呈现页面的 URL,你可以从 @spartacus/core 注入 WindowRef 并记录它的属性 windowRef.location.href。