Add comprehensive local logging to all microservices; log all errors locally and forward to error_log_api

This commit is contained in:
Sven laptop
2026-09-23 20:00:30 +02:00
parent 50634a3ed7
commit b36975b680
4 changed files with 54 additions and 28 deletions
+26 -14
View File
@@ -55,6 +55,7 @@ app.use((req, res, next) => {
if (res.statusCode >= 400 && body && typeof body === "object") {
const rawError =
body.error || body.message || body.details || `HTTP ${res.statusCode}`;
log("warn", `HTTP ${res.statusCode}`, { path: req.originalUrl, method: req.method, error: rawError });
void reportError({
partofservice: `${req.method} ${req.originalUrl}`,
error: rawError,
@@ -86,10 +87,16 @@ app.post("/login", async (req, res) => {
[userCode],
);
const user = result.rows[0];
if (!user) return res.status(401).json({ error: "invalid_credentials" });
if (!user) {
log("warn", "Login attempt for non-existent user", { userCode });
return res.status(401).json({ error: "invalid_credentials" });
}
const ok = await bcrypt.compare(password, user.password);
if (!ok) return res.status(401).json({ error: "invalid_credentials" });
if (!ok) {
log("warn", "Invalid password for user", { userCode });
return res.status(401).json({ error: "invalid_credentials" });
}
const isAdmin = ADMIN_USER_CODES.has(Number(user.usercode));
const payload = {
@@ -99,6 +106,7 @@ app.post("/login", async (req, res) => {
};
const token = jwt.sign(payload, JWT_SECRET, { expiresIn: "1h" });
log("info", "User logged in", { userCode: user.usercode, isAdmin });
res.json({
token,
user: {
@@ -109,28 +117,25 @@ app.post("/login", async (req, res) => {
},
});
} catch (err) {
await reportError({
partofservice: `${req.method} ${req.originalUrl}`,
error: err?.stack || err?.message || String(err),
});
console.error(err);
log("error", "Login error", { error: err.message, stack: err.stack });
reportError({ partofservice: `${req.method} ${req.originalUrl}`, error: err.stack || err.message });
res.status(500).json({ error: friendlyErrorMessage(500) });
}
});
app.get("/me", async (req, res) => {
const auth = req.headers.authorization;
if (!auth || !auth.startsWith("Bearer "))
if (!auth || !auth.startsWith("Bearer ")) {
log("warn", "Missing or invalid Authorization header", { path: req.originalUrl });
return res.status(401).json({ error: "missing_token" });
}
const token = auth.slice(7);
try {
const payload = jwt.verify(token, JWT_SECRET);
res.json({ user: payload });
} catch (err) {
void reportError({
partofservice: `${req.method} ${req.originalUrl}`,
error: err?.stack || err?.message || String(err),
});
log("error", "JWT verification failed", { error: err.message, stack: err.stack });
reportError({ partofservice: `${req.method} ${req.originalUrl}`, error: err.stack || err.message });
res.status(401).json({ error: friendlyErrorMessage(401) });
}
});
@@ -143,8 +148,15 @@ app.get("/me", async (req, res) => {
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Auth API listening on ${PORT}`));
app.get("/health", (_req, res) => {
res.json({ status: "ok", service: "auth_api" });
app.get("/health", async (_req, res) => {
try {
await db.query("SELECT 1");
res.json({ status: "ok", service: "auth_api", database: "ok" });
} catch (err) {
log("error", "Health check DB query failed", { error: err.message, stack: err.stack });
reportError({ partofservice: "GET /health", error: err.stack || err.message });
res.status(503).json({ status: "unavailable", service: "auth_api" });
}
});
module.exports = app;