├── .gitignore ├── README.md ├── docker-compose.yml ├── mariadb ├── Dockerfile └── docker-entrypoint-initdb.d │ ├── column_sandbox_galaxy_sls_errors.sql │ ├── column_sandbox_galaxy_sls_trace_nodes.sql │ ├── column_sandbox_galaxy_sls_traces.sql │ ├── grant_user_sandbox.sql │ ├── sandbox_alarm_rules.sql │ ├── sandbox_applications.sql │ ├── sandbox_fault_rules.sql │ ├── sandbox_groups.sql │ ├── sandbox_ui_dashboards.sql │ ├── sandbox_ui_key_metrics.sql │ └── sandbox_ui_key_traces.sql ├── opentsdb ├── Dockerfile ├── opentsdb.conf └── tools │ └── gen_init_keys.js └── sandbox ├── Dockerfile └── sandbox-app ├── config └── config.default.js ├── package.json ├── pandoraConfig.js ├── procfile.js ├── resource └── favicon.png ├── src ├── app.ts ├── app │ ├── controller │ │ ├── applicationCtrl.ts │ │ ├── errorCtrl.ts │ │ ├── logHubCtrl.ts │ │ ├── metricsCtrl.ts │ │ ├── pageCtrl.ts │ │ ├── remoteDebugCtrl.ts │ │ └── tracingCtrl.ts │ ├── extend │ │ └── context.ts │ ├── middleware │ │ ├── assets.ts │ │ └── user.ts │ └── view │ │ └── index.html ├── config │ ├── config.default.ts │ ├── environment.ts │ ├── metrics.ts │ ├── metricsLayouts │ │ ├── focusLayout.ts │ │ ├── nodeLayout.ts │ │ └── systemLayout.ts │ └── plugin.ts └── lib │ ├── adapter │ ├── keycenter.ts │ ├── privilegeAdapter.ts │ ├── remoteExecuteAdapter.ts │ └── sadMetricsAdapter.ts │ ├── platform │ └── defaultPlatformAdapter.ts │ └── service │ └── logHubService.ts ├── test └── app │ └── controller │ └── applicationCtrl.test.ts ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | ############################ 2 | # NPM files 3 | ############################ 4 | **/node_modules 5 | **/bower_components 6 | node_modules 7 | bower_components 8 | npm-debug.log 9 | .alinode.json 10 | config/config.local.js 11 | undefined/ 12 | package-lock.json 13 | ############################ 14 | # Temp files 15 | ############################ 16 | temp 17 | tmp 18 | .tmp 19 | *.swo 20 | *.swp 21 | *.swn 22 | *.swm 23 | *.diff 24 | *.log 25 | *.patch 26 | *.bak 27 | *.log 28 | *.iml 29 | *.ipr 30 | *.iws 31 | *.out 32 | *.gz 33 | *# 34 | *~ 35 | ~* 36 | 37 | 38 | ############################ 39 | # Editor & OS files 40 | ############################ 41 | .idea 42 | .DS_STORE 43 | .Trashes 44 | .project 45 | .rebooted 46 | .*proj 47 | Thumbs.db 48 | ehthumbs.db 49 | Icon? 50 | nbproject 51 | 52 | ############################ 53 | # Report files 54 | ############################ 55 | coverages 56 | coverage 57 | reports 58 | lib-cov 59 | html-report 60 | nohup.out 61 | out 62 | logs 63 | log 64 | 65 | 66 | ############################ 67 | # Other 68 | ############################ 69 | .node_history 70 | .svn 71 | PRIVATE_TOKEN 72 | .nodejs-cache 73 | run/ 74 | src/run/ 75 | dist/ 76 | 77 | assembly/ 78 | mocks_data/proxy/**/__* 79 | tms 80 | coverage 81 | 82 | ############################ 83 | # visual studio code settings 84 | ############################ 85 | .vscode/ 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sandbox-docker 2 | 3 | 一份基于 Docker Compose 的单机部署的配置。 4 | 5 | ## 简要说明 6 | 7 | Checkout 本项目,并运行如下命令即可启动。 8 | 9 | ```shell 10 | sudo docker-compose build && sudo docker-compose up 11 | ``` 12 | 13 | 访问 7001 端口即可查看数据。 14 | 15 | ## 组件介绍 16 | 17 | 1. /sandbox 18 | * Sandbox 监控平台应用程序,其使用 Pandora.js 启动。 19 | 2. /mariadb 20 | * MariaDB 的一个实例,用于存储错误日志和链路数据 21 | * 配有数据自动清理功能,默认保留 3 天数据 22 | 3. /opentsdb 23 | * 用于存储 Metrics 数据 24 | 25 | ## 如何接入更多应用 26 | 27 | 应用使用 Pandora.js 启动,并安装 `pandora-component-sandbox-log-hub-reporter`。 28 | 29 | 并在应用目录增加如下配置: 30 | 31 | ```javascript 32 | exports.components = { 33 | // 配置使用 LogHub 向 Sandbox 写入数据 34 | sandboxLogHubReporter: { 35 | path: 'pandora-component-sandbox-log-hub-reporter' 36 | }, 37 | // 打开基于 Patch 和 AsyncHooks 自动获取数据 38 | autoPatching: { 39 | path: 'pandora-component-auto-patching' 40 | } 41 | }; 42 | 43 | exports.sandboxLogHubReporter = { 44 | // 配置 LogHub 的地址,即 Sandbox 平台的地址 45 | endpoint: 'http://127.0.0.1:7001/' 46 | }; 47 | 48 | exports.trace = { 49 | // 配置链路采样率 50 | sampling: 10 51 | }; 52 | ``` 53 | 54 | 然后运行 `pandora start` 即可前台启动应用。然后再等一会,如果没有意外,新应用就会出现在 Sandbox 的应用列表上了。 55 | 56 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mariadb: 4 | build: ./mariadb 5 | ports: 6 | - "3306:3306" 7 | opentsdb: 8 | build: ./opentsdb 9 | ports: 10 | - "4242:4242" 11 | sandbox: 12 | build: ./sandbox 13 | ports: 14 | - "7001:7001" 15 | -------------------------------------------------------------------------------- /mariadb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mariadb/server 2 | ENV MARIADB_RANDOM_ROOT_PASSWORD true 3 | ADD ./docker-entrypoint-initdb.d /docker-entrypoint-initdb.d 4 | ENV TZ=Asia/Shanghai 5 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 6 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/column_sandbox_galaxy_sls_errors.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS column_sandbox; 2 | 3 | CREATE TABLE `column_sandbox`.`sandbox_galaxy_sls_errors` ( 4 | `timestamp` datetime NOT NULL COMMENT 'Timestamp', 5 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 6 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 7 | `env` varchar(128) NOT NULL COMMENT 'Environment, Such as dev, prod', 8 | `hostname` varchar(512) NOT NULL COMMENT 'Host Name', 9 | `ip` varchar(512) NOT NULL COMMENT 'IP', 10 | `uuid` varchar(256) NOT NULL COMMENT 'Unique ID', 11 | `error_type` varchar(512) DEFAULT NULL COMMENT 'Error Type', 12 | `error_stack` mediumtext COMMENT 'Error Stack', 13 | `unix_timestamp` bigint(20) DEFAULT NULL COMMENT 'Unix TS', 14 | `log_path` mediumtext COMMENT 'Log Path', 15 | `error_message` mediumtext, 16 | `version` int(11) DEFAULT NULL, 17 | `trace_id` varchar(256) DEFAULT NULL, 18 | `pid` varchar(256) DEFAULT NULL 19 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Error logs' 20 | ; 21 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/column_sandbox_galaxy_sls_trace_nodes.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS column_sandbox; 2 | 3 | CREATE TABLE `column_sandbox`.`sandbox_galaxy_sls_trace_nodes` ( 4 | `timestamp` datetime NOT NULL COMMENT 'Timestamp', 5 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 6 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 7 | `env` varchar(128) NOT NULL COMMENT 'Environment, Such as dev, prod', 8 | `hostname` varchar(512) NOT NULL COMMENT 'Host Name', 9 | `ip` varchar(512) NOT NULL COMMENT 'IP', 10 | `uuid` varchar(256) NOT NULL COMMENT 'Unique ID', 11 | `span_name` varchar(512) DEFAULT NULL COMMENT 'Span Name', 12 | `span_duration` int(11) DEFAULT NULL COMMENT 'Span Duration', 13 | `span_type` int(11) DEFAULT NULL COMMENT 'Span Type', 14 | `span_tags` mediumtext COMMENT 'Span Tags', 15 | `span_id` varchar(128) DEFAULT NULL COMMENT 'Span ID', 16 | `span_rpcid` varchar(128) DEFAULT NULL COMMENT 'Span RPC-ID', 17 | `span_code` varchar(128) DEFAULT NULL, 18 | `span_error` tinyint(4) DEFAULT '0', 19 | `span_method` varchar(128) DEFAULT NULL, 20 | `span_timestamp` varchar(128) DEFAULT NULL, 21 | `pid` varchar(256) DEFAULT NULL, 22 | `trace_id` varchar(256) DEFAULT NULL, 23 | `trace_name` text, 24 | `span_target` mediumtext 25 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Trace Nodes' 26 | ; 27 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/column_sandbox_galaxy_sls_traces.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS column_sandbox; 2 | 3 | CREATE TABLE `column_sandbox`.`sandbox_galaxy_sls_traces` ( 4 | `timestamp` datetime NOT NULL COMMENT 'Timestamp', 5 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 6 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 7 | `env` varchar(128) NOT NULL COMMENT 'Environment, Such as dev, prod', 8 | `hostname` varchar(512) NOT NULL COMMENT 'Host Name', 9 | `ip` varchar(512) NOT NULL COMMENT 'IP', 10 | `uuid` varchar(256) NOT NULL COMMENT 'Unique ID', 11 | `trace_id` varchar(256) DEFAULT NULL COMMENT 'Related Trace ID', 12 | `version` int(11) DEFAULT NULL COMMENT 'Reserved, Version', 13 | `trace_spans` mediumtext, 14 | `unix_timestamp` bigint(20) DEFAULT NULL, 15 | `trace_duration` int(11) DEFAULT NULL, 16 | `pid` varchar(256) DEFAULT NULL, 17 | `trace_name` text, 18 | `trace_status` int(11) DEFAULT '1' 19 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Trace Logs' 20 | ; 21 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/grant_user_sandbox.sql: -------------------------------------------------------------------------------- 1 | CREATE USER 'sandbox'@'%' IDENTIFIED BY 'sandbox'; 2 | GRANT ALL PRIVILEGES ON *.* TO 'sandbox'@'%' WITH GRANT OPTION; 3 | SET global max_length_for_sort_data=1024*1024*8; 4 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/sandbox_alarm_rules.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS sandbox; 2 | 3 | CREATE TABLE `sandbox`.`sandbox_alarm_rules` ( 4 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', 5 | `gmt_create` datetime NOT NULL COMMENT 'Create Time', 6 | `gmt_modified` datetime NOT NULL COMMENT 'Last Modify Time', 7 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 8 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 9 | `rule_name` varchar(256) NOT NULL COMMENT 'Rule Name', 10 | `rule_type` tinyint(3) unsigned DEFAULT '1' COMMENT 'Rule Type, 1: metrics, 2: Error, 3: Trace', 11 | `follower` text NOT NULL COMMENT 'Followers', 12 | `creator` varchar(128) NOT NULL COMMENT 'Creator', 13 | `message` text COMMENT 'Custom Message', 14 | `execute_rule` text NOT NULL COMMENT 'Execute Rule', 15 | `disabled` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as Disabled', 16 | `deleted` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as deleted', 17 | `action` varchar(128) NOT NULL COMMENT 'Notifying Approach', 18 | `action_params` text COMMENT 'Params of Notifying Approach', 19 | PRIMARY KEY (`id`) 20 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Sandbox Alarm Rules' 21 | ; 22 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/sandbox_applications.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS sandbox; 2 | 3 | CREATE TABLE `sandbox`.`sandbox_applications` ( 4 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', 5 | `gmt_create` datetime NOT NULL COMMENT 'Create Time', 6 | `gmt_modified` datetime NOT NULL COMMENT 'Last Modify Time', 7 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 8 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 9 | `scope_id` bigint(20) unsigned DEFAULT NULL COMMENT 'Reserved, Application ID under Scope', 10 | `description` text COMMENT 'Description', 11 | `bu` varchar(256) DEFAULT NULL COMMENT 'Reserved, BU', 12 | `owner` varchar(128) NOT NULL COMMENT 'Owner', 13 | `appops` text COMMENT 'Reserved, Application Related Persons', 14 | `alinode_id` varchar(256) DEFAULT NULL COMMENT 'Reserved, Application ID of Ali-Node Platform', 15 | `alinode_token` varchar(256) DEFAULT NULL COMMENT 'Reserved, Application Token of Ali-Node Platform', 16 | `flag` int(10) unsigned DEFAULT '0' COMMENT 'Flags', 17 | `deleted` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as Deleted', 18 | `state` int(10) unsigned DEFAULT NULL COMMENT 'State', 19 | PRIMARY KEY (`id`) 20 | ) ENGINE=InnoDB AUTO_INCREMENT=1985 DEFAULT CHARSET=utf8 COMMENT='Sandbox Applications' 21 | ; 22 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/sandbox_fault_rules.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS sandbox; 2 | 3 | CREATE TABLE `sandbox`.`sandbox_fault_rules` ( 4 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', 5 | `gmt_create` datetime NOT NULL COMMENT 'Create Time', 6 | `gmt_modified` datetime NOT NULL COMMENT 'Last Modify Time', 7 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 8 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 9 | `related_module` varchar(256) NOT NULL COMMENT 'Related Modules', 10 | `filter_rule` text NOT NULL COMMENT 'Filter Rule', 11 | `fault_rule` text NOT NULL COMMENT 'Fault Rule', 12 | `disabled` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as Disabled', 13 | `deleted` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as Deleted', 14 | PRIMARY KEY (`id`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Sandbox Fault Rules' 16 | ; 17 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/sandbox_groups.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS sandbox; 2 | 3 | CREATE TABLE `sandbox`.`sandbox_groups` ( 4 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', 5 | `gmt_create` datetime NOT NULL COMMENT 'Create Time', 6 | `gmt_modified` datetime NOT NULL COMMENT 'Last Modify Time', 7 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 8 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 9 | `group_name` varchar(128) NOT NULL COMMENT 'Group Name', 10 | `host_list` text COMMENT 'Host List, IP, Hostname', 11 | `deleted` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as deleted', 12 | `hash` varchar(128) NOT NULL COMMENT 'md5(scope|scope_name|group_name) as Unique Hash', 13 | PRIMARY KEY (`id`), 14 | UNIQUE KEY `uk_hash` (`hash`(36)) COMMENT 'Mark Hash as Unique key' 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Sandbox Groups' 16 | ; 17 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/sandbox_ui_dashboards.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS sandbox; 2 | 3 | CREATE TABLE `sandbox`.`sandbox_ui_dashboards` ( 4 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', 5 | `gmt_create` datetime NOT NULL COMMENT 'Create Time', 6 | `gmt_modified` datetime NOT NULL COMMENT 'Last Modify Time', 7 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 8 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 9 | `dashboard_name` varchar(256) NOT NULL COMMENT 'Dashboard Name', 10 | `target` tinyint(3) unsigned DEFAULT '1' COMMENT 'Dashboard Level, Cluster: 1, Single Host: 2', 11 | `config` text NOT NULL COMMENT 'Dashboard Configs', 12 | `deleted` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as deleted', 13 | `focus` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as focused', 14 | PRIMARY KEY (`id`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Sandbox UI Dashboards' 16 | ; 17 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/sandbox_ui_key_metrics.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS sandbox; 2 | 3 | CREATE TABLE `sandbox`.`sandbox_ui_key_metrics` ( 4 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', 5 | `gmt_create` datetime NOT NULL COMMENT 'Create Time', 6 | `gmt_modified` datetime NOT NULL COMMENT 'Last Modify Time', 7 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 8 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 9 | `config` text NOT NULL COMMENT 'Config', 10 | `deleted` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as Deleted', 11 | PRIMARY KEY (`id`) 12 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Sandbox UI Key Metrics' 13 | ; 14 | -------------------------------------------------------------------------------- /mariadb/docker-entrypoint-initdb.d/sandbox_ui_key_traces.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS sandbox; 2 | 3 | CREATE TABLE `sandbox`.`sandbox_ui_key_traces` ( 4 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', 5 | `gmt_create` datetime NOT NULL COMMENT 'Create Time', 6 | `gmt_modified` datetime NOT NULL COMMENT 'Last Modify Time', 7 | `scope` varchar(128) NOT NULL COMMENT 'Application Scope', 8 | `scope_name` varchar(256) NOT NULL COMMENT 'Application Name under Scope', 9 | `trace_name` varchar(2048) NOT NULL COMMENT 'Trace Name', 10 | `focus` tinyint(3) unsigned DEFAULT '1' COMMENT 'Mark as focused', 11 | `deleted` tinyint(3) unsigned DEFAULT '0' COMMENT 'Mark as deleted', 12 | `hash` varchar(128) NOT NULL COMMENT 'md5(scope|scope_name|trace_name) as Unique Hash', 13 | PRIMARY KEY (`id`), 14 | UNIQUE KEY `uk_md5` (`hash`(36)) COMMENT 'Mark Hash as Unique' 15 | ) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8 COMMENT='Sandbox UI Key Traces' 16 | ; 17 | -------------------------------------------------------------------------------- /opentsdb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM petergrace/opentsdb-docker 2 | ADD opentsdb.conf /etc/opentsdb.conf 3 | ENV TZ=Asia/Shanghai 4 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 5 | -------------------------------------------------------------------------------- /opentsdb/opentsdb.conf: -------------------------------------------------------------------------------- 1 | tsd.network.port = 4242 2 | tsd.http.staticroot = /usr/local/share/opentsdb/static/ 3 | tsd.http.cachedir = /tmp/opentsdb 4 | tsd.core.plugin_path = /opentsdb-plugins 5 | tsd.core.auto_create_metrics = true 6 | tsd.storage.fix_duplicates = true 7 | -------------------------------------------------------------------------------- /opentsdb/tools/gen_init_keys.js: -------------------------------------------------------------------------------- 1 | const keys = ["checkhitsdb.checkputandquery","error.all.bucket_count","error.all.count","middleware.hsf.consumer.bucket_count","middleware.hsf.consumer.bucket_sum","middleware.hsf.consumer.error_bucket_count","middleware.hsf.consumer.qps","middleware.hsf.consumer.rt","middleware.hsf.consumer.service.method.bucket_count","middleware.hsf.consumer.service.method.bucket_sum","middleware.hsf.consumer.service.method.error_bucket_count","middleware.hsf.consumer.service.method.qps","middleware.hsf.consumer.service.method.rt","middleware.hsf.consumer.service.method.success_bucket_count","middleware.hsf.consumer.service.method.success_rate","middleware.hsf.consumer.success_bucket_count","middleware.hsf.consumer.success_rate","middleware.hsf.provider.bucket_count","middleware.hsf.provider.bucket_sum","middleware.hsf.provider.error_bucket_count","middleware.hsf.provider.qps","middleware.hsf.provider.rt","middleware.hsf.provider.service.method.bucket_count","middleware.hsf.provider.service.method.bucket_sum","middleware.hsf.provider.service.method.error_bucket_count","middleware.hsf.provider.service.method.qps","middleware.hsf.provider.service.method.rt","middleware.hsf.provider.service.method.success_bucket_count","middleware.hsf.provider.service.method.success_rate","middleware.hsf.provider.success_bucket_count","middleware.hsf.provider.success_rate","middleware.http.request.bucket_count","middleware.http.request.bucket_sum","middleware.http.request.error_bucket_count","middleware.http.request.qps","middleware.http.request.rt","middleware.http.request.success_bucket_count","middleware.http.request.success_rate","middleware.nginx.conn.accepted","middleware.nginx.conn.active","middleware.nginx.conn.handled","middleware.nginx.conn.reading","middleware.nginx.conn.waiting","middleware.nginx.conn.writing","middleware.nginx.request.avg_rt","middleware.nginx.request.processing_time","middleware.nginx.request.qps","middleware.tair.read.bucket_count","middleware.tair.read.bucket_sum","middleware.tair.read.error_bucket_count","middleware.tair.read.group.bucket_count","middleware.tair.read.group.bucket_sum","middleware.tair.read.group.error_bucket_count","middleware.tair.read.group.hit_bucket_count","middleware.tair.read.group.hit_rate","middleware.tair.read.group.qps","middleware.tair.read.group.rt","middleware.tair.read.group.success_bucket_count","middleware.tair.read.group.success_rate","middleware.tair.read.hit_bucket_count","middleware.tair.read.hit_rate","middleware.tair.read.qps","middleware.tair.read.rt","middleware.tair.read.success_bucket_count","middleware.tair.read.success_rate","middleware.tair.write.bucket_count","middleware.tair.write.bucket_sum","middleware.tair.write.error_bucket_count","middleware.tair.write.group.bucket_count","middleware.tair.write.group.bucket_sum","middleware.tair.write.group.error_bucket_count","middleware.tair.write.group.qps","middleware.tair.write.group.rt","middleware.tair.write.group.success_bucket_count","middleware.tair.write.group.success_rate","middleware.tair.write.qps","middleware.tair.write.rt","middleware.tair.write.success_bucket_count","middleware.tair.write.success_rate","node.v8.code_space.physical_space_size","node.v8.code_space.space_available_size","node.v8.code_space.space_size","node.v8.code_space.space_used_size","node.v8.does_zap_garbage","node.v8.heap_size_limit","node.v8.large_object_space.physical_space_size","node.v8.large_object_space.space_available_size","node.v8.large_object_space.space_size","node.v8.large_object_space.space_used_size","node.v8.malloced_memory","node.v8.map_space.physical_space_size","node.v8.map_space.space_available_size","node.v8.map_space.space_size","node.v8.map_space.space_used_size","node.v8.new_space.physical_space_size","node.v8.new_space.space_available_size","node.v8.new_space.space_size","node.v8.new_space.space_used_size","node.v8.old_space.physical_space_size","node.v8.old_space.space_available_size","node.v8.old_space.space_size","node.v8.old_space.space_used_size","node.v8.peak_malloced_memory","node.v8.read_only_space.physical_space_size","node.v8.read_only_space.space_available_size","node.v8.read_only_space.space_size","node.v8.read_only_space.space_used_size","node.v8.total_available_size","node.v8.total_heap_size","node.v8.total_heap_size_executable","node.v8.total_physical_size","node.v8.used_heap_size","sandbox.biz.start_report.parse.bucket_count","sandbox.biz.start_report.parse.bucket_sum","sandbox.biz.start_report.parse.error_bucket_count","sandbox.biz.start_report.parse.qps","sandbox.biz.start_report.parse.rt","sandbox.biz.start_report.parse.success_bucket_count","sandbox.biz.start_report.parse.success_rate","sandbox.biz.start_report.save.bucket_count","sandbox.biz.start_report.save.bucket_sum","sandbox.biz.start_report.save.qps","sandbox.biz.start_report.save.rt","sandbox.biz.start_report.save.success_bucket_count","sandbox.biz.start_report.save.success_rate","sandbox.cb-portal.report.globalPublish.bucket_count","sandbox.cb-portal.report.globalPublish.bucket_sum","sandbox.cb-portal.report.globalPublish.error_bucket_count","sandbox.cb-portal.report.globalPublish.qps","sandbox.cb-portal.report.globalPublish.rt","sandbox.cb-portal.report.globalPublish.success_bucket_count","sandbox.cb-portal.report.globalPublish.success_rate","sandbox.cb-portal.report.localPublish.bucket_count","sandbox.cb-portal.report.localPublish.bucket_sum","sandbox.cb-portal.report.localPublish.error_bucket_count","sandbox.cb-portal.report.localPublish.qps","sandbox.cb-portal.report.localPublish.rt","sandbox.cb-portal.report.localPublish.success_bucket_count","sandbox.cb-portal.report.localPublish.success_rate","sandbox.cb-portal.report.manageMigrated.bucket_count","sandbox.cb-portal.report.manageMigrated.bucket_sum","sandbox.cb-portal.report.manageMigrated.qps","sandbox.cb-portal.report.manageMigrated.rt","sandbox.cb-portal.report.manageMigrated.success_bucket_count","sandbox.cb-portal.report.manageMigrated.success_rate","sandbox.cb-portal.report.menuQuery.bucket_count","sandbox.cb-portal.report.menuQuery.bucket_sum","sandbox.cb-portal.report.menuQuery.qps","sandbox.cb-portal.report.menuQuery.rt","sandbox.cb-portal.report.menuQuery.success_bucket_count","sandbox.cb-portal.report.menuQuery.success_rate","sandbox.cb-portal.report.menuQueryNew.bucket_count","sandbox.cb-portal.report.menuQueryNew.bucket_sum","sandbox.cb-portal.report.menuQueryNew.qps","sandbox.cb-portal.report.menuQueryNew.rt","sandbox.cb-portal.report.menuQueryNew.success_bucket_count","sandbox.cb-portal.report.menuQueryNew.success_rate","sandbox.cb-portal.report.secLogged.bucket_count","sandbox.cb-portal.report.secLogged.bucket_sum","sandbox.cb-portal.report.secLogged.qps","sandbox.cb-portal.report.secLogged.rt","sandbox.cb-portal.report.secLogged.success_bucket_count","sandbox.cb-portal.report.secLogged.success_rate","sandbox.cb-portal.report.userQuery.bucket_count","sandbox.cb-portal.report.userQuery.bucket_sum","sandbox.cb-portal.report.userQuery.error_bucket_count","sandbox.cb-portal.report.userQuery.qps","sandbox.cb-portal.report.userQuery.rt","sandbox.cb-portal.report.userQuery.success_bucket_count","sandbox.cb-portal.report.userQuery.success_rate","sandbox.lzd-media-center-portal.report.logged.bucket_count","sandbox.lzd-media-center-portal.report.logged.bucket_sum","sandbox.lzd-media-center-portal.report.logged.qps","sandbox.lzd-media-center-portal.report.logged.rt","sandbox.lzd-media-center-portal.report.logged.success_bucket_count","sandbox.lzd-media-center-portal.report.logged.success_rate","system.context.switches","system.cpu.guest","system.cpu.idle","system.cpu.iowait","system.cpu.irq","system.cpu.nice","system.cpu.softirq","system.cpu.steal","system.cpu.system","system.cpu.usage","system.cpu.user","system.disk.partition.free","system.disk.partition.total","system.disk.partition.used_ratio","system.interrupts","system.load.15min","system.load.1min","system.load.5min","system.mem.buffers","system.mem.cached","system.mem.free","system.mem.swap.free","system.mem.swap.total","system.mem.swap.used","system.mem.total","system.mem.usage","system.mem.used","system.nettraffic.bond0.net.in.bytes","system.nettraffic.bond0.net.in.bytes.rate","system.nettraffic.bond0.net.in.compressed","system.nettraffic.bond0.net.in.compressed.rate","system.nettraffic.bond0.net.in.dropped","system.nettraffic.bond0.net.in.dropped.rate","system.nettraffic.bond0.net.in.errs","system.nettraffic.bond0.net.in.errs.rate","system.nettraffic.bond0.net.in.fifo.errs","system.nettraffic.bond0.net.in.fifo.errs.rate","system.nettraffic.bond0.net.in.frame.errs","system.nettraffic.bond0.net.in.frame.errs.rate","system.nettraffic.bond0.net.in.multicast","system.nettraffic.bond0.net.in.multicast.rate","system.nettraffic.bond0.net.in.packets","system.nettraffic.bond0.net.in.packets.rate","system.nettraffic.bond0.net.out.bytes","system.nettraffic.bond0.net.out.bytes.rate","system.nettraffic.bond0.net.out.carrier.errs","system.nettraffic.bond0.net.out.carrier.errs.rate","system.nettraffic.bond0.net.out.collisions","system.nettraffic.bond0.net.out.collisions.rate","system.nettraffic.bond0.net.out.compressed","system.nettraffic.bond0.net.out.compressed.rate","system.nettraffic.bond0.net.out.dropped","system.nettraffic.bond0.net.out.dropped.rate","system.nettraffic.bond0.net.out.errs","system.nettraffic.bond0.net.out.errs.rate","system.nettraffic.bond0.net.out.fifo.errs","system.nettraffic.bond0.net.out.fifo.errs.rate","system.nettraffic.bond0.net.out.packets","system.nettraffic.bond0.net.out.packets.rate","system.nettraffic.docker0.net.in.compressed","system.nettraffic.docker0.net.in.compressed.rate","system.nettraffic.docker0.net.in.dropped","system.nettraffic.docker0.net.in.dropped.rate","system.nettraffic.docker0.net.in.errs","system.nettraffic.docker0.net.in.errs.rate","system.nettraffic.docker0.net.in.fifo.errs","system.nettraffic.docker0.net.in.fifo.errs.rate","system.nettraffic.docker0.net.in.frame.errs","system.nettraffic.docker0.net.in.frame.errs.rate","system.nettraffic.docker0.net.in.multicast","system.nettraffic.docker0.net.in.multicast.rate","system.nettraffic.docker0.net.in.packets","system.nettraffic.docker0.net.in.packets.rate","system.nettraffic.docker0.net.out.bytes","system.nettraffic.docker0.net.out.bytes.rate","system.nettraffic.docker0.net.out.carrier.errs","system.nettraffic.docker0.net.out.carrier.errs.rate","system.nettraffic.docker0.net.out.collisions","system.nettraffic.docker0.net.out.collisions.rate","system.nettraffic.docker0.net.out.compressed","system.nettraffic.docker0.net.out.compressed.rate","system.nettraffic.docker0.net.out.dropped","system.nettraffic.docker0.net.out.dropped.rate","system.nettraffic.docker0.net.out.errs","system.nettraffic.docker0.net.out.errs.rate","system.nettraffic.docker0.net.out.fifo.errs","system.nettraffic.docker0.net.out.fifo.errs.rate","system.nettraffic.docker0.net.out.packets","system.nettraffic.docker0.net.out.packets.rate","system.nettraffic.eth0.net.in.bytes","system.nettraffic.eth0.net.in.bytes.rate","system.nettraffic.eth0.net.in.compressed","system.nettraffic.eth0.net.in.compressed.rate","system.nettraffic.eth0.net.in.dropped","system.nettraffic.eth0.net.in.dropped.rate","system.nettraffic.eth0.net.in.errs","system.nettraffic.eth0.net.in.errs.rate","system.nettraffic.eth0.net.in.fifo.errs","system.nettraffic.eth0.net.in.fifo.errs.rate","system.nettraffic.eth0.net.in.frame.errs","system.nettraffic.eth0.net.in.frame.errs.rate","system.nettraffic.eth0.net.in.multicast","system.nettraffic.eth0.net.in.multicast.rate","system.nettraffic.eth0.net.in.packets","system.nettraffic.eth0.net.in.packets.rate","system.nettraffic.eth0.net.out.bytes","system.nettraffic.eth0.net.out.bytes.rate","system.nettraffic.eth0.net.out.carrier.errs","system.nettraffic.eth0.net.out.carrier.errs.rate","system.nettraffic.eth0.net.out.collisions","system.nettraffic.eth0.net.out.collisions.rate","system.nettraffic.eth0.net.out.compressed","system.nettraffic.eth0.net.out.compressed.rate","system.nettraffic.eth0.net.out.dropped","system.nettraffic.eth0.net.out.dropped.rate","system.nettraffic.eth0.net.out.errs","system.nettraffic.eth0.net.out.errs.rate","system.nettraffic.eth0.net.out.fifo.errs","system.nettraffic.eth0.net.out.fifo.errs.rate","system.nettraffic.eth0.net.out.packets","system.nettraffic.eth0.net.out.packets.rate","system.nettraffic.eth1.net.in.bytes","system.nettraffic.eth1.net.in.bytes.rate","system.nettraffic.eth1.net.in.compressed","system.nettraffic.eth1.net.in.compressed.rate","system.nettraffic.eth1.net.in.dropped","system.nettraffic.eth1.net.in.dropped.rate","system.nettraffic.eth1.net.in.errs","system.nettraffic.eth1.net.in.errs.rate","system.nettraffic.eth1.net.in.fifo.errs","system.nettraffic.eth1.net.in.fifo.errs.rate","system.nettraffic.eth1.net.in.frame.errs","system.nettraffic.eth1.net.in.frame.errs.rate","system.nettraffic.eth1.net.in.multicast","system.nettraffic.eth1.net.in.multicast.rate","system.nettraffic.eth1.net.in.packets","system.nettraffic.eth1.net.in.packets.rate","system.nettraffic.eth1.net.out.bytes","system.nettraffic.eth1.net.out.bytes.rate","system.nettraffic.eth1.net.out.carrier.errs","system.nettraffic.eth1.net.out.carrier.errs.rate","system.nettraffic.eth1.net.out.collisions","system.nettraffic.eth1.net.out.collisions.rate","system.nettraffic.eth1.net.out.compressed","system.nettraffic.eth1.net.out.compressed.rate","system.nettraffic.eth1.net.out.dropped","system.nettraffic.eth1.net.out.dropped.rate","system.nettraffic.eth1.net.out.errs","system.nettraffic.eth1.net.out.errs.rate","system.nettraffic.eth1.net.out.fifo.errs","system.nettraffic.eth1.net.out.fifo.errs.rate","system.nettraffic.eth1.net.out.packets","system.nettraffic.eth1.net.out.packets.rate","system.nettraffic.eth2.net.in.compressed","system.nettraffic.eth2.net.in.compressed.rate","system.nettraffic.eth2.net.in.dropped","system.nettraffic.eth2.net.in.dropped.rate","system.nettraffic.eth2.net.in.errs","system.nettraffic.eth2.net.in.errs.rate","system.nettraffic.eth2.net.in.fifo.errs","system.nettraffic.eth2.net.in.fifo.errs.rate","system.nettraffic.eth2.net.in.frame.errs","system.nettraffic.eth2.net.in.frame.errs.rate","system.nettraffic.eth2.net.in.multicast","system.nettraffic.eth2.net.in.multicast.rate","system.nettraffic.eth2.net.in.packets","system.nettraffic.eth2.net.in.packets.rate","system.nettraffic.eth2.net.out.bytes","system.nettraffic.eth2.net.out.bytes.rate","system.nettraffic.eth2.net.out.carrier.errs","system.nettraffic.eth2.net.out.carrier.errs.rate","system.nettraffic.eth2.net.out.collisions","system.nettraffic.eth2.net.out.collisions.rate","system.nettraffic.eth2.net.out.compressed","system.nettraffic.eth2.net.out.compressed.rate","system.nettraffic.eth2.net.out.dropped","system.nettraffic.eth2.net.out.dropped.rate","system.nettraffic.eth2.net.out.errs","system.nettraffic.eth2.net.out.errs.rate","system.nettraffic.eth2.net.out.fifo.errs","system.nettraffic.eth2.net.out.fifo.errs.rate","system.nettraffic.eth2.net.out.packets","system.nettraffic.eth2.net.out.packets.rate","system.nettraffic.eth3.net.in.compressed","system.nettraffic.eth3.net.in.compressed.rate","system.nettraffic.eth3.net.in.dropped","system.nettraffic.eth3.net.in.dropped.rate","system.nettraffic.eth3.net.in.errs","system.nettraffic.eth3.net.in.errs.rate","system.nettraffic.eth3.net.in.fifo.errs","system.nettraffic.eth3.net.in.fifo.errs.rate","system.nettraffic.eth3.net.in.frame.errs","system.nettraffic.eth3.net.in.frame.errs.rate","system.nettraffic.eth3.net.in.multicast","system.nettraffic.eth3.net.in.multicast.rate","system.nettraffic.eth3.net.in.packets","system.nettraffic.eth3.net.in.packets.rate","system.nettraffic.eth3.net.out.bytes","system.nettraffic.eth3.net.out.bytes.rate","system.nettraffic.eth3.net.out.carrier.errs","system.nettraffic.eth3.net.out.carrier.errs.rate","system.nettraffic.eth3.net.out.collisions","system.nettraffic.eth3.net.out.collisions.rate","system.nettraffic.eth3.net.out.compressed","system.nettraffic.eth3.net.out.compressed.rate","system.nettraffic.eth3.net.out.dropped","system.nettraffic.eth3.net.out.dropped.rate","system.nettraffic.eth3.net.out.errs","system.nettraffic.eth3.net.out.errs.rate","system.nettraffic.eth3.net.out.fifo.errs","system.nettraffic.eth3.net.out.fifo.errs.rate","system.nettraffic.eth3.net.out.packets","system.nettraffic.eth3.net.out.packets.rate","system.nettraffic.lo.net.in.bytes","system.nettraffic.lo.net.in.bytes.rate","system.nettraffic.lo.net.in.compressed","system.nettraffic.lo.net.in.compressed.rate","system.nettraffic.lo.net.in.dropped","system.nettraffic.lo.net.in.dropped.rate","system.nettraffic.lo.net.in.errs","system.nettraffic.lo.net.in.errs.rate","system.nettraffic.lo.net.in.fifo.errs","system.nettraffic.lo.net.in.fifo.errs.rate","system.nettraffic.lo.net.in.frame.errs","system.nettraffic.lo.net.in.frame.errs.rate","system.nettraffic.lo.net.in.multicast","system.nettraffic.lo.net.in.multicast.rate","system.nettraffic.lo.net.in.packets","system.nettraffic.lo.net.in.packets.rate","system.nettraffic.lo.net.out.bytes","system.nettraffic.lo.net.out.bytes.rate","system.nettraffic.lo.net.out.carrier.errs","system.nettraffic.lo.net.out.carrier.errs.rate","system.nettraffic.lo.net.out.collisions","system.nettraffic.lo.net.out.collisions.rate","system.nettraffic.lo.net.out.compressed","system.nettraffic.lo.net.out.compressed.rate","system.nettraffic.lo.net.out.dropped","system.nettraffic.lo.net.out.dropped.rate","system.nettraffic.lo.net.out.errs","system.nettraffic.lo.net.out.errs.rate","system.nettraffic.lo.net.out.fifo.errs","system.nettraffic.lo.net.out.fifo.errs.rate","system.nettraffic.lo.net.out.packets","system.nettraffic.lo.net.out.packets.rate","system.nettraffic.veth_natdummy.net.in.compressed","system.nettraffic.veth_natdummy.net.in.compressed.rate","system.nettraffic.veth_natdummy.net.in.dropped","system.nettraffic.veth_natdummy.net.in.dropped.rate","system.nettraffic.veth_natdummy.net.in.errs","system.nettraffic.veth_natdummy.net.in.errs.rate","system.nettraffic.veth_natdummy.net.in.fifo.errs","system.nettraffic.veth_natdummy.net.in.fifo.errs.rate","system.nettraffic.veth_natdummy.net.in.frame.errs","system.nettraffic.veth_natdummy.net.in.frame.errs.rate","system.nettraffic.veth_natdummy.net.in.multicast","system.nettraffic.veth_natdummy.net.in.multicast.rate","system.nettraffic.veth_natdummy.net.in.packets","system.nettraffic.veth_natdummy.net.in.packets.rate","system.nettraffic.veth_natdummy.net.out.bytes","system.nettraffic.veth_natdummy.net.out.bytes.rate","system.nettraffic.veth_natdummy.net.out.carrier.errs","system.nettraffic.veth_natdummy.net.out.carrier.errs.rate","system.nettraffic.veth_natdummy.net.out.collisions","system.nettraffic.veth_natdummy.net.out.collisions.rate","system.nettraffic.veth_natdummy.net.out.compressed","system.nettraffic.veth_natdummy.net.out.compressed.rate","system.nettraffic.veth_natdummy.net.out.dropped","system.nettraffic.veth_natdummy.net.out.dropped.rate","system.nettraffic.veth_natdummy.net.out.errs","system.nettraffic.veth_natdummy.net.out.errs.rate","system.nettraffic.veth_natdummy.net.out.fifo.errs","system.nettraffic.veth_natdummy.net.out.fifo.errs.rate","system.nettraffic.veth_natdummy.net.out.packets","system.nettraffic.veth_natdummy.net.out.packets.rate","system.nettraffic.veth_natdummy0.net.in.compressed","system.nettraffic.veth_natdummy0.net.in.compressed.rate","system.nettraffic.veth_natdummy0.net.in.dropped","system.nettraffic.veth_natdummy0.net.in.dropped.rate","system.nettraffic.veth_natdummy0.net.in.errs","system.nettraffic.veth_natdummy0.net.in.errs.rate","system.nettraffic.veth_natdummy0.net.in.fifo.errs","system.nettraffic.veth_natdummy0.net.in.fifo.errs.rate","system.nettraffic.veth_natdummy0.net.in.frame.errs","system.nettraffic.veth_natdummy0.net.in.frame.errs.rate","system.nettraffic.veth_natdummy0.net.in.multicast","system.nettraffic.veth_natdummy0.net.in.multicast.rate","system.nettraffic.veth_natdummy0.net.in.packets","system.nettraffic.veth_natdummy0.net.in.packets.rate","system.nettraffic.veth_natdummy0.net.out.bytes","system.nettraffic.veth_natdummy0.net.out.bytes.rate","system.nettraffic.veth_natdummy0.net.out.carrier.errs","system.nettraffic.veth_natdummy0.net.out.carrier.errs.rate","system.nettraffic.veth_natdummy0.net.out.collisions","system.nettraffic.veth_natdummy0.net.out.collisions.rate","system.nettraffic.veth_natdummy0.net.out.compressed","system.nettraffic.veth_natdummy0.net.out.compressed.rate","system.nettraffic.veth_natdummy0.net.out.dropped","system.nettraffic.veth_natdummy0.net.out.dropped.rate","system.nettraffic.veth_natdummy0.net.out.errs","system.nettraffic.veth_natdummy0.net.out.errs.rate","system.nettraffic.veth_natdummy0.net.out.fifo.errs","system.nettraffic.veth_natdummy0.net.out.fifo.errs.rate","system.nettraffic.veth_natdummy0.net.out.packets","system.nettraffic.veth_natdummy0.net.out.packets.rate","system.process.blocked","system.process.running","system.tcp.active.opens","system.tcp.attempt.fails","system.tcp.curr.resets","system.tcp.estab.resets","system.tcp.in.errs","system.tcp.in.segs","system.tcp.out.rsts","system.tcp.out.segs","system.tcp.passive.opens","system.tcp.retran.segs","system.tcp.retry.rate","system.tsar.cpu","system.tsar.df","system.tsar.ifin","system.tsar.ifout","system.tsar.load1","system.tsar.load15","system.tsar.load5","system.tsar.mem","system.tsar.mem_buff","system.tsar.mem_cache","system.tsar.mem_free","system.tsar.mem_total","system.tsar.mem_used","system.tsar.nginx_qps","system.tsar.nginx_rt","system.tsar.pktin","system.tsar.pktout","system.tsar.tcp_retry"]; 2 | for(const key of keys) { 3 | console.log(`put ${key} 1514736000 0 init=true`); 4 | } 5 | -------------------------------------------------------------------------------- /sandbox/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node 2 | ENV TZ=Asia/Shanghai 3 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 4 | ENV UNDER_DOCKER true 5 | ADD ./sandbox-app /sandbox-app 6 | WORKDIR /sandbox-app 7 | RUN npm install -g cnpm --registry=https://registry.npm.taobao.org && cnpm install 8 | RUN npm run build 9 | CMD ["npm", "run", "start_prod"] 10 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/config/config.default.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midwayjs/sandbox-docker/8a961294b3d269a5c50c2076d0d1cbb43bac23ff/sandbox/sandbox-app/config/config.default.js -------------------------------------------------------------------------------- /sandbox/sandbox-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sandbox-app", 3 | "version": "0.0.2", 4 | "description": "MVP version of sandbox", 5 | "dependencies": { 6 | "chrome-devtools-frontend": "^1.0.590489", 7 | "egg-view-nunjucks": "^2.2.0", 8 | "md5": "^2.2.1", 9 | "midway": "^1.0.2", 10 | "pandora": "release-2.x", 11 | "pandora-component-auto-patching": "release-2.x", 12 | "pandora-component-sandbox-log-hub-reporter": "^1.0.0", 13 | "sandbox-core": "^0.0.15", 14 | "urllib": "^2.33.0" 15 | }, 16 | "devDependencies": { 17 | "@types/mocha": "^5.2.5", 18 | "@types/node": "^11.9.3", 19 | "midway-bin": "^0.3.2", 20 | "midway-mock": "^0.3.7", 21 | "tslib": "^1.8.1", 22 | "tslint": "^5.9.1", 23 | "webstorm-disable-index": "^1.2.0" 24 | }, 25 | "engines": { 26 | "install-alinode": "3.11.7" 27 | }, 28 | "scripts": { 29 | "start_prod": "pandora start", 30 | "start": "NODE_ENV=local midway-bin dev --ts", 31 | "start_build": "npm run build && NODE_ENV=local midway-bin dev", 32 | "debug": "NODE_ENV=local midway-bin debug --ts", 33 | "test": "npm run lint -- --fix && midway-bin test --ts", 34 | "cov": "midway-bin cov --ts", 35 | "lint": "tslint -c tslint.json --project .", 36 | "ci": "midway-bin cov --ts", 37 | "build": "midway-bin build -c" 38 | }, 39 | "ci": { 40 | "version": "8, 9" 41 | }, 42 | "repository": { 43 | "type": "git", 44 | "url": "" 45 | }, 46 | "license": "MIT", 47 | "midway-server-options": { 48 | "typescript": true 49 | }, 50 | "midway-bin-build": { 51 | "include": [ 52 | "app/view" 53 | ] 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/pandoraConfig.js: -------------------------------------------------------------------------------- 1 | exports.components = { 2 | sandboxLogHubReporter: { 3 | path: 'pandora-component-sandbox-logger-hub-reporter' 4 | }, 5 | autoPatching: { 6 | path: 'pandora-component-auto-patching' 7 | } 8 | }; 9 | 10 | exports.sandboxLogHubReporter = { 11 | endpoint: 'http://127.0.0.1:7001/' 12 | }; 13 | 14 | exports.trace = { 15 | sampling: 10 16 | }; 17 | 18 | exports.autoPatching = { 19 | patchers: { 20 | global: { 21 | recordConsole: true, 22 | recordUnhandled: true, 23 | recordFatal: true 24 | } 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/procfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = pandora => { 3 | pandora 4 | .fork('sandbox-app', 'midway/server'); 5 | }; 6 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/resource/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midwayjs/sandbox-docker/8a961294b3d269a5c50c2076d0d1cbb43bac23ff/sandbox/sandbox-app/resource/favicon.png -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app.ts: -------------------------------------------------------------------------------- 1 | import { dirname } from 'path'; 2 | import staticCache = require('koa-static-cache'); 3 | import { Application } from 'midway'; 4 | import { DebugServer } from 'sandbox-core'; 5 | 6 | export = (app: Application) => { 7 | app.on('server', (server) => { 8 | const debugServer = new DebugServer(server); 9 | debugServer.start(); 10 | }); 11 | app.use(staticCache({ 12 | dir: dirname(require.resolve('chrome-devtools-frontend/front_end/inspector.html')), 13 | prefix: '/chrome-devtools' 14 | })); 15 | }; 16 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/controller/applicationCtrl.ts: -------------------------------------------------------------------------------- 1 | import * as sandboxCore from 'sandbox-core'; 2 | import {TSDB, SandboxApplication, wrapJson} from 'sandbox-core'; 3 | import {get, inject, config} from 'midway'; 4 | 5 | export class ApplicationCtrl extends sandboxCore.ApplicationCtrl { 6 | 7 | 8 | @inject('tsdb') 9 | tsdb: TSDB; 10 | 11 | @config('coreMetrics') 12 | coreMetrics; 13 | 14 | @inject() 15 | defaultPlatformAdapter; 16 | @get('/listByUser') 17 | async listByUser(ctx) { 18 | 19 | const theMetricsName = this.coreMetrics.cpuUsage.metric; 20 | const ret = await this.tsdb.query({ 21 | start: '1h-ago', 22 | queries: [ 23 | { 24 | metric: theMetricsName, 25 | aggregator: 'avg', 26 | downsample: '1h-avg', 27 | tags: { 28 | scope_name: '*', scope: '*' 29 | } 30 | } 31 | ] 32 | }); 33 | const result: Partial[] = []; 34 | for(const item of ret) { 35 | const {scope, scope_name} = item.tags; 36 | result.push({ 37 | id: scope + ':' + scope_name, 38 | flag: 0, 39 | scope: scope, 40 | scopeName: scope_name 41 | }); 42 | } 43 | ctx.body = wrapJson({ 44 | data: result, 45 | total: result.length 46 | }); 47 | 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/controller/errorCtrl.ts: -------------------------------------------------------------------------------- 1 | export { ErrorCtrl } from 'sandbox-core'; 2 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/controller/logHubCtrl.ts: -------------------------------------------------------------------------------- 1 | import { inject, post, controller, provide, priority } from 'midway'; 2 | import {LogHubService} from '../../lib/service/logHubService'; 3 | 4 | @priority(0) 5 | @provide() 6 | @controller('/v2/api/log-hub/') 7 | export class LogHubCtrl { 8 | 9 | @inject('logHubService') 10 | private logHubService: LogHubService; 11 | 12 | @post('/put-trace') 13 | async putTrace(ctx) { 14 | const body = ctx.request.body; 15 | await this.logHubService.putTrace(body); 16 | ctx.body = 'ok'; 17 | } 18 | 19 | @post('/put-metrics') 20 | async putMetrics(ctx) { 21 | const body = ctx.request.body; 22 | await this.logHubService.putMetrics(body); 23 | ctx.body = 'ok'; 24 | } 25 | 26 | @post('/put-error') 27 | async putError(ctx) { 28 | const body = ctx.request.body; 29 | await this.logHubService.putError(body); 30 | ctx.body = 'ok'; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/controller/metricsCtrl.ts: -------------------------------------------------------------------------------- 1 | export { MetricsCtrl } from 'sandbox-core'; 2 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/controller/pageCtrl.ts: -------------------------------------------------------------------------------- 1 | export { Page } from 'sandbox-core'; 2 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/controller/remoteDebugCtrl.ts: -------------------------------------------------------------------------------- 1 | export { RemoteDebugCtrl } from 'sandbox-core'; 2 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/controller/tracingCtrl.ts: -------------------------------------------------------------------------------- 1 | export { TracingCtrl } from 'sandbox-core'; 2 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/extend/context.ts: -------------------------------------------------------------------------------- 1 | import { BaseContext } from 'koa'; 2 | export default { 3 | jsonRes(this: BaseContext, error, data) { 4 | const dataType: any = (typeof data) || null; 5 | if (error) { 6 | this.body = { success: false, msg: error.message, data: null, code: error.code, dataType }; 7 | return true; 8 | } 9 | this.body = { success: true, msg: 'success', dataType, data, code: 0 }; 10 | return false; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/middleware/assets.ts: -------------------------------------------------------------------------------- 1 | export default function assets(options, app) { 2 | return async (ctx, next) => { 3 | ctx.locals.publicPath = '//g.alicdn.com/midway/sandbox-newui/0.0.19/'; 4 | ctx.locals.env = 'prod'; 5 | await next(); 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/middleware/user.ts: -------------------------------------------------------------------------------- 1 | export default function admin(options, app) { 2 | return async (ctx, next) => { 3 | const isAdmin = true; 4 | ctx.isAdmin = isAdmin; 5 | ctx.locals.isAdmin = isAdmin; 6 | const uid = '0'; 7 | ctx.uid = uid; 8 | await next(); 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/app/view/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{title}} 6 | 7 | 8 | 9 |
10 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/config/config.default.ts: -------------------------------------------------------------------------------- 1 | import path = require('path'); 2 | import { readFileSync } from 'fs'; 3 | import { coreMetrics, metricsLayouts, metricsLayoutsOrder } from './metrics'; 4 | import { defaultEnv, envSchemas, envSchemasOrderly } from './environment'; 5 | 6 | module.exports = appInfo => { 7 | 8 | const config: any = {}; 9 | 10 | // Part 1 11 | // 核心配置 12 | config.container = { 13 | loadDir: [ `${appInfo.appDir}/node_modules/sandbox-core/dist/core`, __filename.endsWith('.ts') ? `${appInfo.appDir}/src` : `${appInfo.appDir}/dist` ], 14 | }; 15 | 16 | config.pandora = { 17 | restfulPort: 7002, 18 | }; 19 | 20 | config.tsdb = { 21 | host: process.env.UNDER_DOCKER ? 'opentsdb' : '127.0.0.1', 22 | port: 4242, 23 | }; 24 | 25 | config.dw = { 26 | host: process.env.UNDER_DOCKER ? 'mariadb' : '127.0.0.1', 27 | port: 3306, 28 | username: 'sandbox', 29 | password: 'sandbox', 30 | database: 'column_sandbox', 31 | }; 32 | 33 | config.coreDB = { 34 | host: process.env.UNDER_DOCKER ? 'mariadb' : '127.0.0.1', 35 | port: 3306, 36 | username: 'sandbox', 37 | password: 'sandbox', 38 | database: 'sandbox', 39 | }; 40 | 41 | // Part 2 42 | // 客制化配置 43 | config.coreMetrics = coreMetrics; 44 | config.metricsLayouts = metricsLayouts; 45 | config.metricsLayoutsOrder = metricsLayoutsOrder; 46 | config.defaultEnv = defaultEnv; 47 | config.envSchemas = envSchemas; 48 | config.envSchemasOrderly = envSchemasOrderly; 49 | 50 | // Part 3 51 | // 插件相关的配置 52 | config.view = { 53 | defaultViewEngine: 'nunjucks', 54 | mapping: { 55 | '.nj': 'nunjucks', 56 | '.html': 'nunjucks', 57 | }, 58 | }; 59 | 60 | config.middleware = [ 61 | 'assets', 62 | 'user', 63 | ]; 64 | 65 | config.onerror = { 66 | json(err, ctx) { 67 | ctx.status = 200; 68 | ctx.body = { 69 | success: false, 70 | message: err.message, 71 | data: null, 72 | code: 500, 73 | }; 74 | } 75 | }; 76 | 77 | config.siteFile = { 78 | '/favicon.ico': readFileSync(path.join(__dirname, '../../resource/favicon.png')) 79 | }; 80 | 81 | config.security = { 82 | csrf: { enable: false }, 83 | csp: false, 84 | }; 85 | 86 | config.customLogger = { 87 | dwLogger: { 88 | file: path.join(appInfo.root, `logs/sandbox-datasource-dw.log`) 89 | }, 90 | coreDBLogger: { 91 | file: path.join(appInfo.root, `logs/sandbox-datasource-coredb.log`) 92 | } 93 | }; 94 | 95 | return config; 96 | 97 | }; 98 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/config/environment.ts: -------------------------------------------------------------------------------- 1 | const dev = { 2 | name: 'dev', 3 | humanReadableName: '开发环境' 4 | }; 5 | const prod = { 6 | name: 'prod', 7 | humanReadableName: '生产环境' 8 | }; 9 | export const defaultEnv = dev; 10 | export const envSchemas = { 11 | dev, 12 | prod 13 | }; 14 | export const envSchemasOrderly = [ 15 | dev, 16 | prod 17 | ]; 18 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/config/metrics.ts: -------------------------------------------------------------------------------- 1 | import {systemLayout} from './metricsLayouts/systemLayout'; 2 | import {nodeLayout} from './metricsLayouts/nodeLayout'; 3 | import {focusLayout} from './metricsLayouts/focusLayout'; 4 | 5 | export const coreMetrics = { 6 | cpuUsage: { 7 | aggregator: 'avg', 8 | metric: 'system.cpu.usage', 9 | affix: '%', 10 | normalizedValue: true, 11 | }, 12 | load1: { 13 | aggregator: 'avg', 14 | metric: 'system.load.1min', 15 | }, 16 | memUsage: { 17 | aggregator: 'avg', 18 | metric: 'system.mem.usage', 19 | affix: '%', 20 | normalizedValue: true, 21 | }, 22 | diskUsage: { 23 | aggregator: 'avg', 24 | metric: 'system.disk.partition.used_ratio', 25 | affix: '%', 26 | normalizedValue: true, 27 | }, 28 | qps: { 29 | aggregator: 'sum', 30 | metric: 'middleware.http.request.qps', 31 | }, 32 | rt: { 33 | aggregator: 'avg', 34 | metric: 'middleware.http.request.rt', 35 | }, 36 | errorCount: { 37 | aggregator: 'sum', 38 | metric: 'error.all.bucket_count', 39 | }, 40 | successRate: { 41 | aggregator: 'avg', 42 | metric: 'middleware.http.request.success_rate', 43 | affix: '%', 44 | normalizedValue: true, 45 | }, 46 | }; 47 | 48 | export const metricsLayouts = { 49 | focus: focusLayout, 50 | node: nodeLayout, 51 | system: systemLayout 52 | }; 53 | 54 | export const metricsLayoutsOrder = [ 55 | 'focus', 56 | 'node', 57 | 'system' 58 | ]; 59 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/config/metricsLayouts/focusLayout.ts: -------------------------------------------------------------------------------- 1 | export const focusLayout = [{ 2 | title: '焦点视图', 3 | charts: [ 4 | { 5 | title: 'HTTP Server QPS', 6 | indicators: [ 7 | { 8 | type: 'number', 9 | aggregator: 'sum', 10 | metric: 'middleware.http.request.qps', 11 | title: 'Nginx QPS', 12 | 13 | unit: '次/秒', 14 | }, 15 | ], 16 | }, 17 | { 18 | title: 'HTTP Server RT', 19 | indicators: [ 20 | { 21 | type: 'number', 22 | aggregator: 'avg', 23 | metric: 'middleware.http.request.rt', 24 | title: 'Nginx RT', 25 | 26 | unit: 'ms', 27 | }, 28 | ], 29 | }, 30 | { 31 | title: '访问成功率', 32 | indicators: [ 33 | { 34 | aggregator: 'avg', 35 | metric: 'middleware.http.request.success_rate', 36 | title: '访问成功率', 37 | 38 | type: 'percent', 39 | normalizedValue: true, 40 | }, 41 | ], 42 | }, 43 | { 44 | title: 'CPU Load', 45 | indicators: [ 46 | { 47 | aggregator: 'avg', 48 | metric: 'system.load.1min', 49 | title: 'Load 1', 50 | type: 'number', 51 | }, 52 | { 53 | aggregator: 'avg', 54 | metric: 'system.load.5min', 55 | title: 'Load 5', 56 | type: 'number', 57 | }, 58 | { 59 | aggregator: 'avg', 60 | metric: 'system.load.15min', 61 | title: 'Load 15', 62 | type: 'number', 63 | }, 64 | ], 65 | }, 66 | { 67 | title: '日志错误', 68 | indicators: [ 69 | { 70 | aggregator: 'sum', 71 | metric: 'error.all.bucket_count', 72 | title: '错误数量', 73 | type: 'number', 74 | unit: '条', 75 | }, 76 | ], 77 | }, 78 | { 79 | title: 'CPU 使用率', 80 | indicators: [ 81 | { 82 | aggregator: 'avg', 83 | metric: 'system.cpu.usage', 84 | title: 'CPU 使用率', 85 | type: 'percent', 86 | normalizedValue: true, 87 | }, 88 | ], 89 | }, 90 | { 91 | title: '内存使用率', 92 | indicators: [ 93 | { 94 | aggregator: 'avg', 95 | metric: 'system.mem.usage', 96 | title: '内存使用率', 97 | type: 'percent', 98 | normalizedValue: true, 99 | }, 100 | ], 101 | }, 102 | { 103 | title: '磁盘占用率', 104 | indicators: [ 105 | { 106 | aggregator: 'avg', 107 | metric: 'system.disk.partition.used_ratio', 108 | title: '磁盘占用率', 109 | type: 'percent', 110 | normalizedValue: true, 111 | }, 112 | ], 113 | }, 114 | { 115 | title: '网络吞吐速率', 116 | indicators: [ 117 | 118 | 119 | { 120 | type: 'number', 121 | aggregator: 'sum', 122 | metric: 'system.nettraffic.eth0.net.in.bytes', 123 | unit: 'Bytes/s', 124 | 125 | title: 'eth0 流入', 126 | }, 127 | { 128 | type: 'number', 129 | aggregator: 'sum', 130 | metric: 'system.nettraffic.eth0.net.out.bytes', 131 | unit: 'Bytes/s', 132 | 133 | title: 'eth0 流出', 134 | }, 135 | ], 136 | }, 137 | { 138 | title: 'TCP Retry', 139 | indicators: [ 140 | { 141 | aggregator: 'avg', 142 | metric: 'system.tcp.retry.rate', 143 | title: '重试率', 144 | 145 | type: 'percent', 146 | normalizedValue: false, 147 | }, 148 | ], 149 | }, 150 | ], 151 | }]; 152 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/config/metricsLayouts/nodeLayout.ts: -------------------------------------------------------------------------------- 1 | export const nodeLayout = []; 2 | 3 | const keys = [ 4 | { 5 | metric: 'node.v8.total_heap_size', 6 | title: 'Total Heap Size', 7 | }, 8 | { 9 | metric: 'node.v8.used_heap_size', 10 | title: 'Used Heap Size', 11 | }, 12 | { 13 | metric: 'node.v8.total_heap_size_executable', 14 | title: 'Total Heap Size Executable', 15 | }, 16 | { 17 | metric: 'node.v8.total_available_size', 18 | title: 'Total Available Size', 19 | }, 20 | { 21 | metric: 'node.v8.malloced_memory', 22 | title: 'Malloced Memory', 23 | }, 24 | { 25 | metric: 'node.v8.total_physical_size', 26 | title: 'Total Physical Size', 27 | }, 28 | ]; 29 | 30 | const charts = []; 31 | 32 | for (const key of keys) { 33 | const config = { 34 | title: key.title, 35 | groupByOnHost: ['pid'], 36 | groupByOnCluster: ['hostname'], 37 | analyseHigherLower: true, 38 | indicators: [ 39 | { 40 | type: 'number', 41 | aggregator: 'sum', 42 | metric: key.metric, 43 | unit: '', 44 | title: key.title, 45 | }, 46 | ], 47 | }; 48 | charts.push(config); 49 | } 50 | 51 | 52 | nodeLayout.push({ title: 'Heap Stats', charts }); 53 | 54 | 55 | const spaceKinds = [ 56 | { 57 | name: 'new_space', 58 | title: 'New Space', 59 | }, 60 | { 61 | name: 'old_space', 62 | title: 'Old Space', 63 | }, 64 | { 65 | name: 'code_space', 66 | title: 'Code Space', 67 | }, 68 | { 69 | name: 'map_space', 70 | title: 'Map Space', 71 | }, 72 | { 73 | name: 'large_object_space', 74 | title: 'Large Object Space', 75 | }, 76 | ]; 77 | 78 | const wantedIndicators = [ 79 | { 80 | name: 'space_size', 81 | title: 'Space Size', 82 | }, 83 | { 84 | name: 'space_used_size', 85 | title: 'Space Used Size', 86 | }, 87 | { 88 | name: 'space_available_size', 89 | title: 'Space Available Size', 90 | }, 91 | { 92 | name: 'physical_space_size', 93 | title: 'Physical Space Size', 94 | }, 95 | ]; 96 | 97 | for (const spaceKind of spaceKinds) { 98 | const charts = []; 99 | for (const wi of wantedIndicators) { 100 | const indicators = []; 101 | indicators.push( 102 | { 103 | type: 'number', 104 | aggregator: 'sum', 105 | metric: `node.v8.${spaceKind.name}.${wi.name}`, 106 | unit: '', 107 | title: wi.title, 108 | } 109 | ); 110 | charts.push({ 111 | groupByOnHost: ['pid'], 112 | groupByOnCluster: ['hostname'], 113 | analyseHigherLower: true, 114 | title: `${spaceKind.title} - ${wi.title}`, 115 | indicators, 116 | }); 117 | } 118 | nodeLayout.push({ 119 | title: spaceKind.title, 120 | charts, 121 | }); 122 | } 123 | 124 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/config/metricsLayouts/systemLayout.ts: -------------------------------------------------------------------------------- 1 | export const systemLayout = [ 2 | { 3 | title: '系统指标', 4 | charts: [ 5 | { 6 | title: 'Load 1', 7 | indicators: [ 8 | { 9 | aggregator: 'avg', 10 | metric: 'system.load.1min', 11 | title: 'Load 1', 12 | type: 'number', 13 | }, 14 | ], 15 | }, 16 | { 17 | title: 'Load 5', 18 | indicators: [ 19 | { 20 | aggregator: 'avg', 21 | metric: 'system.load.5min', 22 | title: 'Load 5', 23 | type: 'number', 24 | }, 25 | ], 26 | }, 27 | { 28 | title: 'Load 15', 29 | indicators: [ 30 | { 31 | aggregator: 'avg', 32 | metric: 'system.load.15min', 33 | title: 'Load 15', 34 | type: 'number', 35 | }, 36 | ], 37 | }, 38 | { 39 | title: 'CPU 使用率', 40 | indicators: [ 41 | { 42 | aggregator: 'avg', 43 | metric: 'system.cpu.usage', 44 | title: 'CPU 使用率', 45 | type: 'percent', 46 | normalizedValue: true, 47 | }, 48 | ], 49 | }, 50 | { 51 | title: '内存使用率', 52 | indicators: [ 53 | { 54 | aggregator: 'avg', 55 | metric: 'system.mem.usage', 56 | title: '内存使用率', 57 | type: 'percent', 58 | normalizedValue: true, 59 | }, 60 | ], 61 | }, 62 | { 63 | title: '磁盘占用率', 64 | indicators: [ 65 | { 66 | aggregator: 'avg', 67 | metric: 'system.disk.partition.used_ratio', 68 | title: '磁盘占用率', 69 | type: 'percent', 70 | normalizedValue: true, 71 | }, 72 | ], 73 | }, 74 | { 75 | title: '网络流入', 76 | indicators: [ 77 | { 78 | type: 'number', 79 | aggregator: 'sum', 80 | metric: 'system.nettraffic.eth0.net.in.bytes', 81 | unit: 'Bytes/s', 82 | title: 'eth0 流入', 83 | }, 84 | ], 85 | }, 86 | { 87 | title: '网络流出', 88 | indicators: [ 89 | { 90 | type: 'number', 91 | aggregator: 'sum', 92 | metric: 'system.nettraffic.eth0.net.out.bytes', 93 | unit: 'Bytes/s', 94 | title: 'eth0 流出', 95 | }, 96 | ], 97 | }, 98 | { 99 | title: '包流入', 100 | indicators: [ 101 | { 102 | type: 'number', 103 | aggregator: 'sum', 104 | metric: 'system.nettraffic.eth0.net.in.packets', 105 | unit: '', 106 | title: '入包', 107 | }, 108 | ], 109 | }, 110 | { 111 | title: '包流出', 112 | indicators: [ 113 | { 114 | type: 'number', 115 | aggregator: 'sum', 116 | metric: 'system.nettraffic.eth0.net.out.packets', 117 | unit: '', 118 | title: '出包', 119 | }, 120 | ], 121 | }, 122 | { 123 | title: 'TCP Retry', 124 | indicators: [ 125 | { 126 | aggregator: 'avg', 127 | metric: 'system.tcp.retry.rate', 128 | title: '重试率', 129 | type: 'percent', 130 | normalizedValue: false, 131 | }, 132 | ], 133 | }, 134 | { 135 | title: 'HTTP Server QPS', 136 | indicators: [ 137 | { 138 | type: 'number', 139 | aggregator: 'sum', 140 | metric: 'middleware.http.request.qps', 141 | title: 'Nginx QPS', 142 | unit: '次/秒', 143 | }, 144 | ], 145 | }, 146 | { 147 | title: 'HTTP Server RT', 148 | indicators: [ 149 | { 150 | type: 'number', 151 | aggregator: 'avg', 152 | metric: 'middleware.http.request.rt', 153 | title: 'Nginx RT', 154 | unit: 'ms', 155 | }, 156 | ], 157 | }, 158 | ], 159 | }, 160 | ]; 161 | 162 | for (const chart of systemLayout[0].charts) { 163 | Object.assign(chart, { 164 | groupByOnCluster: ['hostname'], 165 | analyseHigherLower: true, 166 | }); 167 | } 168 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/config/plugin.ts: -------------------------------------------------------------------------------- 1 | export const nunjucks = { 2 | enable: true, 3 | package: 'egg-view-nunjucks', 4 | }; 5 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/lib/adapter/keycenter.ts: -------------------------------------------------------------------------------- 1 | import { provide } from 'midway'; 2 | 3 | @provide('keycenter') 4 | export class Keycenter { 5 | async encrypt(str, keyName, options) { 6 | return str; 7 | } 8 | async decrypt(str, keyName, options) { 9 | return str; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/lib/adapter/privilegeAdapter.ts: -------------------------------------------------------------------------------- 1 | import { provide } from 'midway'; 2 | import { IPrivilegeAdapter } from 'sandbox-core'; 3 | 4 | @provide('privilegeAdapter') 5 | export class PrivilegeAdapter implements IPrivilegeAdapter { 6 | async isAppOps(scope: string, scopeName: string, uid: string): Promise { 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/lib/adapter/remoteExecuteAdapter.ts: -------------------------------------------------------------------------------- 1 | import { exec } from 'child_process'; 2 | import { provide } from 'midway'; 3 | import { HostSelector } from 'sandbox-core'; 4 | import { IRemoteExecuteAdapter } from 'sandbox-core'; 5 | 6 | @provide('remoteExecuteAdapter') 7 | export class RemoteExecuteAdapter implements IRemoteExecuteAdapter { 8 | exec(host: HostSelector, cmd): Promise { 9 | const cmdEscaped = cmd.replace('"', '\\"'); 10 | const shell = `ssh ${host.ip} "${cmdEscaped}"`; 11 | return new Promise((resolve, reject) => { 12 | exec(shell, { 13 | timeout: 5000 14 | }, (error, stdout) => { 15 | if(error) { 16 | return reject(error); 17 | } 18 | resolve(stdout.toString()); 19 | }); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/lib/adapter/sadMetricsAdapter.ts: -------------------------------------------------------------------------------- 1 | import { provide } from 'midway'; 2 | import {AppSelector, TimeWindowOptions} from 'sandbox-core'; 3 | import {ISadMetricsAdapter} from 'sandbox-core'; 4 | 5 | @provide('sadMetricsAdapter') 6 | export class SadMetricsAdapter implements ISadMetricsAdapter { 7 | async getMetricsNames(options: AppSelector & TimeWindowOptions): Promise { 8 | return []; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/lib/platform/defaultPlatformAdapter.ts: -------------------------------------------------------------------------------- 1 | import { provide, inject, config } from 'midway'; 2 | import { IPlatformGroup, IPlatformIdentification, IPlatformAdapter, IPlatformHostResult, TSDB } from 'sandbox-core'; 3 | 4 | @provide('defaultPlatformAdapter') 5 | export class DefaultPlatformAdapter implements IPlatformAdapter { 6 | 7 | name = 'default'; 8 | 9 | @inject('tsdb') 10 | tsdb: TSDB; 11 | 12 | @config('coreMetrics') 13 | coreMetrics; 14 | 15 | async getHosts(app: IPlatformIdentification): Promise> { 16 | 17 | const { scopeName, scope } = app; 18 | 19 | const metricsNameQps = this.coreMetrics.cpuUsage.metric; 20 | const res = await this.tsdb.query({ 21 | start: '1h-ago', 22 | queries: [ 23 | { 24 | metric: metricsNameQps, 25 | aggregator: 'avg', 26 | downsample: '1h-avg', 27 | tags: { 28 | scope_name: scopeName, scope, 29 | env: '*', hostname: '*', ip: '*', 30 | } 31 | } 32 | ] 33 | }); 34 | 35 | const result: IPlatformHostResult = {}; 36 | 37 | for (const item of res) { 38 | const tags = item.tags; 39 | const { env, ip, hostname } = tags; 40 | if(!result.hasOwnProperty(env)) { 41 | result[env] = [{ 42 | name: env, 43 | hosts: [] 44 | }]; 45 | } 46 | const targetEnv = result[env][0]; 47 | targetEnv.hosts.push({ 48 | ip, hostname 49 | }); 50 | } 51 | 52 | return result; 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/src/lib/service/logHubService.ts: -------------------------------------------------------------------------------- 1 | import { provide, inject, config, logger } from 'midway'; 2 | import urllib = require('urllib'); 3 | 4 | const METRICS_BATCH_SLICE_SIZE = 20; 5 | const DEFAULT_SCOPE = 'sandbox'; 6 | const DEFAULT_ENV = 'prod'; 7 | 8 | 9 | @provide('logHubService') 10 | export class LogHubService { 11 | 12 | @logger() 13 | protected logger; 14 | 15 | @inject() 16 | protected traceModel; 17 | 18 | @inject() 19 | protected traceNodeModel; 20 | 21 | @inject() 22 | protected errorModel; 23 | 24 | @config('tsdb') 25 | tsdbConfig; 26 | 27 | async putTrace(traces) { 28 | for(const trace of traces) { 29 | try { 30 | await this.putTraceRecord(trace); 31 | } catch(err) { 32 | this.logger.warn(err); 33 | } 34 | try { 35 | await this.putTraceNodeRecord(trace); 36 | } catch(err) { 37 | this.logger.warn(err); 38 | } 39 | } 40 | } 41 | 42 | async putTraceRecord(trace) { 43 | 44 | const record = { 45 | timestamp: new Date(trace.timestamp), 46 | scope: trace.scope || DEFAULT_SCOPE, 47 | scopeName: trace.appName, 48 | env: trace.env || DEFAULT_ENV, 49 | hostname: trace.host, 50 | ip: trace.ip, 51 | pid: trace.pid, 52 | uuid: trace.seed || trace.traceId, 53 | traceId: trace.traceId, 54 | traceSpans: trace.spans ? JSON.stringify(trace.spans) : null, 55 | unixTimestamp: trace.unix_timestamp || Math.floor(trace.timestamp / 1000), 56 | traceDuration: trace.duration, 57 | traceName: trace.name, 58 | traceStatus: trace.status, 59 | version: 1 60 | }; 61 | 62 | return this.traceModel.create(record, { raw: true }); 63 | 64 | } 65 | 66 | async putTraceNodeRecord(trace) { 67 | 68 | if(!trace.spans) { 69 | return; 70 | } 71 | 72 | for(const span of trace.spans) { 73 | 74 | try { 75 | 76 | const traceId = span.context && span.context.traceId || trace.traceId; 77 | const spanId = span.context && span.context.spanId; 78 | 79 | const record = { 80 | 81 | timestamp: span.timestamp, 82 | spanTimestamp: span.timestamp, 83 | 84 | scope: trace.scope || DEFAULT_SCOPE, 85 | scopeName: trace.appName, 86 | env: trace.env || DEFAULT_ENV, 87 | hostname: trace.host, 88 | ip: trace.ip, 89 | pid: trace.pid, 90 | 91 | 92 | spanName: span.name, 93 | spanDuration: span.duration, 94 | spanTags: span.tags ? JSON.stringify(span.tags) : null, 95 | spanId: spanId, 96 | spanRpcId: span.context && span.context.rpcId, 97 | traceId: traceId, 98 | traceName: trace.name, 99 | spanError: span.tags && span.tags.error ? 1 : 0, 100 | 101 | uuid: traceId + '-' + spanId, 102 | 103 | spanMethod: span.method, 104 | spanTarget: span.target 105 | 106 | }; 107 | 108 | await this.traceNodeModel.create(record, { raw: true }); 109 | 110 | } catch(err) { 111 | this.logger.warn(err); 112 | } 113 | 114 | } 115 | 116 | } 117 | 118 | async putMetrics(list) { 119 | 120 | const {host, port} = this.tsdbConfig; 121 | const nextList = []; 122 | 123 | for(const one of list) { 124 | try { 125 | if(one.value == null || one.metric == null) { 126 | continue; 127 | } 128 | nextList.push({ 129 | metric: one.metric, 130 | timestamp: one.timestamp, 131 | value: one.value || 0, 132 | tags: { 133 | scope: one.scope || DEFAULT_SCOPE, 134 | ip: one.ip, 135 | scope_name: one.appName, 136 | hostname: one.host, 137 | env: one.env || DEFAULT_ENV, 138 | pid: one.pid, 139 | level: one.level, 140 | type: one.type 141 | } 142 | }); 143 | } catch(err) { 144 | this.logger.warn(err); 145 | } 146 | } 147 | 148 | for(let idx = 0, len = Math.ceil(nextList.length / METRICS_BATCH_SLICE_SIZE); idx < len; idx++) { 149 | const start = idx * METRICS_BATCH_SLICE_SIZE; 150 | const end = (idx + 1) * METRICS_BATCH_SLICE_SIZE; 151 | const slice = nextList.slice(start, end); 152 | try { 153 | const resp = await urllib.request(`http://${host}:${port}/api/put?summary&details`, { 154 | method: 'POST', 155 | contentType: 'json', 156 | headers: { 157 | 'Content-Type': 'application/json', 158 | }, 159 | timeout: 10000, 160 | data: slice 161 | }); 162 | if (resp.status !== 200) { 163 | if (resp.data && resp.data.error) { 164 | const err = new Error(resp.data.error.message); 165 | Object.assign(err, resp.data.error); 166 | throw err; 167 | } else { 168 | throw new Error('TSDB unknown error with http code: ' + resp.status); 169 | } 170 | } 171 | } catch(err) { 172 | this.logger.warn(err); 173 | } 174 | } 175 | 176 | } 177 | 178 | 179 | async putError(list) { 180 | 181 | for(const one of list) { 182 | 183 | try { 184 | 185 | const record = { 186 | timestamp: new Date(one.timestamp), 187 | unixTimestamp: one.unix_timestamp, 188 | 189 | scope: one.scope || DEFAULT_SCOPE, 190 | scopeName: one.appName, 191 | ip: one.ip, 192 | hostname: one.host, 193 | env: one.env || DEFAULT_ENV, 194 | pid: one.pid, 195 | errorType: one.errorType, 196 | errorMessage: one.message, 197 | errorStack: one.stack, 198 | traceId: one.traceId, 199 | logPath: one.path, 200 | uuid: one.seed, 201 | 202 | version: 1 203 | }; 204 | 205 | await this.errorModel.create(record, { raw: true }); 206 | 207 | } catch(err) { 208 | this.logger.warn(err); 209 | } 210 | 211 | } 212 | 213 | } 214 | 215 | } 216 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/test/app/controller/applicationCtrl.test.ts: -------------------------------------------------------------------------------- 1 | import {ApplicationCtrl} from '../../../src/app/controller/applicationCtrl'; 2 | import * as core from 'sandbox-core'; 3 | import * as assert from 'assert'; 4 | describe('applicationCtrl', () => { 5 | it('should inherit from sandbox-core', () => { 6 | const myApplicationCtrl = new ApplicationCtrl(); 7 | assert(myApplicationCtrl instanceof core.ApplicationCtrl); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "target": "ES2017", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "experimentalDecorators": true, 8 | "emitDecoratorMetadata": true, 9 | "inlineSourceMap":true, 10 | "noImplicitThis": true, 11 | "noUnusedLocals": true, 12 | "stripInternal": true, 13 | "pretty": true, 14 | "declaration": true, 15 | "outDir": "dist", 16 | "lib": ["es2017", "dom"] 17 | }, 18 | "exclude": [ 19 | "app/public", 20 | "app/views", 21 | "dist", 22 | "node_modules", 23 | "test" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /sandbox/sandbox-app/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:latest", 3 | "rules": { 4 | "quotemark": [ 5 | true, 6 | "single", 7 | "jsx-double" 8 | ], 9 | "no-console": [ 10 | true, 11 | "dir", 12 | "log", 13 | "error", 14 | "warn" 15 | ], 16 | "space-before-function-paren": false, 17 | "interface-name": [ 18 | true, 19 | "no-prefix" 20 | ], 21 | "adjacent-overload-signatures": true, 22 | "member-access": [ 23 | false 24 | ], 25 | "member-ordering": [ 26 | true, 27 | { 28 | "order": "fields-first" 29 | } 30 | ], 31 | "object-literal-sort-keys": false, 32 | "max-classes-per-file": [ 33 | true, 34 | 10 35 | ], 36 | "variable-name": [ 37 | true, 38 | "allow-leading-underscore" 39 | ], 40 | "align": [ 41 | true, 42 | "statements" 43 | ], 44 | "ordered-imports": false 45 | } 46 | } 47 | --------------------------------------------------------------------------------