运维端点
ACE 内置一组运维端点(Actuator),无需额外依赖,通过 opsMiddleware 挂载即可获得 Bean 注册表、配置快照、路由映射和日志级别等诊断能力。所有端点返回 JSON,便于与监控平台集成。
快速启用
在应用入口将 opsMiddleware 注册到路由器:
cangjie
import ace_framework.*
import ace_framework_runtime.*
import ace_router.*
let router = Router()
opsMiddleware(router) // 挂载所有 /ace/* 端点
router.get("/api/hello") { ctx, _ -> ctx.body("hello") }
let app = App()
app.use(router.routes())
listen(app, "0.0.0.0", 8080)也可挂载到子路由,限定访问前缀:
cangjie
let internalRouter = Router("/internal")
opsMiddleware(internalRouter) // 端点变为 /internal/ace/*端点说明
GET /ace/beans
返回当前容器中所有已注册 Bean 的列表,包含 Bean 名称、类型、作用域及是否为 Primary。
bash
curl http://localhost:8080/ace/beansjson
{
"beans": [
{ "name": "userService", "type": "UserService", "scope": "singleton", "primary": true },
{ "name": "orderService", "type": "OrderService", "scope": "singleton", "primary": false },
{ "name": "requestScoped1", "type": "AuthContext", "scope": "request", "primary": false }
],
"total": 3
}GET /ace/env
返回当前合并后的完整配置快照。敏感字段自动打码:字段名含 secret、password、token、key 的值替换为 "****"。
bash
curl http://localhost:8080/ace/envjson
{
"server.port": "8080",
"server.host": "0.0.0.0",
"database.url": "jdbc:sqlite:./data.db",
"database.password": "****",
"jwt.secret": "****",
"app.name": "my-service"
}打码规则
字段名(不区分大小写)包含以下任意关键字时,值替换为 "****": secret / password / token / key
示例:api_key、jwtSecret、db.password、authToken 均会被打码。
GET /ace/mappings
返回所有已注册的路由映射,包含 HTTP 方法、路径模式、处理函数名称和所属 Controller。
bash
curl http://localhost:8080/ace/mappingsjson
{
"mappings": [
{ "method": "GET", "pattern": "/api/users", "handler": "UserController.list", "middlewares": ["authMiddleware"] },
{ "method": "POST", "pattern": "/api/users", "handler": "UserController.create", "middlewares": ["authMiddleware"] },
{ "method": "GET", "pattern": "/api/users/{id}", "handler": "UserController.getOne", "middlewares": [] }
],
"total": 3
}GET /ace/loggers
返回当前所有日志记录器的名称与级别,支持运行时动态调整(通过 POST 写回)。
bash
curl http://localhost:8080/ace/loggersjson
{
"loggers": [
{ "name": "root", "level": "INFO" },
{ "name": "ace.router", "level": "DEBUG" },
{ "name": "ace.framework", "level": "INFO" },
{ "name": "app.service", "level": "WARN" }
]
}动态调整日志级别(POST,无需重启):
bash
curl -X POST http://localhost:8080/ace/loggers \
-H "Content-Type: application/json" \
-d '{"name": "ace.router", "level": "DEBUG"}'安全建议
运维端点暴露了敏感的内部状态,生产环境必须做访问控制。推荐方案:
方案一:@Profile 限制
cangjie
@Profile["dev"]
@Service
class OpsSetup {
@PostConstruct
func setup(): Unit {
opsMiddleware(globalRouter)
}
}方案二:路由 IP 白名单中间件
cangjie
let opsRouter = Router("/ace")
opsRouter.use { ctx, next ->
let ip = ctx.header("X-Real-IP") ?? ctx.remoteAddr()
if (!ip.startsWith("10.") && !ip.startsWith("127.")) {
ctx.status(403)
ctx.body("""{"error":"forbidden"}""")
return
}
await next()
}
opsMiddleware(opsRouter)方案三:独立端口
cangjie
// 主服务:8080
listen(app, "0.0.0.0", 8080)
// 运维服务:仅监听本机,8081
let opsApp = App()
opsApp.use(opsRouter.routes())
listen(opsApp, "127.0.0.1", 8081)生产环境必须保护运维端点
/ace/env 即便对敏感字段打码,仍可能暴露数据库地址、内部服务 URL 等信息。务必通过 IP 白名单、认证中间件或独立内网端口保护所有 /ace/* 路径。