feat: Implement comprehensive log filtering feature with severity, time range, and tag options
This commit is contained in:
@@ -25,13 +25,20 @@ let syncStats = {
|
||||
lastReset: Date.now()
|
||||
};
|
||||
|
||||
// Print stats every 30 seconds
|
||||
// Print stats every 60 seconds (reduced spam)
|
||||
setInterval(() => {
|
||||
if (syncStats.totalSyncs > 0) {
|
||||
const elapsed = Math.round((Date.now() - syncStats.lastReset) / 1000);
|
||||
console.log(`\n[STATS] Last ${elapsed}s: ${syncStats.totalSyncs} syncs`);
|
||||
console.log(` Received: ${syncStats.listsReceived} lists, ${syncStats.fieldsReceived} fields, ${syncStats.itemsReceived} items, ${syncStats.valuesReceived} values`);
|
||||
console.log(` Sent: ${syncStats.listsSent} lists, ${syncStats.fieldsSent} fields, ${syncStats.itemsSent} items, ${syncStats.valuesSent} values\n`);
|
||||
console.log(`\n[STATS] Sync Summary (last ${elapsed}s):`);
|
||||
console.log(` ${syncStats.totalSyncs} sync requests processed`);
|
||||
|
||||
if (syncStats.listsReceived > 0 || syncStats.fieldsReceived > 0 || syncStats.itemsReceived > 0 || syncStats.valuesReceived > 0) {
|
||||
console.log(` [IN] Received: ${syncStats.listsReceived} lists, ${syncStats.fieldsReceived} fields, ${syncStats.itemsReceived} items, ${syncStats.valuesReceived} values`);
|
||||
}
|
||||
|
||||
if (syncStats.listsSent > 0 || syncStats.fieldsSent > 0 || syncStats.itemsSent > 0 || syncStats.valuesSent > 0) {
|
||||
console.log(` [OUT] Sent: ${syncStats.listsSent} lists, ${syncStats.fieldsSent} fields, ${syncStats.itemsSent} items, ${syncStats.valuesSent} values`);
|
||||
}
|
||||
|
||||
// Reset stats
|
||||
syncStats = {
|
||||
@@ -47,7 +54,7 @@ setInterval(() => {
|
||||
lastReset: Date.now()
|
||||
};
|
||||
}
|
||||
}, 30000);
|
||||
}, 60000); // Changed from 30s to 60s
|
||||
|
||||
// Helper function to get prepared statements (lazy initialization)
|
||||
function getUpsertStatements() {
|
||||
@@ -104,16 +111,36 @@ router.post('/sync', async (req: Request, res: Response) => {
|
||||
syncStats.itemsReceived += incomingItems;
|
||||
syncStats.valuesReceived += incomingValues;
|
||||
|
||||
// Log only when there's actual data being synced
|
||||
// Only log significant sync events (not empty syncs)
|
||||
const hasIncomingData = incomingLists > 0 || incomingFields > 0 || incomingItems > 0 || incomingValues > 0;
|
||||
const isInitialSync = lastSyncTimestamp === 0;
|
||||
|
||||
if (hasIncomingData) {
|
||||
console.log(`[SYNC] Received: ${incomingLists} lists, ${incomingFields} fields, ${incomingItems} items, ${incomingValues} values`);
|
||||
// Log list details
|
||||
if (lists && lists.length > 0) {
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
console.log(`\n[SYNC] [${timestamp}] Receiving data from client`);
|
||||
|
||||
if (incomingLists > 0) {
|
||||
console.log(` [LISTS] ${incomingLists} list(s)`);
|
||||
lists.forEach(list => {
|
||||
console.log(` List: ${list.id} - "${list.name}" (updated: ${list.updatedAt}, deleted: ${list.isDeleted})`);
|
||||
const action = list.isDeleted ? 'Deleted' : (lastSyncTimestamp === 0 ? 'Created' : 'Updated');
|
||||
console.log(` ${action}: "${list.name}"`);
|
||||
});
|
||||
}
|
||||
|
||||
if (incomingFields > 0) {
|
||||
console.log(` [FIELDS] ${incomingFields} field(s)`);
|
||||
}
|
||||
|
||||
if (incomingItems > 0) {
|
||||
console.log(` [ITEMS] ${incomingItems} item(s)`);
|
||||
}
|
||||
|
||||
if (incomingValues > 0) {
|
||||
console.log(` [VALUES] ${incomingValues} value(s)`);
|
||||
}
|
||||
} else if (isInitialSync) {
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
console.log(`\n[SYNC] [${timestamp}] Initial sync from new client`);
|
||||
}
|
||||
|
||||
// Save incoming data from client using a transaction
|
||||
@@ -130,7 +157,6 @@ router.post('/sync', async (req: Request, res: Response) => {
|
||||
updatedAt: list.updatedAt,
|
||||
isDeleted: list.isDeleted ? 1 : 0
|
||||
});
|
||||
console.log(` Saved list ${list.id}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,10 +236,12 @@ router.post('/sync', async (req: Request, res: Response) => {
|
||||
syncStats.itemsSent += (serverItems as any[]).length;
|
||||
syncStats.valuesSent += (serverItemValues as any[]).length;
|
||||
|
||||
// Log only when sending data back
|
||||
// Only log when sending significant data back
|
||||
const hasOutgoingData = (serverLists as any[]).length > 0 || (serverFields as any[]).length > 0 || (serverItems as any[]).length > 0 || (serverItemValues as any[]).length > 0;
|
||||
if (hasOutgoingData) {
|
||||
console.log(`[SYNC] Sending: ${(serverLists as any[]).length} lists, ${(serverFields as any[]).length} fields, ${(serverItems as any[]).length} items, ${(serverItemValues as any[]).length} values`);
|
||||
if (hasOutgoingData && !isInitialSync) {
|
||||
console.log(` [OUT] Sending back: ${(serverLists as any[]).length} lists, ${(serverFields as any[]).length} fields, ${(serverItems as any[]).length} items, ${(serverItemValues as any[]).length} values`);
|
||||
} else if (isInitialSync && hasOutgoingData) {
|
||||
console.log(` [OUT] Sending initial data: ${(serverLists as any[]).length} lists, ${(serverFields as any[]).length} fields, ${(serverItems as any[]).length} items, ${(serverItemValues as any[]).length} values`);
|
||||
}
|
||||
|
||||
res.json({
|
||||
@@ -224,7 +252,7 @@ router.post('/sync', async (req: Request, res: Response) => {
|
||||
serverTimestamp
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[SYNC] Error:', error);
|
||||
console.error('[ERROR] Sync error:', error);
|
||||
res.status(500).json({ error: 'Sync failed' });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -189,7 +189,10 @@ router.get('/', (req: Request, res: Response) => {
|
||||
<script>
|
||||
async function loadData() {
|
||||
try {
|
||||
const response = await fetch('/web/data');
|
||||
// Add cache-busting timestamp to URL
|
||||
const response = await fetch('/web/data?_=' + Date.now(), {
|
||||
cache: 'no-store'
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error('HTTP ' + response.status + ': ' + response.statusText);
|
||||
}
|
||||
@@ -298,6 +301,11 @@ router.get('/', (req: Request, res: Response) => {
|
||||
// API endpoint to get all data (no auth required for web UI)
|
||||
router.get('/web/data', async (req: Request, res: Response) => {
|
||||
try {
|
||||
// Add cache control headers to prevent stale data
|
||||
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
||||
res.setHeader('Pragma', 'no-cache');
|
||||
res.setHeader('Expires', '0');
|
||||
|
||||
const lists = db.prepare('SELECT * FROM lists ORDER BY updatedAt DESC').all();
|
||||
const fields = db.prepare('SELECT * FROM fields ORDER BY listId ASC, `order` ASC').all();
|
||||
const items = db.prepare('SELECT * FROM items ORDER BY listId ASC, updatedAt DESC').all();
|
||||
@@ -318,7 +326,8 @@ router.get('/web/data', async (req: Request, res: Response) => {
|
||||
fields: formattedFields.length,
|
||||
items: formattedItems.length,
|
||||
values: (values as any[]).length
|
||||
}
|
||||
},
|
||||
timestamp: Date.now() // Add timestamp for debugging
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
|
||||
Reference in New Issue
Block a user