From 4b6a5c327b7c13e41d8d804b4685feb452c8aefa Mon Sep 17 00:00:00 2001 From: ekzyis Date: Tue, 5 Nov 2024 04:23:19 +0100 Subject: [PATCH] Add context to log --- api/resolvers/wallet.js | 13 ++++--- api/typeDefs/wallet.js | 1 + components/log-message.js | 39 +++++++++++++++---- components/wallet-logger.js | 14 +++---- fragments/wallet.js | 1 + .../20241105021205_log_context/migration.sql | 2 + prisma/schema.prisma | 1 + wallets/index.js | 6 +-- wallets/lnc/client.js | 2 +- wallets/server.js | 8 +++- 10 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 prisma/migrations/20241105021205_log_context/migration.sql diff --git a/api/resolvers/wallet.js b/api/resolvers/wallet.js index 1142b3f0c9..c3adb5d9d4 100644 --- a/api/resolvers/wallet.js +++ b/api/resolvers/wallet.js @@ -668,14 +668,15 @@ export default injectResolvers(resolvers) export const walletLogger = ({ wallet, models }) => { // server implementation of wallet logger interface on client - const log = (level) => async message => { + const log = (level) => async (message, context = {}) => { try { await models.walletLog.create({ data: { userId: wallet.userId, wallet: wallet.type, level, - message + message, + context } }) } catch (err) { @@ -684,10 +685,10 @@ export const walletLogger = ({ wallet, models }) => { } return { - ok: (...message) => log('SUCCESS')(message.join(' ')), - info: (...message) => log('INFO')(message.join(' ')), - error: (...message) => log('ERROR')(message.join(' ')), - warn: (...message) => log('WARN')(message.join(' ')) + ok: (message, context) => log('SUCCESS')(message, context), + info: (message, context) => log('INFO')(message, context), + error: (message, context) => log('ERROR')(message, context), + warn: (message, context) => log('WARN')(message, context) } } diff --git a/api/typeDefs/wallet.js b/api/typeDefs/wallet.js index 4cd011cf26..f654989697 100644 --- a/api/typeDefs/wallet.js +++ b/api/typeDefs/wallet.js @@ -170,6 +170,7 @@ const typeDefs = ` wallet: ID! level: String! message: String! + context: JSONObject } ` diff --git a/components/log-message.js b/components/log-message.js index 731ac3e015..ccad10a52e 100644 --- a/components/log-message.js +++ b/components/log-message.js @@ -1,7 +1,10 @@ import { timeSince } from '@/lib/time' import styles from './log-message.module.css' +import { Fragment, useState } from 'react' + +export default function LogMessage ({ showWallet, wallet, level, message, context, ts }) { + const [show, setShow] = useState(false) -export default function LogMessage ({ showWallet, wallet, level, message, ts }) { let className switch (level.toLowerCase()) { case 'ok': @@ -15,12 +18,34 @@ export default function LogMessage ({ showWallet, wallet, level, message, ts }) default: className = 'text-info' } + + const hasContext = Object.keys(context).length > 0 + + const handleClick = () => { + if (hasContext) { setShow(show => !show) } + } + + const style = hasContext ? { cursor: 'pointer' } : { cursor: 'inherit' } + const indicator = hasContext + ? (show + ? '-' + : '+') + : <> + return ( - - {timeSince(new Date(ts))} - {showWallet ? [{wallet}] : } - {level} - {message} - + <> + + {timeSince(new Date(ts))} + {showWallet ? [{wallet}] : } + {level} + {indicator} {message} + + {show && hasContext && Object.entries(context).map(([key, value], i) => ( + + {key} + {value} + + ))} + ) } diff --git a/components/wallet-logger.js b/components/wallet-logger.js index 3b1e9bada2..bb2a349870 100644 --- a/components/wallet-logger.js +++ b/components/wallet-logger.js @@ -104,8 +104,8 @@ function useWalletLogDB () { export function useWalletLogger (wallet, setLogs) { const { add, clear, notSupported } = useWalletLogDB() - const appendLog = useCallback(async (wallet, level, message) => { - const log = { wallet: tag(wallet), level, message, ts: +new Date() } + const appendLog = useCallback(async (wallet, level, message, context) => { + const log = { wallet: tag(wallet), level, message, ts: +new Date(), context } try { if (notSupported) { console.log('cannot persist wallet log: indexeddb not supported') @@ -150,20 +150,20 @@ export function useWalletLogger (wallet, setLogs) { } }, [clear, deleteServerWalletLogs, setLogs, notSupported]) - const log = useCallback(level => message => { + const log = useCallback(level => (message, context) => { if (!wallet) { // console.error('cannot log: no wallet set') return } - appendLog(wallet, level, message) + appendLog(wallet, level, message, context) console[level !== 'error' ? 'info' : 'error'](`[${tag(wallet)}]`, message) }, [appendLog, wallet]) const logger = useMemo(() => ({ - ok: (...message) => log('ok')(message.join(' ')), - info: (...message) => log('info')(message.join(' ')), - error: (...message) => log('error')(message.join(' ')) + ok: (message, context) => log('ok')(message, context), + info: (message, context) => log('info')(message, context), + error: (message, context) => log('error')(message, context) }), [log]) return { logger, deleteLogs } diff --git a/fragments/wallet.js b/fragments/wallet.js index 32a97149c7..c9cdd65ced 100644 --- a/fragments/wallet.js +++ b/fragments/wallet.js @@ -191,6 +191,7 @@ export const WALLET_LOGS = gql` wallet level message + context } } } diff --git a/prisma/migrations/20241105021205_log_context/migration.sql b/prisma/migrations/20241105021205_log_context/migration.sql new file mode 100644 index 0000000000..8b85977fe0 --- /dev/null +++ b/prisma/migrations/20241105021205_log_context/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "WalletLog" ADD COLUMN "context" JSONB; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 8f994d585a..da9d6e9da8 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -245,6 +245,7 @@ model WalletLog { wallet WalletType level LogLevel message String + context Json? @db.JsonB @@index([userId, createdAt]) } diff --git a/wallets/index.js b/wallets/index.js index 452ecfaafa..0e7fa6a03e 100644 --- a/wallets/index.js +++ b/wallets/index.js @@ -222,13 +222,13 @@ export function useWallet (name) { const sendPayment = useCallback(async (bolt11) => { const hash = bolt11Tags(bolt11).payment_hash - logger.info('sending payment:', `payment_hash=${hash}`) + logger.info(`sending payment: payment_hash=${hash}`) try { const preimage = await wallet.def.sendPayment(bolt11, wallet.config, { logger }) - logger.ok('payment successful:', `payment_hash=${hash}`, `preimage=${preimage}`) + logger.ok(`payment successful: payment_hash=${hash} preimage=${preimage}`) } catch (err) { const message = err.message || err.toString?.() - logger.error('payment failed:', `payment_hash=${hash}`, message) + logger.error(`payment failed: payment_hash=${hash} ${message}`) throw err } }, [wallet, logger]) diff --git a/wallets/lnc/client.js b/wallets/lnc/client.js index 4e6b1fe43c..89a7dd8830 100644 --- a/wallets/lnc/client.js +++ b/wallets/lnc/client.js @@ -26,7 +26,7 @@ async function disconnect (lnc, logger) { }, 50) logger.info('disconnected') } catch (err) { - logger.error('failed to disconnect from lnc', err) + logger.error('failed to disconnect from lnc: ' + err) } } } diff --git a/wallets/server.js b/wallets/server.js index 925d5fd727..57e188f73c 100644 --- a/wallets/server.js +++ b/wallets/server.js @@ -65,7 +65,13 @@ export async function createInvoice (userId, { msats, description, descriptionHa const bolt11 = await parsePaymentRequest({ request: invoice }) - await logger.info(`created invoice for ${formatMsats(bolt11.mtokens)}`) + await logger.info(`created invoice for ${formatMsats(bolt11.mtokens)}`, { + bolt11: invoice, + payment_hash: bolt11.id, + description: bolt11.description, + created_at: bolt11.created_at, + expires_at: bolt11.expires_at + }) if (BigInt(bolt11.mtokens) !== BigInt(msats)) { if (BigInt(bolt11.mtokens) > BigInt(msats)) {