neuron-explorer
Steering-first neuron explorer for Qwen3.5-4B: push every MLP neuron, keep every rollout, browse the results
Structured logging for both halves of a Firebase app, in one pane, and the rule we built it on: logging is an aspect of an app, and it stays out of the business logic.
Developer toolsTypeScript · ShellGitHub @dasasianOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Structured logging for Firebase apps — client, functions, and tools
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
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.Read the full 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