From ca6d2e58412a8635ac4e130048f7fa63fe55d7ec Mon Sep 17 00:00:00 2001 From: phoebus-84 Date: Fri, 3 May 2024 02:32:28 +0200 Subject: [PATCH] feat: add logs --- .../molecules/HiddenLogsButton.svelte | 14 +++++++ src/lib/hooks.client.ts | 16 ++++++++ src/lib/log.ts | 29 +++++++++++++ src/lib/preferences/index.ts | 4 ++ src/lib/preferences/logs.ts | 40 ++++++++++++++++++ src/lib/slangroom/login.ts | 3 +- src/lib/slangroom/verificationFlows.ts | 3 +- src/routes/+layout.svelte | 2 + .../(protected)/[id]/verify/+page.svelte | 3 +- .../(protected)/[id]/verify/_lib/tools.ts | 5 ++- src/routes/logs/+page.svelte | 41 +++++++++++++++++++ src/routes/logs/+page.ts | 6 +++ 12 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 src/lib/components/molecules/HiddenLogsButton.svelte create mode 100644 src/lib/hooks.client.ts create mode 100644 src/lib/log.ts create mode 100644 src/lib/preferences/logs.ts create mode 100644 src/routes/logs/+page.svelte create mode 100644 src/routes/logs/+page.ts diff --git a/src/lib/components/molecules/HiddenLogsButton.svelte b/src/lib/components/molecules/HiddenLogsButton.svelte new file mode 100644 index 0000000..acb9e78 --- /dev/null +++ b/src/lib/components/molecules/HiddenLogsButton.svelte @@ -0,0 +1,14 @@ + + diff --git a/src/lib/hooks.client.ts b/src/lib/hooks.client.ts new file mode 100644 index 0000000..e7260a9 --- /dev/null +++ b/src/lib/hooks.client.ts @@ -0,0 +1,16 @@ +import { log } from '$lib/log'; +import type { HandleClientError } from '@sveltejs/kit'; + +export const handleError: HandleClientError = async ({ error, event, status, message }) => { + await log(String(error)) + await log(JSON.stringify(event)) + await log(JSON.stringify(status)); + await log(message) + + return { + message, + status, + event, + error + }; +}; diff --git a/src/lib/log.ts b/src/lib/log.ts new file mode 100644 index 0000000..056b766 --- /dev/null +++ b/src/lib/log.ts @@ -0,0 +1,29 @@ +// import { dev } from '$app/environment'; +import { setLogPreference } from './preferences/logs'; + +const dev = true; + +export const log = dev ? logAndSave : () => {}; + +async function logAndSave(message: string) { + const stackTrace = new Error().stack; + let callerInfo = ''; + + if (stackTrace) { + const stackLines = stackTrace.split('\n'); + for (let i = 2; i < stackLines.length; i++) { + const match = stackLines[i].match(/at\s+(.*)\s+\((.*):(\d+):(\d+)\)/); + if (match) { + const functionName = match[1]; + const fileName = match[2]?.replace(/^.*\/\/[^/]+/, ''); + const lineNumber = match[3]; + const columnNumber = match[4]; + callerInfo = `${functionName} (${fileName}:${lineNumber}:${columnNumber})`; + break; + } + } + } + const logMessage = callerInfo ? `${callerInfo}: ${message}` : message; + console.log(logMessage); + await setLogPreference(logMessage); +} diff --git a/src/lib/preferences/index.ts b/src/lib/preferences/index.ts index b87026e..950e705 100644 --- a/src/lib/preferences/index.ts +++ b/src/lib/preferences/index.ts @@ -16,6 +16,10 @@ export const removePreference = async (key: string) => { await Preferences.remove({ key }); }; +export const clearPreferences = async () => { + await Preferences.clear(); +}; + export const getStructuredPreferences = async (key: string): Promise => { try { const value = await getPreference(key); diff --git a/src/lib/preferences/logs.ts b/src/lib/preferences/logs.ts new file mode 100644 index 0000000..4844534 --- /dev/null +++ b/src/lib/preferences/logs.ts @@ -0,0 +1,40 @@ +import { getStructuredPreferences, setStructuredPreferences } from '.'; +import dayjs from 'dayjs'; + +// + +export const LOGS_PREFERENCES_KEY = 'logs'; + +export type Log = { + date: number; + message: string; +}; + +const getNow = async () => { + return dayjs().valueOf(); +}; + +export async function setLogPreference(message: string): Promise { + const logs = await getLogsPreference(); + const date = await getNow(); + const c = { + message, + date + }; + if (logs) { + logs.push(c); + await setStructuredPreferences(LOGS_PREFERENCES_KEY, logs); + return c; + } + + await setStructuredPreferences(LOGS_PREFERENCES_KEY, [c]); + return c; +} + +export async function getLogsPreference(): Promise { + return await getStructuredPreferences(LOGS_PREFERENCES_KEY); +} + +export async function clearLogsPreferences(): Promise { + await setStructuredPreferences(LOGS_PREFERENCES_KEY, []); +} \ No newline at end of file diff --git a/src/lib/slangroom/login.ts b/src/lib/slangroom/login.ts index bb64726..1ea956f 100644 --- a/src/lib/slangroom/login.ts +++ b/src/lib/slangroom/login.ts @@ -2,6 +2,7 @@ import { Slangroom } from '@slangroom/core'; import { pocketbase } from '@slangroom/pocketbase'; import authenticate from './authenticate.zen?raw'; import { backendUri } from '$lib/backendUri'; +import { log } from '$lib/log'; const slangroom = new Slangroom(pocketbase); @@ -17,7 +18,7 @@ export const login = async (email: string, password: string) => { const res = await slangroom.execute(authenticate, {data}); return res.result.output; } catch (e: unknown) { - console.log(e); + log(e); throw new Error(JSON.stringify(e)); } }; diff --git a/src/lib/slangroom/verificationFlows.ts b/src/lib/slangroom/verificationFlows.ts index 1360fbc..7680fc2 100644 --- a/src/lib/slangroom/verificationFlows.ts +++ b/src/lib/slangroom/verificationFlows.ts @@ -3,6 +3,7 @@ import { Slangroom } from '@slangroom/core'; import getPbList from '$lib/slangroom/getPbList.zen?raw'; import getPbRecord from '$lib/slangroom/getPbRecord.zen?raw'; import { pocketbase, type ShowRecordParameters } from '@slangroom/pocketbase'; +import { log } from '$lib/log'; export type VerificationFlow = { collectionId: string; @@ -93,7 +94,7 @@ export const getVerificationFlow = async (id: string): Promise //@ts-expect-error output needs to be typed return res.result?.output; } catch (e: unknown) { - console.log(e); + log(JSON.stringify(e)); throw new Error(JSON.stringify(e)); } }; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 5b6f65b..f26dc24 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -12,6 +12,7 @@ import { ParaglideJS } from '@inlang/paraglide-js-adapter-sveltekit'; import { i18n } from '$lib/i18n'; import { removeOldRuAndSid } from '$lib/preferences/sidRu'; + import HiddenLogsButton from '$lib/components/molecules/HiddenLogsButton.svelte'; document.addEventListener( 'deviceready', @@ -38,6 +39,7 @@ + diff --git a/src/routes/[[lang]]/(protected)/[id]/verify/+page.svelte b/src/routes/[[lang]]/(protected)/[id]/verify/+page.svelte index ac708f9..0236a4d 100644 --- a/src/routes/[[lang]]/(protected)/[id]/verify/+page.svelte +++ b/src/routes/[[lang]]/(protected)/[id]/verify/+page.svelte @@ -15,6 +15,7 @@ import { backendUri } from '$lib/backendUri'; import { saveRuAndSid } from '$lib/preferences/sidRu'; import { jwsToId, jwsToIdSuccess } from './_lib/tools'; + import { log } from '$lib/log'; export let data: any; @@ -43,7 +44,7 @@ await PushNotifications.addListener('pushNotificationReceived', (notification) => { incomingNotification = notification; - console.log('Push notification received: ', notification); + log(`Push notification received: /n ${JSON.stringify(notification)}`); }); }; diff --git a/src/routes/[[lang]]/(protected)/[id]/verify/_lib/tools.ts b/src/routes/[[lang]]/(protected)/[id]/verify/_lib/tools.ts index 3719afb..f7b45f1 100644 --- a/src/routes/[[lang]]/(protected)/[id]/verify/_lib/tools.ts +++ b/src/routes/[[lang]]/(protected)/[id]/verify/_lib/tools.ts @@ -6,6 +6,7 @@ import { zencode } from '@slangroom/zencode'; import { getRuAndSid } from '$lib/preferences/sidRu'; import verify from '$lib/mobile_zencode/verifier/verify.zen?raw'; import verifyKeys from '$lib/mobile_zencode/verifier/verify.keys.json?raw'; +import { log } from '$lib/log'; const slangroom = new Slangroom(http, helpers, zencode); export const jwsToIdSuccess = 'Signature_verification_successful' as const; @@ -33,11 +34,11 @@ export const jwsToId = async (jws: string): Promise => { claims_url: ru }; const res = await slangroom.execute(verify, { data: dataVerify, keys: JSON.parse(verifyKeys) }); - console.log(res); + log(JSON.stringify(res)); const message = res.result.result as typeof jwsToIdSuccess | typeof jwsToIdFailure; return { message, id }; } catch (e) { - console.log(e); + log(JSON.stringify(e)); return {message:jwsToIdFailure, id} } }; diff --git a/src/routes/logs/+page.svelte b/src/routes/logs/+page.svelte new file mode 100644 index 0000000..892a87c --- /dev/null +++ b/src/routes/logs/+page.svelte @@ -0,0 +1,41 @@ + + +
+
+ back + clear + clear storage +
+ {#if logs} + {#each logs as log} + {@const date = dayjs(log.date)} +
+
+
{date.format('YY/MM/DD')}
+
{date.format('HH:mm:ss')}
+
+
{log.message}
+
+ {/each} + {/if} +
diff --git a/src/routes/logs/+page.ts b/src/routes/logs/+page.ts new file mode 100644 index 0000000..f894a06 --- /dev/null +++ b/src/routes/logs/+page.ts @@ -0,0 +1,6 @@ +import { getLogsPreference } from '$lib/preferences/logs.js'; + +export const load = async () => { + const logs = await getLogsPreference() || []; + return { logs }; +};