# 日志格式规范

## 结构化日志

所有日志必须使用结构化格式，禁止字符串拼接。

### 正确示例
```go
log.WithFields(log.Fields{
    "user_id":    userID,
    "action":     "login",
    "request_id": requestID,
    "duration":   duration.Milliseconds(),
}).Info("用户登录成功")
```

### 错误示例
```go
// ❌ 禁止
log.Info("用户 " + username + " 登录成功，耗时 " + duration.String())
```

## 必须字段

| 字段 | 说明 | 示例 |
|:---|:---|:---|
| request_id | 请求唯一标识 | uuid |
| user_id | 操作用户ID | 123 |
| action | 操作类型 | login, create_user |
| duration | 耗时（毫秒） | 150 |

## 日志级别

| 级别 | 使用场景 |
|:---|:---|
| ERROR | 错误，需要关注和处理 |
| WARN | 警告，可能的问题 |
| INFO | 重要业务事件 |
| DEBUG | 调试信息，生产环境关闭 |

## 敏感信息脱敏

必须脱敏的字段：
- 密码（任何形式）
- Token / Secret
- 身份证号
- 银行卡号
- 手机号（中间四位）

```go
// 脱敏工具
func maskPhone(phone string) string {
    if len(phone) >= 11 {
        return phone[:3] + "****" + phone[7:]
    }
    return "****"
}
```
