Ich habe soweit automatisiert the Emails sortieren aber ich muss noch schauen was es fur bugs es gibt wenn die app online ist deswegen wurde ich mit diesen Commit die website veroffentlichen obwohjl es sein konnte das es noch nicht fertig ist und verkaufs bereit
135 lines
3.3 KiB
JavaScript
135 lines
3.3 KiB
JavaScript
/**
|
|
* Request Logger Middleware
|
|
* Logs all incoming requests with timing information
|
|
*/
|
|
|
|
// ANSI color codes for terminal output
|
|
const colors = {
|
|
reset: '\x1b[0m',
|
|
bright: '\x1b[1m',
|
|
dim: '\x1b[2m',
|
|
red: '\x1b[31m',
|
|
green: '\x1b[32m',
|
|
yellow: '\x1b[33m',
|
|
blue: '\x1b[34m',
|
|
magenta: '\x1b[35m',
|
|
cyan: '\x1b[36m',
|
|
}
|
|
|
|
/**
|
|
* Get color based on status code
|
|
*/
|
|
function getStatusColor(status) {
|
|
if (status >= 500) return colors.red
|
|
if (status >= 400) return colors.yellow
|
|
if (status >= 300) return colors.cyan
|
|
if (status >= 200) return colors.green
|
|
return colors.reset
|
|
}
|
|
|
|
/**
|
|
* Get color based on HTTP method
|
|
*/
|
|
function getMethodColor(method) {
|
|
const methodColors = {
|
|
GET: colors.green,
|
|
POST: colors.blue,
|
|
PUT: colors.yellow,
|
|
PATCH: colors.yellow,
|
|
DELETE: colors.red,
|
|
}
|
|
return methodColors[method] || colors.reset
|
|
}
|
|
|
|
/**
|
|
* Format duration for display
|
|
*/
|
|
function formatDuration(ms) {
|
|
if (ms < 1) return `${(ms * 1000).toFixed(0)}µs`
|
|
if (ms < 1000) return `${ms.toFixed(0)}ms`
|
|
return `${(ms / 1000).toFixed(2)}s`
|
|
}
|
|
|
|
/**
|
|
* Logger middleware
|
|
*/
|
|
export function logger(options = {}) {
|
|
const {
|
|
skip = () => false,
|
|
format = 'dev',
|
|
} = options
|
|
|
|
return (req, res, next) => {
|
|
if (skip(req, res)) {
|
|
return next()
|
|
}
|
|
|
|
const startTime = process.hrtime.bigint()
|
|
const timestamp = new Date().toISOString()
|
|
|
|
// Capture response
|
|
const originalSend = res.send
|
|
res.send = function (body) {
|
|
const endTime = process.hrtime.bigint()
|
|
const duration = Number(endTime - startTime) / 1e6 // Convert to ms
|
|
|
|
const statusColor = getStatusColor(res.statusCode)
|
|
const methodColor = getMethodColor(req.method)
|
|
|
|
// Log format
|
|
const logLine = [
|
|
`${colors.dim}[${timestamp}]${colors.reset}`,
|
|
`${methodColor}${req.method.padEnd(7)}${colors.reset}`,
|
|
`${req.originalUrl}`,
|
|
`${statusColor}${res.statusCode}${colors.reset}`,
|
|
`${colors.dim}${formatDuration(duration)}${colors.reset}`,
|
|
].join(' ')
|
|
|
|
console.log(logLine)
|
|
|
|
// Log errors in detail
|
|
if (res.statusCode >= 400 && body) {
|
|
try {
|
|
const parsed = typeof body === 'string' ? JSON.parse(body) : body
|
|
if (parsed.error) {
|
|
console.log(` ${colors.red}→ ${parsed.error.message}${colors.reset}`)
|
|
}
|
|
} catch (e) {
|
|
// Body is not JSON
|
|
}
|
|
}
|
|
|
|
return originalSend.call(this, body)
|
|
}
|
|
|
|
next()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log levels
|
|
*/
|
|
export const log = {
|
|
info: (message, data = {}) => {
|
|
console.log(`${colors.blue}[INFO]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
|
|
},
|
|
|
|
warn: (message, data = {}) => {
|
|
console.log(`${colors.yellow}[WARN]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
|
|
},
|
|
|
|
error: (message, data = {}) => {
|
|
console.error(`${colors.red}[ERROR]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
|
|
},
|
|
|
|
debug: (message, data = {}) => {
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.log(`${colors.magenta}[DEBUG]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
|
|
}
|
|
},
|
|
|
|
success: (message, data = {}) => {
|
|
console.log(`${colors.green}[OK]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
|
|
},
|
|
}
|