Skip to content

Commit 5def8cf

Browse files
committed
Log exchange-rate queries when verbose logging is enabled
When the Verbose Logging setting is on, the bulk rates loop logs the exact request body for each query (a condensed JSON string that can be replayed verbatim against the rates server), a resolved/no-rate outcome summary, non-OK HTTP responses, and thrown errors. Non-OK responses were previously dropped with no output at all.
1 parent adbf63e commit 5def8cf

1 file changed

Lines changed: 86 additions & 5 deletions

File tree

src/actions/ExchangeRateActions.ts

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
asRatesParams,
99
type RatesParams
1010
} from '../util/exchangeRates'
11+
import { log } from '../util/logger'
1112
import { fetchRates } from '../util/network'
1213
import { datelog, fixFiatCurrencyCode, removeIsoPrefix } from '../util/utils'
1314

@@ -73,11 +74,22 @@ type ExchangeRateCacheFile = ReturnType<typeof asExchangeRateCacheFile>
7374

7475
let exchangeRateCache: ExchangeRateCacheFile | undefined
7576

77+
/**
78+
* Returns the in-memory exchange-rate cache, including the subscribed
79+
* pair lists, for inclusion in support log output. The logged blob can be
80+
* turned back into rate-server query bodies with
81+
* `scripts/ratesCacheToQueries.ts`.
82+
*/
83+
export function getExchangeRateCacheDump(): ExchangeRateCacheFile | undefined {
84+
return exchangeRateCache
85+
}
86+
7687
export function updateExchangeRates(): ThunkAction<Promise<void>> {
7788
return async (dispatch, getState) => {
7889
const state = getState()
79-
const { account } = state.core
90+
const { account, context } = state.core
8091
const { defaultIsoFiat } = state.ui.settings
92+
const verbose = context.logSettings?.defaultLogLevel === 'info'
8193
const now = Date.now()
8294
const yesterday = getYesterdayDateRoundDownHour(now).toISOString()
8395

@@ -112,7 +124,8 @@ export function updateExchangeRates(): ThunkAction<Promise<void>> {
112124
defaultIsoFiat,
113125
exchangeRateCache,
114126
now,
115-
yesterday
127+
yesterday,
128+
verbose
116129
)
117130

118131
dispatch({
@@ -182,13 +195,16 @@ async function loadExchangeRateCache(): Promise<ExchangeRateCacheFile> {
182195

183196
/**
184197
* Fetches exchange rates from the server, and writes them out to disk.
198+
* When `verbose` is set, requested pairs, resolved pairs, and errors are
199+
* written to the captured logs.
185200
*/
186201
async function fetchExchangeRates(
187202
account: EdgeAccount,
188203
accountIsoFiat: string,
189204
cache: ExchangeRateCacheFile,
190205
now: number,
191-
yesterday: string
206+
yesterday: string,
207+
verbose: boolean
192208
): Promise<void> {
193209
const { currencyWallets } = account
194210

@@ -318,11 +334,17 @@ async function fetchExchangeRates(
318334
}
319335

320336
const requests = convertToRatesParams(cryptoPairMap, fiatPairMap)
321-
const promises = requests.map(async query => {
337+
const promises = requests.map(async (query, queryIndex) => {
338+
// Log the exact request body so it can be replayed verbatim against the
339+
// rates server (e.g. `curl -X POST .../v3/rates -d <body>`):
340+
const body = JSON.stringify(query)
341+
if (verbose) {
342+
log(`rates query ${queryIndex} request: ${body}`)
343+
}
322344
const options = {
323345
method: 'POST',
324346
headers: { 'Content-Type': 'application/json' },
325-
body: JSON.stringify(query)
347+
body
326348
}
327349
try {
328350
const response = await fetchRates('v3/rates', options)
@@ -331,6 +353,30 @@ async function fetchExchangeRates(
331353
const cleanedRates = asRatesParams(json)
332354
const targetFiat = fixFiatCurrencyCode(cleanedRates.targetFiat)
333355

356+
if (verbose) {
357+
// The requested pairs are already logged above (request body), so
358+
// here we only summarize the outcome and name the pairs the server
359+
// returned without a rate:
360+
let resolvedCount = 0
361+
const noRateKeys: string[] = []
362+
for (const entry of cleanedRates.crypto) {
363+
if (entry.rate != null) resolvedCount++
364+
else
365+
noRateKeys.push(cryptoRateLogKey(entry, cleanedRates.targetFiat))
366+
}
367+
for (const entry of cleanedRates.fiat) {
368+
if (entry.rate != null) resolvedCount++
369+
else noRateKeys.push(fiatRateLogKey(entry, cleanedRates.targetFiat))
370+
}
371+
log(
372+
`rates query ${queryIndex} result: ${resolvedCount} resolved, ${
373+
noRateKeys.length
374+
} no-rate${
375+
noRateKeys.length > 0 ? `: ${noRateKeys.join(', ')}` : ''
376+
}`
377+
)
378+
}
379+
334380
for (const cryptoRate of cleanedRates.crypto) {
335381
const { asset, isoDate, rate } = cryptoRate
336382
if (rate == null) continue
@@ -408,8 +454,18 @@ async function fetchExchangeRates(
408454

409455
rateObj.expiration = rateExpiration
410456
}
457+
} else if (verbose) {
458+
const text = await response.text()
459+
log(
460+
`rates query ${queryIndex} failed: HTTP ${
461+
response.status
462+
}: ${text.slice(0, 200)}`
463+
)
411464
}
412465
} catch (error: unknown) {
466+
if (verbose) {
467+
log(`rates query ${queryIndex} error: ${String(error)}`)
468+
}
413469
console.log(
414470
`buildExchangeRates error querying rates server ${String(error)}`
415471
)
@@ -494,6 +550,31 @@ const getYesterdayDateRoundDownHour = (now?: Date | number): Date => {
494550
return yesterday
495551
}
496552

553+
/**
554+
* Compact log key for a crypto rate entry:
555+
* `pluginId[_tokenId]_targetFiat[@isoDate]`
556+
*/
557+
function cryptoRateLogKey(
558+
entry: RatesParams['crypto'][number],
559+
targetFiat: string
560+
): string {
561+
const { asset, isoDate } = entry
562+
const tokenIdStr = asset.tokenId != null ? `_${asset.tokenId}` : ''
563+
const dateStr = isoDate != null ? `@${isoDate.toISOString()}` : ''
564+
return `${asset.pluginId}${tokenIdStr}_${targetFiat}${dateStr}`
565+
}
566+
567+
/**
568+
* Compact log key for a fiat rate entry: `fiatCode_targetFiat[@isoDate]`
569+
*/
570+
function fiatRateLogKey(
571+
entry: RatesParams['fiat'][number],
572+
targetFiat: string
573+
): string {
574+
const dateStr = entry.isoDate != null ? `@${entry.isoDate.toISOString()}` : ''
575+
return `${entry.fiatCode}_${targetFiat}${dateStr}`
576+
}
577+
497578
/**
498579
* Convert maps to an array of RatesParams objects grouped by targetFiat.
499580
*/

0 commit comments

Comments
 (0)