Files
sofarr/server/index.js
Gronod f28d94d9a3 perf: background poller for near-instant dashboard responses
- New poller.js polls all services on a configurable interval
- POLL_INTERVAL env var (default 5000ms / 5 seconds)
- All data stored in cache with TTL of 3x poll interval
- Dashboard endpoint now reads from cache only (no network calls)
- API responses are near-instant regardless of service count
- First poll runs immediately on server start
2026-05-16 00:32:16 +01:00

87 lines
2.9 KiB
JavaScript

const express = require('express');
const cors = require('cors');
const path = require('path');
const cookieParser = require('cookie-parser');
const fs = require('fs');
require('dotenv').config();
// Setup logging with levels
// Levels: debug (0), info (1), warn (2), error (3), silent (4)
const LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };
const currentLevel = LOG_LEVELS[(process.env.LOG_LEVEL || 'info').toLowerCase()] || 1;
const logFile = fs.createWriteStream(path.join(__dirname, '../server.log'), { flags: 'a' });
const originalConsoleLog = console.log;
const originalConsoleError = console.error;
const originalConsoleWarn = console.warn;
const originalConsoleDebug = console.debug;
function shouldLog(level) {
return level >= currentLevel;
}
console.debug = function(...args) {
if (!shouldLog(LOG_LEVELS.debug)) return;
const message = args.join(' ');
originalConsoleDebug.apply(console, args);
logFile.write(`[${new Date().toISOString()}] DEBUG: ${message}\n`);
};
console.log = function(...args) {
if (!shouldLog(LOG_LEVELS.info)) return;
const message = args.join(' ');
originalConsoleLog.apply(console, args);
logFile.write(`[${new Date().toISOString()}] ${message}\n`);
};
console.warn = function(...args) {
if (!shouldLog(LOG_LEVELS.warn)) return;
const message = args.join(' ');
originalConsoleWarn.apply(console, args);
logFile.write(`[${new Date().toISOString()}] WARN: ${message}\n`);
};
console.error = function(...args) {
if (!shouldLog(LOG_LEVELS.error)) return;
const message = args.join(' ');
originalConsoleError.apply(console, args);
logFile.write(`[${new Date().toISOString()}] ERROR: ${message}\n`);
};
const sabnzbdRoutes = require('./routes/sabnzbd');
const sonarrRoutes = require('./routes/sonarr');
const radarrRoutes = require('./routes/radarr');
const embyRoutes = require('./routes/emby');
const dashboardRoutes = require('./routes/dashboard');
const authRoutes = require('./routes/auth');
const { startPoller, POLL_INTERVAL } = require('./utils/poller');
const app = express();
const PORT = process.env.PORT || 3001;
app.use(cors());
app.use(cookieParser());
app.use(express.json());
app.use(express.static(path.join(__dirname, '../public')));
app.use('/api/sabnzbd', sabnzbdRoutes);
app.use('/api/sonarr', sonarrRoutes);
app.use('/api/radarr', radarrRoutes);
app.use('/api/emby', embyRoutes);
app.use('/api/dashboard', dashboardRoutes);
app.use('/api/auth', authRoutes);
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '../public/index.html'));
});
app.listen(PORT, () => {
console.log(`=================================`);
console.log(` sofarr - Your Downloads Dashboard`);
console.log(` Server running on port ${PORT}`);
console.log(` Log level: ${process.env.LOG_LEVEL || 'info'}`);
console.log(` Poll interval: ${POLL_INTERVAL}ms`);
console.log(`=================================`);
startPoller();
});