AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
Structured logging for Firebase apps — client, functions, and tools
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Structured logging for both halves of a Firebase app.
Your web app crashed at app-4f2a.js:1:98432. This tells you it was Checkout.tsx:42 — in your own Google Cloud project, next to your backend logs. Nothing leaves.查看完整 README ↗Structured logging for both halves of a Firebase app.
Your web app crashed at app-4f2a.js:1:98432. This tells you it was Checkout.tsx:42 — in your own Google Cloud project, next to your backend logs. Nothing leaves.
Checkout.tsx:42. Your source maps stay on your server and never reach the browser. Source mapslabels.userId="…". Labelsfsl logs and two skills come with the package. fsl logs · Skillsnpm install @dasasian/firebase-structured-logger
Needs Node 22 or later.
In the browser:
import { initLogger, setupGlobalErrorHandler } from '@dasasian/firebase-structured-logger/client'
import { getFunctions, httpsCallable } from 'firebase/functions'
export const logger = initLogger({
appId: 'my-app',
releaseId: import.meta.env.VITE_RELEASE_ID ?? 'dev',
logFunction: httpsCallable(getFunctions(), 'logFrontendEvent'),
})
setupGlobalErrorHandler()
In your Cloud Functions:
import { onCall } from 'firebase-functions/v2/https'
import { initLogger, createClientLogFunction, withLogging } from '@dasasian/firebase-structured-logger/functions'
initLogger({ appId: 'my-app' })
export const logFrontendEvent = createClientLogFunction()
export const checkout = onCall(
withLogging({ functionName: 'checkout' }, async (request) => {
await chargeCard(request.data)
}),
)
The handler holds no log code. What it throws is logged with functionName and the caller's userId, and thrown again.
The full setup, with source maps, is in Get started.
Logging is an aspect of your app, not a part of each function. You state each fact one time, in the place where it is true, and fsl puts it on every entry.
| Where | You write | You get |
|---|---|---|
| At startup | setupGlobalErrorHandler() | Every uncaught error, with its stack resolved to your source. |
| Where the user signs in | logger.setUser(uid) | The user on every entry from then on. |
| On the button | data-fsl-action="apply_discount" | The click, as a step in the trail of any later error. |
| On the dialog | data-fsl-view="Attachment" | Every entry written while the dialog is open says so. |
| Around the handler | withLogging({ functionName: 'checkout' }, handler) | The function name and the caller's verified user id on every entry, and what the handler throws. |
The two attributes need enableActions() and enableViews() once at startup. A function takes no logger and no context, and it has no try and catch for the sake of a log. See one function, before and after.
backend/node_modules/.bin/fsl install-skills, run from the project root, adds /fsl-review and /fsl-logs to your project; use the folder where you installed the package in place of backend. Do not use npx fsl there: in a folder with no install, it runs another package with the same name. node_modules/@dasasian/firebase-structured-logger/CAPABILITIES.md says what an app can add. llms.txt lists every page.
MIT © Dasasian