Skip to content

Commit da787a8

Browse files
authored
Merge pull request #550 from vtex/metrics/requestDetailsTrace
Add disk cache steps and retry count to tracing
2 parents bf2a84e + e1e27b2 commit da787a8

File tree

5 files changed

+61
-23
lines changed

5 files changed

+61
-23
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## [Unreleased]
99

10+
## [6.46.0] - 2023-10-25
11+
### Added
12+
- Add disk cache steps and retry count to tracing
13+
1014
### Changed
1115
- Stop updating client cache when revalidated and still expired
1216

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vtex/api",
3-
"version": "6.45.24",
3+
"version": "6.46.0",
44
"description": "VTEX I/O API client",
55
"main": "lib/index.js",
66
"typings": "lib/index.d.ts",

src/HttpClient/middlewares/cache.ts

+48-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { AxiosRequestConfig, AxiosResponse } from 'axios'
2+
import { Span } from 'opentracing'
23

34
import { CacheLayer } from '../../caches/CacheLayer'
45
import { LOCALE_HEADER, SEGMENT_HEADER, SESSION_HEADER } from '../../constants'
6+
import { IOContext } from '../../service/worker/runtime/typings'
7+
import { ErrorReport } from '../../tracing'
58
import { HttpLogEvents } from '../../tracing/LogEvents'
69
import { HttpCacheLogFields } from '../../tracing/LogFields'
710
import { CustomHttpTags } from '../../tracing/Tags'
@@ -90,7 +93,7 @@ export const cacheMiddleware = ({ type, storage }: CacheOptions) => {
9093
return await next()
9194
}
9295

93-
const span = ctx.tracing?.rootSpan
96+
const { rootSpan: span, tracer, logger } = ctx.tracing ?? {}
9497

9598
const key = cacheKey(ctx.config)
9699
const segmentToken = ctx.config.headers[SEGMENT_HEADER]
@@ -103,8 +106,18 @@ export const cacheMiddleware = ({ type, storage }: CacheOptions) => {
103106
[HttpCacheLogFields.KEY_WITH_SEGMENT]: keyWithSegment,
104107
})
105108

106-
const cacheHasWithSegment = await storage.has(keyWithSegment)
107-
const cached = cacheHasWithSegment ? await storage.get(keyWithSegment) : await storage.get(key)
109+
110+
const cacheReadSpan = createCacheSpan(cacheType, 'read', tracer, span)
111+
let cached: void | Cached
112+
try {
113+
const cacheHasWithSegment = await storage.has(keyWithSegment)
114+
cached = cacheHasWithSegment ? await storage.get(keyWithSegment) : await storage.get(key)
115+
} catch (error) {
116+
ErrorReport.create({ originalError: error }).injectOnSpan(cacheReadSpan)
117+
logger?.warn({ message: 'Error reading from the HttpClient cache', error })
118+
} finally {
119+
cacheReadSpan?.finish()
120+
}
108121

109122
if (cached && cached.response) {
110123
const {etag: cachedEtag, response, expiration, responseType, responseEncoding} = cached as Cached
@@ -208,24 +221,32 @@ export const cacheMiddleware = ({ type, storage }: CacheOptions) => {
208221
return
209222
}
210223

211-
await storage.set(setKey, {
212-
etag,
213-
expiration,
214-
response: {data: cacheableData, headers, status},
215-
responseEncoding,
216-
responseType,
217-
})
218-
219-
span?.log({
220-
event: HttpLogEvents.LOCAL_CACHE_SAVED,
221-
[HttpCacheLogFields.CACHE_TYPE]: cacheType,
222-
[HttpCacheLogFields.KEY_SET]: setKey,
223-
[HttpCacheLogFields.AGE]: currentAge,
224-
[HttpCacheLogFields.ETAG]: etag,
225-
[HttpCacheLogFields.EXPIRATION_TIME]: (expiration - Date.now())/1000,
226-
[HttpCacheLogFields.RESPONSE_ENCONDING]: responseEncoding,
227-
[HttpCacheLogFields.RESPONSE_TYPE]: responseType,
228-
})
224+
const cacheWriteSpan = createCacheSpan(cacheType, 'write', tracer, span)
225+
try {
226+
await storage.set(setKey, {
227+
etag,
228+
expiration,
229+
response: {data: cacheableData, headers, status},
230+
responseEncoding,
231+
responseType,
232+
})
233+
234+
span?.log({
235+
event: HttpLogEvents.LOCAL_CACHE_SAVED,
236+
[HttpCacheLogFields.CACHE_TYPE]: cacheType,
237+
[HttpCacheLogFields.KEY_SET]: setKey,
238+
[HttpCacheLogFields.AGE]: currentAge,
239+
[HttpCacheLogFields.ETAG]: etag,
240+
[HttpCacheLogFields.EXPIRATION_TIME]: (expiration - Date.now())/1000,
241+
[HttpCacheLogFields.RESPONSE_ENCONDING]: responseEncoding,
242+
[HttpCacheLogFields.RESPONSE_TYPE]: responseType,
243+
})
244+
} catch (error) {
245+
ErrorReport.create({ originalError: error }).injectOnSpan(cacheWriteSpan)
246+
logger?.warn({ message: 'Error writing to the HttpClient cache', error })
247+
} finally {
248+
cacheWriteSpan?.finish()
249+
}
229250

230251
return
231252
}
@@ -234,6 +255,12 @@ export const cacheMiddleware = ({ type, storage }: CacheOptions) => {
234255
}
235256
}
236257

258+
const createCacheSpan = (cacheType: string, operation: 'read' | 'write', tracer?: IOContext['tracer'], parentSpan?: Span) => {
259+
if (tracer && tracer.isTraceSampled && cacheType === 'disk') {
260+
return tracer.startSpan(`${operation}-disk-cache`, { childOf: parentSpan })
261+
}
262+
}
263+
237264
export interface Cached {
238265
etag: string
239266
expiration: number

src/HttpClient/middlewares/request/setupAxios/interceptors/exponentialBackoff.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { AxiosInstance } from 'axios'
22
import { HttpLogEvents } from '../../../../../tracing/LogEvents'
33
import { HttpRetryLogFields } from '../../../../../tracing/LogFields'
4+
import { CustomHttpTags } from '../../../../../tracing/Tags'
45
import { isAbortedOrNetworkErrorOrRouterTimeout } from '../../../../../utils/retry'
56
import { RequestConfig } from '../../../../typings'
6-
import { TraceableRequestConfig } from '../../../tracing'
77

88
function fixConfig(axiosInstance: AxiosInstance, config: RequestConfig) {
99
if (axiosInstance.defaults.httpAgent === config.httpAgent) {
@@ -66,6 +66,10 @@ const onResponseError = (http: AxiosInstance) => (error: any) => {
6666
config.transformRequest = [data => data]
6767

6868
config.tracing?.rootSpan?.log({ event: HttpLogEvents.SETUP_REQUEST_RETRY, [HttpRetryLogFields.RETRY_NUMBER]: config.retryCount, [HttpRetryLogFields.RETRY_IN]: delay })
69+
config.tracing?.rootSpan?.addTags({
70+
[CustomHttpTags.HTTP_RETRY_COUNT]: config.retryCount,
71+
[CustomHttpTags.HTTP_RETRY_ERROR_CODE]: error.code,
72+
})
6973

7074
return new Promise(resolve => setTimeout(() => resolve(http(config)), delay))
7175
}

src/tracing/Tags.ts

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ export const enum CustomHttpTags {
6969
HTTP_MEMOIZATION_CACHE_RESULT = 'http.cache.memoization',
7070
HTTP_DISK_CACHE_RESULT = 'http.cache.disk',
7171
HTTP_ROUTER_CACHE_RESULT = 'http.cache.router',
72+
73+
HTTP_RETRY_ERROR_CODE = 'http.retry.error.code',
74+
HTTP_RETRY_COUNT = 'http.retry.count',
7275
}
7376

7477
export const UserlandTags = {

0 commit comments

Comments
 (0)