Skip to content

Node.js Backend

import { createGunsoleClient } from "gunsole-js";
const gun = createGunsoleClient({
projectId: "my-api",
apiKey: "dev",
mode: "local",
env: process.env.NODE_ENV,
appName: "api-server",
appVersion: process.env.npm_package_version,
defaultTags: {
service: "api",
},
});
// Catch unhandled errors
gun.attachGlobalErrorHandlers();

Log every request:

import express from "express";
const app = express();
app.use((req, res, next) => {
const start = Date.now();
res.on("finish", () => {
const duration = Date.now() - start;
const level = res.statusCode >= 500 ? "error" : res.statusCode >= 400 ? "warn" : "info";
gun[level]({
bucket: "http",
message: `${req.method} ${req.path}${res.statusCode} (${duration}ms)`,
context: {
method: req.method,
path: req.path,
statusCode: res.statusCode,
duration,
userAgent: req.get("user-agent"),
ip: req.ip,
},
tags: {
method: req.method,
route: req.route?.path || req.path,
status: String(res.statusCode),
},
});
});
next();
});
async function query(sql, params) {
const start = Date.now();
try {
const result = await db.query(sql, params);
gun.debug({
bucket: "db",
message: `Query OK (${Date.now() - start}ms)`,
context: { sql, params, rowCount: result.rowCount },
tags: { operation: sql.trim().split(" ")[0].toUpperCase() },
});
return result;
} catch (err) {
gun.error({
bucket: "db",
message: `Query failed: ${err.message}`,
context: { sql, params, error: err.message },
tags: { operation: sql.trim().split(" ")[0].toUpperCase() },
});
throw err;
}
}

Flush remaining logs before exiting:

process.on("SIGTERM", async () => {
await gun.flush();
gun.destroy();
process.exit(0);
});

If you’re on Node.js < 18 where fetch isn’t built-in:

import fetch from "node-fetch";
const gun = createGunsoleClient({
projectId: "my-api",
apiKey: "dev",
mode: "local",
fetch: fetch,
});