Fullmoon错误处理与日志系统构建健壮的Web应用终极指南【免费下载链接】fullmoonFast and minimalistic Redbean-based Lua web framework in one file.项目地址: https://gitcode.com/gh_mirrors/fu/fullmoonFullmoon是一个基于Redbean的快速、轻量级Lua Web框架它提供了一套完整的错误处理和日志系统帮助开发者构建健壮的Web应用程序。无论你是刚刚接触Fullmoon的新手还是正在寻找提升应用稳定性的方法本文将为你详细解析Fullmoon的错误处理机制和日志系统的完整使用方法。为什么错误处理和日志对Web应用至关重要✨在现代Web开发中错误处理和日志记录是保证应用稳定性的关键因素。Fullmoon框架通过精心设计的错误处理机制和灵活的日志系统让开发者能够快速定位问题详细的错误信息和日志记录帮助快速诊断问题提升用户体验优雅的错误页面避免用户看到技术性错误信息监控应用健康通过日志了解应用运行状态和性能表现增强安全性记录可疑请求和异常行为Fullmoon错误处理系统详解 内置错误状态码处理Fullmoon提供了简单直观的错误状态码处理方式。你可以直接使用serveError函数返回特定的HTTP状态码local fm require fullmoon -- 返回403禁止访问错误 fm.setRoute(/admin, fm.serve403) -- 返回404未找到错误 fm.setRoute(/missing-page, fm.serve404) -- 自定义错误状态和消息 fm.setRoute(/custom-error, function(r) return fm.serveError(418, Im a teapot, 这个服务器拒绝冲泡咖啡因为它是一个茶壶) end)自定义错误页面模板Fullmoon允许你为不同的HTTP状态码创建自定义错误页面。默认情况下框架提供了基本的错误模板但你可以轻松覆盖它们-- 自定义404错误页面 fm.setTemplate(404, [[ !DOCTYPE html html head title页面未找到 - 404/title style body { font-family: Arial, sans-serif; text-align: center; padding: 50px; } h1 { color: #e74c3c; } /style /head body h1哎呀页面走丢了 ♂️/h1 p您请求的页面不存在请检查URL是否正确。/p pa href/返回首页/a/p /body /html ]]) -- 自定义500服务器错误页面 fm.setTemplate(500, [[ !DOCTYPE html html head title服务器错误 - 500/title style body { font-family: Arial, sans-serif; text-align: center; padding: 50px; } h1 { color: #c0392b; } .debug { background: #f8f9fa; padding: 20px; margin: 20px auto; max-width: 800px; text-align: left; } /style /head body h1服务器遇到了一些问题 ⚠️/h1 p我们的工程师已经收到通知正在努力修复中。/p {% if message then %} div classdebug h3调试信息/h3 pre{% message %}/pre /div {% end %} pa href/返回首页/a/p /body /html ]])条件路由中的错误处理Fullmoon的条件路由系统允许你在路由匹配失败时返回特定的错误响应-- 限制上传文件大小超过限制返回413错误 local function isLessThan(n) return function(l) return tonumber(l) n end end fm.setRoute(fm.POST{/upload, ContentLength {isLessThan(100000), otherwise 413} }, function(r) -- 处理上传逻辑 fm.storeAsset(uploaded, r.body) return 文件上传成功 end) -- 限制特定IP访问其他IP返回403错误 fm.setRoute({/admin-panel, clientAddr {fm.isLoopbackIp, otherwise 403} }, function(r) return 欢迎访问管理面板 end)优雅的异常处理机制Fullmoon提供了强大的异常处理能力让你可以在代码中抛出错误并优雅地处理-- 在路由处理函数中使用错误抛出 fm.setRoute(/api/data/:id, function(r) local data fetchDataFromDatabase(r.params.id) if not data then -- 抛出404错误 error(fm.serve404) end if data.status deleted then -- 抛出410已删除错误 error(fm.serve410) end return fm.serveContent(data-template, data) end) -- 自定义错误处理函数 local function handleDatabaseError(err) fm.logError(数据库错误: .. err) return fm.serveError(503, 服务暂时不可用, 数据库连接出现问题请稍后重试) end fm.setRoute(/user/:id, function(r) local ok, user pcall(function() return getUserById(r.params.id) end) if not ok then return handleDatabaseError(user) end return fm.serveContent(user-profile, {user user}) end)Fullmoon日志系统全面解析 多级别日志记录Fullmoon提供了四个日志级别满足不同场景的需求-- 调试级别日志 - 用于开发调试 fm.logDebug(路由匹配: %s, r.path) fm.logDebug(用户ID: %s, 会话: %s, userId, sessionId) -- 详细级别日志 - 记录详细信息 fm.logVerbose(请求处理开始: %s %s, r.method, r.path) fm.logVerbose(请求头: %s, jsonEncode(r.headers)) -- 信息级别日志 - 记录常规操作 fm.logInfo(用户登录成功: %s, username) fm.logInfo(文件上传完成: %s, 大小: %d字节, filename, fileSize) -- 警告级别日志 - 记录需要注意的问题 fm.logWarn(数据库连接池接近上限: %d/%d, current, max) fm.logWarn(API调用频率过高: %s, clientIP) -- 错误级别日志由框架自动记录日志配置与优化你可以在应用启动时配置日志行为-- 在运行应用时配置日志 fm.run({ addr localhost, port 8080, logPath /var/log/fullmoon/app.log, -- 指定日志文件路径 logMessages true, -- 记录响应头信息 logBodies false -- 不记录请求体保护敏感数据 })实际应用场景示例让我们看几个在实际应用中使用日志的完整示例-- 示例1用户认证日志 fm.setRoute(fm.POST/login, function(r) local username r.params.username local password r.params.password fm.logInfo(登录尝试: %s, username) local user authenticateUser(username, password) if user then fm.logInfo(登录成功: %s, username) r.session.userId user.id return fm.serveRedirect(/dashboard) else fm.logWarn(登录失败: %s, username) return fm.serveContent(login, { error 用户名或密码错误 }) end end) -- 示例2API请求监控 local apiLogger function(r, startTime) local endTime os.clock() local duration endTime - startTime local status GetStatus() fm.logInfo(API请求: %s %s - 状态: %d - 耗时: %.3f秒, r.method, r.path, status, duration) if duration 1.0 then -- 慢请求警告 fm.logWarn(慢请求检测: %s %s 耗时 %.3f秒, r.method, r.path, duration) end end fm.setRoute(/api/*, function(r) local startTime os.clock() -- 处理API请求... local result processApiRequest(r) -- 记录日志 apiLogger(r, startTime) return result end) -- 示例3错误追踪和报告 local errorTracker { errors {}, maxErrors 100 } local function trackError(err, context) local errorInfo { timestamp os.date(%Y-%m-%d %H:%M:%S), error err, context context, path GetPath(), method GetMethod(), clientIP FormatIp(GetRemoteAddr()) } table.insert(errorTracker.errors, 1, errorInfo) -- 保持错误列表大小 if #errorTracker.errors errorTracker.maxErrors then table.remove(errorTracker.errors) end fm.logError(错误记录: %s - 路径: %s, err, context.path or 未知) end -- 全局错误处理中间件 local function errorHandler(handler) return function(r) local ok, result pcall(handler, r) if not ok then trackError(result, {path r.path, params r.params}) return fm.serveError(500, 服务器内部错误) end return result end end fm.setRoute(/admin/errors, function(r) return fm.serveContent(error-dashboard, { errors errorTracker.errors }) end)高级错误处理技巧 自定义验证器和错误处理Fullmoon的验证器系统可以创建复杂的验证逻辑-- 创建用户注册验证器 local signupValidator fm.makeValidator{ {username, minlen 3, maxlen 20, pattern ^[a-zA-Z0-9_]$, msg 用户名必须为3-20位字母数字或下划线 }, {email, pattern ^[%w._%%-][%w.-]%.[%a]$, msg 请输入有效的邮箱地址 }, {password, minlen 8, test function(pass) -- 检查密码强度 local hasUpper pass:match(%u) local hasLower pass:match(%l) local hasDigit pass:match(%d) return hasUpper and hasLower and hasDigit end, msg 密码必须包含大小写字母和数字 }, otherwise function(errors) -- 返回验证错误 return fm.serveContent(signup-form, { errors errors, formData r.params }) end } fm.setRoute(fm.POST/signup, function(r) local valid, errors signupValidator(r.params) if valid then -- 创建用户账户 createUser(r.params.username, r.params.email, r.params.password) fm.logInfo(新用户注册: %s, r.params.username) return fm.serveRedirect(/welcome) end -- 验证失败错误已通过otherwise处理 return false end)中间件错误处理模式创建可重用的错误处理中间件-- 数据库连接中间件 local function withDatabase(handler) return function(r) local db, err connectToDatabase() if not db then fm.logError(数据库连接失败: %s, err) return fm.serveError(503, 数据库服务不可用) end r.db db local ok, result pcall(handler, r) -- 确保数据库连接关闭 db:close() if not ok then fm.logError(处理请求时出错: %s, result) return fm.serveError(500, 处理请求时发生错误) end return result end end -- 使用中间件 fm.setRoute(/user/profile, withDatabase(function(r) local user r.db:query(SELECT * FROM users WHERE id ?, r.session.userId) if not user then return fm.serveError(404, 用户不存在) end return fm.serveContent(user-profile, {user user}) end))性能监控和错误预警-- 性能监控中间件 local performanceMonitor { requests {}, slowThreshold 1.0, -- 1秒 errorThreshold 0.01 -- 1%错误率 } local function monitorPerformance(handler) return function(r) local startTime os.clock() local startMemory collectgarbage(count) local ok, result pcall(handler, r) local endTime os.clock() local endMemory collectgarbage(count) local duration endTime - startTime local memoryUsed endMemory - startMemory -- 记录性能数据 local stats { path r.path, method r.method, duration duration, memory memoryUsed, success ok, timestamp os.time() } table.insert(performanceMonitor.requests, 1, stats) -- 保持最近1000个请求的记录 if #performanceMonitor.requests 1000 then table.remove(performanceMonitor.requests) end -- 检测慢请求 if duration performanceMonitor.slowThreshold then fm.logWarn(慢请求: %s %s 耗时 %.3f秒, r.method, r.path, duration) end -- 检测高内存使用 if memoryUsed 1024 then -- 1MB fm.logWarn(高内存使用: %s %s 使用 %.2fKB, r.method, r.path, memoryUsed) end if not ok then fm.logError(请求处理失败: %s - 错误: %s, r.path, result) end return result end end -- 应用性能监控到所有路由 local originalSetRoute fm.setRoute fm.setRoute function(route, handler) if type(handler) function then handler monitorPerformance(handler) end return originalSetRoute(route, handler) end最佳实践和实用建议 1. 分层错误处理策略-- 第一层输入验证错误400系列 local function validateInput(data, rules) -- 返回400错误 end -- 第二层业务逻辑错误自定义 local function businessLogic(data) -- 返回业务特定的错误 end -- 第三层系统错误500系列 local function systemOperation() -- 捕获并记录系统级错误 end -- 第四层全局错误处理 fm.setRoute(/*, function(r) local ok, result xpcall(function() -- 处理请求 return processRequest(r) end, function(err) -- 全局错误处理 fm.logError(未捕获的异常: %s, err) return fm.serveError(500, 系统错误) end) return result end)2. 结构化日志记录-- 创建结构化日志记录器 local structuredLogger { debug function(fields, message, ...) fm.logDebug(%s | %s, jsonEncode(fields), message:format(...)) end, info function(fields, message, ...) fm.logInfo(%s | %s, jsonEncode(fields), message:format(...)) end, warn function(fields, message, ...) fm.logWarn(%s | %s, jsonEncode(fields), message:format(...)) end, error function(fields, message, ...) fm.logError(%s | %s, jsonEncode(fields), message:format(...)) end } -- 使用结构化日志 fm.setRoute(/api/v1/users, function(r) local logFields { endpoint /api/v1/users, method r.method, clientIP FormatIp(r.remoteAddr), userId r.session.userId or anonymous } structuredLogger.info(logFields, 处理用户列表请求) -- 处理请求... return result end)3. 生产环境配置-- 生产环境配置 local function setupProductionEnvironment() -- 设置适当的日志级别 if GetLogLevel then local currentLevel GetLogLevel() if currentLevel kLogInfo then -- 生产环境只记录警告和错误 LogInfo function() end LogVerbose function() end LogDebug function() end end end -- 配置错误模板 fm.setTemplate(404, production404Template) fm.setTemplate(500, production500Template) -- 设置安全头 fm.run({ addr 0.0.0.0, port 80, headers { [X-Content-Type-Options] nosniff, [X-Frame-Options] DENY, [X-XSS-Protection] 1; modeblock }, logPath /var/log/fullmoon/access.log, logMessages true }) end总结与下一步行动 Fullmoon的错误处理和日志系统为构建健壮的Web应用提供了坚实的基础。通过合理利用这些功能你可以创建用户友好的错误页面- 提升用户体验实现细粒度的错误处理- 提高代码质量建立完善的日志系统- 便于调试和监控构建可维护的应用架构- 降低维护成本记住良好的错误处理不是事后的想法而是应用设计的重要组成部分。从项目开始就考虑错误处理和日志记录将为你的应用带来长期的稳定性收益。现在就开始在你的Fullmoon项目中实施这些最佳实践吧如果你需要更多帮助可以参考官方文档中的日志配置部分和错误处理示例它们提供了更多实用的代码示例和配置选项。通过掌握Fullmoon的错误处理和日志系统你将能够构建出更加健壮、可靠且易于维护的Web应用程序。【免费下载链接】fullmoonFast and minimalistic Redbean-based Lua web framework in one file.项目地址: https://gitcode.com/gh_mirrors/fu/fullmoon创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考