UNPKG

nginx-log-analyzer

Version:
124 lines (102 loc) 3.84 kB
#!/usr/bin/env node const fs = require("fs"); const readline = require("readline"); const chalk = require("chalk"); const uaParser = require("ua-parser-js"); // Function to analyze the log file async function analyzeLogFile(filePath) { const logData = { totalRequests: 0, statusCodes: {}, referrers: {}, urls: {}, browsers: {}, }; try { const fileStream = fs.createReadStream(filePath); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity, }); console.log(chalk.blue("Reading log file...")); // Process each line of the log file for await (const line of rl) { // Extract relevant data from the log line const logParts = line.match(/"([^"]*)"|(\S+)/g); if (!logParts || logParts.length < 10) continue; // Skip malformed or empty lines logData.totalRequests += 1; // Count only valid lines const method = logParts[5]?.replace(/"/g, "").split(" ")[0]; const url = logParts[5]?.replace(/"/g, "").split(" ")[1]; const statusCode = logParts[6]; const referrer = logParts[8]; const userAgent = logParts[9]?.replace(/"/g, ""); // Count HTTP status codes if (statusCode) { logData.statusCodes[statusCode] = (logData.statusCodes[statusCode] || 0) + 1; } if (referrer) { logData.referrers[referrer] = (logData.referrers[referrer] || 0) + 1; } // Count accessed URLs if (url) { logData.urls[url] = (logData.urls[url] || 0) + 1; } // Parse User-Agent and count browsers if (userAgent) { const parsedUA = uaParser(userAgent); const browserName = parsedUA.browser.name || "Unknown"; logData.browsers[browserName] = (logData.browsers[browserName] || 0) + 1; } } console.log(chalk.green("Log analysis completed!")); return logData; } catch (error) { console.error(chalk.red(`Error: ${error.message}`)); return null; } } // Function to print analysis results function printAnalysisResults(logData) { if (!logData) { console.log(chalk.red("Log analysis failed.")); return; } console.log(chalk.yellow("\n--- Log Analysis Results ---\n")); console.log(chalk.green(`Total Requests: ${logData.totalRequests}`)); console.log(chalk.grey("\nReferrers:")); for (const [status, count] of Object.entries(logData.referrers).sort( (a, b) => b[1] - a[1] )) { const percentage = ((count / logData.totalRequests) * 100).toFixed(2); console.log(` ${status}: ${count} (${percentage}%)`); } console.log(chalk.blue("\nHTTP Status Codes:")); for (const [status, count] of Object.entries(logData.statusCodes).sort( (a, b) => b[1] - a[1] )) { const percentage = ((count / logData.totalRequests) * 100).toFixed(2); console.log(` ${status}: ${count} (${percentage}%)`); } console.log(chalk.magenta("\nMost Frequently Accessed PATHs:")); const sortedUrls = Object.entries(logData.urls).sort((a, b) => b[1] - a[1]); sortedUrls.slice(0, 10).forEach(([url, count]) => { const percentage = ((count / logData.totalRequests) * 100).toFixed(2); console.log(` ${url}: ${count} (${percentage}%)`); }); console.log(chalk.cyan("\nTop Browsers:")); const sortedBrowsers = Object.entries(logData.browsers).sort( (a, b) => b[1] - a[1] ); sortedBrowsers.slice(0, 5).forEach(([browser, count]) => { const percentage = ((count / logData.totalRequests) * 100).toFixed(2); console.log(` ${browser}: ${count} (${percentage}%)`); }); } // Read file path from command-line arguments and analyze the log const logFilePath = process.argv[2]; if (!logFilePath) { console.log(chalk.red("Log file parameter is required.")); process.exit(); } analyzeLogFile(logFilePath).then(printAnalysisResults);