Skip to content

ysicing-archived/caddy2-4xxlog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Caddy2 4xx请求上报插件

这个Caddy2插件可以自动捕获并上报HTTP 4xx状态码请求到指定的HTTP接口。

功能特性

  • 自动捕获并上报HTTP 4xx状态码请求
  • 异步上报,不影响主请求处理
  • 简单轻量的设计
  • 只需配置上报地址和超时时间
  • 零配置部署支持(使用默认上报地址)

工作原理

该插件作为Caddy2的HTTP中间件运行,通过以下步骤捕获和处理4xx请求:

  1. 拦截所有HTTP请求响应
  2. 检查响应状态码是否在400-499范围内
  3. 对于4xx响应,异步收集请求详情并上报到配置的端点
  4. 不干扰原始请求的处理和返回结果
┌─────────┐      ┌──────────┐      ┌─────────────┐
│  客户端  │ ──▶ │  Caddy2   │ ──▶ │ 下游处理程序  │
└─────────┘      └──────────┘      └─────────────┘
                      │
                      │ 4xx状态码
                      ▼
              ┌───────────────┐
              │ 4xxlog插件    │
              └───────────────┘
                      │
                      │ 异步上报
                      ▼
              ┌───────────────┐
              │ 上报接口      │
              └───────────────┘

安装

方法1:使用xcaddy构建

xcaddy build --with github.com/ysicing/caddy2-4xxlog

方法2:作为Go模块引入

go get github.com/ysicing/caddy2-4xxlog

然后在你的Caddy构建文件中引入:

package main

import (
	"github.com/caddyserver/caddy/v2"
	_ "github.com/ysicing/caddy2-4xxlog" // 引入插件
)

func main() {
	caddy.Main()
}

配置示例

Caddyfile配置示例

  1. 基本配置
{
    order 4xxlog before handle_path
}

localhost {
    4xxlog {
        report_url http://example.com/report
        timeout 5s
    }

    # 后续的任何产生4xx状态码的指令都会被捕获
    file_server
}
  1. 零配置部署(使用默认值)
{
    order 4xxlog before handle_path
}

localhost {
    # 使用默认上报地址 http://10.25.255.80:8080/api/logs
    # 默认超时时间为5秒
    4xxlog
    
    file_server
}
  1. 多站点配置
{
    order 4xxlog before handle_path
}

# 站点1
site1.example.com {
    4xxlog {
        report_url http://monitor.example.com/site1/report
        timeout 5s
    }
    reverse_proxy backend1:8080
}

# 站点2
site2.example.com {
    4xxlog {
        report_url http://monitor.example.com/site2/report
        timeout 5s
    }
    reverse_proxy backend2:8080
}
  1. 与其他中间件组合
{
    order 4xxlog before handle_path
}

api.example.com {
    # 启用4xx请求上报
    4xxlog {
        report_url http://monitor.example.com/report
        timeout 5s
    }

    # 基本认证(可能产生401)
    basicauth {
        alice JDJhJDE0JHR5S3k4ZVJ3Z0s4WC41QzRnUk9tdWVCYTVGYmdUdEljYm1IMkFZV3VXcWJ5RzF3WnFkc3Zp
    }

    # 速率限制(可能产生429)
    rate_limit {
        zone dynamic
        rate 10r/s
    }

    # 反向代理(可能产生502、504等)
    reverse_proxy backend:8080 {
        fail_duration 10s
        unhealthy_status 502 504
    }
}

插件会捕获所有由以上配置产生的4xx状态码,包括但不限于:

  • 401 Unauthorized(认证失败)
  • 403 Forbidden(授权失败)
  • 404 Not Found(资源不存在)
  • 429 Too Many Requests(速率限制)

无论状态码是由哪个指令或中间件产生的,只要是4xx范围内的状态码都会被捕获并上报。

JSON配置

{
  "apps": {
    "http": {
      "servers": {
        "example": {
          "listen": [":80"],
          "routes": [
            {
              "handle": [
                {
                  "handler": "4xxlog",
                  "report_url": "http://example.com/report",
                  "timeout": "5s"
                }
              ]
            }
          ]
        }
      }
    }
  }
}

配置参数

  • report_url: 上报接口地址(默认值:http://10.25.255.80:8080/api/logs
  • timeout: 上报请求超时时间(默认:5s)

上报数据格式

插件使用HTTP POST方法将4xx请求信息以JSON格式发送到配置的report_url。

数据结构

{
  "timestamp": "2024-01-01T12:00:00Z",
  "method": "GET",
  "url": "example.com",
  "path": "/path/to/resource",
  "status_code": 404,
  "client_ip": "192.168.1.1",
  "user_agent": "Mozilla/5.0 ..."
}

字段说明

字段 类型 描述
timestamp string 请求时间,ISO8601/RFC3339格式
method string HTTP请求方法(GET, POST, PUT等)
url string 主机名
path string 请求的路径部分
status_code number HTTP响应状态码(400-499)
client_ip string 客户端IP地址和端口
user_agent string 客户端User-Agent字符串

性能考虑

插件专为高性能设计:

  1. 异步上报:所有的上报操作都在单独的goroutine中执行,不会阻塞主请求处理
  2. 轻量级缓冲:仅在必要时缓冲响应内容
  3. 超时控制:防止上报操作影响服务器性能
  4. 错误处理:上报失败会记录到日志,但不会影响原始请求处理

最佳实践

部署建议

  1. 调整顺序:确保4xxlog插件在处理路径之前执行

    {
      order 4xxlog before handle_path
    }
    
  2. 调整超时时间:根据您的上报服务响应时间调整timeout参数

    4xxlog {
      report_url http://example.com/report
      timeout 2s  # 如果上报服务响应快,可以减少超时时间
    }
    
  3. 监控上报失败:启用debug日志以监控上报失败情况

    {
      debug
    }
    

接收服务建议

  1. 实现高可用性:确保上报接收服务高可用,避免丢失数据
  2. 处理峰值负载:设计接收服务以处理可能的请求峰值
  3. 数据分析:将收集的数据用于分析常见错误模式和改进用户体验

本地测试

项目包含Caddyfile.local文件,可用于本地测试插件功能:

# 使用本地配置文件启动Caddy
caddy run --config Caddyfile.local

# 测试各种4xx状态码
curl http://localhost:2015/not-exist           # 触发404
curl http://localhost:2015/forbidden           # 触发403
curl http://localhost:2015/unauthorized        # 触发401

上报的数据将发送到在:8080/api/logs监听的服务端点。

开发

构建

# 克隆仓库
git clone https://github.com/ysicing/caddy2-4xxlog.git
cd caddy2-4xxlog

# 构建
go build

# 使用xcaddy构建包含此插件的Caddy
xcaddy build --with github.com/ysicing/caddy2-4xxlog=.

开发测试

# 运行单元测试
go test ./...

# 使用任务执行器
task build  # 构建插件
task run    # 运行本地测试实例

调试技巧

  1. 启用Caddy的详细日志以查看上报过程:

    {
      debug
    }
    
  2. 检查日志中的以下关键信息:

    • detect 4xx status code - 表示检测到4xx状态码
    • prepare to send 4xxlog report - 表示准备发送上报数据
    • send 4xxlog report success - 表示成功上报
    • send 4xxlog report failed - 表示上报失败

常见问题解答

Q: 插件会影响网站的性能吗?
A: 不会。插件使用异步操作上报数据,不会阻塞主请求处理流程。

Q: 上报服务不可用时会发生什么?
A: 上报失败会被记录到日志中,但不会影响原始请求处理。您的网站将继续正常运行。

Q: 我可以过滤特定的4xx状态码吗?
A: 当前版本会上报所有4xx状态码。如果需要过滤特定状态码,您可以在接收服务端实现过滤逻辑。

Q: 如何监控上报是否成功?
A: 启用Caddy的debug日志级别,插件会记录上报成功和失败的情况。

许可证

本项目采用MIT许可证。详情请参阅LICENSE文件。

贡献

欢迎提交PR和Issue!

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages