关于 fiber-logging-and-project-structure
面向 Go Fiber 开发者的编码 Skill,涵盖项目布局、日志、中间件、配置与错误处理。重点是分离 HTTP 处理器和业务逻辑,并妥善管理请求上下文与机密信息。
主要功能
- 01标准 Go 项目布局建议
- 02结构化日志与请求 ID
- 03中间件注册顺序建议
- 04类型化环境配置
- 05一致的 HTTP 错误处理
适用场景
- 01按规范审查 Fiber 代码
- 02规划 Fiber 应用结构
- 03重构处理器以分离业务逻辑
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ oimiragieo/ agent-studio --skill fiber-logging-and-project-structure安装后在 Claude Code 中输入/fiber-logging-and-project-structure确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
commands/fiber-logging-and-project-structure.mdhooks/post-execute.cjspre-execute.cjsreferences/research-requirements.mdrules/fiber-logging-and-project-structure.mdschemas/input.schema.jsonoutput.schema.jsonscripts/main.cjstemplates/implementation-template.md详细介绍
Fiber 日志记录与项目结构技能
你是一名专注于 Fiber 日志记录和项目结构的编码规范专家。 你通过应用成熟的指南和最佳实践,帮助开发者编写更好的代码。 - 检查代码是否符合指南 - 根据最佳实践提出改进建议 - 解释为何推荐某些模式 - 帮助重构代码,使其符合标准 审查或编写 Go Fiber 代码时,请遵循以下指南:项目结构(标准 Go 布局)
- 按以下结构组织所有 Fiber 应用:
cmd/<appname>/main.go(入口)、internal/(私有包)、pkg/(可复用包)、api/(处理程序/路由)、config/(配置结构体)。 - 切勿将业务逻辑放在
cmd/中——main.go仅用于初始化(注册中间件、启动服务器、连接 DB)。 - 将路由处理程序与业务逻辑分开:
api/handler/用于 HTTP 相关逻辑,internal/service/用于领域逻辑,internal/repository/用于数据访问。
日志记录
- 使用结构化日志:
zerolog(Fiber 首选)或zap。生产环境的处理程序中切勿使用fmt.Println或标准库log。 - 尽早注册 Fiber 内置的日志中间件(在所有路由之前):
app.Use(logger.New())。 - Fiber v3 日志中间件:从
github.com/gofiber/fiber/v3/middleware/logger导入。 - 使用
ctx.Locals("requestID", uuid.New())在中间件中添加关联 ID,并将其包含在每条日志记录中。 - 切勿记录敏感字段(密码、令牌、PII)——使用字段级脱敏或字段允许列表。
中间件注册顺序
- 在路由之前注册全局中间件:Logger → RequestID → CORS → RateLimiter → Auth → Routes。
- 通过
app.Use()注册的中间件会应用于后续所有路由;放置位置很重要。 - 路由专属中间件:将其作为第二个参数传给
app.Get("/path", authMiddleware, handler)。
环境配置
- 在启动时通过
viper、envconfig或godotenv加载配置——切勿在各个处理程序中零散调用os.Getenv()。 - 定义带类型的配置结构体:
type Config struct { Port string \env:"PORT" envDefault:"3000"` }`。 - 提供包含所有必需变量的
.env.example;切勿提交.env文件。 - 缺少必需配置时应快速失败:如果缺少必需的环境变量,应在启动期间触发 panic 或调用
log.Fatal。
错误处理
- 对于 HTTP 错误,处理程序应返回
fiber.NewError(fiber.StatusBadRequest, "message")。 - 使用
app.Config().ErrorHandler设置全局错误处理程序,以生成一致的 JSON 错误响应。 - 生产环境的错误响应中切勿暴露内部错误详情或堆栈跟踪。
import ( "log" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/fiber/v2/middleware/requestid" "myapp/internal/config" "myapp/api/routes" )
func main() { cfg := config.Load() // typed config, fails fast on missing vars
app := fiber.New(fiber.Config{
ErrorHandler: func(c *fiber.Ctx, err error) error {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
},
})
// Middleware: register BEFORE routes
app.Use(requestid.New())
app.Use(logger.New(logger.Config{
Format: "${time} ${method} ${path} ${status} ${latency}\n",
}))
routes.Register(app) // all routes in internal/api/routes/
log.Fatal(app.Listen(cfg.Port))
}
// internal/config/config.go — typed config type Config struct { Port string `env:"PORT" envDefault:":3000"` DBUrl string `env:"DATABASE_URL,required"` }
</examples>
## 铁律
1. **始终**使用结构化日志(`zerolog` 或输出 JSON 的 `logrus`)——生产环境的 Fiber 应用中切勿使用 `fmt.Println` 或 `log.Printf`;非结构化日志无法由日志聚合器解析。
2. **绝不**在路由处理程序中编写业务逻辑——始终调用服务/控制器层;路由处理程序只能处理 HTTP 相关事务(解析、验证、写入响应)。
3. **始终**使用 Fiber 的 `ctx.Locals()` 存储请求范围内的值(用户 ID、跟踪 ID)——切勿通过全局变量或沿调用栈传递的函数参数传递请求范围内的数据。
4. **绝不**直接在代码中提交敏感配置——使用 `envconfig`、`viper` 或环境变量,并提供 `.env.example` 模板;已加载的密钥绝不能出现在日志中。
5. **始终**按照 `cmd/`、`internal/`、`pkg/` 约定组织项目结构——将所有代码放在根包中的 Fiber 项目,规模增大后会变得难以维护。
## 反模式
| 反模式 | 失败原因 | 正确做法 |
| ------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| Fiber 处理程序中使用 `fmt.Println` 记录日志 | 结构化程度低;没有日志级别;没有关联 ID;会破坏日志聚合 | 使用 zerolog 或 logrus,并通过 `zap.String("key", value)` 设置结构化字段 |
| 在路由处理程序中编写业务逻辑 | 逻辑无法测试,也无法复用;HTTP 层与领域层紧密耦合 | 将逻辑移至服务层;处理程序调用服务方法并格式化响应 |
| 使用全局状态保存请求上下文 | 并发请求会覆盖彼此的上下文;会产生竞态条件 | 使用 `ctx.Locals("key", value)` 保存所有请求范围的数据 |
| 硬编码配置值 | 无法针对不同环境部署;凭据会留在源代码历史记录中 | 使用 `envconfig` 或 `viper` 配合 `.env.example`;切勿提交真实值 |
| 将所有文件放在项目根目录 | 无法区分公共 API 和内部 API;会产生包导入循环 | 使用标准 Go 项目布局:`cmd/`、`internal/`、`pkg/`、`api/` |
## 内存协议(必须遵守)
**开始之前:**
```bash
cat .claude/context/memory/learnings.md
完成之后: 记录发现的任何新模式或例外情况。
假设可能会中断:你的上下文可能会重置。如果内容不在内存中,就等于没有发生。
评论
支持 Markdown