对外暴露的 Restful API

在 Pandora.js 中,我们提供了一批将内置的 EndPoint 汇聚的数据通过 Http 对外暴露的能力,每一个 EndPoint 都可以有配套的 Resource 资源对外输出,这里的数据格式是通过 koakoa-router 来简单扩展的。

通用行为

这些接口可以通过 http://127.1:7002/ 来访问,比如 curl http://127.1:7002/info。 该接口只监听了本地回环(127.0.0.1),外部无法访问,无安全问题。

所有的接口都是通过统一的结构进行封装,真正的数据都是在 data 字段中。

  1. {
  2. data: {
  3. // xxxx
  4. }
  5. timestamp: Date.now(),
  6. success: false, // true or false
  7. message: 'some fail message'
  8. }

每个接口都可以传递 appName 参数来访问特定应用自己的数据。

  1. GET /error?appName=yourAppName
  2. GET /metris/list?appName=yourAppName

列举一些常见的 Resource

Pandora.js 中埋入了一些默认的 EndPoint 和Resource,具体可以参考 Pandora.js 的默认配置文件,这些 Resource 列举的数据并不一定完全一致,所有的 key 会根据应用当前执行的 Indicator 变化。

注意,下面所有列举的 Resource 都去除了外面的包装,只展示 data 字段的部分

DaemonResource

暴露 Daemon 的一些数据。

  1. GET /daemon
  2. [
  3. {
  4. "cwd": "xxx",
  5. "pid": 12321,
  6. "uptime": 232,
  7. "loadedGlobalConfigPaths": [
  8. "/xxx/xxx/xxx"
  9. ]
  10. }
  11. ]

InfoResource

暴露 InfoEndPoint 的数据,返回应用名等信息。

  1. GET /info
  2. [
  3. {
  4. "appName": "xxx",
  5. "appDir": "xxxx",
  6. "node": {
  7. "node": "8.9.1",
  8. "alinode": "2.3.0",
  9. "versions": {
  10. "http_parser": "2.7.0",
  11. "node": "6.9.4",
  12. "v8": "5.1.281.89",
  13. "uv": "1.9.1",
  14. "zlib": "1.2.8",
  15. "ares": "1.10.1-DEV",
  16. "icu": "57.1",
  17. "modules": "48",
  18. "openssl": "1.0.2j"
  19. },
  20. "features": {
  21. "debug": false,
  22. "uv": true,
  23. "ipv6": true,
  24. "tls_npn": true,
  25. "tls_alpn": true,
  26. "tls_sni": true,
  27. "tls_ocsp": true,
  28. "tls": true
  29. }
  30. }
  31. }
  32. ]

HealthResource

提供暴露 HealthEndPoint 的能力,简单做了一些格式化。

  1. GET /health
  2. {
  3. "status": "DOWN",
  4. "disk_space": {
  5. "status": "UP"
  6. },
  7. "port": {
  8. "status": "DOWN"
  9. }
  10. }

ErrorResource

暴露 ErrorEndPoint 的数据,提供访问错误数据的能力。

  1. GET /error
  2. [
  3. {
  4. "method": "error",
  5. "timestamp": 1346846400,
  6. "errType": "TypeError",
  7. "message": "Cannot read property 'name' of null",
  8. "stack": "2017-11-29 15:01:20 Error: read ECONNRESET",
  9. "traceId": "1231455",
  10. "path": "/xxx/xx.log"
  11. }
  12. ]

ProcessResource

暴露 ProcessEndPoint 的数据。

  1. GET /process
  2. [
  3. {
  4. "pid": "72795",
  5. "title": "/Users/harry/.nvm/versions/node/v6.9.4/bin/node",
  6. "argv": [
  7. "/Users/harry/.nvm/versions/node/v6.9.4/bin/node",
  8. "/Users/harry/project/pandora.js/packages/cluster/dest/application/entry.js",
  9. "--entry",
  10. "/Users/harry/project/node/pandora-app/dest/entry/app.js"
  11. ],
  12. "execArgv": [],
  13. "execPath": "/Users/harry/.nvm/versions/node/v6.9.4/bin/node",
  14. "cpu": 4.6,
  15. "memory": 90796032,
  16. "uptime": 267.667
  17. }
  18. ]

MetricsResource

对外暴露 MetricsEndPoint 的数据,这里的接口不止一个。

1、列出所有的 metrics,该接口不会进行过滤,会把应用下的所有 metrics 指标罗列出来

  1. GET /metrics/list
  2. [
  3. {
  4. "metric": "sys.cpu.nice",
  5. "timestamp": 1346846400,
  6. "value": 18,
  7. "type": "COUNTER",
  8. "level": "CRITICAL",
  9. "tags": {
  10. "host": "web01",
  11. "dc": "lga"
  12. }
  13. },
  14. {
  15. //xxx
  16. }
  17. ]

2、列出特定分组的 metrics,比如列出 system 组下的数据,/metrics/system

  1. GET /metrics/:group
  2. [
  3. {
  4. "metric": "sys.cpu.nice",
  5. "timestamp": 1346846400,
  6. "value": 18,
  7. "type": "COUNTER",
  8. "level": "CRITICAL",
  9. "tags": {
  10. "host": "web01",
  11. "dc": "lga"
  12. }
  13. },
  14. {
  15. //xxx
  16. }
  17. ]

TraceResource

暴露 TraceEndPoint 采集的数据。

  1. GET /trace
  2. [
  3. {
  4. "timestamp": "1511977377963",
  5. "appName": "DEFAULT_APP",
  6. "traceId": "1e084d5515118598316151001dd73d",
  7. "duration": 139,
  8. "pid": "23131",
  9. "ip": "127.0.0.1",
  10. "spans": [
  11. {
  12. "name": "http",
  13. "startMs": 1511859831616,
  14. "duration": 138,
  15. "context": {
  16. "traceId": "1e084d5515118598316151001dd73d",
  17. "spanId": "6f0f2be0d9e9a9e9"
  18. },
  19. "references": [],
  20. "tags": {
  21. "http.method": {
  22. "value": "GET",
  23. "type": "string"
  24. },
  25. "http.url": {
  26. "value": "/",
  27. "type": "string"
  28. },
  29. "http.client": {
  30. "value": false,
  31. "type": "bool"
  32. },
  33. "rpc_type": {
  34. "value": 0,
  35. "type": "number"
  36. },
  37. "http.status_code": {
  38. "type": "number",
  39. "value": 200
  40. }
  41. },
  42. "logs": [],
  43. }
  44. }
  45. ]

自定义 Resource

Resource 基础类型定义如下,只需要提供 prefixroute 方法即可。

  1. export interface ActuatorResource {
  2. prefix: string;
  3. route(routers);
  4. }

如下是一个简单的实现类,构造函数中接受一个 endPointService 用来获取启用的 EndPoint ,通过路由方法对外暴露接口即可。

prefix 是路由前缀,这里必须对每个不同的 Resource 定义路由前缀,以避免出错。

  1. export class ErrorResource implements ActuatorResource {
  2. prefix = '/error';
  3. endPointService: EndPointService;
  4. constructor(endPointService) {
  5. this.endPointService = endPointService;
  6. }
  7. route(router) {
  8. const errorEndPoint = this.endPointService.getEndPoint('error');
  9. router.get('/', async (ctx, next) => {
  10. try {
  11. ctx.ok(await errorEndPoint.invoke(ctx.query['appName']));
  12. } catch (err) {
  13. ctx.fail(err.message);
  14. }
  15. await next();
  16. });
  17. }
  18. }

我们对 koa2 的上下文 ctx 提供了一个快捷返回结构的函数,通过 ok()fail() 函数即可将最后的结果返回出去。

返回的格式基本如下

  1. {
  2. data: {
  3. // xxxx
  4. }
  5. timestamp: Date.now(),
  6. success: false, // true or false
  7. message: 'some fail message'
  8. }

除了在代码中定义之外,还需要在 Pandora.js 的配置中加载,具体格式如下。

  1. actuator: {
  2. endPoints: {
  3. info: {
  4. enabled: true,
  5. target: InfoEndPoint,
  6. resource: InfoResource,
  7. },
  8. process: {
  9. enabled: true,
  10. target: ProcessEndPoint,
  11. resource: ProcessResource,
  12. },
  13. },
  14. },

每个 Resource 只能放到相应的 EndPoint 层级下,目前 EndPoint 和 Resource 是一一对应的,你无法单独创建 Resource 暴露接口。