refactor(logging): replace console.* with structured logger across server

Add server/logger.js - zero-dependency, level-based logger that outputs
JSON in production and human-readable format in development. Controlled
via LOG_LEVEL env var (debug/info/warn/error, default: info).

Replaces all 100 console.log/warn/error calls in 14 server files.
This commit is contained in:
Ulas
2026-04-03 22:05:22 +02:00
parent 5b1e6915ac
commit 3b90074723
16 changed files with 185 additions and 100 deletions
+11 -8
View File
@@ -14,6 +14,9 @@
'use strict';
const { createLogger } = require('../logger');
const log = createLogger('Apple');
const db = require('../db');
const APPLE_COLOR = '#FC3C44';
@@ -55,7 +58,7 @@ function getCredentials() {
function saveCredentials(url, username, password) {
// Warnung wenn DB-Verschluesselung nicht aktiv - Credentials liegen dann im Klartext
if (!process.env.DB_ENCRYPTION_KEY) {
console.warn('[Apple] WARNUNG: DB_ENCRYPTION_KEY nicht gesetzt - CalDAV-Credentials werden unverschluesselt gespeichert.');
log.warn('WARNUNG: DB_ENCRYPTION_KEY nicht gesetzt - CalDAV-Credentials werden unverschluesselt gespeichert.');
}
cfgSet('apple_caldav_url', url);
cfgSet('apple_username', username);
@@ -64,7 +67,7 @@ function saveCredentials(url, username, password) {
function clearCredentials() {
['apple_caldav_url', 'apple_username', 'apple_app_password', 'apple_last_sync'].forEach(cfgDel);
console.log('[Apple] Verbindung getrennt.');
log.info('Verbindung getrennt.');
}
// --------------------------------------------------------
@@ -304,14 +307,14 @@ async function sync() {
const calendars = await client.fetchCalendars();
if (!calendars.length) {
console.warn('[Apple] Keine Kalender gefunden.');
log.warn('Keine Kalender gefunden.');
return;
}
// created_by: ersten existierenden User verwenden (nicht hardcoded ID 1)
const owner = db.get().prepare('SELECT id FROM users ORDER BY id ASC LIMIT 1').get();
if (!owner) {
console.warn('[Apple] Kein User in der Datenbank - Sync übersprungen.');
log.warn('Kein User in der Datenbank - Sync übersprungen.');
return;
}
const createdBy = owner.id;
@@ -326,7 +329,7 @@ async function sync() {
try {
calObjects = await client.fetchCalendarObjects({ calendar: cal });
} catch (err) {
console.warn(`[Apple] Kalender "${cal.displayName || '(unbenannt)'}" nicht abrufbar: ${err.message}`);
log.warn(`Kalender "${cal.displayName || '(unbenannt)'}" nicht abrufbar: ${err.message}`);
continue;
}
@@ -365,7 +368,7 @@ async function sync() {
);
}
} catch (err) {
console.error(`[Apple] Upsert-Fehler für UID ${ev.uid}:`, err.message);
log.error(`Upsert-Fehler für UID ${ev.uid}:`, err.message);
}
}
}
@@ -396,12 +399,12 @@ async function sync() {
UPDATE calendar_events SET external_calendar_id = ?, external_source = 'apple' WHERE id = ?
`).run(uid, event.id);
} catch (err) {
console.error(`[Apple] Outbound-Fehler für Event ${event.id}:`, err.message);
log.error(`Outbound-Fehler für Event ${event.id}:`, err.message);
}
}
cfgSet('apple_last_sync', new Date().toISOString());
console.log(`[Apple] Sync abgeschlossen - ${totalObjects} Objekte aus ${syncCalendars.length} Kalendern inbound, ${localEvents.length} lokal → iCloud.`);
log.info(`Sync abgeschlossen - ${totalObjects} Objekte aus ${syncCalendars.length} Kalendern inbound, ${localEvents.length} lokal → iCloud.`);
}
module.exports = { sync, getStatus, saveCredentials, clearCredentials, testConnection };
+9 -6
View File
@@ -13,6 +13,9 @@
'use strict';
const { createLogger } = require('../logger');
const log = createLogger('Google');
const { google } = require('googleapis');
const crypto = require('crypto');
const db = require('../db');
@@ -127,7 +130,7 @@ async function handleCallback(code) {
cfgSet('google_refresh_token', tokens.refresh_token);
if (tokens.expiry_date) cfgSet('google_token_expiry', String(tokens.expiry_date));
console.log('[Google] OAuth erfolgreich - Tokens gespeichert.');
log.info('OAuth erfolgreich - Tokens gespeichert.');
}
/**
@@ -147,7 +150,7 @@ function getStatus() {
function disconnect() {
['google_access_token', 'google_refresh_token', 'google_token_expiry',
'google_sync_token', 'google_last_sync'].forEach(cfgDel);
console.log('[Google] Verbindung getrennt.');
log.info('Verbindung getrennt.');
}
/**
@@ -189,7 +192,7 @@ async function sync() {
} catch (err) {
if (err.code === 410) {
// syncToken abgelaufen → vollständiger Resync
console.warn('[Google] syncToken ungültig - vollständiger Resync.');
log.warn('syncToken ungültig - vollständiger Resync.');
cfgDel('google_sync_token');
syncToken = null;
continue;
@@ -225,12 +228,12 @@ async function sync() {
UPDATE calendar_events SET external_calendar_id = ?, external_source = 'google' WHERE id = ?
`).run(created.data.id, event.id);
} catch (err) {
console.error(`[Google] Outbound-Fehler für Event ${event.id}:`, err.message);
log.error(`Outbound-Fehler für Event ${event.id}:`, err.message);
}
}
cfgSet('google_last_sync', new Date().toISOString());
console.log(`[Google] Sync abgeschlossen - ${localEvents.length} lokal → Google, Inbound via syncToken.`);
log.info(`Sync abgeschlossen - ${localEvents.length} lokal → Google, Inbound via syncToken.`);
}
// --------------------------------------------------------
@@ -299,7 +302,7 @@ function upsertGoogleEvents(items) {
try {
insertOrUpdate(item);
} catch (err) {
console.error(`[Google] Upsert-Fehler für Event ${item.id}:`, err.message);
log.error(`Upsert-Fehler für Event ${item.id}:`, err.message);
}
}
}