Enhance logging in API calls and request/response middleware with sensitive data filtering and compact format
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m28s

This commit is contained in:
2026-02-28 21:24:25 +01:00
parent 8e18149ad1
commit ed8fb134ad
2 changed files with 84 additions and 40 deletions

View File

@@ -18,19 +18,75 @@ function buildUrl(apiCall, params = {}) {
async function apiCall(apiCallName, params = {}, xmlBody = null) {
const url = buildUrl(apiCallName, params);
// Logging: compact key=value style, filter sensitive params
function formatUTC(d) {
const pad = n => String(n).padStart(2, '0');
const Y = d.getUTCFullYear();
const M = pad(d.getUTCMonth() + 1);
const D = pad(d.getUTCDate());
const h = pad(d.getUTCHours());
const m = pad(d.getUTCMinutes());
const s = pad(d.getUTCSeconds());
return `${Y}-${M}-${D} ${h}:${m}:${s} UTC`;
}
const SENSITIVE_KEYS = [/pass/i, /pwd/i, /password/i, /token/i, /jwt/i, /secret/i, /authorization/i, /auth/i, /api[_-]?key/i];
const isSensitive = key => SENSITIVE_KEYS.some(rx => rx.test(key));
function sanitizeParams(p) {
try {
const out = [];
for (const k of Object.keys(p || {})) {
if (k.toLowerCase() === 'checksum') continue; // never log checksum
if (isSensitive(k)) {
out.push(`${k}=[FILTERED]`);
} else {
let v = p[k];
if (typeof v === 'string' && v.length > 100) v = v.slice(0, 100) + '...[truncated]';
out.push(`${k}=${String(v)}`);
}
}
return out.join('&') || '-';
} catch (e) {
return '-';
}
}
const start = Date.now();
try {
const fetchOptions = xmlBody
? { method: 'POST', headers: { 'Content-Type': 'application/xml' }, body: xmlBody }
: {};
const response = await fetch(url, fetchOptions);
const duration = Date.now() - start;
const xml = await response.text();
const result = await xml2js.parseStringPromise(xml, {
explicitArray: false,
trim: true,
});
// Compact log: time=... method=GET path=getMeetings format=xml status=200 duration=12.34 bbb_returncode=SUCCESS params=meetingID=123
try {
const tokens = [];
tokens.push(`time=${formatUTC(new Date())}`);
tokens.push(`method=${xmlBody ? 'POST' : 'GET'}`);
tokens.push(`path=${apiCallName}`);
tokens.push(`format=xml`);
tokens.push(`status=${response.status}`);
tokens.push(`duration=${(duration).toFixed(2)}`);
const bbbCode = result && result.response && result.response.returncode ? result.response.returncode : '-';
tokens.push(`bbb_returncode=${bbbCode}`);
const safeParams = sanitizeParams(params);
tokens.push(`params=${safeParams}`);
console.info(tokens.join(' '));
} catch (e) {
// ignore logging errors
}
return result.response;
} catch (error) {
console.error(`BBB API error (${apiCallName}):`, error.message);
const duration = Date.now() - start;
console.error(`BBB API error (${apiCallName}) status=error duration=${(duration).toFixed(2)} err=${error.message}`);
throw error;
}
}