Full Code of open-falcon/falcon-plus for AI

master 93491806585f cached
560 files
2.2 MB
611.8k tokens
1284 symbols
1 requests
Download .txt
Showing preview only (2,433K chars total). Download the full file or copy to clipboard to get everything.
Repository: open-falcon/falcon-plus
Branch: master
Commit: 93491806585f
Files: 560
Total size: 2.2 MB

Directory structure:
gitextract_lxxa1vqu/

├── .dockerignore
├── .gitignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.module
├── Dockerfile_arm64
├── LICENSE
├── Makefile
├── NOTICE
├── README.md
├── VERSION
├── api-standard.md
├── cmd/
│   ├── check.go
│   ├── monitor.go
│   ├── reload.go
│   ├── restart.go
│   ├── start.go
│   └── stop.go
├── common/
│   ├── .gitignore
│   ├── LICENSE
│   ├── NOTICE
│   ├── backend_pool/
│   │   ├── rpc_backends.go
│   │   └── tsdb_backends.go
│   ├── db/
│   │   └── db.go
│   ├── model/
│   │   ├── agent.go
│   │   ├── event.go
│   │   ├── expression.go
│   │   ├── graph.go
│   │   ├── host.go
│   │   ├── influxdb.go
│   │   ├── judge.go
│   │   ├── metric.go
│   │   ├── nodata.go
│   │   ├── prometheus.go
│   │   ├── rpc.go
│   │   ├── strategy.go
│   │   ├── template.go
│   │   ├── transfer.go
│   │   └── tsdb.go
│   ├── proc/
│   │   └── proc.go
│   ├── sdk/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── requests/
│   │   │   ├── auth_request.go
│   │   │   └── post.go
│   │   └── sender/
│   │       ├── linkedlist.go
│   │       ├── make.go
│   │       ├── push.go
│   │       └── sender.go
│   └── utils/
│       ├── counter.go
│       ├── date.go
│       ├── formatter.go
│       ├── func.go
│       ├── func_test.go
│       ├── map.go
│       ├── md5.go
│       ├── md5_test.go
│       ├── objpool.go
│       ├── statistics.go
│       ├── tags.go
│       └── tags_test.go
├── config/
│   ├── agent.json
│   ├── aggregator.json
│   ├── alarm.json
│   ├── api.json
│   ├── confgen.sh
│   ├── falcon2p8s.json
│   ├── gateway.json
│   ├── graph.json
│   ├── hbs.json
│   ├── judge.json
│   ├── nodata.json
│   └── transfer.json
├── docker/
│   ├── README.md
│   ├── confgen4docker.sh
│   ├── ctrl.sh
│   ├── k8s-cluster/
│   │   ├── Dockerfile.tpl
│   │   ├── README.md
│   │   ├── build.sh
│   │   ├── init.sh
│   │   └── modules/
│   │       ├── falcon-agent.yaml
│   │       ├── falcon-aggregator.yaml
│   │       ├── falcon-alarm.yaml
│   │       ├── falcon-api.yaml
│   │       ├── falcon-dashboard.yaml
│   │       ├── falcon-graph-01.yaml
│   │       ├── falcon-hbs.yaml
│   │       ├── falcon-judge.yaml
│   │       ├── falcon-nodata.yaml
│   │       └── falcon-transfer.yaml
│   ├── k8s-example/
│   │   ├── README.md
│   │   ├── init_mysql_data.sh
│   │   ├── mysql.yaml
│   │   ├── openfalcon-dashboard.yaml
│   │   ├── openfalcon-plus.yaml
│   │   └── redis.yaml
│   ├── mysql-init/
│   │   ├── Dockerfile
│   │   └── init_mysql_data.sh
│   └── supervisord.conf
├── docker-compose.yml
├── docker_test.sh
├── docs/
│   ├── LICENSE.md
│   ├── Makefile
│   ├── README.md
│   ├── _config.yml
│   ├── _includes/
│   │   └── nav.html
│   ├── _layouts/
│   │   └── default.html
│   ├── _posts/
│   │   ├── 2017-01-01-authentication.md
│   │   ├── 2017-01-01-response-status-codes.md
│   │   ├── Admin/
│   │   │   ├── 2017-01-01-admin_change_role.md
│   │   │   ├── 2017-01-01-admin_change_user_passwd.md
│   │   │   ├── 2017-01-01-admin_delete_user.md
│   │   │   └── 2017-12-07-admin_login.md
│   │   ├── Aggregator/
│   │   │   ├── 2017-01-01-aggreator_create.md
│   │   │   ├── 2017-01-01-aggreator_delete.md
│   │   │   ├── 2017-01-01-aggreator_of_hostgroup.md
│   │   │   ├── 2017-01-01-aggreator_update.md
│   │   │   └── 2017-01-01-get_aggreator_by_id.md
│   │   ├── Alarm/
│   │   │   ├── 2017-01-01-alarm_eventcases_get_by_id.md
│   │   │   ├── 2017-01-01-alarm_eventcases_list.md
│   │   │   ├── 2017-01-01-alarm_eventnote_create.md
│   │   │   ├── 2017-01-01-alarm_eventnote_get.md
│   │   │   └── 2017-01-01-alarm_events_create.md
│   │   ├── DashboardGraph/
│   │   │   ├── 2017-01-01-dashboard_graph_create.md
│   │   │   ├── 2017-01-01-dashboard_graph_create_tmpgraph.md
│   │   │   ├── 2017-01-01-dashboard_graph_delete.md
│   │   │   ├── 2017-01-01-dashboard_graph_get.md
│   │   │   ├── 2017-01-01-dashboard_graph_get_tmpgraph_by_id.md
│   │   │   ├── 2017-01-01-dashboard_graph_update.md
│   │   │   └── 2017-01-01-dashboard_graphs_gets_by_screenid.md
│   │   ├── DashboardScreen/
│   │   │   ├── 2017-01-01-dashboard_screen_create.md
│   │   │   ├── 2017-01-01-dashboard_screen_delete.md
│   │   │   ├── 2017-01-01-dashboard_screen_get_by_id.md
│   │   │   ├── 2017-01-01-dashboard_screen_gets_all.md
│   │   │   ├── 2017-01-01-dashboard_screen_gets_by_pid.md
│   │   │   └── 2017-01-01-dashboard_screen_update.md
│   │   ├── Expression/
│   │   │   ├── 2017-01-01-expression_create.md
│   │   │   ├── 2017-01-01-expression_delete.md
│   │   │   ├── 2017-01-01-expression_info_by_id.md
│   │   │   ├── 2017-01-01-expression_list.md
│   │   │   └── 2017-01-01-expression_update.md
│   │   ├── Graph/
│   │   │   ├── 2017-01-01-endpoint_counter.md
│   │   │   ├── 2017-01-01-endpoints.md
│   │   │   ├── 2017-01-01-grafana.md
│   │   │   └── 2017-01-01-graph_histroy.md
│   │   ├── Host/
│   │   │   ├── 2017-01-01-host_maintain.md
│   │   │   ├── 2017-01-01-host_related_hostgroup.md
│   │   │   ├── 2017-01-01-host_related_template.md
│   │   │   └── 2017-01-01-host_reset.md
│   │   ├── HostGroup/
│   │   │   ├── 2017-01-01-hostgroup_add_host.md
│   │   │   ├── 2017-01-01-hostgroup_create.md
│   │   │   ├── 2017-01-01-hostgroup_delete.md
│   │   │   ├── 2017-01-01-hostgroup_get_info_by_id.md
│   │   │   ├── 2017-01-01-hostgroup_list.md
│   │   │   ├── 2017-01-01-hostgroup_template_bind.md
│   │   │   ├── 2017-01-01-hostgroup_template_list.md
│   │   │   ├── 2017-01-01-hostgroup_template_unbind.md
│   │   │   ├── 2017-01-01-hostgroup_unbind_host.md
│   │   │   ├── 2017-01-01-hostgroup_update.md
│   │   │   └── 2017-08-22-hostgroup_update_partial_hosts.md
│   │   ├── NoData/
│   │   │   ├── 2017-01-01-nodata_create.md
│   │   │   ├── 2017-01-01-nodata_delete.md
│   │   │   ├── 2017-01-01-nodata_info_by_id.md
│   │   │   ├── 2017-01-01-nodata_list.md
│   │   │   └── 2017-01-01-nodata_update.md
│   │   ├── Plugin/
│   │   │   ├── 2017-01-01-plugin_create.md
│   │   │   ├── 2017-01-01-plugin_delete.md
│   │   │   └── 2017-01-01-plugin_info_by_id.md
│   │   ├── Strategy/
│   │   │   ├── 2017-01-01-metric_tmplist.md
│   │   │   ├── 2017-01-01-strategy_create.md
│   │   │   ├── 2017-01-01-strategy_delete.md
│   │   │   ├── 2017-01-01-strategy_info_by_id.md
│   │   │   ├── 2017-01-01-strategy_list.md
│   │   │   └── 2017-01-01-strategy_update.md
│   │   ├── Team/
│   │   │   ├── 2017-01-01-team_create.md
│   │   │   ├── 2017-01-01-team_delete_by_id.md
│   │   │   ├── 2017-01-01-team_info_by_id.md
│   │   │   ├── 2017-01-01-team_info_by_name.md
│   │   │   ├── 2017-01-01-team_list.md
│   │   │   ├── 2017-01-01-team_update.md
│   │   │   └── 2018-11-19-add-user-to-team.md
│   │   ├── Template/
│   │   │   ├── 2017-01-01-tpl_action_create.md
│   │   │   ├── 2017-01-01-tpl_action_update.md
│   │   │   ├── 2017-01-01-tpl_create.md
│   │   │   ├── 2017-01-01-tpl_delete.md
│   │   │   ├── 2017-01-01-tpl_hgp_list.md
│   │   │   ├── 2017-01-01-tpl_info_by_id.md
│   │   │   ├── 2017-01-01-tpl_list.md
│   │   │   └── 2017-01-01-tpl_update.md
│   │   └── User/
│   │       ├── 2017-01-01-user_change_password.md
│   │       ├── 2017-01-01-user_create.md
│   │       ├── 2017-01-01-user_current.md
│   │       ├── 2017-01-01-user_get_info_by_id.md
│   │       ├── 2017-01-01-user_get_info_by_name.md
│   │       ├── 2017-01-01-user_get_teams.md
│   │       ├── 2017-01-01-user_is_in_teams.md
│   │       ├── 2017-01-01-user_list.md
│   │       ├── 2017-01-01-user_login.md
│   │       ├── 2017-01-01-user_logout.md
│   │       ├── 2017-01-01-user_update.md
│   │       └── 2019-04-14-update-specific-user.md
│   ├── assets.css
│   ├── assets.js
│   ├── doc/
│   │   ├── admin.html
│   │   ├── admin.html.json
│   │   ├── aggregator.html
│   │   ├── aggregator.html.json
│   │   ├── alarm.html
│   │   ├── alarm.html.json
│   │   ├── expression.html
│   │   ├── expression.html.json
│   │   ├── graph.html
│   │   ├── graph.html.json
│   │   ├── host.html
│   │   ├── host.html.json
│   │   ├── hostgroup.html
│   │   ├── hostgroup.html.json
│   │   ├── nodata.html
│   │   ├── nodata.html.json
│   │   ├── plugin.html
│   │   ├── plugin.html.json
│   │   ├── team.html
│   │   ├── team.html.json
│   │   ├── template.html
│   │   ├── template.html.json
│   │   ├── user.html
│   │   └── user.html.json
│   ├── index.html
│   └── robots.txt
├── g/
│   ├── g.go
│   ├── tool.go
│   └── tool_test.go
├── go.mod
├── go.sum
├── main.go
├── modules/
│   ├── agent/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   ├── builtin.go
│   │   │   ├── collector.go
│   │   │   ├── ips.go
│   │   │   ├── plugin.go
│   │   │   └── reporter.go
│   │   ├── funcs/
│   │   │   ├── agent.go
│   │   │   ├── checker.go
│   │   │   ├── common.go
│   │   │   ├── cpustat.go
│   │   │   ├── dfstat.go
│   │   │   ├── diskstats.go
│   │   │   ├── du.go
│   │   │   ├── du_test.go
│   │   │   ├── funcs.go
│   │   │   ├── gpu.go
│   │   │   ├── ifstat.go
│   │   │   ├── kernel.go
│   │   │   ├── loadavg.go
│   │   │   ├── meminfo.go
│   │   │   ├── netstat.go
│   │   │   ├── portstat.go
│   │   │   ├── procs.go
│   │   │   ├── snmp.go
│   │   │   ├── sockstat.go
│   │   │   └── urlstat.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── const.go
│   │   │   ├── g.go
│   │   │   ├── logger.go
│   │   │   ├── rpc.go
│   │   │   ├── tool.go
│   │   │   ├── transfer.go
│   │   │   ├── var.go
│   │   │   └── var_test.go
│   │   ├── http/
│   │   │   ├── admin.go
│   │   │   ├── cpu.go
│   │   │   ├── df.go
│   │   │   ├── health.go
│   │   │   ├── http.go
│   │   │   ├── iostat.go
│   │   │   ├── kernel.go
│   │   │   ├── memory.go
│   │   │   ├── page.go
│   │   │   ├── plugin.go
│   │   │   ├── push.go
│   │   │   ├── run.go
│   │   │   └── system.go
│   │   ├── main.go
│   │   ├── plugins/
│   │   │   ├── plugins.go
│   │   │   ├── reader.go
│   │   │   └── scheduler.go
│   │   ├── public/
│   │   │   ├── css/
│   │   │   │   ├── font-awesome/
│   │   │   │   │   ├── css/
│   │   │   │   │   │   └── archive/
│   │   │   │   │   │       ├── font-awesome-ie7.css
│   │   │   │   │   │       └── font-awesome.css
│   │   │   │   │   └── font/
│   │   │   │   │       └── FontAwesome.otf
│   │   │   │   ├── g.css
│   │   │   │   ├── odometer.css
│   │   │   │   ├── pages/
│   │   │   │   │   └── dashboard.css
│   │   │   │   └── style.css
│   │   │   ├── index.html
│   │   │   └── js/
│   │   │       ├── base.js
│   │   │       ├── bootstrap.js
│   │   │       ├── dashboard.js
│   │   │       ├── jquery.js
│   │   │       └── odometer.js
│   │   └── version.go
│   ├── aggregator/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   ├── computer.go
│   │   │   ├── query.go
│   │   │   ├── run.go
│   │   │   ├── run_test.go
│   │   │   ├── updater.go
│   │   │   └── worker.go
│   │   ├── db/
│   │   │   ├── db.go
│   │   │   └── reader.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── g.go
│   │   │   └── items.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── http.go
│   │   │   └── proc.go
│   │   ├── main.go
│   │   ├── sdk/
│   │   │   ├── sdk.go
│   │   │   └── sdk_test.go
│   │   └── version.go
│   ├── alarm/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── api/
│   │   │   ├── links.go
│   │   │   ├── portal.go
│   │   │   ├── portal_test.go
│   │   │   ├── uic.go
│   │   │   └── uic_test.go
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   ├── builder.go
│   │   │   ├── callback.go
│   │   │   ├── combiner.go
│   │   │   ├── event_cleaner.go
│   │   │   ├── event_consumer.go
│   │   │   ├── event_reader.go
│   │   │   ├── im_sender.go
│   │   │   ├── init_sender.go
│   │   │   ├── mail_sender.go
│   │   │   ├── model.go
│   │   │   └── sms_sender.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── eventdto.go
│   │   │   ├── g.go
│   │   │   ├── logger.go
│   │   │   └── redis.go
│   │   ├── gitversion
│   │   ├── http/
│   │   │   ├── controller.go
│   │   │   └── http.go
│   │   ├── main.go
│   │   ├── model/
│   │   │   ├── database.go
│   │   │   ├── event/
│   │   │   │   ├── event.go
│   │   │   │   └── event_operation.go
│   │   │   ├── im.go
│   │   │   ├── mail.go
│   │   │   └── sms.go
│   │   ├── redi/
│   │   │   ├── msg_reader.go
│   │   │   └── msg_writer.go
│   │   └── version.go
│   ├── falcon2p8s/
│   │   ├── .gitignore
│   │   ├── ReadMe.md
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── const.go
│   │   │   ├── g.go
│   │   │   ├── logger.go
│   │   │   └── var.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── cron.go
│   │   │   ├── helper.go
│   │   │   └── http.go
│   │   ├── main.go
│   │   ├── middlewares/
│   │   │   └── scraping.go
│   │   ├── rpc/
│   │   │   ├── model.go
│   │   │   ├── receiver.go
│   │   │   └── rpc.go
│   │   ├── sm.example.yaml
│   │   ├── utils/
│   │   │   └── func.go
│   │   └── version.go
│   ├── gateway/
│   │   └── README.md
│   ├── graph/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── api/
│   │   │   ├── graph.go
│   │   │   └── rpc.go
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   └── clean.go
│   │   ├── doc/
│   │   │   └── README.md
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── db.go
│   │   │   ├── g.go
│   │   │   ├── git.go
│   │   │   ├── logger.go
│   │   │   ├── utils.go
│   │   │   └── utils_test.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── helper.go
│   │   │   ├── http.go
│   │   │   ├── index.go
│   │   │   └── proc.go
│   │   ├── index/
│   │   │   ├── cache.go
│   │   │   ├── index.go
│   │   │   ├── index_update_all_task.go
│   │   │   └── index_update_incr_task.go
│   │   ├── main.go
│   │   ├── proc/
│   │   │   └── proc.go
│   │   ├── rrdtool/
│   │   │   ├── migrate.go
│   │   │   ├── rrdtool.go
│   │   │   ├── sync_disk.go
│   │   │   └── utils.go
│   │   ├── store/
│   │   │   ├── history.go
│   │   │   ├── linkedlist.go
│   │   │   └── store.go
│   │   ├── test/
│   │   │   ├── debug
│   │   │   ├── graph.list
│   │   │   └── http.recv.history
│   │   └── version.go
│   ├── hbs/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── cache/
│   │   │   ├── agents.go
│   │   │   ├── cache.go
│   │   │   ├── expressions.go
│   │   │   ├── groups.go
│   │   │   ├── hosts.go
│   │   │   ├── plugins.go
│   │   │   ├── strategies.go
│   │   │   └── templates.go
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── db/
│   │   │   ├── agent.go
│   │   │   ├── db.go
│   │   │   ├── expression.go
│   │   │   ├── group.go
│   │   │   ├── host.go
│   │   │   ├── plugin.go
│   │   │   ├── strategy.go
│   │   │   └── template.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   └── g.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── http.go
│   │   │   └── proc.go
│   │   ├── main.go
│   │   ├── rpc/
│   │   │   ├── agent.go
│   │   │   ├── hbs.go
│   │   │   └── rpc.go
│   │   └── version.go
│   ├── judge/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   ├── cleaner.go
│   │   │   └── strategy.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── g.go
│   │   │   ├── redis.go
│   │   │   ├── rpc.go
│   │   │   └── var.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── http.go
│   │   │   └── info.go
│   │   ├── main.go
│   │   ├── rpc/
│   │   │   ├── receiver.go
│   │   │   └── rpc.go
│   │   ├── store/
│   │   │   ├── func.go
│   │   │   ├── history.go
│   │   │   ├── judge.go
│   │   │   └── linkedlist.go
│   │   └── version.go
│   ├── nodata/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── cfg.example.json
│   │   ├── collector/
│   │   │   ├── collector.go
│   │   │   └── collector_cron.go
│   │   ├── config/
│   │   │   ├── config.go
│   │   │   ├── config_cron.go
│   │   │   └── service/
│   │   │       ├── db.go
│   │   │       ├── host.go
│   │   │       └── mockcfg.go
│   │   ├── control
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── g.go
│   │   │   ├── git.go
│   │   │   └── proc.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── debug_http.go
│   │   │   ├── http.go
│   │   │   └── proc_http.go
│   │   ├── judge/
│   │   │   ├── judge.go
│   │   │   ├── judge_cron.go
│   │   │   └── status.go
│   │   ├── main.go
│   │   ├── scripts/
│   │   │   ├── debug
│   │   │   └── nodata-db-schema.sql
│   │   ├── sender/
│   │   │   └── sender.go
│   │   └── version.go
│   └── transfer/
│       ├── .gitignore
│       ├── LICENSE
│       ├── NOTICE
│       ├── README.md
│       ├── cfg.example.json
│       ├── control
│       ├── g/
│       │   ├── cfg.go
│       │   ├── g.go
│       │   └── git.go
│       ├── http/
│       │   ├── api.go
│       │   ├── common.go
│       │   ├── debug_http.go
│       │   ├── http.go
│       │   └── proc_http.go
│       ├── main.go
│       ├── proc/
│       │   └── proc.go
│       ├── receiver/
│       │   ├── receiver.go
│       │   ├── rpc/
│       │   │   ├── rpc.go
│       │   │   └── rpc_transfer.go
│       │   └── socket/
│       │       ├── socket.go
│       │       └── socket_telnet.go
│       ├── scripts/
│       │   ├── info
│       │   ├── info.py
│       │   ├── last
│       │   ├── last_raw
│       │   ├── query
│       │   └── query.py
│       ├── sender/
│       │   ├── conn_pools.go
│       │   ├── node_rings.go
│       │   ├── send_queues.go
│       │   ├── send_tasks.go
│       │   ├── sender.go
│       │   └── sender_cron.go
│       ├── test/
│       │   ├── debug
│       │   └── rpcclient.py
│       └── version.go
├── scripts/
│   └── mysql/
│       ├── .gitignore
│       ├── LICENSE
│       ├── NOTICE
│       └── db_schema/
│           ├── 1_uic-db-schema.sql
│           ├── 2_portal-db-schema.sql
│           ├── 3_dashboard-db-schema.sql
│           ├── 4_graph-db-schema.sql
│           └── 5_alarms-db-schema.sql
├── test/
│   └── README.md
├── vagrant/
│   └── Vagrantfile
└── version.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
docs/
outrun/
tmp/
bin/
*.tar.gz
open-falcon


================================================
FILE: .gitignore
================================================
bin/
out/
*.swp
*.swo
*.tar.gz
docs/_site
.idea
open-falcon
build

================================================
FILE: .travis.yml
================================================
sudo: required

language: go

arch:
  - amd64
  - arm64
go:
  - "1.15"

env:
  - DB_USER=root DB_PASSWORD=test123456 DB_HOST=127.0.0.1 DB_PORT=13306 REDIS_HOST=127.0.0.1 REDIS_PORT=16379 API_PORT=18080 API_HOST=127.0.0.1

services:
  - docker

before_install:
  - tmpdaemon=$(mktemp)
  - sudo jq '."registry-mirrors" += ["https://mirror.gcr.io"]' /etc/docker/daemon.json > $tmpdaemon
  - sudo mv $tmpdaemon /etc/docker/daemon.json
  - sudo systemctl daemon-reload
  - sudo systemctl restart docker
  - docker system info

script:
  - go get -u github.com/go-sql-driver/mysql
  - make fmt
  - make fmt-check
  - make misspell-check
  - make all
  - bash ./docker_test.sh

after_success:
  - go test -race -coverprofile=coverage.txt -covermode=atomic github.com/open-falcon/falcon-plus/modules/api/test
  - bash <(curl -s https://codecov.io/bash)


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct

## 1. Purpose

A primary goal of Open-Falcon is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof).

This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior.

We invite all those who participate in Open-Falcon to help us create safe and positive experiences for everyone.

## 2. Open Source Citizenship

A supplemental goal of this Code of Conduct is to increase open source citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community.

Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society.

If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know.

## 3. Expected Behavior

The following behaviors are expected and requested of all community members:

*   Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community.
*   Exercise consideration and respect in your speech and actions.
*   Attempt collaboration before conflict.
*   Refrain from demeaning, discriminatory, or harassing behavior and speech.
*   Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential.
*   Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations.

## 4. Unacceptable Behavior

The following behaviors are considered harassment and are unacceptable within our community:

*   Violence, threats of violence or violent language directed against another person.
*   Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language.
*   Posting or displaying sexually explicit or violent material.
*   Posting or threatening to post other people’s personally identifying information ("doxing").
*   Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability.
*   Inappropriate photography or recording.
*   Inappropriate physical contact. You should have someone’s consent before touching them.
*   Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances.
*   Deliberate intimidation, stalking or following (online or in person).
*   Advocating for, or encouraging, any of the above behavior.
*   Sustained disruption of community events, including talks and presentations.

## 5. Consequences of Unacceptable Behavior

Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated.

Anyone asked to stop unacceptable behavior is expected to comply immediately.

If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event).

## 6. Reporting Guidelines

If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. root@open-falcon.com.



Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.

## 7. Addressing Grievances

If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify Open Falcon with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies.



## 8. Scope

We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues–online and in-person–as well as in all one-on-one communications pertaining to community business.

This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members.

## 9. Contact info

root@open-falcon.com

## 10. License and attribution

This Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/).

Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy).

Retrieved on November 22, 2016 from [http://citizencodeofconduct.org/](http://citizencodeofconduct.org/)


================================================
FILE: CONTRIBUTING.md
================================================
### COMMUNITY
Open-Falcon is developed in the open. Here are some of the channels we use to communicate and contribute:

**Mailing lists:**
- [openfalcon-users](https://groups.google.com/forum/#!forum/openfalcon-users) – for discussions around openfalcon usage and community support
- [openfalcon-developers](https://groups.google.com/forum/#!forum/openfalcon-developers) – for discussions around openfalcon development

**Issue tracker:** 
- Use the GitHub issue tracker for the various [Open-Falcon repositories](http://github.com/open-falcon) to file bugs and features request. If you need support, please send your questions to the [openfalcon-users](https://groups.google.com/forum/#!forum/openfalcon-users) mailing list rather than filing a GitHub issue.

*Please do not ask individual project members for support. Use the channels above instead, where the whole community can help you and benefit from the solutions provided. If community support is insufficient for your situation, please refer to the Commercial Support section below.*

### CONTRIBUTING
We welcome community contributions! Open-Falcon uses GitHub to manage reviews of pull requests.

- If you have a trivial fix or improvement, go ahead and create a pull request, addressing (with `@...`) the maintainer of this repository in the description of the pull request.
- If you plan to do something more involved, first discuss your ideas on our [mailing list](https://groups.google.com/forum/#!forum/openfalcon-developers). This will avoid unnecessary work and surely give you and us a good deal of inspiration.


================================================
FILE: Dockerfile
================================================
# Build container;
FROM openfalcon/makegcc-golang:1.15-alpine
LABEL maintainer laiwei.ustc@gmail.com
USER root

ENV FALCON_DIR=/open-falcon PROJ_PATH=${GOPATH}/src/github.com/open-falcon/falcon-plus

RUN mkdir -p $FALCON_DIR && \
    mkdir -p $FALCON_DIR/logs && \
    apk add --no-cache ca-certificates bash git supervisor
COPY . ${PROJ_PATH}

WORKDIR ${PROJ_PATH}
RUN make all \
    && make pack4docker \
    && tar -zxf open-falcon-v*.tar.gz -C ${FALCON_DIR} \
    && rm -rf ${PROJ_PATH}

# Final container;
FROM alpine:3.13
LABEL maintainer laiwei.ustc@gmail.com
USER root

ENV FALCON_DIR=/open-falcon

RUN mkdir -p $FALCON_DIR/logs && \
    apk add --no-cache ca-certificates bash git supervisor

ADD docker/supervisord.conf /etc/supervisord.conf

COPY --from=0 ${FALCON_DIR} ${FALCON_DIR}

EXPOSE 8433 8080
WORKDIR ${FALCON_DIR}

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]


================================================
FILE: Dockerfile.module
================================================
# Build container;
FROM openfalcon/makegcc-golang:1.15-alpine
LABEL maintainer laiwei.ustc@gmail.com
USER root

ENV FALCON_DIR=/open-falcon PROJ_PATH=${GOPATH}/src/github.com/open-falcon/falcon-plus

RUN mkdir -p $FALCON_DIR && \
    apk add --no-cache ca-certificates git

COPY . ${PROJ_PATH}

WORKDIR ${PROJ_PATH}

ARG MODULE

RUN make $MODULE \
    && make pack4docker CMD=$MODULE \
    && tar -zxf open-falcon-v*.tar.gz -C ${FALCON_DIR} \
    && rm -rf ${PROJ_PATH}

# Final container;
FROM alpine:3.13
LABEL maintainer laiwei.ustc@gmail.com
USER root

ENV FALCON_DIR=/open-falcon

RUN mkdir -p $FALCON_DIR/logs && \
    apk update && \
    apk add --no-cache ca-certificates bash git iproute2

COPY --from=0 ${FALCON_DIR} ${FALCON_DIR}

EXPOSE 8433 8080
WORKDIR ${FALCON_DIR}


================================================
FILE: Dockerfile_arm64
================================================
FROM jimmytinsley/makegcc-golang
LABEL maintainer laiwei.ustc@gmail.com
USER root

ENV FALCON_DIR=/open-falcon PROJ_PATH=${GOPATH}/src/github.com/open-falcon/falcon-plus

RUN mkdir -p $FALCON_DIR && \
    mkdir -p $FALCON_DIR/logs && \
    apk add --no-cache ca-certificates bash git supervisor
COPY . ${PROJ_PATH}

WORKDIR ${PROJ_PATH}
RUN make all \
    && make pack4docker \
    && tar -zxf open-falcon-v*.tar.gz -C ${FALCON_DIR} \
    && rm -rf ${PROJ_PATH}

# Final container;
FROM alpine:3.7
LABEL maintainer laiwei.ustc@gmail.com
USER root

ENV FALCON_DIR=/open-falcon

RUN mkdir -p $FALCON_DIR/logs && \
    apk add --no-cache ca-certificates bash git supervisor

ADD docker/supervisord.conf /etc/supervisord.conf

COPY --from=0 ${FALCON_DIR} ${FALCON_DIR}

EXPOSE 8433 8080
WORKDIR ${FALCON_DIR}

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]



================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: Makefile
================================================
CMD = agent aggregator graph hbs judge nodata transfer gateway api alarm falcon2p8s
TARGET = open-falcon
PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
GOFILES := $(shell find . -name "*.go" -type f -not -path "./vendor/*")
GOFMT ?= gofmt "-s"
VERSION := $(shell cat VERSION)

all: $(CMD) $(TARGET)

.PHONY: misspell-check
misspell-check:
	@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
		go get -u github.com/client9/misspell/cmd/misspell; \
	fi
	misspell -error $(GOFILES)

.PHONY: misspell
misspell:
	@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
		go get -u github.com/client9/misspell/cmd/misspell; \
	fi
	misspell -w $(GOFILES)

vet:
	go vet $(PACKAGES)

fmt:
	$(GOFMT) -w $(GOFILES)

.PHONY: fmt-check
fmt-check:
	# get all go files and run go fmt on them
	@diff=$$($(GOFMT) -d $(GOFILES)); \
	if [ -n "$$diff" ]; then \
		echo "Please run 'make fmt' and commit the result:"; \
		echo "$${diff}"; \
		exit 1; \
	fi;

$(CMD):
	if [ $@ = "gateway" ]; then \
		GO111MODULE=on go build -ldflags "-X main.BinaryName=gateway -X main.GitCommit=`git rev-parse --short HEAD` -X main.Version=$(VERSION)" \
			-o bin/gateway/falcon-gateway ./modules/transfer ; \
	else \
		GO111MODULE=on go build -ldflags "-X main.BinaryName=$@ -X main.GitCommit=`git rev-parse --short HEAD` -X main.Version=$(VERSION)" \
			-o bin/$@/falcon-$@ ./modules/$@ ; \
	fi

.PHONY: $(TARGET)
$(TARGET): $(GOFILES)
	GO111MODULE=on go build -ldflags "-X main.BinaryName=Open-Falcon -X main.GitCommit=`git rev-parse --short HEAD` -X main.Version=$(VERSION)" -o open-falcon

checkbin: bin/ config/ open-falcon

pack: checkbin
	@if [ -e out ] ; then rm -rf out; fi
	@mkdir out
	@$(foreach var,$(CMD),mkdir -p ./out/$(var)/bin;)
	@$(foreach var,$(CMD),mkdir -p ./out/$(var)/config;)
	@$(foreach var,$(CMD),mkdir -p ./out/$(var)/logs;)
	@$(foreach var,$(CMD),cp ./config/$(var).json ./out/$(var)/config/cfg.json;)
	@$(foreach var,$(CMD),cp ./bin/$(var)/falcon-$(var) ./out/$(var)/bin;)
	@cp -r ./modules/agent/public ./out/agent/
	@(cd ./out && ln -s ./agent/public ./public)
	@(cd ./out && mkdir -p ./agent/plugin && ln -s ./agent/plugin ./plugin)
	@cp -r ./modules/api/data ./out/api/
	@mkdir out/graph/data
	@bash ./config/confgen.sh
	@cp $(TARGET) ./out/$(TARGET)
	tar -C out -zcf open-falcon-v$(VERSION).tar.gz .
	@rm -rf out

pack4docker: checkbin
	@if [ -e out ] ; then rm -rf out; fi
	@mkdir out
	@$(foreach var,$(CMD),mkdir -p ./out/$(var)/bin;)
	@$(foreach var,$(CMD),mkdir -p ./out/$(var)/config;)
	@$(foreach var,$(CMD),mkdir -p ./out/$(var)/logs;)
	@$(foreach var,$(CMD),cp ./config/$(var).json ./out/$(var)/config/cfg.json;)
	@$(foreach var,$(CMD),cp ./bin/$(var)/falcon-$(var) ./out/$(var)/bin;)
	@if expr "$(CMD)" : "agent" > /dev/null; then \
		(cp -r ./modules/agent/public ./out/agent/); \
		(cd ./out && ln -s ./agent/public ./public); \
		(cd ./out && mkdir -p ./agent/plugin && ln -s ./agent/plugin ./plugin); \
	fi
	@if expr "$(CMD)" : "api" > /dev/null; then \
		cp -r ./modules/api/data ./out/api/; \
	fi
	@if expr "$(CMD)" : "graph" > /dev/null; then \
		mkdir out/graph/data; \
	fi
	@cp ./docker/ctrl.sh ./out/ && chmod +x ./out/ctrl.sh
	@cp $(TARGET) ./out/$(TARGET)
	tar -C out -zcf open-falcon-v$(VERSION).tar.gz .
	@rm -rf out

.PHONY: test
test:
	@go test ./modules/api/test

clean:
	@rm -rf ./bin
	@rm -rf ./out
	@rm -rf ./$(TARGET)
	@rm -rf open-falcon-v$(VERSION).tar.gz

.PHONY: clean all agent aggregator graph hbs judge nodata transfer gateway api alarm


================================================
FILE: NOTICE
================================================
Open-Falcon

Copyright (c) 2014-2017 Xiaomi, Inc. All Rights Reserved.

This product is licensed to you under the Apache License, Version 2.0 (the "License").
You may not use this product except in compliance with the License.

This product may include a number of subcomponents with separate copyright notices
and license terms. Your use of these subcomponents is subject to the terms and
conditions of the subcomponent's license, as noted in the LICENSE file.


================================================
FILE: README.md
================================================
# Falcon+

![Open-Falcon](./logo.png)

[![Build Status](https://travis-ci.org/open-falcon/falcon-plus.svg?branch=plus-dev)](https://travis-ci.org/open-falcon/falcon-plus)
[![License](https://img.shields.io/badge/LICENSE-Apache2.0-ff69b4.svg)](http://www.apache.org/licenses/LICENSE-2.0.html)
[![Backers on Open Collective](https://opencollective.com/falcon-plus/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/falcon-plus/sponsors/badge.svg)](#sponsors)

# Notice

If you are heavily using k8s and adopting microservices architecture, we recommend you to upgrade to use [Nightingale](https://github.com/ccfos/nightingale) building your modern monitoring system.

- [Nightingale](https://github.com/ccfos/nightingale) is an enterprise-level cloud-native monitoring tool, which can be used as drop-in replacement of Prometheus for alerting and management.
- [Categraf](https://github.com/flashcatcloud/categraf) is one-stop telemetry collector for Nightingale / Prometheus / M3DB / VictoriaMetrics / Thanos / Influxdb / TDengine.

It is recommended that you use [FlashDuty](https://flashcat.cloud/product/flashduty?from=categraf) as the OnCall system to realize alarm aggregation convergence, claiming, upgrading, scheduling, and coordination, so that the alarm can be reached efficiently and ensure that the alarm processing is not missed.


# Documentations

- [Usage](http://book.open-falcon.org)
- [Open-Falcon API](http://open-falcon.org/falcon-plus)

# Prerequisite

- Git >= 1.7.5
- Go >= 1.6

# Getting Started

## Docker

Please refer to ./docker/[README.md](https://github.com/open-falcon/falcon-plus/blob/master/docker/README.md).

## Build from source
**before start, please make sure you prepared this:**

```
yum install -y redis
yum install -y mysql-server

```

*NOTE: be sure to check redis and mysql-server have successfully started.*

And then

```
# Please make sure that you have set `$GOPATH` and `$GOROOT` correctly.
# If you have not golang in your host, please follow [https://golang.org/doc/install] to install golang.

mkdir -p $GOPATH/src/github.com/open-falcon
cd $GOPATH/src/github.com/open-falcon
git clone https://github.com/open-falcon/falcon-plus.git

```

**And do not forget to init the database first (if you have not loaded the database schema before)**

```
cd $GOPATH/src/github.com/open-falcon/falcon-plus/scripts/mysql/db_schema/
mysql -h 127.0.0.1 -u root -p < 1_uic-db-schema.sql
mysql -h 127.0.0.1 -u root -p < 2_portal-db-schema.sql
mysql -h 127.0.0.1 -u root -p < 3_dashboard-db-schema.sql
mysql -h 127.0.0.1 -u root -p < 4_graph-db-schema.sql
mysql -h 127.0.0.1 -u root -p < 5_alarms-db-schema.sql
```

**NOTE: if you are upgrading from v0.1 to v0.2.0(or above),then**. [More upgrading instruction](http://www.jianshu.com/p/6fb2c2b4d030)

    mysql -h 127.0.0.1 -u root -p < 5_alarms-db-schema.sql

# Compilation

```
cd $GOPATH/src/github.com/open-falcon/falcon-plus/

# make all modules
make all

# make specified module
make agent

# pack all modules
make pack
```

* *after `make pack` you will got `open-falcon-vx.x.x.tar.gz`*
* *if you want to edit configure file for each module, you can edit `config/xxx.json` before you do `make pack`*

#  Unpack and Decompose

```
export WorkDir="$HOME/open-falcon"
mkdir -p $WorkDir
tar -xzvf open-falcon-vx.x.x.tar.gz -C $WorkDir
cd $WorkDir
```

# Start all modules in single host
```
cd $WorkDir
./open-falcon start

# check modules status
./open-falcon check

```

# Run More Open-Falcon Commands

for example:

```
# ./open-falcon [start|stop|restart|check|monitor|reload] module
./open-falcon start agent

./open-falcon check
        falcon-graph         UP           53007
          falcon-hbs         UP           53014
        falcon-judge         UP           53020
     falcon-transfer         UP           53026
       falcon-nodata         UP           53032
   falcon-aggregator         UP           53038
        falcon-agent         UP           53044
      falcon-gateway         UP           53050
          falcon-api         UP           53056
        falcon-alarm         UP           53063
```

* For debugging , You can check `$WorkDir/$moduleName/logs/xxx.log`

# Install Frontend Dashboard
- Follow [this](https://github.com/open-falcon/dashboard).

**NOTE: if you want to use grafana as the dashboard, please check [this](https://github.com/open-falcon/grafana-openfalcon-datasource).**

# Package Release

```
make clean all pack
```

# API Standard
- [API Standard](https://github.com/open-falcon/falcon-plus/blob/master/api-standard.md)


# Q&A

- Any issue or question is welcome, Please feel free to open [github issues](https://github.com/open-falcon/falcon-plus/issues) :)
- [FAQ](http://book.open-falcon.org/zh_0_2/faq/)


## Contributors

This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/open-falcon/falcon-plus/contributors"><img src="https://opencollective.com/falcon-plus/contributors.svg?width=890&button=false" /></a>


================================================
FILE: VERSION
================================================
0.3.x


================================================
FILE: api-standard.md
================================================
# HTTP API建议规范

## 说明
本规范参考阮一峰的《[RESTful API设计指南](http://www.ruanyifeng.com/blog/2014/05/restful_api.html)》编写,部分内容做了适应性的调整和修改。

## 协议
本文档目前只针对HTTP与HTTPS协议,提供参考规范和建议。

## 域名
应尽量将API模块部署在专用域名之下。
```
http://api.open-falcon.com
```

## 版本(Versioning)
应将API版本号放入URL。
```
http://api.open-falcon.com/v1/
```

## 路径(Endpoint)
路径又称``“终点”(endpoint)``,表示API的具体网址。

 路径中以``“/”``区分的每一项都应该是``小写英文单词``,若包含多个单词,需要用``下划线``分隔。
在RESTful架构中,每个网址代表一种``资源(resource)``,所以网址中不应包含动词,如show、delete等。只能有名词,而且所用的名词往往与数据库的表格名对应。

一般来说,数据库中的表都是同种记录的``“集合”(collection)``,所以API中的名词也应该使用``复数``。

以Open-Falcon举例,API模块提供各种关于监控系统的信息,包括数据及报警:
```
· http://api.open-falcon.com/v1/counters
· http://api.open-falcon.com/v1/strategies
· http://api.open-falcon.com/v1/points
```

## HTTP动词
对于资源的具体操作类型,由HTTP动词表示。

常用的HTTP动词有下面五个(括号里是对应的SQL命令)。

```
· GET(SELECT):从服务器取出资源(一项或多项)
· POST(CREATE):在服务器新建一个资源
· PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
· PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)
· DELETE(DELETE):从服务器删除资源
```
PATCH一般不常用,更新资源建议使用```PUT```。

还有两个不常用的动词。
```
HEAD:获取资源的元数据。
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
```

以下是一些例子
```
· GET /v1/users : 获取所有的用户
· GET /v1/users/{int:ID} : 获取指定的用户信息
· POST /v1/users : 新增一个用户
· PUT /v1/users/{int:ID} : 更新某个指定用户的信息(提供用户的全部信息)
· PATCH /v1/users/{int:ID}  : 更新某个指定用户的信息(提供用户的部分信息)
```

## 请求参数、请求体
如果记录数很多,服务器不可能都将他们返回给用户。API应该提供参数,支持过滤结果返回。
下面是一些常见的参数。
```
· ?limit=10 : 指定返回记录的数量
· ?offset=10 : 指定返回记录的开始位置
· ?page=2&per_page=100 : 指定第几页,以及每页的记录数
· ?sortby=name&order=asc : 指定返回结果按照哪个属性排序,以及排序顺序
· ?type_id=1 : 指定筛选条件
```
其中,参数的命名规则为``snake_case``,即单词全部小写,单词间使用下划线分隔。 

参数的设计允许存在``冗余``,即允许API路径和URL参数偶尔有重复。比如,GET /services/ID/domains 与 GET /services?domain_id=ID 的含义是相同的。

另外,参考HTTP协议(1.0版和1.1版)的主要设计者Roy Thomas Fielding所言,任何HTTP请求都允许包含请求体,但发送一个请求体非空的GET请求是没有意义的。因此GET请求请求体应该为``空``。

对于POST、PUT、DELETE请求,若请求体不为空,则请求体格式应该为JSON,如: 
```
{
	"id" : 1,
	"name" : "ZhangSan"
}
```
需要注意的是,JSON中key的命名规则同样需要遵循``snake_case``。 

## 状态码(Status Code)
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
```
· 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
· 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
· 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
· 204 NO CONTENT - [DELETE]:用户删除数据成功。
· 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
· 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
· 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
· 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
· 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
· 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
· 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
· 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
```
状态码的完整列表,参见[这里](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)。

## 返回结果
服务器返回的数据格式,统一为``JSON``。针对资源的不同操作,服务器向用户返回的结果

应该符合以下规范:
```
· GET /collection : 返回资源对象的列表(数组)
· DELETE /collection/resource : 返回如下的json响应,其中data为被删除对象.
· GET /collection/resource : 返回单个资源对象
· POST /collection : 返回新生成的资源对象
· PUT /collection/resource : 返回更改后的完整的资源对象 
```

响应格式统一如下: ``此处草版略复杂,待讨论修正``
```
{
    "code": 200,    // http status code
    "data": data,    // return data if success
    "ret_msg": "return message if failed",    // return message if failed, when success, it's empty
    "debug_msg": "used for debug",    // used for debug when failed,when success, it's emptuy
    "url_manual": "manual url to show if failed",    // manual url to show if failed
    "url_redirect": "used for 3xx results",    // used for 3xx results
    “response_type": "application/json"    // response body type
}

```


================================================
FILE: cmd/check.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"strings"

	"github.com/open-falcon/falcon-plus/g"
	"github.com/spf13/cobra"
)

var Check = &cobra.Command{
	Use:   "check [Module ...]",
	Short: "Check the status of Open-Falcon modules",
	Long: `
Check if the specified Open-Falcon modules are running.
Modules:
  ` + "all " + strings.Join(g.AllModulesInOrder, " "),
	RunE: check,
}

func check(c *cobra.Command, args []string) error {
	args = g.RmDup(args)

	if len(args) == 0 {
		args = g.AllModulesInOrder
	}

	for _, moduleName := range args {
		if !g.HasModule(moduleName) {
			return fmt.Errorf("%s doesn't exist", moduleName)
		}

		if g.IsRunning(moduleName) {
			fmt.Printf("%20s %10s %15s \n", g.ModuleApps[moduleName], "UP", g.Pid(moduleName))
		} else {
			fmt.Printf("%20s %10s %15s \n", g.ModuleApps[moduleName], "DOWN", "-")
		}
	}

	return nil
}


================================================
FILE: cmd/monitor.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"
	"os/exec"
	"strings"

	"github.com/open-falcon/falcon-plus/g"
	"github.com/spf13/cobra"
)

var Monitor = &cobra.Command{
	Use:   "monitor [Module ...]",
	Short: "Display an Open-Falcon module's log",
	Long: `
Display the log of the specified Open-Falcon module.
A module represents a single node in a cluster.
Modules:
  ` + strings.Join(g.AllModulesInOrder, " "),
	RunE: monitor,
}

func checkMonReq(name string) error {
	if !g.HasModule(name) {
		return fmt.Errorf("%s doesn't exist", name)
	}

	if !g.HasLogfile(name) {
		r := g.Rel(g.LogPath(name))
		return fmt.Errorf("expect logfile: %s", r)
	}

	return nil
}

func monitor(c *cobra.Command, args []string) error {
	if len(args) < 1 {
		return c.Usage()
	}
	var tailArgs []string = []string{"-f"}
	for _, moduleName := range args {
		if err := checkMonReq(moduleName); err != nil {
			return err
		}

		tailArgs = append(tailArgs, g.LogPath(moduleName))
	}
	cmd := exec.Command("tail", tailArgs...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}


================================================
FILE: cmd/reload.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import "github.com/spf13/cobra"

var Reload = &cobra.Command{
	Use:   "reload [Module ...]",
	Short: "Reload an Open-Falcon module's configuration file",
	Long: `
Reload the configuration file of the specified Open-Falcon module.
A module represents a single node in a cluster.
Modules:
  `,
	RunE: reload,
}

func reload(c *cobra.Command, args []string) error {
	if len(args) != 1 {
		return c.Usage()
	}
	return nil
}


================================================
FILE: cmd/restart.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"strings"
	"time"

	"github.com/open-falcon/falcon-plus/g"
	"github.com/spf13/cobra"
)

var Restart = &cobra.Command{
	Use:   "restart [Module ...]",
	Short: "Restart Open-Falcon modules",
	Long: `
Restart the specified Open-Falcon modules and run until a stop command is received.
A module represents a single node in a cluster.
Modules:
  ` + "all " + strings.Join(g.AllModulesInOrder, " "),
	RunE: restart,
}

func restart(c *cobra.Command, args []string) error {
	args = g.RmDup(args)

	if len(args) == 0 {
		args = g.AllModulesInOrder
	}

	for _, moduleName := range args {
		if err := stop(c, []string{moduleName}); err != nil {
			return err
		}
		if strings.Contains(moduleName, "graph") {
			time.Sleep(2 * time.Second)
		} else {
			time.Sleep(1 * time.Second)
		}
		if err := start(c, []string{moduleName}); err != nil {
			return err
		}
	}
	return nil
}


================================================
FILE: cmd/start.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
	"time"

	"github.com/open-falcon/falcon-plus/g"
	"github.com/spf13/cobra"
)

var Start = &cobra.Command{
	Use:   "start [Module ...]",
	Short: "Start Open-Falcon modules",
	Long: `
Start the specified Open-Falcon modules and run until a stop command is received.
A module represents a single node in a cluster.
Modules:
	` + "all " + strings.Join(g.AllModulesInOrder, " "),
	RunE:          start,
	SilenceUsage:  true,
	SilenceErrors: true,
}

var PreqOrderFlag bool
var ConsoleOutputFlag bool

func cmdArgs(name string) []string {
	return []string{"-c", g.Cfg(name)}
}

func openLogFile(name string) (*os.File, error) {
	logDir := g.LogDir(name)
	if err := os.MkdirAll(logDir, 0755); err != nil {
		return nil, err
	}

	logPath := g.LogPath(name)
	logOutput, err := os.OpenFile(logPath, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
	if err != nil {
		return nil, err
	}

	return logOutput, nil
}

func execModule(co bool, name string) error {
	cmd := exec.Command(g.Bin(name), cmdArgs(name)...)

	if co {
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		return cmd.Run()
	}

	logOutput, err := openLogFile(name)
	if err != nil {
		return err
	}
	defer logOutput.Close()
	cmd.Stdout = logOutput
	cmd.Stderr = logOutput
	return cmd.Start()
}

func checkStartReq(name string) error {
	if !g.HasModule(name) {
		return fmt.Errorf("%s doesn't exist", name)
	}

	if !g.HasCfg(name) {
		r := g.Rel(g.Cfg(name))
		return fmt.Errorf("expect config file: %s", r)
	}

	return nil
}

func isStarted(name string) bool {
	ticker := time.NewTicker(time.Millisecond * 100)
	defer ticker.Stop()
	timeout := time.After(time.Second)
	for {
		select {
		case <-ticker.C:
			if g.IsRunning(name) {
				return true
			}
		case <-timeout:
			return false
		}
	}
}

func start(c *cobra.Command, args []string) error {
	args = g.RmDup(args)

	if PreqOrderFlag {
		args = g.PreqOrder(args)
	}

	if len(args) == 0 {
		args = g.AllModulesInOrder
	}

	for _, moduleName := range args {
		if err := checkStartReq(moduleName); err != nil {
			return err
		}

		// Skip starting if the module is already running
		if g.IsRunning(moduleName) {
			fmt.Print("[", g.ModuleApps[moduleName], "] ", g.Pid(moduleName), "\n")
			continue
		}

		if err := execModule(ConsoleOutputFlag, moduleName); err != nil {
			return err
		}

		if isStarted(moduleName) {
			fmt.Print("[", g.ModuleApps[moduleName], "] ", g.Pid(moduleName), "\n")
			continue
		}

		return fmt.Errorf("[%s] failed to start", g.ModuleApps[moduleName])
	}
	return nil
}


================================================
FILE: cmd/stop.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"
	"os/exec"
	"strings"

	"github.com/open-falcon/falcon-plus/g"
	"github.com/spf13/cobra"
)

var Stop = &cobra.Command{
	Use:   "stop [Module ...]",
	Short: "Stop Open-Falcon modules",
	Long: `
Stop the specified Open-Falcon modules.
A module represents a single node in a cluster.
Modules:
  ` + "all " + strings.Join(g.AllModulesInOrder, " "),
	RunE: stop,
}

func stop(c *cobra.Command, args []string) error {
	args = g.RmDup(args)

	if len(args) == 0 {
		args = g.AllModulesInOrder
	}

	for _, moduleName := range args {
		if !g.HasModule(moduleName) {
			return fmt.Errorf("%s doesn't exist", moduleName)
		}

		if !g.IsRunning(moduleName) {
			fmt.Print("[", g.ModuleApps[moduleName], "] down\n")
			continue
		}

		cmd := exec.Command("kill", "-TERM", g.Pid(moduleName))
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		err := cmd.Run()
		if err == nil {
			fmt.Print("[", g.ModuleApps[moduleName], "] down\n")
			continue
		}
		return err
	}
	return nil
}


================================================
FILE: common/.gitignore
================================================
*.swp
*.swo
/var
.DS_Store
*.iml
*.idea



================================================
FILE: common/LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: common/NOTICE
================================================
Open-Falcon

Copyright (c) 2014-2015 Xiaomi, Inc. All Rights Reserved.

This product is licensed to you under the Apache License, Version 2.0 (the "License").
You may not use this product except in compliance with the License.

This product may include a number of subcomponents with separate copyright notices
and license terms. Your use of these subcomponents is subject to the terms and
conditions of the subcomponent's license, as noted in the LICENSE file.


================================================
FILE: common/backend_pool/rpc_backends.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package backend_pool

import (
	"fmt"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
	"sync"
	"time"

	connp "github.com/toolkits/conn_pool"
	rpcpool "github.com/toolkits/conn_pool/rpc_conn_pool"
)

// ConnPools Manager
type SafeRpcConnPools struct {
	sync.RWMutex
	M           map[string]*connp.ConnPool
	MaxConns    int
	MaxIdle     int
	ConnTimeout int
	CallTimeout int
}

func CreateSafeRpcConnPools(maxConns, maxIdle, connTimeout, callTimeout int, cluster []string) *SafeRpcConnPools {
	cp := &SafeRpcConnPools{M: make(map[string]*connp.ConnPool), MaxConns: maxConns, MaxIdle: maxIdle,
		ConnTimeout: connTimeout, CallTimeout: callTimeout}

	ct := time.Duration(cp.ConnTimeout) * time.Millisecond
	for _, address := range cluster {
		if _, exist := cp.M[address]; exist {
			continue
		}
		cp.M[address] = createOneRpcPool(address, address, ct, maxConns, maxIdle)
	}

	return cp
}

func CreateSafeJsonrpcConnPools(maxConns, maxIdle, connTimeout, callTimeout int, cluster []string) *SafeRpcConnPools {
	cp := &SafeRpcConnPools{M: make(map[string]*connp.ConnPool), MaxConns: maxConns, MaxIdle: maxIdle,
		ConnTimeout: connTimeout, CallTimeout: callTimeout}

	ct := time.Duration(cp.ConnTimeout) * time.Millisecond
	for _, address := range cluster {
		if _, exist := cp.M[address]; exist {
			continue
		}
		cp.M[address] = createOneJsonrpcPool(address, address, ct, maxConns, maxIdle)
	}

	return cp
}

// 同步发送, 完成发送或超时后 才能返回
func (this *SafeRpcConnPools) Call(addr, method string, args interface{}, resp interface{}) error {
	connPool, exists := this.Get(addr)
	if !exists {
		return fmt.Errorf("%s has no connection pool", addr)
	}

	conn, err := connPool.Fetch()
	if err != nil {
		return fmt.Errorf("%s get connection fail: conn %v, err %v. proc: %s", addr, conn, err, connPool.Proc())
	}

	rpcClient := conn.(*rpcpool.RpcClient)
	callTimeout := time.Duration(this.CallTimeout) * time.Millisecond

	done := make(chan error, 1)
	go func() {
		done <- rpcClient.Call(method, args, resp)
	}()

	select {
	case <-time.After(callTimeout):
		connPool.ForceClose(conn)
		return fmt.Errorf("%s, call timeout", addr)
	case err = <-done:
		if err != nil {
			connPool.ForceClose(conn)
			err = fmt.Errorf("%s, call failed, err %v. proc: %s", addr, err, connPool.Proc())
		} else {
			connPool.Release(conn)
		}
		return err
	}
}

func (this *SafeRpcConnPools) Get(address string) (*connp.ConnPool, bool) {
	this.RLock()
	defer this.RUnlock()
	p, exists := this.M[address]
	return p, exists
}

func (this *SafeRpcConnPools) Destroy() {
	this.Lock()
	defer this.Unlock()
	addresses := make([]string, 0, len(this.M))
	for address := range this.M {
		addresses = append(addresses, address)
	}

	for _, address := range addresses {
		this.M[address].Destroy()
		delete(this.M, address)
	}
}

func (this *SafeRpcConnPools) Proc() []string {
	procs := []string{}
	for _, cp := range this.M {
		procs = append(procs, cp.Proc())
	}
	return procs
}

func createOneRpcPool(name string, address string, connTimeout time.Duration, maxConns int, maxIdle int) *connp.ConnPool {
	p := connp.NewConnPool(name, address, int32(maxConns), int32(maxIdle))
	p.New = func(connName string) (connp.NConn, error) {
		_, err := net.ResolveTCPAddr("tcp", p.Address)
		if err != nil {
			return nil, err
		}

		conn, err := net.DialTimeout("tcp", p.Address, connTimeout)
		if err != nil {
			return nil, err
		}

		return rpcpool.NewRpcClient(rpc.NewClient(conn), connName), nil
	}

	return p
}

func createOneJsonrpcPool(name string, address string, connTimeout time.Duration, maxConns int, maxIdle int) *connp.ConnPool {
	p := connp.NewConnPool(name, address, int32(maxConns), int32(maxIdle))
	p.New = func(connName string) (connp.NConn, error) {
		_, err := net.ResolveTCPAddr("tcp", p.Address)
		if err != nil {
			return nil, err
		}

		conn, err := net.DialTimeout("tcp", p.Address, connTimeout)
		if err != nil {
			return nil, err
		}

		return rpcpool.NewRpcClientWithCodec(jsonrpc.NewClientCodec(conn), connName), nil
	}

	return p
}


================================================
FILE: common/backend_pool/tsdb_backends.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package backend_pool

import (
	"fmt"
	"net"
	"time"

	connp "github.com/toolkits/conn_pool"
)

// TSDB
type TsdbClient struct {
	cli  *struct{ net.Conn }
	name string
}

func (t TsdbClient) Name() string {
	return t.name
}

func (t TsdbClient) Closed() bool {
	return t.cli.Conn == nil
}

func (t TsdbClient) Close() error {
	if t.cli != nil {
		err := t.cli.Close()
		t.cli.Conn = nil
		return err
	}
	return nil
}

func newTsdbConnPool(address string, maxConns int, maxIdle int, connTimeout int) *connp.ConnPool {
	pool := connp.NewConnPool("tsdb", address, int32(maxConns), int32(maxIdle))

	pool.New = func(name string) (connp.NConn, error) {
		_, err := net.ResolveTCPAddr("tcp", address)
		if err != nil {
			return nil, err
		}

		conn, err := net.DialTimeout("tcp", address, time.Duration(connTimeout)*time.Millisecond)
		if err != nil {
			return nil, err
		}

		return TsdbClient{
			cli:  &struct{ net.Conn }{conn},
			name: name,
		}, nil
	}

	return pool
}

type TsdbConnPoolHelper struct {
	p           *connp.ConnPool
	maxConns    int
	maxIdle     int
	connTimeout int
	callTimeout int
	address     string
}

func NewTsdbConnPoolHelper(address string, maxConns, maxIdle, connTimeout, callTimeout int) *TsdbConnPoolHelper {
	return &TsdbConnPoolHelper{
		p:           newTsdbConnPool(address, maxConns, maxIdle, connTimeout),
		maxConns:    maxConns,
		maxIdle:     maxIdle,
		connTimeout: connTimeout,
		callTimeout: callTimeout,
		address:     address,
	}
}

func (t *TsdbConnPoolHelper) Send(data []byte) (err error) {
	conn, err := t.p.Fetch()
	if err != nil {
		return fmt.Errorf("get connection fail: err %v. proc: %s", err, t.p.Proc())
	}

	cli := conn.(TsdbClient).cli

	done := make(chan error, 1)
	go func() {
		_, err = cli.Write(data)
		done <- err
	}()

	select {
	case <-time.After(time.Duration(t.callTimeout) * time.Millisecond):
		t.p.ForceClose(conn)
		return fmt.Errorf("%s, call timeout", t.address)
	case err = <-done:
		if err != nil {
			t.p.ForceClose(conn)
			err = fmt.Errorf("%s, call failed, err %v. proc: %s", t.address, err, t.p.Proc())
		} else {
			t.p.Release(conn)
		}
		return err
	}
}

func (t *TsdbConnPoolHelper) Destroy() {
	if t.p != nil {
		t.p.Destroy()
	}
}


================================================
FILE: common/db/db.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package db

// graph.endpoint
type GraphEndpoint struct {
	Id       int64
	Endpoint string
}

// graph.tag_endpoint
type GraphTagEndpoint struct {
	Id         int64
	Tag        string
	EndpointId int64
}

// graph.endpoint_counter
type GraphEndpointCounter struct {
	Id         int64
	EndpointId int64
	Counter    string
}


================================================
FILE: common/model/agent.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
)

type AgentReportRequest struct {
	Hostname      string
	IP            string
	AgentVersion  string
	PluginVersion string
}

func (this *AgentReportRequest) String() string {
	return fmt.Sprintf(
		"<Hostname:%s, IP:%s, AgentVersion:%s, PluginVersion:%s>",
		this.Hostname,
		this.IP,
		this.AgentVersion,
		this.PluginVersion,
	)
}

type AgentUpdateInfo struct {
	LastUpdate    int64
	ReportRequest *AgentReportRequest
}

type AgentHeartbeatRequest struct {
	Hostname string
	Checksum string
}

func (this *AgentHeartbeatRequest) String() string {
	return fmt.Sprintf(
		"<Hostname: %s, Checksum: %s>",
		this.Hostname,
		this.Checksum,
	)
}

type AgentPluginsResponse struct {
	Plugins   []string
	Timestamp int64
}

func (this *AgentPluginsResponse) String() string {
	return fmt.Sprintf(
		"<Plugins:%v, Timestamp:%v>",
		this.Plugins,
		this.Timestamp,
	)
}

// e.g. net.port.listen or proc.num
type BuiltinMetric struct {
	Metric string
	Tags   string
}

func (this *BuiltinMetric) String() string {
	return fmt.Sprintf(
		"%s/%s",
		this.Metric,
		this.Tags,
	)
}

type BuiltinMetricResponse struct {
	Metrics   []*BuiltinMetric
	Checksum  string
	Timestamp int64
}

func (this *BuiltinMetricResponse) String() string {
	return fmt.Sprintf(
		"<Metrics:%v, Checksum:%s, Timestamp:%v>",
		this.Metrics,
		this.Checksum,
		this.Timestamp,
	)
}

type BuiltinMetricSlice []*BuiltinMetric

func (this BuiltinMetricSlice) Len() int {
	return len(this)
}
func (this BuiltinMetricSlice) Swap(i, j int) {
	this[i], this[j] = this[j], this[i]
}
func (this BuiltinMetricSlice) Less(i, j int) bool {
	return this[i].String() < this[j].String()
}


================================================
FILE: common/model/event.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"

	"github.com/open-falcon/falcon-plus/common/utils"
)

// 机器监控和实例监控都会产生Event,共用这么一个struct
type Event struct {
	Id          string            `json:"id"`
	Strategy    *Strategy         `json:"strategy"`
	Expression  *Expression       `json:"expression"`
	Status      string            `json:"status"` // OK or PROBLEM
	Endpoint    string            `json:"endpoint"`
	LeftValue   float64           `json:"leftValue"`
	CurrentStep int               `json:"currentStep"`
	EventTime   int64             `json:"eventTime"`
	PushedTags  map[string]string `json:"pushedTags"`
}

func (this *Event) FormattedTime() string {
	return utils.UnixTsFormat(this.EventTime)
}

func (this *Event) String() string {
	return fmt.Sprintf(
		"<Endpoint:%s, Status:%s, Strategy:%v, Expression:%v, LeftValue:%s, CurrentStep:%d, PushedTags:%v, TS:%s>",
		this.Endpoint,
		this.Status,
		this.Strategy,
		this.Expression,
		utils.ReadableFloat(this.LeftValue),
		this.CurrentStep,
		this.PushedTags,
		this.FormattedTime(),
	)
}

func (this *Event) ExpressionId() int {
	if this.Expression != nil {
		return this.Expression.Id
	}

	return 0
}

func (this *Event) StrategyId() int {
	if this.Strategy != nil {
		return this.Strategy.Id
	}

	return 0
}

func (this *Event) TplId() int {
	if this.Strategy != nil {
		return this.Strategy.Tpl.Id
	}

	return 0
}

func (this *Event) Tpl() *Template {
	if this.Strategy != nil {
		return this.Strategy.Tpl
	}

	return nil
}

func (this *Event) ActionId() int {
	if this.Expression != nil {
		return this.Expression.ActionId
	}

	return this.Strategy.Tpl.ActionId
}

func (this *Event) Priority() int {
	if this.Strategy != nil {
		return this.Strategy.Priority
	}
	return this.Expression.Priority
}

func (this *Event) Note() string {
	if this.Strategy != nil {
		return this.Strategy.Note
	}
	return this.Expression.Note
}

func (this *Event) Metric() string {
	if this.Strategy != nil {
		return this.Strategy.Metric
	}
	return this.Expression.Metric
}

func (this *Event) RightValue() float64 {
	if this.Strategy != nil {
		return this.Strategy.RightValue
	}
	return this.Expression.RightValue
}

func (this *Event) Operator() string {
	if this.Strategy != nil {
		return this.Strategy.Operator
	}
	return this.Expression.Operator
}

func (this *Event) Func() string {
	if this.Strategy != nil {
		return this.Strategy.Func
	}
	return this.Expression.Func
}

func (this *Event) MaxStep() int {
	if this.Strategy != nil {
		return this.Strategy.MaxStep
	}
	return this.Expression.MaxStep
}

func (this *Event) Counter() string {
	return fmt.Sprintf("%s/%s %s", this.Endpoint, this.Metric(), utils.SortedTags(this.PushedTags))
}


================================================
FILE: common/model/expression.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"

	"github.com/open-falcon/falcon-plus/common/utils"
)

type Expression struct {
	Id         int               `json:"id"`
	Metric     string            `json:"metric"`
	Tags       map[string]string `json:"tags"`
	Func       string            `json:"func"`       // e.g. max(#3) all(#3)
	Operator   string            `json:"operator"`   // e.g. < !=
	RightValue float64           `json:"rightValue"` // critical value
	MaxStep    int               `json:"maxStep"`
	Priority   int               `json:"priority"`
	Note       string            `json:"note"`
	ActionId   int               `json:"actionId"`
}

func (this *Expression) String() string {
	return fmt.Sprintf(
		"<Id:%d, Metric:%s, Tags:%v, %s%s%s MaxStep:%d, P%d %s ActionId:%d>",
		this.Id,
		this.Metric,
		this.Tags,
		this.Func,
		this.Operator,
		utils.ReadableFloat(this.RightValue),
		this.MaxStep,
		this.Priority,
		this.Note,
		this.ActionId,
	)
}

type ExpressionResponse struct {
	Expressions []*Expression `json:"expressions"`
}


================================================
FILE: common/model/graph.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
	"math"

	MUtils "github.com/open-falcon/falcon-plus/common/utils"
)

// DsType 即RRD中的Datasource的类型:GAUGE|COUNTER|DERIVE
type GraphItem struct {
	Endpoint  string            `json:"endpoint"`
	Metric    string            `json:"metric"`
	Tags      map[string]string `json:"tags"`
	Value     float64           `json:"value"`
	Timestamp int64             `json:"timestamp"`
	DsType    string            `json:"dstype"`
	Step      int               `json:"step"`
	Heartbeat int               `json:"heartbeat"`
	Min       string            `json:"min"`
	Max       string            `json:"max"`
}

func (this *GraphItem) String() string {
	return fmt.Sprintf(
		"<Endpoint:%s, Metric:%s, Tags:%v, Value:%v, TS:%d %v DsType:%s, Step:%d, Heartbeat:%d, Min:%s, Max:%s>",
		this.Endpoint,
		this.Metric,
		this.Tags,
		this.Value,
		this.Timestamp,
		MUtils.UnixTsFormat(this.Timestamp),
		this.DsType,
		this.Step,
		this.Heartbeat,
		this.Min,
		this.Max,
	)
}

func (this *GraphItem) PrimaryKey() string {
	return MUtils.PK(this.Endpoint, this.Metric, this.Tags)
}

func (t *GraphItem) Checksum() string {
	return MUtils.Checksum(t.Endpoint, t.Metric, t.Tags)
}

func (this *GraphItem) UUID() string {
	return MUtils.UUID(this.Endpoint, this.Metric, this.Tags, this.DsType, this.Step)
}

type GraphDeleteParam struct {
	Endpoint string `json:"endpoint"`
	Metric   string `json:"metric"`
	Step     int    `json:"step"`
	DsType   string `json:"dstype"`
	Tags     string `json:"tags"`
}

type GraphDeleteResp struct {
}

// ConsolFun 是RRD中的概念,比如:MIN|MAX|AVERAGE
type GraphQueryParam struct {
	Start     int64  `json:"start"`
	End       int64  `json:"end"`
	ConsolFun string `json:"consolFuc"`
	Endpoint  string `json:"endpoint"`
	Counter   string `json:"counter"`
	Step      int    `json:"step"`
}

type GraphQueryResponse struct {
	Endpoint string     `json:"endpoint"`
	Counter  string     `json:"counter"`
	DsType   string     `json:"dstype"`
	Step     int        `json:"step"`
	Values   []*RRDData `json:"Values"` //大写为了兼容已经再用这个api的用户
}

// 页面上已经可以看到DsType和Step了,直接带进查询条件,Graph更易处理
type GraphAccurateQueryParam struct {
	Checksum  string `json:"checksum"`
	Start     int64  `json:"start"`
	End       int64  `json:"end"`
	ConsolFun string `json:"consolFuc"`
	DsType    string `json:"dsType"`
	Step      int    `json:"step"`
}

type GraphAccurateQueryResponse struct {
	Values []*RRDData `json:"Values"`
}

type JsonFloat float64

func (v JsonFloat) MarshalJSON() ([]byte, error) {
	f := float64(v)
	if math.IsNaN(f) || math.IsInf(f, 0) {
		return []byte("null"), nil
	} else {
		return []byte(fmt.Sprintf("%f", f)), nil
	}
}

type RRDData struct {
	Timestamp int64     `json:"timestamp"`
	Value     JsonFloat `json:"value"`
}

func NewRRDData(ts int64, val float64) *RRDData {
	return &RRDData{Timestamp: ts, Value: JsonFloat(val)}
}

func (this *RRDData) String() string {
	return fmt.Sprintf(
		"<RRDData:Value:%v TS:%d %v>",
		this.Value,
		this.Timestamp,
		MUtils.UnixTsFormat(this.Timestamp),
	)
}

type GraphInfoParam struct {
	Endpoint string `json:"endpoint"`
	Counter  string `json:"counter"`
}

type GraphInfoResp struct {
	ConsolFun string `json:"consolFun"`
	Step      int    `json:"step"`
	Filename  string `json:"filename"`
}

type GraphFullyInfo struct {
	Endpoint  string `json:"endpoint"`
	Counter   string `json:"counter"`
	ConsolFun string `json:"consolFun"`
	Step      int    `json:"step"`
	Filename  string `json:"filename"`
	Addr      string `json:"addr"`
}

type GraphLastParam struct {
	Endpoint string `json:"endpoint"`
	Counter  string `json:"counter"`
}

type GraphLastResp struct {
	Endpoint string   `json:"endpoint"`
	Counter  string   `json:"counter"`
	Value    *RRDData `json:"value"`
}


================================================
FILE: common/model/host.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
)

type Host struct {
	Id   int
	Name string
}

func (this *Host) String() string {
	return fmt.Sprintf(
		"<id:%d,name:%s>",
		this.Id,
		this.Name,
	)
}


================================================
FILE: common/model/influxdb.go
================================================
package model

type InfluxdbItem struct {
	Measurement string                 `json:"metric"`
	Tags        map[string]string      `json:"tags"`
	Fileds      map[string]interface{} `json:"fileds"`
	Timestamp   int64                  `json:"timestamp"`
}


================================================
FILE: common/model/judge.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"

	"github.com/open-falcon/falcon-plus/common/utils"
)

type JudgeItem struct {
	Endpoint  string            `json:"endpoint"`
	Metric    string            `json:"metric"`
	Value     float64           `json:"value"`
	Timestamp int64             `json:"timestamp"`
	JudgeType string            `json:"judgeType"`
	Tags      map[string]string `json:"tags"`
}

func (this *JudgeItem) String() string {
	return fmt.Sprintf("<Endpoint:%s, Metric:%s, Value:%f, Timestamp:%d, JudgeType:%s Tags:%v>",
		this.Endpoint,
		this.Metric,
		this.Value,
		this.Timestamp,
		this.JudgeType,
		this.Tags)
}

func (this *JudgeItem) PrimaryKey() string {
	return utils.Md5(utils.PK(this.Endpoint, this.Metric, this.Tags))
}

type HistoryData struct {
	Timestamp int64   `json:"timestamp"`
	Value     float64 `json:"value"`
}


================================================
FILE: common/model/metric.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"

	MUtils "github.com/open-falcon/falcon-plus/common/utils"
)

type MetricValue struct {
	Endpoint  string      `json:"endpoint"`
	Metric    string      `json:"metric"`
	Value     interface{} `json:"value"`
	Step      int64       `json:"step"`
	Type      string      `json:"counterType"`
	Tags      string      `json:"tags"`
	Timestamp int64       `json:"timestamp"`
}

func (this *MetricValue) String() string {
	return fmt.Sprintf(
		"<Endpoint:%s, Metric:%s, Type:%s, Tags:%s, Step:%d, Time:%d, Value:%v>",
		this.Endpoint,
		this.Metric,
		this.Type,
		this.Tags,
		this.Step,
		this.Timestamp,
		this.Value,
	)
}

// Same As `MetricValue`
type JsonMetaData struct {
	Metric      string      `json:"metric"`
	Endpoint    string      `json:"endpoint"`
	Timestamp   int64       `json:"timestamp"`
	Step        int64       `json:"step"`
	Value       interface{} `json:"value"`
	CounterType string      `json:"counterType"`
	Tags        string      `json:"tags"`
}

func (t *JsonMetaData) String() string {
	return fmt.Sprintf("<JsonMetaData Endpoint:%s, Metric:%s, Tags:%s, DsType:%s, Step:%d, Value:%v, Timestamp:%d>",
		t.Endpoint, t.Metric, t.Tags, t.CounterType, t.Step, t.Value, t.Timestamp)
}

type MetaData struct {
	Metric      string            `json:"metric"`
	Endpoint    string            `json:"endpoint"`
	Timestamp   int64             `json:"timestamp"`
	Step        int64             `json:"step"`
	Value       float64           `json:"value"`
	CounterType string            `json:"counterType"`
	Tags        map[string]string `json:"tags"`
}

func (t *MetaData) String() string {
	return fmt.Sprintf("<MetaData Endpoint:%s, Metric:%s, Timestamp:%d, Step:%d, Value:%f, Tags:%v>",
		t.Endpoint, t.Metric, t.Timestamp, t.Step, t.Value, t.Tags)
}

func (t *MetaData) PK() string {
	return MUtils.PK(t.Endpoint, t.Metric, t.Tags)
}


================================================
FILE: common/model/nodata.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"

	"github.com/open-falcon/falcon-plus/common/utils"
	ttime "github.com/toolkits/time"
)

type NodataItem struct {
	Counter string `json:"counter"`
	Ts      int64  `json:"ts"`
	FStatus string `json:"fstatus"`
	FTs     int64  `json:"fts"`
}

func (this *NodataItem) String() string {
	return fmt.Sprintf("{NodataItem counter:%s ts:%s fecthStatus:%s fetchTs:%s}",
		this.Counter, ttime.FormatTs(this.Ts), this.FStatus, ttime.FormatTs(this.FTs))
}

type NodataConfig struct {
	Id       int               `json:"id"`
	Name     string            `json:"name"`
	ObjType  string            `json:"objType"`
	Endpoint string            `json:"endpoint"`
	Metric   string            `json:"metric"`
	Tags     map[string]string `json:"tags"`
	Type     string            `json:"type"`
	Step     int64             `json:"step"`
	Mock     float64           `json:"mock"`
}

func NewNodataConfig(id int, name string, objType string, endpoint string, metric string, tags map[string]string, dstype string, step int64, mock float64) *NodataConfig {
	return &NodataConfig{id, name, objType, endpoint, metric, tags, dstype, step, mock}
}

func (this *NodataConfig) String() string {
	return fmt.Sprintf("{NodataConfig id:%d, name:%s, objType:%s, endpoint:%s, metric:%s, tags:%s, type:%s, step:%d, mock:%f}",
		this.Id, this.Name, this.ObjType, this.Endpoint, this.Metric, utils.SortedTags(this.Tags), this.Type, this.Step, this.Mock)
}


================================================
FILE: common/model/prometheus.go
================================================
package model

// MetricType Prometheus指标类型:GAUGE|COUNTER
type P8sItem struct {
	Endpoint   string            `json:"endpoint"`
	Metric     string            `json:"metric"`
	Tags       map[string]string `json:"tags"`
	Value      float64           `json:"value"`
	Timestamp  int64             `json:"timestamp"`
	MetricType string            `json:"metric_type"`
	Step       int               `json:"step"`
}


================================================
FILE: common/model/rpc.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
)

// code == 0 => success
// code == 1 => bad request
type SimpleRpcResponse struct {
	Code int `json:"code"`
}

func (this *SimpleRpcResponse) String() string {
	return fmt.Sprintf("<Code: %d>", this.Code)
}

type NullRpcRequest struct {
}


================================================
FILE: common/model/strategy.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"

	"github.com/open-falcon/falcon-plus/common/utils"
)

type Strategy struct {
	Id         int               `json:"id"`
	Metric     string            `json:"metric"`
	Tags       map[string]string `json:"tags"`
	Func       string            `json:"func"`       // e.g. max(#3) all(#3)
	Operator   string            `json:"operator"`   // e.g. < !=
	RightValue float64           `json:"rightValue"` // critical value
	MaxStep    int               `json:"maxStep"`
	Priority   int               `json:"priority"`
	Note       string            `json:"note"`
	Tpl        *Template         `json:"tpl"`
}

func (this *Strategy) String() string {
	return fmt.Sprintf(
		"<Id:%d, Metric:%s, Tags:%v, %s%s%s MaxStep:%d, P%d, %s, %v>",
		this.Id,
		this.Metric,
		this.Tags,
		this.Func,
		this.Operator,
		utils.ReadableFloat(this.RightValue),
		this.MaxStep,
		this.Priority,
		this.Note,
		this.Tpl,
	)
}

type HostStrategy struct {
	Hostname   string     `json:"hostname"`
	Strategies []Strategy `json:"strategies"`
}

type StrategiesResponse struct {
	HostStrategies []*HostStrategy `json:"hostStrategies"`
}


================================================
FILE: common/model/template.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
)

type Template struct {
	Id       int    `json:"id"`
	Name     string `json:"name"`
	ParentId int    `json:"parentId"`
	ActionId int    `json:"actionId"`
	Creator  string `json:"creator"`
}

func (this *Template) String() string {
	return fmt.Sprintf(
		"<Id:%d, Name:%s, ParentId:%d, ActionId:%d, Creator:%s>",
		this.Id,
		this.Name,
		this.ParentId,
		this.ActionId,
		this.Creator,
	)
}


================================================
FILE: common/model/transfer.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
)

type TransferResponse struct {
	Message string
	Total   int
	Invalid int
	Latency int64
}

func (this *TransferResponse) String() string {
	return fmt.Sprintf(
		"<Total=%v, Invalid:%v, Latency=%vms, Message:%s>",
		this.Total,
		this.Invalid,
		this.Latency,
		this.Message,
	)
}


================================================
FILE: common/model/tsdb.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
	"strings"
)

type TsdbItem struct {
	Metric    string            `json:"metric"`
	Tags      map[string]string `json:"tags"`
	Value     float64           `json:"value"`
	Timestamp int64             `json:"timestamp"`
}

func (this *TsdbItem) String() string {
	return fmt.Sprintf(
		"<Metric:%s, Tags:%v, Value:%v, TS:%d>",
		this.Metric,
		this.Tags,
		this.Value,
		this.Timestamp,
	)
}

func (this *TsdbItem) TsdbString() (s string) {
	s = fmt.Sprintf("put %s %d %.3f ", this.Metric, this.Timestamp, this.Value)

	for k, v := range this.Tags {
		key := strings.ToLower(strings.Replace(k, " ", "_", -1))
		value := strings.Replace(v, " ", "_", -1)
		s += key + "=" + value + " "
	}

	return s
}


================================================
FILE: common/proc/proc.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package proc

import (
	"sync"
	"time"
)

const (
	DefaultOtherMaxSize      = 100 // 默认的 自定义统计字段的最大值
	DefaultSCounterQpsPeriod = 1   // QPS计算周期, 默认值为1s
)

// 基本的计数器
type SCounterBase struct {
	sync.RWMutex
	Name string
	Cnt  int64
	Time string
	ts   int64
	// 自定义统计指标
	Other map[string]interface{}
}

func NewSCounterBase(name string) *SCounterBase {
	uts := time.Now().Unix()
	return &SCounterBase{Name: name, Cnt: 0, Time: formatTs(uts), ts: uts,
		Other: make(map[string]interface{})}
}

func (this *SCounterBase) Get() *SCounterBase {
	this.RLock()
	defer this.RUnlock()
	return this
}

// to be abandoned
func (this *SCounterBase) Set(cnt int64) {
	this.Lock()
	defer this.Unlock()

	this.Cnt = cnt
	this.ts = time.Now().Unix()
	this.Time = formatTs(this.ts)
}

func (this *SCounterBase) SetCnt(cnt int64) {
	this.Lock()
	defer this.Unlock()

	this.Cnt = cnt
	this.ts = time.Now().Unix()
	this.Time = formatTs(this.ts)
}

func (this *SCounterBase) PutOther(key string, value interface{}) bool {
	this.Lock()
	defer this.Unlock()

	ret := false
	_, exist := this.Other[key]
	if exist {
		this.Other[key] = value
		ret = true
	} else {
		if len(this.Other) < DefaultOtherMaxSize {
			this.Other[key] = value
			ret = true
		}
	}

	return ret
}

func formatTs(ts int64) string {
	return time.Unix(ts, 0).Format("2006-01-02 15:04:05")
}

// QPS统计,只支持 增加计数操作
type SCounterQps struct {
	sync.RWMutex
	Name string
	Cnt  int64
	Qps  int64
	Time string
	ts   int64
	// for qps
	lastTs  int64
	lastCnt int64
	// 自定义统计指标
	Other map[string]interface{}
}

func NewSCounterQps(name string) *SCounterQps {
	uts := time.Now().Unix()
	return &SCounterQps{Name: name, Cnt: 0, Time: formatTs(uts), ts: uts,
		Qps: 0, lastCnt: 0, lastTs: uts,
		Other: make(map[string]interface{})}
}

func (this *SCounterQps) Get() *SCounterQps {
	this.RLock()
	defer this.RUnlock()

	this.incrByDirty(0) // update qps
	return this
}

func (this *SCounterQps) Incr() {
	this.IncrBy(int64(1))
}

func (this *SCounterQps) IncrBy(incr int64) {
	this.Lock()
	defer this.Unlock()

	this.incrByDirty(incr)
}

func (this *SCounterQps) PutOther(key string, value interface{}) bool {
	this.Lock()
	defer this.Unlock()

	ret := false
	_, exist := this.Other[key]
	if exist {
		this.Other[key] = value
		ret = true
	} else {
		if len(this.Other) < DefaultOtherMaxSize {
			this.Other[key] = value
			ret = true
		}
	}

	return ret
}

// 操作我的时候,请加写锁
func (this *SCounterQps) incrByDirty(incr int64) {
	this.Cnt += incr
	this.ts = time.Now().Unix()
	this.Time = formatTs(this.ts)

	// qps
	if this.ts-this.lastTs > DefaultSCounterQpsPeriod {
		this.Qps = int64((this.Cnt - this.lastCnt) / (this.ts - this.lastTs))
		this.lastTs = this.ts
		this.lastCnt = this.Cnt
	}
}


================================================
FILE: common/sdk/.gitignore
================================================
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so

# Folders
_obj
_test

# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out

*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*

_testmain.go

*.exe
*.test
*.prof

*.swp
*.swo
*.log
.idea
.DS_Store
/sdk*
/gitversion

================================================
FILE: common/sdk/README.md
================================================


================================================
FILE: common/sdk/requests/auth_request.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package requests

import (
	"encoding/json"
	"errors"
	"github.com/toolkits/net/httplib"
	"time"
)

func CurlPlus(uri, method, token_name, token_sig string, headers, params map[string]string) (req *httplib.BeegoHttpRequest, err error) {
	if method == "GET" {
		req = httplib.Get(uri)
	} else if method == "POST" {
		req = httplib.Post(uri)
	} else if method == "PUT" {
		req = httplib.Put(uri)
	} else if method == "DELETE" {
		req = httplib.Delete(uri)
	} else if method == "HEAD" {
		req = httplib.Head(uri)
	} else {
		err = errors.New("invalid http method")
		return
	}

	req = req.SetTimeout(1*time.Second, 5*time.Second)

	token, _ := json.Marshal(map[string]string{
		"name": token_name,
		"sig":  token_sig,
	})
	req.Header("Apitoken", string(token))

	for hk, hv := range headers {
		req.Header(hk, hv)
	}

	for pk, pv := range params {
		req.Param(pk, pv)
	}

	return
}


================================================
FILE: common/sdk/requests/post.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package requests

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
)

func PostJsonBody(url string, v interface{}) (response []byte, err error) {
	bs, err := json.Marshal(v)
	if err != nil {
		return response, err
	}

	bf := bytes.NewBuffer(bs)

	resp, err := http.Post(url, "application/json", bf)
	if err != nil {
		return response, err
	}

	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)

}


================================================
FILE: common/sdk/sender/linkedlist.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sender

import (
	"container/list"
	"sync"

	"github.com/open-falcon/falcon-plus/common/model"
)

type SafeLinkedList struct {
	sync.RWMutex
	L *list.List
}

func NewSafeLinkedList() *SafeLinkedList {
	return &SafeLinkedList{L: list.New()}
}

func (this *SafeLinkedList) PopBack(limit int) []*model.JsonMetaData {
	this.RLock()
	defer this.RUnlock()
	sz := this.L.Len()
	if sz == 0 {
		return []*model.JsonMetaData{}
	}

	if sz < limit {
		limit = sz
	}

	ret := make([]*model.JsonMetaData, 0, limit)
	for i := 0; i < limit; i++ {
		e := this.L.Back()
		ret = append(ret, e.Value.(*model.JsonMetaData))
		this.L.Remove(e)
	}

	return ret
}

func (this *SafeLinkedList) PushFront(v interface{}) *list.Element {
	this.Lock()
	defer this.Unlock()
	return this.L.PushFront(v)
}

func (this *SafeLinkedList) Front() *list.Element {
	this.RLock()
	defer this.RUnlock()
	return this.L.Front()
}

func (this *SafeLinkedList) Len() int {
	this.RLock()
	defer this.RUnlock()
	return this.L.Len()
}


================================================
FILE: common/sdk/sender/make.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sender

import (
	"time"

	"github.com/open-falcon/falcon-plus/common/model"
)

func MakeMetaData(endpoint, metric, tags string, val interface{}, counterType string, step_and_ts ...int64) *model.JsonMetaData {
	md := model.JsonMetaData{
		Endpoint:    endpoint,
		Metric:      metric,
		Tags:        tags,
		Value:       val,
		CounterType: counterType,
	}

	argc := len(step_and_ts)
	if argc == 0 {
		md.Step = 60
		md.Timestamp = time.Now().Unix()
	} else if argc == 1 {
		md.Step = step_and_ts[0]
		md.Timestamp = time.Now().Unix()
	} else if argc == 2 {
		md.Step = step_and_ts[0]
		md.Timestamp = step_and_ts[1]
	}

	return &md
}

func MakeGaugeValue(endpoint, metric, tags string, val interface{}, step_and_ts ...int64) *model.JsonMetaData {
	return MakeMetaData(endpoint, metric, tags, val, "GAUGE", step_and_ts...)
}

func MakeCounterValue(endpoint, metric, tags string, val interface{}, step_and_ts ...int64) *model.JsonMetaData {
	return MakeMetaData(endpoint, metric, tags, val, "COUNTER", step_and_ts...)
}

func PushGauge(endpoint, metric, tags string, val interface{}, step_and_ts ...int64) {
	md := MakeGaugeValue(endpoint, metric, tags, val, step_and_ts...)
	MetaDataQueue.PushFront(md)
}

func PushCounter(endpoint, metric, tags string, val interface{}, step_and_ts ...int64) {
	md := MakeCounterValue(endpoint, metric, tags, val, step_and_ts...)
	MetaDataQueue.PushFront(md)
}

func Push(endpoint, metric, tags string, val interface{}, counterType string, step_and_ts ...int64) {
	md := MakeMetaData(endpoint, metric, tags, val, counterType, step_and_ts...)
	MetaDataQueue.PushFront(md)
}


================================================
FILE: common/sdk/sender/push.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sender

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/open-falcon/falcon-plus/common/model"
)

func PostPush(L []*model.JsonMetaData) error {
	bs, err := json.Marshal(L)
	if err != nil {
		return err
	}

	bf := bytes.NewBuffer(bs)

	resp, err := http.Post(PostPushUrl, "application/json", bf)
	if err != nil {
		return err
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	content := string(body)

	if resp.StatusCode != 200 {
		return fmt.Errorf("status code %d != 200, response: %s", resp.StatusCode, content)
	}

	if Debug {
		log.Println("[D] response:", content)
	}

	return nil
}


================================================
FILE: common/sdk/sender/sender.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sender

import (
	"log"
	"time"
)

const LIMIT = 200

var MetaDataQueue = NewSafeLinkedList()
var PostPushUrl string
var Debug bool

func StartSender() {
	go startSender()
}

func startSender() {
	for {
		L := MetaDataQueue.PopBack(LIMIT)
		if len(L) == 0 {
			time.Sleep(time.Millisecond * 200)
			continue
		}

		err := PostPush(L)
		if err != nil {
			log.Println("[E] push to transfer fail", err)
		}
	}
}


================================================
FILE: common/utils/counter.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"fmt"
)

func Counter(metric string, tags map[string]string) string {
	if tags == nil || len(tags) == 0 {
		return metric
	}
	return fmt.Sprintf("%s/%s", metric, SortedTags(tags))
}


================================================
FILE: common/utils/date.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"time"
)

func UnixTsFormat(ts int64) string {
	return time.Unix(ts, 0).Format("2006-01-02 15:04:05")
}


================================================
FILE: common/utils/formatter.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"strconv"
	"strings"
)

func ReadableFloat(raw float64) string {
	val := strconv.FormatFloat(raw, 'f', 5, 64)
	if strings.Contains(val, ".") {
		val = strings.TrimRight(val, "0")
		val = strings.TrimRight(val, ".")
	}

	return val
}


================================================
FILE: common/utils/func.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"bytes"
	"math/rand"
	"strconv"
	"time"
)

func PK(endpoint, metric string, tags map[string]string) string {
	ret := bufferPool.Get().(*bytes.Buffer)
	ret.Reset()
	defer bufferPool.Put(ret)

	if tags == nil || len(tags) == 0 {
		ret.WriteString(endpoint)
		ret.WriteString("/")
		ret.WriteString(metric)

		return ret.String()
	}
	ret.WriteString(endpoint)
	ret.WriteString("/")
	ret.WriteString(metric)
	ret.WriteString("/")
	ret.WriteString(SortedTags(tags))
	return ret.String()
}

func PK2(endpoint, counter string) string {
	ret := bufferPool.Get().(*bytes.Buffer)
	ret.Reset()
	defer bufferPool.Put(ret)

	ret.WriteString(endpoint)
	ret.WriteString("/")
	ret.WriteString(counter)

	return ret.String()
}

func UUID(endpoint, metric string, tags map[string]string, dstype string, step int) string {
	ret := bufferPool.Get().(*bytes.Buffer)
	ret.Reset()
	defer bufferPool.Put(ret)

	if tags == nil || len(tags) == 0 {
		ret.WriteString(endpoint)
		ret.WriteString("/")
		ret.WriteString(metric)
		ret.WriteString("/")
		ret.WriteString(dstype)
		ret.WriteString("/")
		ret.WriteString(strconv.Itoa(step))

		return ret.String()
	}
	ret.WriteString(endpoint)
	ret.WriteString("/")
	ret.WriteString(metric)
	ret.WriteString("/")
	ret.WriteString(SortedTags(tags))
	ret.WriteString("/")
	ret.WriteString(dstype)
	ret.WriteString("/")
	ret.WriteString(strconv.Itoa(step))

	return ret.String()
}

func Checksum(endpoint string, metric string, tags map[string]string) string {
	pk := PK(endpoint, metric, tags)
	return Md5(pk)
}

func ChecksumOfUUID(endpoint, metric string, tags map[string]string, dstype string, step int64) string {
	return Md5(UUID(endpoint, metric, tags, dstype, int(step)))
}

func init() {
	rand.Seed(time.Now().UTC().UnixNano())
}

func RandString(l int) string {
	bytes := make([]byte, l)
	for i := 0; i < l; i++ {
		bytes[i] = byte(RandInt(65, 90))
	}
	return string(bytes)
}

func RandInt(min int, max int) int {
	return min + rand.Intn(max-min)
}


================================================
FILE: common/utils/func_test.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"fmt"
	"testing"
)

func origPK(endpoint, metric string, tags map[string]string) string {
	if tags == nil || len(tags) == 0 {
		return fmt.Sprintf("%s/%s", endpoint, metric)
	}
	return fmt.Sprintf("%s/%s/%s", endpoint, metric, SortedTags(tags))
}

func origPK2(endpoint, counter string) string {
	return fmt.Sprintf("%s/%s", endpoint, counter)
}

func origUUID(endpoint, metric string, tags map[string]string, dstype string, step int) string {
	if tags == nil || len(tags) == 0 {
		return fmt.Sprintf("%s/%s/%s/%d", endpoint, metric, dstype, step)
	}
	return fmt.Sprintf("%s/%s/%s/%s/%d", endpoint, metric, SortedTags(tags), dstype, step)
}

var pkCase = []struct {
	endpoint string
	metric   string
	tags     map[string]string
	except   string
}{
	{"endpoint1", "metric1", nil, "endpoint1/metric1"},
	{"endpoint1", "metric1", map[string]string{}, "endpoint1/metric1"},
	{"endpoint1", "metric1", map[string]string{"k1": "v1", "k2": "v2"}, "endpoint1/metric1/k1=v1,k2=v2"},
	{"endpoint1", "metric1", map[string]string{"k2": "v2", "k1": "v1"}, "endpoint1/metric1/k1=v1,k2=v2"},
}

var pk2Case = []struct {
	endpoint string
	counter  string
	except   string
}{
	{"endpoint1", "counter1", "endpoint1/counter1"},
}

var uuidCase = []struct {
	endpoint string
	metric   string
	tags     map[string]string
	dstype   string
	step     int
	except   string
}{
	{"endpoint1", "metric1", nil, "ds", 10, "endpoint1/metric1/ds/10"},
	{"endpoint1", "metric1", map[string]string{}, "ds", 10, "endpoint1/metric1/ds/10"},
	{"endpoint1", "metric1", map[string]string{"k1": "v1", "k2": "v2"}, "ds", 10, "endpoint1/metric1/k1=v1,k2=v2/ds/10"},
	{"endpoint1", "metric1", map[string]string{"k2": "v2", "k1": "v1"}, "ds", 10, "endpoint1/metric1/k1=v1,k2=v2/ds/10"},
}

func Test_PK(t *testing.T) {
	for _, pk := range pkCase {
		if PK(pk.endpoint, pk.metric, pk.tags) != origPK(pk.endpoint, pk.metric, pk.tags) || PK(pk.endpoint, pk.metric, pk.tags) != pk.except {
			t.Error("not except")
		}
	}
}

func Test_PK2(t *testing.T) {
	for _, pk2 := range pk2Case {
		if PK2(pk2.endpoint, pk2.counter) != origPK2(pk2.endpoint, pk2.counter) || PK2(pk2.endpoint, pk2.counter) != pk2.except {
			t.Error("not except")
		}
	}
}

func Test_UUID(t *testing.T) {
	for _, uuid := range uuidCase {
		if UUID(uuid.endpoint, uuid.metric, uuid.tags, uuid.dstype, uuid.step) != origUUID(uuid.endpoint, uuid.metric, uuid.tags, uuid.dstype, uuid.step) ||
			UUID(uuid.endpoint, uuid.metric, uuid.tags, uuid.dstype, uuid.step) != uuid.except {
			t.Error("not except")
		}
	}
}

var (
	testTags = map[string]string{"k1": "v1", "k2": "v2"}
)

func Benchmark_PK(b *testing.B) {
	for i := 0; i < b.N; i++ {
		PK("endpoint1", "metric1", testTags)
	}
}

func Benchmark_PK_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origPK("endpoint1", "metric1", testTags)
	}
}

func Benchmark_PK2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		PK2("endpoint1", "counter1")
	}
}

func Benchmark_PK2_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origPK2("endpoint1", "counter1")
	}
}

func Benchmark_UUID(b *testing.B) {
	for i := 0; i < b.N; i++ {
		UUID("endpoint1", "metric1", testTags, "dt", 10)
	}
}

func Benchmark_UUID_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origUUID("endpoint1", "metric1", testTags, "dt", 10)
	}
}


================================================
FILE: common/utils/map.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"sort"
)

// TODO 以下的部分, 考虑放到公共组件库
func KeysOfMap(m map[string]string) []string {
	keys := make(sort.StringSlice, len(m))
	i := 0
	for key := range m {
		keys[i] = key
		i++
	}

	keys.Sort()
	return []string(keys)
}


================================================
FILE: common/utils/md5.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"crypto/md5"
	"encoding/hex"
)

func Md5(raw string) string {
	h := md5.Sum([]byte(raw))
	return hex.EncodeToString(h[:])
}


================================================
FILE: common/utils/md5_test.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"crypto/md5"
	"fmt"
	"io"
	"testing"
)

func origMd5(raw string) string {
	h := md5.New()
	io.WriteString(h, raw)

	return fmt.Sprintf("%x", h.Sum(nil))
}

func Test_Md5(t *testing.T) {
	if Md5("1234567890123") != origMd5("1234567890123") {
		t.Error("not expect")
	}
}

func Benchmark_Md5(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Md5("1234567890123")
	}
}

func Benchmark_Md5_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origMd5("1234567890123")
	}
}


================================================
FILE: common/utils/objpool.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"bytes"
	"sync"
)

var bufferPool = sync.Pool{New: func() interface{} { return new(bytes.Buffer) }}


================================================
FILE: common/utils/statistics.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import "math"

func ComputeMean(values []float64) float64 {
	var sum float64

	for _, value := range values {
		sum = sum + value
	}

	return (sum / float64(len(values)))
}

func ComputeStdDeviation(values []float64) float64 {
	var (
		mean         float64
		vp           []float64
		stdDiv, temp float64
	)

	vp = make([]float64, len(values))

	/*Calculate mean of the data points*/
	mean = ComputeMean(values)
	/*Calculate standard deviation of individual data points*/
	for i, v := range values {
		temp = v - mean
		vp[i] = (temp * temp)
	}

	/* Finally, Compute standard Deviation of data points
	 * by taking mean of individual std. Deviation.
	 */
	stdDiv = ComputeMean(vp)
	return float64(math.Sqrt(float64(stdDiv)))
}


================================================
FILE: common/utils/tags.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"bytes"
	"fmt"
	"sort"
	"strings"
)

func SortedTags(tags map[string]string) string {
	if tags == nil {
		return ""
	}

	size := len(tags)

	if size == 0 {
		return ""
	}

	ret := bufferPool.Get().(*bytes.Buffer)
	ret.Reset()
	defer bufferPool.Put(ret)

	if size == 1 {
		for k, v := range tags {
			ret.WriteString(k)
			ret.WriteString("=")
			ret.WriteString(v)
		}
		return ret.String()
	}

	keys := make([]string, size)
	i := 0
	for k := range tags {
		keys[i] = k
		i++
	}

	sort.Strings(keys)

	for j, key := range keys {
		ret.WriteString(key)
		ret.WriteString("=")
		ret.WriteString(tags[key])
		if j != size-1 {
			ret.WriteString(",")
		}
	}

	return ret.String()
}

func DictedTagstring(s string) map[string]string {
	if s == "" {
		return map[string]string{}
	}

	if strings.ContainsRune(s, ' ') {
		s = strings.Replace(s, " ", "", -1)
	}

	tag_dict := make(map[string]string)
	tags := strings.Split(s, ",")
	for _, tag := range tags {
		idx := strings.IndexRune(tag, '=')
		if idx != -1 {
			tag_dict[tag[:idx]] = tag[idx+1:]
		}
	}
	return tag_dict
}

func SplitTagsString(s string) (err error, tags map[string]string) {
	err = nil
	tags = make(map[string]string)

	s = strings.Replace(s, " ", "", -1)
	if s == "" {
		return
	}

	tagSlice := strings.Split(s, ",")
	for _, tag := range tagSlice {
		tag_pair := strings.SplitN(tag, "=", 2)
		if len(tag_pair) == 2 {
			tags[tag_pair[0]] = tag_pair[1]
		} else {
			err = fmt.Errorf("bad tag %s", tag)
			return
		}
	}

	return
}


================================================
FILE: common/utils/tags_test.go
================================================
// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

import (
	"fmt"
	"sort"
	"strings"
	"testing"
)

var testCases4map2string = []struct {
	tags   map[string]string
	expect string
}{
	{map[string]string{"1": "1"}, "1=1"},
	{map[string]string{"1": "1", "2": "2"}, "1=1,2=2"},
	{map[string]string{"1": "1", "2": "2", "0": "0"}, "0=0,1=1,2=2"},
}

var testCases4string2map = []struct {
	tags   string
	expect map[string]string
}{
	{"1=1", map[string]string{"1": "1"}},
	{"1=1,2=2", map[string]string{"1": "1", "2": "2"}},
	{"0=0,1=1,2=2", map[string]string{"1": "1", "2": "2", "0": "0"}},
	{"0,1=1,2=2", map[string]string{"1": "1", "2": "2"}},
	{"0=,1=1,2=2", map[string]string{"0": "", "1": "1", "2": "2"}},
	{"=0,1=1,2=2", map[string]string{"": "0", "1": "1", "2": "2"}},
	{"0=0, 1=1, 2=2", map[string]string{"0": "0", "1": "1", "2": "2"}},
}

func origSortedTags(tags map[string]string) string {
	if tags == nil {
		return ""
	}

	size := len(tags)

	if size == 0 {
		return ""
	}

	if size == 1 {
		for k, v := range tags {
			return fmt.Sprintf("%s=%s", k, v)
		}
	}

	keys := make([]string, size)
	i := 0
	for k := range tags {
		keys[i] = k
		i++
	}

	sort.Strings(keys)

	ret := make([]string, size)
	for j, key := range keys {
		ret[j] = fmt.Sprintf("%s=%s", key, tags[key])
	}

	return strings.Join(ret, ",")
}

func origDictedTagstring(s string) map[string]string {
	if s == "" {
		return map[string]string{}
	}
	s = strings.Replace(s, " ", "", -1)

	tag_dict := make(map[string]string)
	tags := strings.Split(s, ",")
	for _, tag := range tags {
		tag_pair := strings.SplitN(tag, "=", 2)
		if len(tag_pair) == 2 {
			tag_dict[tag_pair[0]] = tag_pair[1]
		}
	}
	return tag_dict
}

func Test_SortedTags(t *testing.T) {
	for _, testCase := range testCases4map2string {
		if r := SortedTags(testCase.tags); r != testCase.expect || SortedTags(testCase.tags) != origSortedTags(testCase.tags) {
			t.Errorf("expect %v, got %v\n", testCase.expect, r)
		}
	}
}
func Test_DictedTagstring(t *testing.T) {
	for _, testCase := range testCases4string2map {
		r := DictedTagstring(testCase.tags)
		origR := origDictedTagstring(testCase.tags)

		if len(r) != len(testCase.expect) || len(r) != len(origR) {
			t.FailNow()
		}
		for k, v := range r {
			if expectV, exist := testCase.expect[k]; !exist || v != expectV || v != origR[k] {
				t.Errorf("expect %v, got %v\n", testCase.expect, r)
			}
		}
	}
}

func Benchmark_SortedTags_1pair(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SortedTags(map[string]string{"1": "1"})
	}
}

func Benchmark_SortedTags_1pair_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origSortedTags(map[string]string{"1": "1"})
	}
}

func Benchmark_SortedTags_2pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SortedTags(map[string]string{"1": "1", "2": "2"})
	}
}

func Benchmark_SortedTags_2pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origSortedTags(map[string]string{"1": "1", "2": "2"})
	}
}

func Benchmark_SortedTags_3pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SortedTags(map[string]string{"1": "1", "2": "2", "3": "3"})
	}
}

func Benchmark_SortedTags_3pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origSortedTags(map[string]string{"1": "1", "2": "2", "3": "3"})
	}
}

func Benchmark_SortedTags_4pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SortedTags(map[string]string{"1": "1", "2": "2", "3": "3", "4": "4"})
	}
}

func Benchmark_SortedTags_4pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origSortedTags(map[string]string{"1": "1", "2": "2", "3": "3", "4": "4"})
	}
}

func Benchmark_SortedTags_5pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SortedTags(map[string]string{"1": "1", "2": "2", "3": "3", "4": "4", "5": "5"})
	}
}

func Benchmark_SortedTags_5pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origSortedTags(map[string]string{"1": "1", "2": "2", "3": "3", "4": "4", "5": "5"})
	}
}

func Benchmark_SortedTags_6pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SortedTags(map[string]string{"1": "1", "2": "2", "3": "3", "4": "4", "5": "5", "0": "0"})
	}
}

func Benchmark_SortedTags_6pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origSortedTags(map[string]string{"1": "1", "2": "2", "3": "3", "4": "4", "5": "5", "0": "0"})
	}
}

func Benchmark_DictedTagstring_1pair(b *testing.B) {
	for i := 0; i < b.N; i++ {
		DictedTagstring("1=1")
	}
}

func Benchmark_DictedTagstring_1pair_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origDictedTagstring("1=1")
	}
}

func Benchmark_DictedTagstring_2pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		DictedTagstring("1=1,2=2")
	}
}

func Benchmark_DictedTagstring_2pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origDictedTagstring("1=1,2=2")
	}
}

func Benchmark_DictedTagstring_3pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		DictedTagstring("1=1,2=2,3=3")
	}
}

func Benchmark_DictedTagstring_3pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origDictedTagstring("1=1,2=2,3=3")
	}
}

func Benchmark_DictedTagstring_4pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		DictedTagstring("1=1,2=2,3=3,4=4")
	}
}

func Benchmark_DictedTagstring_4pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origDictedTagstring("1=1,2=2,3=3,4=4")
	}
}

func Benchmark_DictedTagstring_5pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		DictedTagstring("1=1,2=2,3=3,4=4,5=5")
	}
}

func Benchmark_DictedTagstring_5pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origDictedTagstring("1=1,2=2,3=3,4=4,5=5")
	}
}

func Benchmark_DictedTagstring_6pairs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		DictedTagstring("1=1,2=2,3=3,4=4,5=5,6=6")
	}
}

func Benchmark_DictedTagstring_6pairs_orig(b *testing.B) {
	for i := 0; i < b.N; i++ {
		origDictedTagstring("1=1,2=2,3=3,4=4,5=5,6=6")
	}
}


================================================
FILE: config/agent.json
================================================
{
    "debug": true,
    "hostname": "%%AGENT_HOSTNAME%%",
    "ip": "",
    "plugin": {
        "enabled": false,
        "dir": "./plugin",
        "git": "https://github.com/open-falcon/plugin.git",
        "logs": "./logs"
    },
    "heartbeat": {
        "enabled": true,
        "addr": "%%HBS_RPC%%",
        "interval": 60,
        "timeout": 1000
    },
    "transfer": {
        "enabled": true,
        "addrs": [
            "%%TRANSFER_RPC%%"
        ],
        "interval": 60,
        "timeout": 1000
    },
    "http": {
        "enabled": true,
        "listen": ":1988",
        "backdoor": false
    },
    "collector": {
        "ifacePrefix": ["eth", "em"],
        "mountPoint": []
    },
    "default_tags": {
    },
    "ignore": {
        "cpu.busy": true,
        "df.bytes.free": true,
        "df.bytes.total": true,
        "df.bytes.used": true,
        "df.bytes.used.percent": true,
        "df.inodes.total": true,
        "df.inodes.free": true,
        "df.inodes.used": true,
        "df.inodes.used.percent": true,
        "mem.memtotal": true,
        "mem.memused": true,
        "mem.memused.percent": true,
        "mem.memfree": true,
        "mem.swaptotal": true,
        "mem.swapused": true,
        "mem.swapfree": true
    }
}


================================================
FILE: config/aggregator.json
================================================
{
    "debug": true,
    "http": {
        "enabled": true,
        "listen": "%%AGGREGATOR_HTTP%%"
    },
    "database": {
        "addr": "%%MYSQL%%/falcon_portal?loc=Local&parseTime=true",
        "idle": 10,
        "ids": [1, -1],
        "interval": 55
    },
    "api": {
        "connect_timeout": 500,
        "request_timeout": 2000,
        "plus_api": "http://127.0.0.1:8080",
        "plus_api_token": "%%PLUS_API_DEFAULT_TOKEN%%",
        "push_api": "http://127.0.0.1:1988/v1/push"
    }
}


================================================
FILE: config/alarm.json
================================================
{
    "log_level": "debug",
    "http": {
        "enabled": true,
        "listen": "0.0.0.0:9912"
    },
    "redis": {
        "addr": "%%REDIS%%",
        "maxIdle": 5,
        "highQueues": [
            "event:p0",
            "event:p1",
            "event:p2"
        ],
        "lowQueues": [
            "event:p3",
            "event:p4",
            "event:p5",
            "event:p6"
        ],
        "userIMQueue": "/queue/user/im",
        "userSmsQueue": "/queue/user/sms",
        "userMailQueue": "/queue/user/mail"
    },
    "api": {
        "im": "http://127.0.0.1:10086/wechat",
        "sms": "http://127.0.0.1:10086/sms",
        "mail": "http://127.0.0.1:10086/mail",
        "dashboard": "http://127.0.0.1:8081",
        "plus_api":"http://127.0.0.1:8080",
        "plus_api_token": "%%PLUS_API_DEFAULT_TOKEN%%"
    },
    "falcon_portal": {
        "addr": "%%MYSQL%%/alarms?charset=utf8&loc=Local",
        "idle": 10,
        "max": 100
    },
    "worker": {
        "im": 10,
        "sms": 10,
        "mail": 50
    },
    "housekeeper": {
        "event_retention_days": 7,
        "event_delete_batch": 100
    }
}


================================================
FILE: config/api.json
================================================
{
	"log_level": "debug",
	"db": {
		"falcon_portal": "%%MYSQL%%/falcon_portal?charset=utf8&parseTime=True&loc=Local",
		"graph": "%%MYSQL%%/graph?charset=utf8&parseTime=True&loc=Local",
		"uic": "%%MYSQL%%/uic?charset=utf8&parseTime=True&loc=Local",
		"dashboard": "%%MYSQL%%/dashboard?charset=utf8&parseTime=True&loc=Local",
		"alarms": "%%MYSQL%%/alarms?charset=utf8&parseTime=True&loc=Local",
		"db_bug": true
	},
	"graphs": {
		"cluster": {
			"graph-00": "%%GRAPH_RPC%%"
		},
		"max_conns": 100,
		"max_idle": 100,
		"conn_timeout": 1000,
		"call_timeout": 5000,
		"numberOfReplicas": 500
	},
	"metric_list_file": "./api/data/metric",
	"web_port": "%%PLUS_API_HTTP%%",
	"access_control": true,
	"signup_disable": false,
	"salt": "",
	"skip_auth": false,
	"default_token": "%%PLUS_API_DEFAULT_TOKEN%%",
	"gen_doc": false,
	"gen_doc_path": "doc/module.html"
}


================================================
FILE: config/confgen.sh
================================================
#!/bin/bash

confs=(
    '%%AGENT_HTTP%%=0.0.0.0:1988'
    '%%AGGREGATOR_HTTP%%=0.0.0.0:6055'
    '%%GRAPH_HTTP%%=0.0.0.0:6071'
    '%%GRAPH_RPC%%=0.0.0.0:6070'
    '%%HBS_HTTP%%=0.0.0.0:6031'
    '%%HBS_RPC%%=0.0.0.0:6030'
    '%%JUDGE_HTTP%%=0.0.0.0:6081'
    '%%JUDGE_RPC%%=0.0.0.0:6080'
    '%%NODATA_HTTP%%=0.0.0.0:6090'
    '%%TRANSFER_HTTP%%=0.0.0.0:6060'
    '%%TRANSFER_RPC%%=0.0.0.0:8433'
    '%%REDIS%%=127.0.0.1:6379'
    '%%MYSQL%%=root:@tcp(127.0.0.1:3306)'
    '%%PLUS_API_DEFAULT_TOKEN%%=default-token-used-in-server-side'
    '%%PLUS_API_HTTP%%=0.0.0.0:8080'
    '%%AGENT_HOSTNAME%%='
 )

configurer() {
    for i in "${confs[@]}"
    do
        search="${i%%=*}"
        replace="${i##*=}"

        uname=`uname`
        if [ "$uname" == "Darwin" ] ; then
            # Note the "" and -e  after -i, needed in OS X
            find ./out/*/config/*.json -type f -exec sed -i .tpl -e "s/${search}/${replace}/g" {} \;
        else
            find ./out/*/config/*.json -type f -exec sed -i "s/${search}/${replace}/g" {} \;
        fi
    done
}
configurer


================================================
FILE: config/falcon2p8s.json
================================================
{
    "log_level": "debug",
    "concurrent": 100,
    "http": {
        "listen": "0.0.0.0:9090"
    },
    "rpc": {
        "listen": "0.0.0.0:8080"
    }
}

================================================
FILE: config/gateway.json
================================================
{
    "debug": true,
    "minStep": 30,
    "http": {
        "enabled": true,
        "listen": "0.0.0.0:16060"
    },
    "rpc": {
        "enabled": true,
        "listen": "0.0.0.0:18433"
    },
    "socket": {
        "enabled": true,
        "listen": "0.0.0.0:14444",
        "timeout": 3600
    },
    "judge": {
        "enabled": false,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "replicas": 500,
        "cluster": {
            "judge-00" : "%%JUDGE_RPC%%"
        }
    },
    "graph": {
        "enabled": false,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "replicas": 500,
        "cluster": {
            "graph-00" : "%%GRAPH_RPC%%"
        }
    },
    "tsdb": {
        "enabled": false,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "retry": 3,
        "address": "127.0.0.1:8088"
    },
    "transfer": {
        "enabled": true,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "retry": 3,
        "cluster": {
            "t1": "%%TRANSFER_RPC%%"
        }
    },
    "influxdb": {
        "enabled": false,
        "batch": 200,
        "retry": 3,
        "maxConns": 32,
        "username": "admin",
        "password": "123456",
        "precision": "s",
        "db": "foo",
        "address": "http://127.0.0.1:8086",
        "timeout": 5000
    }
}


================================================
FILE: config/graph.json
================================================
{
    "debug": false,
    "http": {
        "enabled": true,
        "listen": "%%GRAPH_HTTP%%"
    },
    "rpc": {
        "enabled": true,
        "listen": "%%GRAPH_RPC%%"
    },
    "rrd": {
        "storage": "./data/6070"
    },
    "db": {
        "dsn": "%%MYSQL%%/graph?loc=Local&parseTime=true",
        "maxIdle": 4
    },
    "callTimeout": 5000,
    "ioWorkerNum": 64,
    "migrate": {
            "enabled": false,
            "concurrency": 2,
            "replicas": 500,
            "cluster": {
                    "graph-00" : "127.0.0.1:6070"
            }
    }
}


================================================
FILE: config/hbs.json
================================================
{
    "debug": true,
    "database": "%%MYSQL%%/falcon_portal?loc=Local&parseTime=true",
    "hosts": "",
    "maxConns": 20,
    "maxIdle": 15,
    "listen": ":6030",
    "trustable": [""],
    "http": {
        "enabled": true,
        "listen": "%%HBS_HTTP%%"
    }
}


================================================
FILE: config/judge.json
================================================
{
    "debug": true,
    "debugHost": "nil",
    "remain": 11,
    "http": {
        "enabled": true,
        "listen": "%%JUDGE_HTTP%%"
    },
    "rpc": {
        "enabled": true,
        "listen": "%%JUDGE_RPC%%"
    },
    "hbs": {
        "servers": ["%%HBS_RPC%%"],
        "timeout": 300,
        "interval": 60
    },
    "alarm": {
        "enabled": true,
        "minInterval": 300,
        "queuePattern": "event:p%v",
        "redis": {
            "dsn": "%%REDIS%%",
            "maxIdle": 5,
            "connTimeout": 5000,
            "readTimeout": 5000,
            "writeTimeout": 5000
        }
    }
}


================================================
FILE: config/nodata.json
================================================
{
    "debug": true,
    "http": {
        "enabled": true,
        "listen": "%%NODATA_HTTP%%"
    },
    "plus_api":{
        "connectTimeout": 500,
        "requestTimeout": 2000,
        "addr": "http://127.0.0.1:8080",
        "token": "default-token-used-in-server-side"
    },
    "config": {
        "enabled": true,
        "dsn": "%%MYSQL%%/falcon_portal?loc=Local&parseTime=true&wait_timeout=604800",
        "maxIdle": 4
    },
    "collector":{
        "enabled": true,
        "batch": 200,
        "concurrent": 10
    },
    "sender":{
        "enabled": true,
        "connectTimeout": 500,
        "requestTimeout": 2000,
        "transferAddr": "%%TRANSFER_HTTP%%",
        "batch": 500
    }
}


================================================
FILE: config/transfer.json
================================================
{
    "debug": true,
    "minStep": 30,
    "http": {
        "enabled": true,
        "listen": "%%TRANSFER_HTTP%%"
    },
    "rpc": {
        "enabled": true,
        "listen": "%%TRANSFER_RPC%%"
    },
    "socket": {
        "enabled": true,
        "listen": "0.0.0.0:4444",
        "timeout": 3600
    },
    "judge": {
        "enabled": true,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "replicas": 500,
        "cluster": {
            "judge-00" : "%%JUDGE_RPC%%"
        }
    },
    "graph": {
        "enabled": true,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "replicas": 500,
        "cluster": {
            "graph-00" : "%%GRAPH_RPC%%"
        }
    },
    "tsdb": {
        "enabled": false,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "retry": 3,
        "address": "127.0.0.1:8088"
    },
    "transfer": {
        "enabled": false,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "retry": 3,
        "cluster": {
            "t1": "127.0.0.1:8433"
        }
    },
    "influxdb": {
        "enabled": false,
        "batch": 200,
        "retry": 3,
        "maxConns": 32,
        "username": "admin",
        "password": "123456",
        "precision": "s",
        "db": "foo",
        "address": "http://127.0.0.1:8086",
        "timeout": 5000
    },
    "p8s_relay": {
        "enabled": false,
        "batch": 200,
        "connTimeout": 1000,
        "callTimeout": 5000,
        "maxConns": 32,
        "maxIdle": 32,
        "replicas": 500,
        "notSyncMetrics": [
            "gpu.",
            "snmp."
        ],
        "cluster": {
            "p8s-relay-00" : "192.168.1.1:8080",
            "p8s-relay-01" : "192.168.1.2:8080"
        }
    }
}


================================================
FILE: docker/README.md
================================================
## Running open-falcon container

`the latest version in docker hub is v0.3`

##### 1. Start mysql and init the mysql table before the first running

```
## start mysql in container
docker run -itd \
    --name falcon-mysql \
    -v /home/work/mysql-data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=test123456 \
    -p 3306:3306 \
    mysql:5.7

## init mysql table before the first running
cd /tmp && \
git clone --depth=1 https://github.com/open-falcon/falcon-plus.git && \
cd /tmp/falcon-plus/ && \
for x in `ls ./scripts/mysql/db_schema/*.sql`; do
    echo init mysql table $x ...;
    docker exec -i falcon-mysql mysql -uroot -ptest123456 < $x;
done

rm -rf /tmp/falcon-plus/
```

##### 2. Start redis in container

```
docker run --name falcon-redis -p6379:6379 -d redis:4-alpine3.8
```

##### 3. Start falcon-plus modules in one container

```
## pull images from hub.docker.com/openfalcon
docker pull openfalcon/falcon-plus:v0.3

## run falcon-plus container
docker run -itd --name falcon-plus \
        --link=falcon-mysql:db.falcon \
        --link=falcon-redis:redis.falcon \
        -p 8433:8433 \
        -p 8080:8080 \
        -e MYSQL_PORT=root:test123456@tcp\(db.falcon:3306\) \
        -e REDIS_PORT=redis.falcon:6379  \
        -v /home/work/open-falcon/data:/open-falcon/data \
        -v /home/work/open-falcon/logs:/open-falcon/logs \
        openfalcon/falcon-plus:v0.3

## start falcon backend modules, such as graph,api,etc.
docker exec falcon-plus sh ctrl.sh start \
        graph hbs judge transfer nodata aggregator agent gateway api alarm

## or you can just start/stop/restart specific module as: 
docker exec falcon-plus sh ctrl.sh start/stop/restart xxx

## check status of backend modules
docker exec falcon-plus ./open-falcon check

## or you can check logs at /home/work/open-falcon/logs/ in your host
ls -l /home/work/open-falcon/logs/
    
```

##### 4. Start falcon-dashboard in container

```
docker run -itd --name falcon-dashboard \
    -p 8081:8081 \
    --link=falcon-mysql:db.falcon \
    --link=falcon-plus:api.falcon \
    -e API_ADDR=http://api.falcon:8080/api/v1 \
    -e PORTAL_DB_HOST=db.falcon \
    -e PORTAL_DB_PORT=3306 \
    -e PORTAL_DB_USER=root \
    -e PORTAL_DB_PASS=test123456 \
    -e PORTAL_DB_NAME=falcon_portal \
    -e ALARM_DB_HOST=db.falcon \
    -e ALARM_DB_PORT=3306 \
    -e ALARM_DB_USER=root \
    -e ALARM_DB_PASS=test123456 \
    -e ALARM_DB_NAME=alarms \
    -w /open-falcon/dashboard openfalcon/falcon-dashboard:v0.2.1  \
    './control startfg'
```

##### 5. Start falcon-agent in container

```
sudo docker run -d --restart always --name falcon-agent \
    -e NUX_ROOTFS=/rootfs \
    -v /:/rootfs:ro \
    openfalcon/falcon-plus:v0.3 \
    ./agent/bin/falcon-agent -c /open-falcon/agent/config/cfg.json
```

----

## Building open-falcon images from source code

##### Building falcon-plus

```
cd /tmp && \
git clone https://github.com/open-falcon/falcon-plus.git && \
cd /tmp/falcon-plus/ && \
docker build -t falcon-plus:v0.3 .
```

##### Building falcon-dashboard

```
cd /tmp && \
git clone https://github.com/open-falcon/dashboard.git  && \
cd /tmp/dashboard/ && \
docker build -t falcon-dashboard:v0.2.1 .
```


================================================
FILE: docker/confgen4docker.sh
================================================
#!/bin/bash

confs=(
    '%%AGENT_HTTP%%=0.0.0.0:1988'
    '%%AGGREGATOR_HTTP%%=0.0.0.0:6055'
    '%%GRAPH_HTTP%%=0.0.0.0:6071'
    '%%GRAPH_RPC%%=0.0.0.0:6070'
    '%%HBS_HTTP%%=0.0.0.0:6031'
    '%%HBS_RPC%%=0.0.0.0:6030'
    '%%JUDGE_HTTP%%=0.0.0.0:6081'
    '%%JUDGE_RPC%%=0.0.0.0:6080'
    '%%NODATA_HTTP%%=0.0.0.0:6090'
    '%%TRANSFER_HTTP%%=0.0.0.0:6060'
    '%%TRANSFER_RPC%%=0.0.0.0:8433'
    '%%PLUS_API_DEFAULT_TOKEN%%=default-token-used-in-server-side'
    '%%PLUS_API_HTTP%%=0.0.0.0:8080'
    '%%AGENT_HOSTNAME%%='
 )

configurer() {
    for i in "${confs[@]}"
    do
        search="${i%%=*}"
        replace="${i##*=}"

        uname=`uname`
        if [ "$uname" == "Darwin" ] ; then
            # Note the "" and -e  after -i, needed in OS X
            find ./out/*/config/*.json -type f -exec sed -i .tpl -e "s/${search}/${replace}/g" {} \;
        else
            find ./out/*/config/*.json -type f -exec sed -i "s/${search}/${replace}/g" {} \;
        fi
    done
}
configurer


================================================
FILE: docker/ctrl.sh
================================================
#!/bin/sh

DOCKER_DIR=/open-falcon
of_bin=$DOCKER_DIR/open-falcon
DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')

# Search $1 and replace with $2 or $3(defualt)
replace() {
    replacement=$2
    if [ -z "$replacement" ]; then
      replacement=$3
    fi
    find $DOCKER_DIR/*/config/*.json -type f -exec sed -i "s/$1/$replacement/g" {} \;
}

replace "%%MYSQL%%" "$MYSQL_PORT" "$DOCKER_HOST_IP:3306"
replace "%%REDIS%%" "$REDIS_PORT" "$DOCKER_HOST_IP:6379"
replace "%%AGGREGATOR_HTTP%%" "$AGGREGATOR_HTTP" "0.0.0.0:6055"
replace "%%GRAPH_HTTP%%" "$GRAPH_HTTP" "0.0.0.0:6071"
replace "%%GRAPH_RPC%%" "$GRAPH_RPC" "0.0.0.0:6070"
replace "%%HBS_HTTP%%" "$HBS_HTTP" "0.0.0.0:6031"
replace "%%HBS_RPC%%" "$HBS_RPC" "0.0.0.0:6030"
replace "%%JUDGE_HTTP%%" "$JUDGE_HTTP" "0.0.0.0:6081"
replace "%%JUDGE_RPC%%" "$JUDGE_RPC" "0.0.0.0:6080"
replace "%%NODATA_HTTP%%" "$NODATA_HTTP" "0.0.0.0:6090"
replace "%%TRANSFER_HTTP%%" "$TRANSFER_HTTP" "0.0.0.0:6060"
replace "%%TRANSFER_RPC%%" "$TRANSFER_RPC" "0.0.0.0:8433"
replace "%%PLUS_API_HTTP%%" "$PLUS_API_HTTP" "0.0.0.0:8080"
replace "%%AGENT_HOSTNAME%%" "$AGENT_HOSTNAME" ""

#use absolute path of metric_list_file in docker
TAB=$'\t'; sed -i "s|.*metric_list_file.*|${TAB}\"metric_list_file\": \"$DOCKER_DIR/api/data/metric\",|g" $DOCKER_DIR/api/config/*.json;

action=$1
module_name=$2
case $action in
 run)
        $DOCKER_DIR/"$module_name"/bin/falcon-"$module_name" -c /open-falcon/"$module_name"/config/cfg.json
        ;;
 *)
        supervisorctl $*
        ;;
esac


================================================
FILE: docker/k8s-cluster/Dockerfile.tpl
================================================
FROM alpine:3.7
LABEL maintainer tabsp@qq.com
USER root

ENV FALCON_DIR=/open-falcon
# agent
RUN apk add --no-cache ca-certificates git curl
# alarm
ADD https://github.com/golang/go/raw/master/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip

COPY build/%%MODULE_NAME%% ${FALCON_DIR}/%%MODULE_NAME%%
WORKDIR ${FALCON_DIR}

CMD ["/open-falcon/%%MODULE_NAME%%/bin/falcon-%%MODULE_NAME%%", "-c", "/open-falcon/%%MODULE_NAME%%/config/cfg.json"]


================================================
FILE: docker/k8s-cluster/README.md
================================================
## 分布式部署 open-falcon 到 k8s 集群

### 构建

克隆源码:

```shell
git clone https://github.com/open-falcon/falcon-plus.git && cd falcon-plus 
```

编译源码并构建 Docker 镜像

```shell
./docker/k8s-cluster/build.sh
```

### 部署

注意点:

1. graph 为有状态组件,部署方式为每个节点一个 Deployment,同时 replica 设置为 1
2. 所有配置文件使用挂载目录的方式持久化,可以改为 ConfigMap 管理配置
3. 镜像可以使用构建脚本自己构建后推送到自己的私仓使用(推荐),或者直接使用我构建好的,仓库地址在 docker/k8s-cluster/build.sh 查看或修改

================================================
FILE: docker/k8s-cluster/build.sh
================================================
#!/bin/bash
MODULES=(
    'agent'
    'aggregator'
    'alarm'
    'api'
    'gateway'
    'graph'
    'hbs'
    'judge'
    'nodata'
    'transfer'
)
DOCKER_REGISTRY=registry.cn-hangzhou.aliyuncs.com/open-falcon
VERSION=v0.3

clean() {
    echo "clean..."
    if [ -d "build" ]; then
        rm -rf build/
    fi
    mkdir build
}

build() {
    echo "build source..."
    if [ `uname -m` == "aarch64" ]; then
        BASE_IMAGE=jimmytinsley/makegcc-golang
    else
        BASE_IMAGE=openfalcon/makegcc-golang:1.10-alpine
    fi
    docker run -it --rm \
        --name build \
        -v "$(pwd)":"/go/src/github.com/open-falcon/falcon-plus" \
        -w "/go/src/github.com/open-falcon/falcon-plus" \
        $BASE_IMAGE \
        docker/k8s-cluster/init.sh
}

buildDockerImages() {
    echo "build docker images..."
    for i in "${MODULES[@]}"; do
        echo "build $i"
        awk -v module="$i" '{ gsub(/%%MODULE_NAME%%/, module); print $0 }' docker/k8s-cluster/Dockerfile.tpl > docker/k8s-cluster/Dockerfile
        docker build -f docker/k8s-cluster/Dockerfile -t $DOCKER_REGISTRY/$i:$VERSION .
        rm docker/k8s-cluster/Dockerfile
    done
}

clean
build
buildDockerImages


================================================
FILE: docker/k8s-cluster/init.sh
================================================
#!/bin/sh

apk add --no-cache ca-certificates git bash \
&& make all \
&& make pack4docker \
&& tar -zxf open-falcon-v*.tar.gz -C build \
&& rm open-falcon-v*.tar.gz

================================================
FILE: docker/k8s-cluster/modules/falcon-agent.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-agent
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 1988
  selector:
    name: falcon-agent
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-agent
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-agent
    spec:
      containers:
        - name: falcon-agent
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/agent:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 1988
              name: http
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/agent/config
              name: falcon-agent-config
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-agent/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-agent-config
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-aggregator.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-aggregator
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 6055
  selector:
    name: falcon-aggregator
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-aggregator
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-aggregator
    spec:
      containers:
        - name: falcon-aggregator
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/aggregator:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6055
              name: http
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/aggregator/config
              name: falcon-aggregator-config
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-aggregator/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-aggregator-config
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-alarm.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-alarm
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 9912
  selector:
    name: falcon-alarm
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-alarm
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-alarm
    spec:
      containers:
        - name: falcon-alarm
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/alarm:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9912
              name: http
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/alarm/config
              name: falcon-alarm-config
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-alarm/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-alarm-config
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-api.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-api
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 8080
  selector:
    name: falcon-api
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-api
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-api
    spec:
      containers:
        - name: falcon-api
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/api:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
              name: http
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/api/config
              name: falcon-api-config
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-api/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-api-config
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-dashboard.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-dashboard
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 8081
  selector:
    name: falcon-dashboard
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-dashboard
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-dashboard
    spec:
      containers:
      - name: falcon-dashboard
        image: openfalcon/falcon-dashboard:v0.2.1
        command: ["sh","-c","cd /open-falcon/dashboard &&  ./control startfg"]
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8081
        env:
        - name: API_ADDR
          value: http://falcon-api:8080/api/v1
        - name: PORTAL_DB_HOST
          value: 127.0.0.1
        - name: PORTAL_DB_PORT
          value: "3306"
        - name: PORTAL_DB_USER
          value: root
        - name: PORTAL_DB_PASS
          value: xxx
        - name: PORTAL_DB_NAME
          value: falcon_portal
        - name: ALARM_DB_HOST
          value: 127.0.0.1
        - name: ALARM_DB_PORT
          value: "3306"
        - name: ALARM_DB_USER
          value: root
        - name: ALARM_DB_PASS
          value: root
        - name: ALARM_DB_NAME
          value: alarms
        volumeMounts:
          - mountPath: /etc/localtime
            name: tz-config
      volumes:
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-graph-01.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-graph-01
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: rpc
      port: 6070
    - name: http
      port: 6071
  selector:
    name: falcon-graph-01
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-graph-01
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-graph-01
    spec:
      containers:
        - name: falcon-graph-01
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/graph:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6070
              name: rpc
              protocol: TCP
            - containerPort: 6071
              name: http
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/graph/config
              name: falcon-graph-config
            - mountPath: /open-falcon/graph/data
              name: falcon-graph-data
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-graph/01/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-graph-config
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-graph/01/data
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-graph-data
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-hbs.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-hbs
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: rpc
      port: 6030
    - name: http
      port: 6031
  selector:
    name: falcon-hbs
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-hbs
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-hbs
    spec:
      containers:
        - name: falcon-hbs
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/hbs:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6030
              name: rpc
              protocol: TCP
            - containerPort: 6031
              name: http
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/hbs/config
              name: falcon-hbs-config
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-hbs/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-hbs-config
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-judge.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-judge
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: rpc
      port: 6080
    - name: http
      port: 6081
  selector:
    name: falcon-judge
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-judge
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-judge
    spec:
      containers:
        - name: falcon-judge
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/judge:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6080
              name: rpc
              protocol: TCP
            - containerPort: 6081
              name: http
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/judge/config
              name: falcon-judge-config
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-judge/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-judge-config
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-nodata.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-nodata
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 6090
  selector:
    name: falcon-nodata
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-nodata
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-nodata
    spec:
      containers:
        - name: falcon-nodata
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/nodata:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6090
              name: http
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/nodata/config
              name: falcon-nodata-config
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-nodata/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-nodata-config
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-cluster/modules/falcon-transfer.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  namespace: open-falcon
  name: falcon-transfer
  labels:
    app: open-falcon
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 6060
    - name: rpc
      port: 8433
  selector:
    name: falcon-transfer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: open-falcon
  name: falcon-transfer
  labels:
    app: open-falcon
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: falcon-transfer
    spec:
      containers:
        - name: falcon-transfer
          image: registry.cn-hangzhou.aliyuncs.com/open-falcon/transfer:v0.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6060
              name: http
              protocol: TCP
            - containerPort: 8433
              name: rpc
              protocol: TCP
          volumeMounts:
            - mountPath: /open-falcon/transfer/config
              name: falcon-transfer-config
            - mountPath: /etc/localtime
              name: tz-config
      volumes:
        - flexVolume:
            driver: alicloud/nas
            options:
              path: /open-falcon/falcon-transfer/config
              server: xxx.cn-hangzhou.nas.aliyuncs.com
              vers: "4.0"
          name: falcon-transfer-config
        - hostPath:
            path: /etc/localtime
            type: ''
          name: tz-config

================================================
FILE: docker/k8s-example/README.md
================================================
## Running open-falcon in kubernetes

work on kubernetes 1.14 ,  the `kubectl version` like:
```
Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.0", GitCommit:"641856db18352033a0d96dbc99153fa3b27298e5", GitTreeState:"clean", BuildDate:"2019-03-25T15:53:57Z", GoVersion:"go1.12.1", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.0", GitCommit:"641856db18352033a0d96dbc99153fa3b27298e5", GitTreeState:"clean", BuildDate:"2019-03-25T15:45:25Z", GoVersion:"go1.12.1", Compiler:"gc", Platform:"linux/amd64"}
```

##### 1. Start mysql in k8s and init the mysql table before the first running

if mysql is already in k8s you can break this step

```
kubectl apply -f mysql.yaml
```

init mysql table before the first running

```
sh init_mysql_data.sh
```

##### 2. Start redis in k8s

if redis is already in k8s you can also break this step

```
kubectl apply -f redis.yaml
```

##### 3. Start falcon-plus modules in one pod

```
kubectl apply -f openfalcon-plus.yaml
```

##### 4. Start falcon-dashboard in k8s

```
kubectl apply -f openfalcon-dashboard.yaml
```

##### 5. browse the dashboard view

```
[tyhall51@192-168-10-21 k8s-example]$ kubectl get svc
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                         AGE
kubernetes              ClusterIP   10.96.0.1       <none>        443/TCP                         105d
mysql                   NodePort    10.110.20.201   <none>        3306:30535/TCP                  25m
open-falcon             NodePort    10.97.12.125    <none>        8433:31952/TCP,8080:31957/TCP   53s
open-falcon-dashboard   NodePort    10.96.119.231   <none>        8081:30191/TCP                  3s
redis                   ClusterIP   10.98.212.126   <none>        6379/TCP                        32m
```

get **open-falcon-dashboard** service localhost port **30191** , then can visit  `http://192.168.10.21:30191` in webrowser 。


[mailto](mailto:studyoo@foxmail.com)



================================================
FILE: docker/k8s-example/init_mysql_data.sh
================================================
#!/bin/sh

mysql_pod=$(kubectl get pods | grep mysql | awk '{print $1}')
cd /tmp && \
	git clone --depth=1 https://github.com/open-falcon/falcon-plus && \
	cd /tmp/falcon-plus/ && \
	for x in `ls ./scripts/mysql/db_schema/*.sql`; do
	    echo init mysql table $x ...;
	    kubectl exec -it $mysql_pod -- mysql -uroot -p123456 < $x;
	done

rm -rf /tmp/falcon-plus/

================================================
FILE: docker/k8s-example/mysql.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: db
spec:
  type: NodePort
  ports:
  - port: 3306
    targetPort: mysqlport
  selector:
    app: db
    name: mysql
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: db
        name: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        imagePullPolicy: IfNotPresent
        env:
        - name: TZ
          value: "Asia/Shanghai"
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
        ports:
        - containerPort: 3306
          name: mysqlport
        volumeMounts:
        - name: mysqldata
          subPath: mysql_data
          mountPath: /var/lib/mysql
      volumes:
        - name: mysqldata
          emptyDir: {}


================================================
FILE: docker/k8s-example/openfalcon-dashboard.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  name: open-falcon-dashboard
  labels:
    app: monitor
spec:
  type: NodePort
  ports:
    - name: web
      port: 8081
  selector:
    name: open-falcon-dashboard
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: open-falcon-dashboard
  labels:
    app: monitor
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: open-falcon-dashboard
    spec:
      containers:
      - name: open-falcon-dashboard
        image: openfalcon/falcon-dashboard:v0.2.1
        command: ["sh","-c","cd /open-falcon/dashboard &&  ./control startfg"]
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8081
        env:
        - name: API_ADDR
          value: http://open-falcon:8080/api/v1
        - name: PORTAL_DB_HOST
          value: mysql
        - name: PORTAL_DB_PORT
          value: "3306"
        - name: PORTAL_DB_USER
          value: root
        - name: PORTAL_DB_PASS
          value: 1qazxsw2
        - name: PORTAL_DB_NAME
          value: falcon_portal
        - name: ALARM_DB_HOST
          value: mysql
        - name: ALARM_DB_PORT
          value: "3306"
        - name: ALARM_DB_USER
          value: root
        - name: ALARM_DB_PASS
          value: 1qazxsw2
        - name: ALARM_DB_NAME
          value: alarms


================================================
FILE: docker/k8s-example/openfalcon-plus.yaml
================================================
apiVersion: v1
kind: ConfigMap
metadata:
  name: openfalcon-configmap
data:
  entrypoint.sh: |-
    #!/bin/bash
    /bin/sh -c 'sleep 10 && sh ctrl.sh start graph hbs judge transfer nodata aggregator gateway api alarm'  & /usr/bin/supervisord -c /etc/supervisord.conf
   agent.json: |-
    {
        "debug": true,
        "hostname": "",
        "ip": "",
        "plugin": {
            "enabled": false,
            "dir": "./plugin",
            "git": "https://github.com/open-falcon/plugin.git",
            "logs": "./logs"
        },
        "heartbeat": {
            "enabled": true,
            "addr": "open-falcon:6030",
            "interval": 60,
            "timeout": 1000
        },
        "transfer": {
            "enabled": true,
            "addrs": [
                "open-falcon:8433"
            ],
            "interval": 60,
            "timeout": 1000
        },
        "http": {
            "enabled": true,
            "listen": ":1988",
            "backdoor": false
        },
        "collector": {
            "ifacePrefix": ["eth", "em"],
            "mountPoint": []
        },
        "default_tags": {
        },
        "ignore": {
            "sys.disk.rw": true,
            "df.bytes.free": true,
            "df.bytes.total": true,
            "df.bytes.used": true,
            "df.inodes.total": true,
            "df.inodes.free": true,
            "df.inodes.used": true,
            "mem.memtotal": true,
            "mem.memused": true,
            "mem.memfree": true,
            "mem.swaptotal": true,
            "mem.swapused": true,
            "mem.swapfree": true,
            "df.statistics.total": true,
            "df.statistics.used": true
        }
    }
---
apiVersion: v1
kind: Service
metadata:
  name: open-falcon
  labels:
    app: monitor
spec:
  type: NodePort
  ports:
    - name: tcp
      port: 8433
    - name: web
      port: 8080
  selector:
    name: open-falcon
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: open-falcon
  labels:
    app: monitor
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: open-falcon
    spec:
      containers:
      - name: open-falcon
        image: openfalcon/falcon-plus:v0.3
        workingDir: /open-falcon
        command:
        - /bin/entrypoint.sh
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8433
        - containerPort: 8080
        env:
        - name: MYSQL_PORT
          value: root:123456@tcp(mysql:3306)
        - name: REDIS_PORT
          value: redis:6379
        volumeMounts:
        - name: open-falcon-data
          mountPath: /open-falcon/data
        - name: configmap-volume
          mountPath: /bin/entrypoint.sh
          readOnly: true
          subPath: entrypoint.sh
      volumes:
      - name: open-falcon-data
        emptyDir: {}
      - name: configmap-volume
        configMap:
          defaultMode: 0700
          name: openfalcon-configmap
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: falcon-plus
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    k8s-app: falcon-agent
    kubernetes.io/cluster-service: 'true'
    version: v1
  name: falcon-agent
spec:
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: falcon-agent
      kubernetes.io/cluster-service: 'true'
      version: v1
  template:
    metadata:
      creationTimestamp: null
      labels:
        k8s-app: falcon-agent
        kubernetes.io/cluster-service: 'true'
        version: v1
    spec:
      containers:
        - args:
            - '-c'
            - /open-falcon/config/agent.json
          command:
            - ./agent/bin/falcon-agent
          env:
            - name: GIN_MODE
              value: release
            - name: NUX_ROOTFS
              value: /rootfs
            - name: FALCON_ENDPOINT
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: spec.nodeName
          image: 'openfalcon/falcon-plus:v0.3'
          workingDir: /open-falcon
          imagePullPolicy: IfNotPresent
          name: falcon-agent
          resources:
            limits:
              cpu: 200m
              memory: 200Mi
            requests:
              cpu: 200m
              memory: 200Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            - mountPath: /rootfs
              name: rootfs
              readOnly: true
            - mountPath: /open-falcon/config
              name: configmap-volume
              readOnly: true
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: falcon-plus
      serviceAccountName: falcon-plus
      terminationGracePeriodSeconds: 30
      volumes:
        - hostPath:
            path: /
            type: ''
          name: rootfs
        - name: configmap-volume
          configMap:
            defaultMode: 0700
            name: openfalcon-configmap
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate

================================================
FILE: docker/k8s-example/redis.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: db
spec:
  ports:
    - port: 6379
  selector:
    app: db
    name: redis
---
apiVersion: extensions/v1beta1 
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: db
        name: redis
    spec:
      containers:
      - image: redis:alpine
        name: redis
        livenessProbe:
          tcpSocket:
            port: 6379
        ports:
        - containerPort: 6379
          name: redis


================================================
FILE: docker/mysql-init/Dockerfile
================================================
from alpine:3.5

env MYSQL_HOST=mysql \
    MYSQL_USER=root \
    MYSQL_PASSWORD=test123456

run apk add --no-cache mysql-client git
copy init_mysql_data.sh /

cmd ["/init_mysql_data.sh"]


================================================
FILE: docker/mysql-init/init_mysql_data.sh
================================================
#!/bin/sh

Host=${MYSQL_HOST}
User=${MYSQL_USER}
Password=${MYSQL_PASSWORD}

cd /tmp && \
        git clone --depth=1 https://github.com/open-falcon/falcon-plus && \
        cd /tmp/falcon-plus/ && \
        for x in `ls ./scripts/mysql/db_schema/*.sql`; do
            echo init mysql table $x ...;
            mysql -h${Host} -u${User} -p${Password} < $x;
        done

rm -rf /tmp/falcon-plus/

================================================
FILE: docker/supervisord.conf
================================================
[supervisord]
childlogdir = /open-falcon/logs/
logfile = /open-falcon/logs/supervisord.log
pidfile = /var/run/supervisord.pid
nodaemon = true
directory = /open-falcon

[unix_http_server]
file = /var/run/supervisor.sock
chmod = 0777
chown= nobody:nogroup

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl = unix:///var/run/supervisor.sock

[program:graph]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:hbs]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:judge]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:transfer]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:nodata]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:aggregator]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:agent]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:gateway]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:api]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false

[program:alarm]
user = root
directory = /open-falcon/%(program_name)s
command = /open-falcon/%(program_name)s/bin/falcon-%(program_name)s -c /open-falcon/%(program_name)s/config/cfg.json
stdout_logfile = /open-falcon/logs/%(program_name)s.log
stderr_logfile = /open-falcon/logs/%(program_name)s.err
autostart=false



================================================
FILE: docker-compose.yml
================================================
version: '3.5'

services:
  mysql:
    container_name: falcon-mysql
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - ./scripts/mysql/db_schema:/docker-entrypoint-initdb.d/
      - mysql-data:/var/lib/mysql

  redis:
    container_name: falcon-redis
    image: redis:4-alpine3.8

  hbs: &falcon
    container_name: falcon-hbs
    build:
      context: ./
      args:
        MODULE: hbs
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-hbs:dev
    environment:
      MYSQL_PORT: root:root@tcp\(falcon-mysql:3306\)
      REDIS_PORT: falcon-redis:6379
      AGGREGATOR_HTTP: falcon-aggregator:6055
      GRAPH_HTTP: falcon-graph:6071
      GRAPH_RPC: falcon-graph:6070
      HBS_HTTP: falcon-hbs:6031
      HBS_RPC: falcon-hbs:6030
      JUDGE_HTTP: falcon-judge:6081
      JUDGE_RPC: falcon-judge:6080
      NODATA_HTTP: falcon-nodata:6090
      TRANSFER_HTTP: falcon-transfer:6060
      TRANSFER_RPC: falcon-transfer:8433
      PLUS_API_HTTP: falcon-api:8080
      AGENT_HOSTNAME: docker-agent
    depends_on:
      - mysql
      - redis
    command: "sh ctrl.sh run hbs"

  agent:
    <<: *falcon
    build:
      context: ./
      args:
        MODULE: agent
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-agent:dev
    container_name: falcon-agent
    depends_on:
      - hbs
      - transfer
    command: "sh ctrl.sh run agent"

  aggregator:
    <<: *falcon
    build:
      context: ./
      args:
        MODULE: aggregator
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-aggregator:dev
    container_name: falcon-aggregator
    command: "sh ctrl.sh run aggregator"

  nodata:
    <<: *falcon
    build:
      context: ./
      args:
        MODULE: nodata
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-nodata:dev
    container_name: falcon-nodata
    command: "sh ctrl.sh run nodata"

  api:
    <<: *falcon
    build:
      context: ./
      args:
        MODULE: api
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-api:dev
    container_name: falcon-api
    command: "sh ctrl.sh run api"
    ports:
      - 8080:8080

  alarm:
    <<: *falcon
    build:
      context: ./
      args:
        MODULE: alarm
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-alarm:dev
    container_name: falcon-alarm
    command: "sh ctrl.sh run alarm"

  transfer:
    <<: *falcon
    build:
      context: ./
      args:
        MODULE: transfer
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-transfer:dev
    container_name: falcon-transfer
    depends_on:
      - graph
    command: "sh ctrl.sh run transfer"

  judge:
    <<: *falcon
    build:
      context: ./
      args:
        MODULE: judge
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-judge:dev
    container_name: falcon-judge
    command: "sh ctrl.sh run judge"

  graph:
    <<: *falcon
    build:
      context: ./
      args:
        MODULE: graph
      dockerfile: Dockerfile.module
    image: openfalcon/falcon-graph:dev
    container_name: falcon-graph
    volumes:
      - graph-data:/open-falcon/data
    command: "sh ctrl.sh run graph"

  dashboard:
    container_name: falcon-dashboard
    image: openfalcon/falcon-dashboard:v0.2.1
    entrypoint: ./control startfg
    environment:
      API_ADDR: http://falcon-api:8080/api/v1
      PORTAL_DB_HOST: mysql
      PORTAL_DB_PORT: 3306
      PORTAL_DB_USER: root
      PORTAL_DB_PASS: root
      PORTAL_DB_NAME: falcon_portal
      ALARM_DB_HOST: mysql
      ALARM_DB_PORT: 3306
      ALARM_DB_USER: root
      ALARM_DB_PASS: root
      ALARM_DB_NAME: alarms
    working_dir: /open-falcon/dashboard
    ports:
      - 8081:8081

volumes:
  mysql-data:
  graph-data:


================================================
FILE: docker_test.sh
================================================
#!/bin/bash

export DB_USER=root
export DB_PASSWORD=test123456
export DB_HOST=127.0.0.1
export DB_PORT=13306
export REDIS_HOST=127.0.0.1
export REDIS_PORT=16379
export API_PORT=18080
export API_HOST=127.0.0.1

docker rm -f falcon-mysql falcon-redis falcon-plus &> /dev/null
if [[ `uname -m` == "aarch64" ]]; then
	docker run --name falcon-mysql -e MYSQL_ROOT_PASSWORD=$DB_PASSWORD -p $DB_PORT:3306 -d mariadb:10.3
else
	docker run --name falcon-mysql -e MYSQL_ROOT_PASSWORD=$DB_PASSWORD -p $DB_PORT:3306 -d mysql:5.7
fi
docker run --name falcon-redis -p $REDIS_PORT:6379 -d redis:4-alpine3.8

echo "waiting mysql start..."
sleep 15
for x in `ls ./scripts/mysql/db_schema/*.sql`; do
    echo "- - -" $x ...
    mysql -h $DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASSWORD < $x
done

commit_id=`git rev-parse --short HEAD`
image_tag="falcon-plus:$commit_id"

#build docker image from source code
if [[ `uname -m` == "aarch64" ]]; then
	docker build -t $image_tag -f Dockerfile_arm64 .
else
	docker build -t $image_tag .
fi

## run falcon-plus container
docker run -itd --name falcon-plus \
	 --link=falcon-mysql:db.falcon \
	 --link=falcon-redis:redis.falcon \
	 -p 18433:8433 \
	 -p 18080:8080 \
	 -e MYSQL_PORT=$DB_USER:$DB_PASSWORD@tcp\(db.falcon:3306\) \
	 -e REDIS_PORT=redis.falcon:6379  \
	 $image_tag
sleep 15

## start falcon backend modules, such as graph,api,etc.
docker exec falcon-plus sh ctrl.sh start \
		graph hbs judge transfer nodata aggregator agent gateway api alarm

echo "sleep 15s waiting for falcon-plus process ready..."
sleep 15

make test


================================================
FILE: docs/LICENSE.md
================================================
The MIT License (MIT)

Copyright (c) [year] [fullname]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: docs/Makefile
================================================
SRC = $(wildcard lib/*/*.js)
HTML = $(wildcard lib/*/*.html)
TEMPLATES = $(HTML:.html=.js)
LESS = $(wildcard lib/*/*.less)
CSS = $(LESS:.less=.css)

build: components $(SRC) $(TEMPLATES) $(CSS)
	@component build --verbose --out . --name assets

components: component.json
	@component install

%.js: %.html
	@component convert $<

%.css: %.less
	@lessc $< $@

clean:
	rm -fr build components $(TEMPLATES)

.PHONY: clean


================================================
FILE: docs/README.md
================================================
## The "What ?" and the "Why ?"

**Carte** is a simple Jekyll based documentation website for APIs. It is designed as a boilerplate to build your own documentation and is heavily inspired from [Swagger](http://swagger.wordnik.com/) and [I/O docs](http://www.mashery.com/product/io-docs). Fork it, add specifications for your APIs calls and customize the theme. <small>Go ahead, see if we care.</small>

We built **Carte** because the existing options (Swagger and the likes) were trying to do too much and did not match our needs:

1. Most of our API calls are sending JSON objects, as opposed to a series of parameters,
1. Being able to query the real API is nice, but running anything but `GET` calls can get tricky ("What do you mean I deleted my stuff? I was just trying out the API calls!"),
1. Overall, setting up a separate server for what really requires a good static documentation seemed overkill.

The real value of **Carte** is its structure for describing APIs, not its underlying technical stack (or lack-thereof). In a nutshell; **we built a static template for your API documentation, feel free to re-use it**.

## Install

It' Jekyll god dammit:

1. Clone this repository on your local,
1. [Install Jekyll](https://github.com/mojombo/jekyll/wiki/install),
1. Go at the root of the repository and run ```jekyll serve --watch```,
1. Go to http://localhost:4000,
1. [Great success! High five!](http://www.youtube.com/watch?v=wWWyJwHQ-4E)

## How to...

### Adding a new API call

You can add a new API call by simply adding a new post in the `_posts` folder. Jekyll by default forces you to specify a date in the file path: it makes us sad pandas too, but you'll have to stick to this format. You can use dates to control the order in which API calls are displayed in the interface.

Each API call can define a few values in its YAML header:

Variable | Mandatory | Default | Description
--- | --- | --- | ---
``title`` | Y | - | A short description of what that calls does.
``path`` | N | - | The URL for the API call, including potential parameters.
``type`` | N | - | Set it to `PUT`, `GET`, `POST`, `DELETE` or nothing (for parts of your documentation that do not relate to an actual API call).

A typical header:

```
---
path: '/stuff/:id'
title: 'Delete a thing'
type: 'DELETE'

layout: nil
---
```

We then describe the request and response (or whatever else you wish to talk about) in the body of our post. Check the placeholders present in the `_posts` folder to get an idea of what it can look like.

### Grouping calls

Adding a category to your YAML header will allows you to group methods in the navigation. It is particularly helpful as you start having a lot of methods and need to organize them. For example:

```
---
category: Stuff
path: '/stuff/:id'
title: 'Delete a thing'
type: 'DELETE'

layout: nil
---
```

### Edit the design

The default UI is mostly described through the `css/style.css` file and a couple short jQuery scripts in the `/_layouts/default.html` layout. Hack it to oblivion.


================================================
FILE: docs/_config.yml
================================================
---
exclude: ['README.markdown']
permalink: ':title'
safe: false
title: 'Falcon+ API'
project_name: 'Falcon+'


================================================
FILE: docs/_includes/nav.html
================================================
<h1>{{ site.title }}</h1>
<ul id='links'>
  {% for post in site.posts %}
    {% if post.category == null %}
    <li><a href='#{{ post.url }}'>{{ post.title }}</a></li>
    {% endif %}
  {% endfor %}
  {% for category in site.categories %}
  <li><h2>{{ category | first }}</h2>
    <ul>
    {% for posts in category %}
      {% for post in posts %}        
        <li class='{{ post.type }}'><a href='#{{ post.url }}'>{{ post.title }}</a></li>
      {% endfor %}
    {% endfor %}
    </ul>
  </li>
{% endfor %}
</ul>

================================================
FILE: docs/_layouts/default.html
================================================
<!DOCTYPE html>
<head>
  <title>{{ site.title }}</title>
  <meta charset='utf-8'/>
  <meta name='description' content='Documentation website'/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'/>
  <link href='assets.css' rel='stylesheet' type='text/css'>
</head>
<body>  
  {{ content }}
  
  <!--[if lt IE 9]><script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script><![endif]-->
  <script src='assets.js' type='text/javascript'></script>
  <script>require('boot');</script>
</body>
</html>


================================================
FILE: docs/_posts/2017-01-01-authentication.md
================================================
---
title: 'Auth Session'
apiurl: '/api/v1/user/auth_session'
type: 'GET'
layout: default
---

透过Session检查去判定使用者可否存取资源

### RequestHeader
透过RequestHeader 的 Apitoken做验证
```"RequestHeader": {
  "Apitoken": "{\"name\":\"root\",\"sig\":\"427d6803b78311e68afd0242ac130006\"}",
  "X-Forwarded-For": " 127.0.0.1"
}```

### Response

Session 为有效
```Status: 200```
```{"message":"session is vaild!"}```

For errors responses, see the [response status codes documentation](#/response-status-codes).


================================================
FILE: docs/_posts/2017-01-01-response-status-codes.md
================================================
---
title: 'Response status codes'

layout: default
---

### Success

* `POST`, `GET`, `PUT`, `DELETE` returns `200` on success,
* 当参数使用不正确的时候会回覆 `400`

### 参考

return code 请参考 [status.go](https://golang.org/src/net/http/status.go)


================================================
FILE: docs/_posts/Admin/2017-01-01-admin_change_role.md
================================================
---
category: Admin
apiurl: '/api/v1/admin/change_user_role'
title: "Change User's role"
type: 'PUT'
sample_doc: 'admin.html'
layout: default
---

* [Session](#/authentication) Required
* `Admin` usage
* admin:
  * accept option:
    * yes
    * no

### Request
```{"user_id": 14, "admin": "yes"}```

### Response

```Status: 200```
```{"message":"user role update sccuessful, affect row: 1"}```


================================================
FILE: docs/_posts/Admin/2017-01-01-admin_change_user_passwd.md
================================================
---
category: Admin
apiurl: '/api/v1/admin/change_user_passwd'
title: "Change User's Password"
type: 'PUT'
sample_doc: 'admin.html'
layout: default
---

* [Session](#/authentication) Required
* `Admin` usage

### Request
```{"user_id": 14, "password": "newpasswd"}```

### Response

```Status: 200```
```{"message":"password updated!"}```


================================================
FILE: docs/_posts/Admin/2017-01-01-admin_delete_user.md
================================================
---
category: Admin
apiurl: '/api/v1/admin/delete_user'
title: 'Delete User'
type: 'DELETE'
sample_doc: 'admin.html'
layout: default
---

* [Session](#/authentication) Required
* `Admin` usage

### Request
```{"user_id": 31}```

### Response

```Status: 200```
```{"message":"user 31 has been delete, affect row: 1"}```


================================================
FILE: docs/_posts/Admin/2017-12-07-admin_login.md
================================================
---
category: Admin
apiurl: '/api/v1/admin/login'
title: 'Admin Login'
type: 'POST'
sample_doc: 'admin.html'
layout: default
---

SSO 登入

* [Session](#/authentication) Required
* `Admin` usage

### Request
```{
  "name": "test2",
}```

### Response

```Status: 200```
```{
  "sig": "9d791331c0ea11e690c5001500c6ca5a",
  "name": "test2",
  "admin": false
}```

For errors responses, see the [response status codes documentation](#/response-status-codes).


================================================
FILE: docs/_posts/Aggregator/2017-01-01-aggreator_create.md
================================================
---
category: Aggregator
apiurl: '/api/v1/aggregator'
title: "Create Aggregator to a HostGroup"
type: 'POST'
sample_doc: 'aggregator.html'
layout: default
---

* [Session](#/authentication) Required
* numerator: 分子
* denominator: 分母
* step: 汇报周期(秒为单位)

### Request

```{
  "tags": "",
  "step": 60,
  "numerator": "$(cpu.idle)",
  "metric": "test.idle",
  "hostgroup_id": 343,
  "endpoint": "testenp",
  "denominator": "2"
}```

### Response

```Status: 200```
```{
  "id": 16,
  "grp_id": 343,
  "numerator": "$(cpu.idle)",
  "denominator": "2",
  "endpoint": "testenp",
  "metric": "test.idle",
  "tags": "",
  "ds_type": "GAUGE",
  "step": 60,
  "creator": "root"
}``
Download .txt
gitextract_lxxa1vqu/

├── .dockerignore
├── .gitignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.module
├── Dockerfile_arm64
├── LICENSE
├── Makefile
├── NOTICE
├── README.md
├── VERSION
├── api-standard.md
├── cmd/
│   ├── check.go
│   ├── monitor.go
│   ├── reload.go
│   ├── restart.go
│   ├── start.go
│   └── stop.go
├── common/
│   ├── .gitignore
│   ├── LICENSE
│   ├── NOTICE
│   ├── backend_pool/
│   │   ├── rpc_backends.go
│   │   └── tsdb_backends.go
│   ├── db/
│   │   └── db.go
│   ├── model/
│   │   ├── agent.go
│   │   ├── event.go
│   │   ├── expression.go
│   │   ├── graph.go
│   │   ├── host.go
│   │   ├── influxdb.go
│   │   ├── judge.go
│   │   ├── metric.go
│   │   ├── nodata.go
│   │   ├── prometheus.go
│   │   ├── rpc.go
│   │   ├── strategy.go
│   │   ├── template.go
│   │   ├── transfer.go
│   │   └── tsdb.go
│   ├── proc/
│   │   └── proc.go
│   ├── sdk/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── requests/
│   │   │   ├── auth_request.go
│   │   │   └── post.go
│   │   └── sender/
│   │       ├── linkedlist.go
│   │       ├── make.go
│   │       ├── push.go
│   │       └── sender.go
│   └── utils/
│       ├── counter.go
│       ├── date.go
│       ├── formatter.go
│       ├── func.go
│       ├── func_test.go
│       ├── map.go
│       ├── md5.go
│       ├── md5_test.go
│       ├── objpool.go
│       ├── statistics.go
│       ├── tags.go
│       └── tags_test.go
├── config/
│   ├── agent.json
│   ├── aggregator.json
│   ├── alarm.json
│   ├── api.json
│   ├── confgen.sh
│   ├── falcon2p8s.json
│   ├── gateway.json
│   ├── graph.json
│   ├── hbs.json
│   ├── judge.json
│   ├── nodata.json
│   └── transfer.json
├── docker/
│   ├── README.md
│   ├── confgen4docker.sh
│   ├── ctrl.sh
│   ├── k8s-cluster/
│   │   ├── Dockerfile.tpl
│   │   ├── README.md
│   │   ├── build.sh
│   │   ├── init.sh
│   │   └── modules/
│   │       ├── falcon-agent.yaml
│   │       ├── falcon-aggregator.yaml
│   │       ├── falcon-alarm.yaml
│   │       ├── falcon-api.yaml
│   │       ├── falcon-dashboard.yaml
│   │       ├── falcon-graph-01.yaml
│   │       ├── falcon-hbs.yaml
│   │       ├── falcon-judge.yaml
│   │       ├── falcon-nodata.yaml
│   │       └── falcon-transfer.yaml
│   ├── k8s-example/
│   │   ├── README.md
│   │   ├── init_mysql_data.sh
│   │   ├── mysql.yaml
│   │   ├── openfalcon-dashboard.yaml
│   │   ├── openfalcon-plus.yaml
│   │   └── redis.yaml
│   ├── mysql-init/
│   │   ├── Dockerfile
│   │   └── init_mysql_data.sh
│   └── supervisord.conf
├── docker-compose.yml
├── docker_test.sh
├── docs/
│   ├── LICENSE.md
│   ├── Makefile
│   ├── README.md
│   ├── _config.yml
│   ├── _includes/
│   │   └── nav.html
│   ├── _layouts/
│   │   └── default.html
│   ├── _posts/
│   │   ├── 2017-01-01-authentication.md
│   │   ├── 2017-01-01-response-status-codes.md
│   │   ├── Admin/
│   │   │   ├── 2017-01-01-admin_change_role.md
│   │   │   ├── 2017-01-01-admin_change_user_passwd.md
│   │   │   ├── 2017-01-01-admin_delete_user.md
│   │   │   └── 2017-12-07-admin_login.md
│   │   ├── Aggregator/
│   │   │   ├── 2017-01-01-aggreator_create.md
│   │   │   ├── 2017-01-01-aggreator_delete.md
│   │   │   ├── 2017-01-01-aggreator_of_hostgroup.md
│   │   │   ├── 2017-01-01-aggreator_update.md
│   │   │   └── 2017-01-01-get_aggreator_by_id.md
│   │   ├── Alarm/
│   │   │   ├── 2017-01-01-alarm_eventcases_get_by_id.md
│   │   │   ├── 2017-01-01-alarm_eventcases_list.md
│   │   │   ├── 2017-01-01-alarm_eventnote_create.md
│   │   │   ├── 2017-01-01-alarm_eventnote_get.md
│   │   │   └── 2017-01-01-alarm_events_create.md
│   │   ├── DashboardGraph/
│   │   │   ├── 2017-01-01-dashboard_graph_create.md
│   │   │   ├── 2017-01-01-dashboard_graph_create_tmpgraph.md
│   │   │   ├── 2017-01-01-dashboard_graph_delete.md
│   │   │   ├── 2017-01-01-dashboard_graph_get.md
│   │   │   ├── 2017-01-01-dashboard_graph_get_tmpgraph_by_id.md
│   │   │   ├── 2017-01-01-dashboard_graph_update.md
│   │   │   └── 2017-01-01-dashboard_graphs_gets_by_screenid.md
│   │   ├── DashboardScreen/
│   │   │   ├── 2017-01-01-dashboard_screen_create.md
│   │   │   ├── 2017-01-01-dashboard_screen_delete.md
│   │   │   ├── 2017-01-01-dashboard_screen_get_by_id.md
│   │   │   ├── 2017-01-01-dashboard_screen_gets_all.md
│   │   │   ├── 2017-01-01-dashboard_screen_gets_by_pid.md
│   │   │   └── 2017-01-01-dashboard_screen_update.md
│   │   ├── Expression/
│   │   │   ├── 2017-01-01-expression_create.md
│   │   │   ├── 2017-01-01-expression_delete.md
│   │   │   ├── 2017-01-01-expression_info_by_id.md
│   │   │   ├── 2017-01-01-expression_list.md
│   │   │   └── 2017-01-01-expression_update.md
│   │   ├── Graph/
│   │   │   ├── 2017-01-01-endpoint_counter.md
│   │   │   ├── 2017-01-01-endpoints.md
│   │   │   ├── 2017-01-01-grafana.md
│   │   │   └── 2017-01-01-graph_histroy.md
│   │   ├── Host/
│   │   │   ├── 2017-01-01-host_maintain.md
│   │   │   ├── 2017-01-01-host_related_hostgroup.md
│   │   │   ├── 2017-01-01-host_related_template.md
│   │   │   └── 2017-01-01-host_reset.md
│   │   ├── HostGroup/
│   │   │   ├── 2017-01-01-hostgroup_add_host.md
│   │   │   ├── 2017-01-01-hostgroup_create.md
│   │   │   ├── 2017-01-01-hostgroup_delete.md
│   │   │   ├── 2017-01-01-hostgroup_get_info_by_id.md
│   │   │   ├── 2017-01-01-hostgroup_list.md
│   │   │   ├── 2017-01-01-hostgroup_template_bind.md
│   │   │   ├── 2017-01-01-hostgroup_template_list.md
│   │   │   ├── 2017-01-01-hostgroup_template_unbind.md
│   │   │   ├── 2017-01-01-hostgroup_unbind_host.md
│   │   │   ├── 2017-01-01-hostgroup_update.md
│   │   │   └── 2017-08-22-hostgroup_update_partial_hosts.md
│   │   ├── NoData/
│   │   │   ├── 2017-01-01-nodata_create.md
│   │   │   ├── 2017-01-01-nodata_delete.md
│   │   │   ├── 2017-01-01-nodata_info_by_id.md
│   │   │   ├── 2017-01-01-nodata_list.md
│   │   │   └── 2017-01-01-nodata_update.md
│   │   ├── Plugin/
│   │   │   ├── 2017-01-01-plugin_create.md
│   │   │   ├── 2017-01-01-plugin_delete.md
│   │   │   └── 2017-01-01-plugin_info_by_id.md
│   │   ├── Strategy/
│   │   │   ├── 2017-01-01-metric_tmplist.md
│   │   │   ├── 2017-01-01-strategy_create.md
│   │   │   ├── 2017-01-01-strategy_delete.md
│   │   │   ├── 2017-01-01-strategy_info_by_id.md
│   │   │   ├── 2017-01-01-strategy_list.md
│   │   │   └── 2017-01-01-strategy_update.md
│   │   ├── Team/
│   │   │   ├── 2017-01-01-team_create.md
│   │   │   ├── 2017-01-01-team_delete_by_id.md
│   │   │   ├── 2017-01-01-team_info_by_id.md
│   │   │   ├── 2017-01-01-team_info_by_name.md
│   │   │   ├── 2017-01-01-team_list.md
│   │   │   ├── 2017-01-01-team_update.md
│   │   │   └── 2018-11-19-add-user-to-team.md
│   │   ├── Template/
│   │   │   ├── 2017-01-01-tpl_action_create.md
│   │   │   ├── 2017-01-01-tpl_action_update.md
│   │   │   ├── 2017-01-01-tpl_create.md
│   │   │   ├── 2017-01-01-tpl_delete.md
│   │   │   ├── 2017-01-01-tpl_hgp_list.md
│   │   │   ├── 2017-01-01-tpl_info_by_id.md
│   │   │   ├── 2017-01-01-tpl_list.md
│   │   │   └── 2017-01-01-tpl_update.md
│   │   └── User/
│   │       ├── 2017-01-01-user_change_password.md
│   │       ├── 2017-01-01-user_create.md
│   │       ├── 2017-01-01-user_current.md
│   │       ├── 2017-01-01-user_get_info_by_id.md
│   │       ├── 2017-01-01-user_get_info_by_name.md
│   │       ├── 2017-01-01-user_get_teams.md
│   │       ├── 2017-01-01-user_is_in_teams.md
│   │       ├── 2017-01-01-user_list.md
│   │       ├── 2017-01-01-user_login.md
│   │       ├── 2017-01-01-user_logout.md
│   │       ├── 2017-01-01-user_update.md
│   │       └── 2019-04-14-update-specific-user.md
│   ├── assets.css
│   ├── assets.js
│   ├── doc/
│   │   ├── admin.html
│   │   ├── admin.html.json
│   │   ├── aggregator.html
│   │   ├── aggregator.html.json
│   │   ├── alarm.html
│   │   ├── alarm.html.json
│   │   ├── expression.html
│   │   ├── expression.html.json
│   │   ├── graph.html
│   │   ├── graph.html.json
│   │   ├── host.html
│   │   ├── host.html.json
│   │   ├── hostgroup.html
│   │   ├── hostgroup.html.json
│   │   ├── nodata.html
│   │   ├── nodata.html.json
│   │   ├── plugin.html
│   │   ├── plugin.html.json
│   │   ├── team.html
│   │   ├── team.html.json
│   │   ├── template.html
│   │   ├── template.html.json
│   │   ├── user.html
│   │   └── user.html.json
│   ├── index.html
│   └── robots.txt
├── g/
│   ├── g.go
│   ├── tool.go
│   └── tool_test.go
├── go.mod
├── go.sum
├── main.go
├── modules/
│   ├── agent/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   ├── builtin.go
│   │   │   ├── collector.go
│   │   │   ├── ips.go
│   │   │   ├── plugin.go
│   │   │   └── reporter.go
│   │   ├── funcs/
│   │   │   ├── agent.go
│   │   │   ├── checker.go
│   │   │   ├── common.go
│   │   │   ├── cpustat.go
│   │   │   ├── dfstat.go
│   │   │   ├── diskstats.go
│   │   │   ├── du.go
│   │   │   ├── du_test.go
│   │   │   ├── funcs.go
│   │   │   ├── gpu.go
│   │   │   ├── ifstat.go
│   │   │   ├── kernel.go
│   │   │   ├── loadavg.go
│   │   │   ├── meminfo.go
│   │   │   ├── netstat.go
│   │   │   ├── portstat.go
│   │   │   ├── procs.go
│   │   │   ├── snmp.go
│   │   │   ├── sockstat.go
│   │   │   └── urlstat.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── const.go
│   │   │   ├── g.go
│   │   │   ├── logger.go
│   │   │   ├── rpc.go
│   │   │   ├── tool.go
│   │   │   ├── transfer.go
│   │   │   ├── var.go
│   │   │   └── var_test.go
│   │   ├── http/
│   │   │   ├── admin.go
│   │   │   ├── cpu.go
│   │   │   ├── df.go
│   │   │   ├── health.go
│   │   │   ├── http.go
│   │   │   ├── iostat.go
│   │   │   ├── kernel.go
│   │   │   ├── memory.go
│   │   │   ├── page.go
│   │   │   ├── plugin.go
│   │   │   ├── push.go
│   │   │   ├── run.go
│   │   │   └── system.go
│   │   ├── main.go
│   │   ├── plugins/
│   │   │   ├── plugins.go
│   │   │   ├── reader.go
│   │   │   └── scheduler.go
│   │   ├── public/
│   │   │   ├── css/
│   │   │   │   ├── font-awesome/
│   │   │   │   │   ├── css/
│   │   │   │   │   │   └── archive/
│   │   │   │   │   │       ├── font-awesome-ie7.css
│   │   │   │   │   │       └── font-awesome.css
│   │   │   │   │   └── font/
│   │   │   │   │       └── FontAwesome.otf
│   │   │   │   ├── g.css
│   │   │   │   ├── odometer.css
│   │   │   │   ├── pages/
│   │   │   │   │   └── dashboard.css
│   │   │   │   └── style.css
│   │   │   ├── index.html
│   │   │   └── js/
│   │   │       ├── base.js
│   │   │       ├── bootstrap.js
│   │   │       ├── dashboard.js
│   │   │       ├── jquery.js
│   │   │       └── odometer.js
│   │   └── version.go
│   ├── aggregator/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   ├── computer.go
│   │   │   ├── query.go
│   │   │   ├── run.go
│   │   │   ├── run_test.go
│   │   │   ├── updater.go
│   │   │   └── worker.go
│   │   ├── db/
│   │   │   ├── db.go
│   │   │   └── reader.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── g.go
│   │   │   └── items.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── http.go
│   │   │   └── proc.go
│   │   ├── main.go
│   │   ├── sdk/
│   │   │   ├── sdk.go
│   │   │   └── sdk_test.go
│   │   └── version.go
│   ├── alarm/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── api/
│   │   │   ├── links.go
│   │   │   ├── portal.go
│   │   │   ├── portal_test.go
│   │   │   ├── uic.go
│   │   │   └── uic_test.go
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   ├── builder.go
│   │   │   ├── callback.go
│   │   │   ├── combiner.go
│   │   │   ├── event_cleaner.go
│   │   │   ├── event_consumer.go
│   │   │   ├── event_reader.go
│   │   │   ├── im_sender.go
│   │   │   ├── init_sender.go
│   │   │   ├── mail_sender.go
│   │   │   ├── model.go
│   │   │   └── sms_sender.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── eventdto.go
│   │   │   ├── g.go
│   │   │   ├── logger.go
│   │   │   └── redis.go
│   │   ├── gitversion
│   │   ├── http/
│   │   │   ├── controller.go
│   │   │   └── http.go
│   │   ├── main.go
│   │   ├── model/
│   │   │   ├── database.go
│   │   │   ├── event/
│   │   │   │   ├── event.go
│   │   │   │   └── event_operation.go
│   │   │   ├── im.go
│   │   │   ├── mail.go
│   │   │   └── sms.go
│   │   ├── redi/
│   │   │   ├── msg_reader.go
│   │   │   └── msg_writer.go
│   │   └── version.go
│   ├── falcon2p8s/
│   │   ├── .gitignore
│   │   ├── ReadMe.md
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── const.go
│   │   │   ├── g.go
│   │   │   ├── logger.go
│   │   │   └── var.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── cron.go
│   │   │   ├── helper.go
│   │   │   └── http.go
│   │   ├── main.go
│   │   ├── middlewares/
│   │   │   └── scraping.go
│   │   ├── rpc/
│   │   │   ├── model.go
│   │   │   ├── receiver.go
│   │   │   └── rpc.go
│   │   ├── sm.example.yaml
│   │   ├── utils/
│   │   │   └── func.go
│   │   └── version.go
│   ├── gateway/
│   │   └── README.md
│   ├── graph/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── api/
│   │   │   ├── graph.go
│   │   │   └── rpc.go
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   └── clean.go
│   │   ├── doc/
│   │   │   └── README.md
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── db.go
│   │   │   ├── g.go
│   │   │   ├── git.go
│   │   │   ├── logger.go
│   │   │   ├── utils.go
│   │   │   └── utils_test.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── helper.go
│   │   │   ├── http.go
│   │   │   ├── index.go
│   │   │   └── proc.go
│   │   ├── index/
│   │   │   ├── cache.go
│   │   │   ├── index.go
│   │   │   ├── index_update_all_task.go
│   │   │   └── index_update_incr_task.go
│   │   ├── main.go
│   │   ├── proc/
│   │   │   └── proc.go
│   │   ├── rrdtool/
│   │   │   ├── migrate.go
│   │   │   ├── rrdtool.go
│   │   │   ├── sync_disk.go
│   │   │   └── utils.go
│   │   ├── store/
│   │   │   ├── history.go
│   │   │   ├── linkedlist.go
│   │   │   └── store.go
│   │   ├── test/
│   │   │   ├── debug
│   │   │   ├── graph.list
│   │   │   └── http.recv.history
│   │   └── version.go
│   ├── hbs/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── cache/
│   │   │   ├── agents.go
│   │   │   ├── cache.go
│   │   │   ├── expressions.go
│   │   │   ├── groups.go
│   │   │   ├── hosts.go
│   │   │   ├── plugins.go
│   │   │   ├── strategies.go
│   │   │   └── templates.go
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── db/
│   │   │   ├── agent.go
│   │   │   ├── db.go
│   │   │   ├── expression.go
│   │   │   ├── group.go
│   │   │   ├── host.go
│   │   │   ├── plugin.go
│   │   │   ├── strategy.go
│   │   │   └── template.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   └── g.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── http.go
│   │   │   └── proc.go
│   │   ├── main.go
│   │   ├── rpc/
│   │   │   ├── agent.go
│   │   │   ├── hbs.go
│   │   │   └── rpc.go
│   │   └── version.go
│   ├── judge/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── NOTICE
│   │   ├── README.md
│   │   ├── cfg.example.json
│   │   ├── control
│   │   ├── cron/
│   │   │   ├── cleaner.go
│   │   │   └── strategy.go
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── g.go
│   │   │   ├── redis.go
│   │   │   ├── rpc.go
│   │   │   └── var.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── http.go
│   │   │   └── info.go
│   │   ├── main.go
│   │   ├── rpc/
│   │   │   ├── receiver.go
│   │   │   └── rpc.go
│   │   ├── store/
│   │   │   ├── func.go
│   │   │   ├── history.go
│   │   │   ├── judge.go
│   │   │   └── linkedlist.go
│   │   └── version.go
│   ├── nodata/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── cfg.example.json
│   │   ├── collector/
│   │   │   ├── collector.go
│   │   │   └── collector_cron.go
│   │   ├── config/
│   │   │   ├── config.go
│   │   │   ├── config_cron.go
│   │   │   └── service/
│   │   │       ├── db.go
│   │   │       ├── host.go
│   │   │       └── mockcfg.go
│   │   ├── control
│   │   ├── g/
│   │   │   ├── cfg.go
│   │   │   ├── g.go
│   │   │   ├── git.go
│   │   │   └── proc.go
│   │   ├── http/
│   │   │   ├── common.go
│   │   │   ├── debug_http.go
│   │   │   ├── http.go
│   │   │   └── proc_http.go
│   │   ├── judge/
│   │   │   ├── judge.go
│   │   │   ├── judge_cron.go
│   │   │   └── status.go
│   │   ├── main.go
│   │   ├── scripts/
│   │   │   ├── debug
│   │   │   └── nodata-db-schema.sql
│   │   ├── sender/
│   │   │   └── sender.go
│   │   └── version.go
│   └── transfer/
│       ├── .gitignore
│       ├── LICENSE
│       ├── NOTICE
│       ├── README.md
│       ├── cfg.example.json
│       ├── control
│       ├── g/
│       │   ├── cfg.go
│       │   ├── g.go
│       │   └── git.go
│       ├── http/
│       │   ├── api.go
│       │   ├── common.go
│       │   ├── debug_http.go
│       │   ├── http.go
│       │   └── proc_http.go
│       ├── main.go
│       ├── proc/
│       │   └── proc.go
│       ├── receiver/
│       │   ├── receiver.go
│       │   ├── rpc/
│       │   │   ├── rpc.go
│       │   │   └── rpc_transfer.go
│       │   └── socket/
│       │       ├── socket.go
│       │       └── socket_telnet.go
│       ├── scripts/
│       │   ├── info
│       │   ├── info.py
│       │   ├── last
│       │   ├── last_raw
│       │   ├── query
│       │   └── query.py
│       ├── sender/
│       │   ├── conn_pools.go
│       │   ├── node_rings.go
│       │   ├── send_queues.go
│       │   ├── send_tasks.go
│       │   ├── sender.go
│       │   └── sender_cron.go
│       ├── test/
│       │   ├── debug
│       │   └── rpcclient.py
│       └── version.go
├── scripts/
│   └── mysql/
│       ├── .gitignore
│       ├── LICENSE
│       ├── NOTICE
│       └── db_schema/
│           ├── 1_uic-db-schema.sql
│           ├── 2_portal-db-schema.sql
│           ├── 3_dashboard-db-schema.sql
│           ├── 4_graph-db-schema.sql
│           └── 5_alarms-db-schema.sql
├── test/
│   └── README.md
├── vagrant/
│   └── Vagrantfile
└── version.go
Download .txt
SYMBOL INDEX (1284 symbols across 285 files)

FILE: cmd/check.go
  function check (line 35) | func check(c *cobra.Command, args []string) error {

FILE: cmd/monitor.go
  function checkMonReq (line 38) | func checkMonReq(name string) error {
  function monitor (line 51) | func monitor(c *cobra.Command, args []string) error {

FILE: cmd/reload.go
  function reload (line 30) | func reload(c *cobra.Command, args []string) error {

FILE: cmd/restart.go
  function restart (line 36) | func restart(c *cobra.Command, args []string) error {

FILE: cmd/start.go
  function cmdArgs (line 44) | func cmdArgs(name string) []string {
  function openLogFile (line 48) | func openLogFile(name string) (*os.File, error) {
  function execModule (line 63) | func execModule(co bool, name string) error {
  function checkStartReq (line 82) | func checkStartReq(name string) error {
  function isStarted (line 95) | func isStarted(name string) bool {
  function start (line 111) | func start(c *cobra.Command, args []string) error {

FILE: cmd/stop.go
  function stop (line 38) | func stop(c *cobra.Command, args []string) error {

FILE: common/backend_pool/rpc_backends.go
  type SafeRpcConnPools (line 30) | type SafeRpcConnPools struct
    method Call (line 70) | func (this *SafeRpcConnPools) Call(addr, method string, args interface...
    method Get (line 104) | func (this *SafeRpcConnPools) Get(address string) (*connp.ConnPool, bo...
    method Destroy (line 111) | func (this *SafeRpcConnPools) Destroy() {
    method Proc (line 125) | func (this *SafeRpcConnPools) Proc() []string {
  function CreateSafeRpcConnPools (line 39) | func CreateSafeRpcConnPools(maxConns, maxIdle, connTimeout, callTimeout ...
  function CreateSafeJsonrpcConnPools (line 54) | func CreateSafeJsonrpcConnPools(maxConns, maxIdle, connTimeout, callTime...
  function createOneRpcPool (line 133) | func createOneRpcPool(name string, address string, connTimeout time.Dura...
  function createOneJsonrpcPool (line 152) | func createOneJsonrpcPool(name string, address string, connTimeout time....

FILE: common/backend_pool/tsdb_backends.go
  type TsdbClient (line 26) | type TsdbClient struct
    method Name (line 31) | func (t TsdbClient) Name() string {
    method Closed (line 35) | func (t TsdbClient) Closed() bool {
    method Close (line 39) | func (t TsdbClient) Close() error {
  function newTsdbConnPool (line 48) | func newTsdbConnPool(address string, maxConns int, maxIdle int, connTime...
  type TsdbConnPoolHelper (line 71) | type TsdbConnPoolHelper struct
    method Send (line 91) | func (t *TsdbConnPoolHelper) Send(data []byte) (err error) {
    method Destroy (line 120) | func (t *TsdbConnPoolHelper) Destroy() {
  function NewTsdbConnPoolHelper (line 80) | func NewTsdbConnPoolHelper(address string, maxConns, maxIdle, connTimeou...

FILE: common/db/db.go
  type GraphEndpoint (line 18) | type GraphEndpoint struct
  type GraphTagEndpoint (line 24) | type GraphTagEndpoint struct
  type GraphEndpointCounter (line 31) | type GraphEndpointCounter struct

FILE: common/model/agent.go
  type AgentReportRequest (line 21) | type AgentReportRequest struct
    method String (line 28) | func (this *AgentReportRequest) String() string {
  type AgentUpdateInfo (line 38) | type AgentUpdateInfo struct
  type AgentHeartbeatRequest (line 43) | type AgentHeartbeatRequest struct
    method String (line 48) | func (this *AgentHeartbeatRequest) String() string {
  type AgentPluginsResponse (line 56) | type AgentPluginsResponse struct
    method String (line 61) | func (this *AgentPluginsResponse) String() string {
  type BuiltinMetric (line 70) | type BuiltinMetric struct
    method String (line 75) | func (this *BuiltinMetric) String() string {
  type BuiltinMetricResponse (line 83) | type BuiltinMetricResponse struct
    method String (line 89) | func (this *BuiltinMetricResponse) String() string {
  type BuiltinMetricSlice (line 98) | type BuiltinMetricSlice
    method Len (line 100) | func (this BuiltinMetricSlice) Len() int {
    method Swap (line 103) | func (this BuiltinMetricSlice) Swap(i, j int) {
    method Less (line 106) | func (this BuiltinMetricSlice) Less(i, j int) bool {

FILE: common/model/event.go
  type Event (line 24) | type Event struct
    method FormattedTime (line 36) | func (this *Event) FormattedTime() string {
    method String (line 40) | func (this *Event) String() string {
    method ExpressionId (line 54) | func (this *Event) ExpressionId() int {
    method StrategyId (line 62) | func (this *Event) StrategyId() int {
    method TplId (line 70) | func (this *Event) TplId() int {
    method Tpl (line 78) | func (this *Event) Tpl() *Template {
    method ActionId (line 86) | func (this *Event) ActionId() int {
    method Priority (line 94) | func (this *Event) Priority() int {
    method Note (line 101) | func (this *Event) Note() string {
    method Metric (line 108) | func (this *Event) Metric() string {
    method RightValue (line 115) | func (this *Event) RightValue() float64 {
    method Operator (line 122) | func (this *Event) Operator() string {
    method Func (line 129) | func (this *Event) Func() string {
    method MaxStep (line 136) | func (this *Event) MaxStep() int {
    method Counter (line 143) | func (this *Event) Counter() string {

FILE: common/model/expression.go
  type Expression (line 23) | type Expression struct
    method String (line 36) | func (this *Expression) String() string {
  type ExpressionResponse (line 52) | type ExpressionResponse struct

FILE: common/model/graph.go
  type GraphItem (line 25) | type GraphItem struct
    method String (line 38) | func (this *GraphItem) String() string {
    method PrimaryKey (line 55) | func (this *GraphItem) PrimaryKey() string {
    method Checksum (line 59) | func (t *GraphItem) Checksum() string {
    method UUID (line 63) | func (this *GraphItem) UUID() string {
  type GraphDeleteParam (line 67) | type GraphDeleteParam struct
  type GraphDeleteResp (line 75) | type GraphDeleteResp struct
  type GraphQueryParam (line 79) | type GraphQueryParam struct
  type GraphQueryResponse (line 88) | type GraphQueryResponse struct
  type GraphAccurateQueryParam (line 97) | type GraphAccurateQueryParam struct
  type GraphAccurateQueryResponse (line 106) | type GraphAccurateQueryResponse struct
  type JsonFloat (line 110) | type JsonFloat
    method MarshalJSON (line 112) | func (v JsonFloat) MarshalJSON() ([]byte, error) {
  type RRDData (line 121) | type RRDData struct
    method String (line 130) | func (this *RRDData) String() string {
  function NewRRDData (line 126) | func NewRRDData(ts int64, val float64) *RRDData {
  type GraphInfoParam (line 139) | type GraphInfoParam struct
  type GraphInfoResp (line 144) | type GraphInfoResp struct
  type GraphFullyInfo (line 150) | type GraphFullyInfo struct
  type GraphLastParam (line 159) | type GraphLastParam struct
  type GraphLastResp (line 164) | type GraphLastResp struct

FILE: common/model/host.go
  type Host (line 21) | type Host struct
    method String (line 26) | func (this *Host) String() string {

FILE: common/model/influxdb.go
  type InfluxdbItem (line 3) | type InfluxdbItem struct

FILE: common/model/judge.go
  type JudgeItem (line 23) | type JudgeItem struct
    method String (line 32) | func (this *JudgeItem) String() string {
    method PrimaryKey (line 42) | func (this *JudgeItem) PrimaryKey() string {
  type HistoryData (line 46) | type HistoryData struct

FILE: common/model/metric.go
  type MetricValue (line 23) | type MetricValue struct
    method String (line 33) | func (this *MetricValue) String() string {
  type JsonMetaData (line 47) | type JsonMetaData struct
    method String (line 57) | func (t *JsonMetaData) String() string {
  type MetaData (line 62) | type MetaData struct
    method String (line 72) | func (t *MetaData) String() string {
    method PK (line 77) | func (t *MetaData) PK() string {

FILE: common/model/nodata.go
  type NodataItem (line 24) | type NodataItem struct
    method String (line 31) | func (this *NodataItem) String() string {
  type NodataConfig (line 36) | type NodataConfig struct
    method String (line 52) | func (this *NodataConfig) String() string {
  function NewNodataConfig (line 48) | func NewNodataConfig(id int, name string, objType string, endpoint strin...

FILE: common/model/prometheus.go
  type P8sItem (line 4) | type P8sItem struct

FILE: common/model/rpc.go
  type SimpleRpcResponse (line 23) | type SimpleRpcResponse struct
    method String (line 27) | func (this *SimpleRpcResponse) String() string {
  type NullRpcRequest (line 31) | type NullRpcRequest struct

FILE: common/model/strategy.go
  type Strategy (line 23) | type Strategy struct
    method String (line 36) | func (this *Strategy) String() string {
  type HostStrategy (line 52) | type HostStrategy struct
  type StrategiesResponse (line 57) | type StrategiesResponse struct

FILE: common/model/template.go
  type Template (line 21) | type Template struct
    method String (line 29) | func (this *Template) String() string {

FILE: common/model/transfer.go
  type TransferResponse (line 21) | type TransferResponse struct
    method String (line 28) | func (this *TransferResponse) String() string {

FILE: common/model/tsdb.go
  type TsdbItem (line 22) | type TsdbItem struct
    method String (line 29) | func (this *TsdbItem) String() string {
    method TsdbString (line 39) | func (this *TsdbItem) TsdbString() (s string) {

FILE: common/proc/proc.go
  constant DefaultOtherMaxSize (line 23) | DefaultOtherMaxSize      = 100
  constant DefaultSCounterQpsPeriod (line 24) | DefaultSCounterQpsPeriod = 1
  type SCounterBase (line 28) | type SCounterBase struct
    method Get (line 44) | func (this *SCounterBase) Get() *SCounterBase {
    method Set (line 51) | func (this *SCounterBase) Set(cnt int64) {
    method SetCnt (line 60) | func (this *SCounterBase) SetCnt(cnt int64) {
    method PutOther (line 69) | func (this *SCounterBase) PutOther(key string, value interface{}) bool {
  function NewSCounterBase (line 38) | func NewSCounterBase(name string) *SCounterBase {
  function formatTs (line 88) | func formatTs(ts int64) string {
  type SCounterQps (line 93) | type SCounterQps struct
    method Get (line 114) | func (this *SCounterQps) Get() *SCounterQps {
    method Incr (line 122) | func (this *SCounterQps) Incr() {
    method IncrBy (line 126) | func (this *SCounterQps) IncrBy(incr int64) {
    method PutOther (line 133) | func (this *SCounterQps) PutOther(key string, value interface{}) bool {
    method incrByDirty (line 153) | func (this *SCounterQps) incrByDirty(incr int64) {
  function NewSCounterQps (line 107) | func NewSCounterQps(name string) *SCounterQps {

FILE: common/sdk/requests/auth_request.go
  function CurlPlus (line 24) | func CurlPlus(uri, method, token_name, token_sig string, headers, params...

FILE: common/sdk/requests/post.go
  function PostJsonBody (line 24) | func PostJsonBody(url string, v interface{}) (response []byte, err error) {

FILE: common/sdk/sender/linkedlist.go
  type SafeLinkedList (line 24) | type SafeLinkedList struct
    method PopBack (line 33) | func (this *SafeLinkedList) PopBack(limit int) []*model.JsonMetaData {
    method PushFront (line 55) | func (this *SafeLinkedList) PushFront(v interface{}) *list.Element {
    method Front (line 61) | func (this *SafeLinkedList) Front() *list.Element {
    method Len (line 67) | func (this *SafeLinkedList) Len() int {
  function NewSafeLinkedList (line 29) | func NewSafeLinkedList() *SafeLinkedList {

FILE: common/sdk/sender/make.go
  function MakeMetaData (line 23) | func MakeMetaData(endpoint, metric, tags string, val interface{}, counte...
  function MakeGaugeValue (line 47) | func MakeGaugeValue(endpoint, metric, tags string, val interface{}, step...
  function MakeCounterValue (line 51) | func MakeCounterValue(endpoint, metric, tags string, val interface{}, st...
  function PushGauge (line 55) | func PushGauge(endpoint, metric, tags string, val interface{}, step_and_...
  function PushCounter (line 60) | func PushCounter(endpoint, metric, tags string, val interface{}, step_an...
  function Push (line 65) | func Push(endpoint, metric, tags string, val interface{}, counterType st...

FILE: common/sdk/sender/push.go
  function PostPush (line 28) | func PostPush(L []*model.JsonMetaData) error {

FILE: common/sdk/sender/sender.go
  constant LIMIT (line 22) | LIMIT = 200
  function StartSender (line 28) | func StartSender() {
  function startSender (line 32) | func startSender() {

FILE: common/utils/counter.go
  function Counter (line 21) | func Counter(metric string, tags map[string]string) string {

FILE: common/utils/date.go
  function UnixTsFormat (line 21) | func UnixTsFormat(ts int64) string {

FILE: common/utils/formatter.go
  function ReadableFloat (line 22) | func ReadableFloat(raw float64) string {

FILE: common/utils/func.go
  function PK (line 24) | func PK(endpoint, metric string, tags map[string]string) string {
  function PK2 (line 44) | func PK2(endpoint, counter string) string {
  function UUID (line 56) | func UUID(endpoint, metric string, tags map[string]string, dstype string...
  function Checksum (line 85) | func Checksum(endpoint string, metric string, tags map[string]string) st...
  function ChecksumOfUUID (line 90) | func ChecksumOfUUID(endpoint, metric string, tags map[string]string, dst...
  function init (line 94) | func init() {
  function RandString (line 98) | func RandString(l int) string {
  function RandInt (line 106) | func RandInt(min int, max int) int {

FILE: common/utils/func_test.go
  function origPK (line 22) | func origPK(endpoint, metric string, tags map[string]string) string {
  function origPK2 (line 29) | func origPK2(endpoint, counter string) string {
  function origUUID (line 33) | func origUUID(endpoint, metric string, tags map[string]string, dstype st...
  function Test_PK (line 74) | func Test_PK(t *testing.T) {
  function Test_PK2 (line 82) | func Test_PK2(t *testing.T) {
  function Test_UUID (line 90) | func Test_UUID(t *testing.T) {
  function Benchmark_PK (line 103) | func Benchmark_PK(b *testing.B) {
  function Benchmark_PK_orig (line 109) | func Benchmark_PK_orig(b *testing.B) {
  function Benchmark_PK2 (line 115) | func Benchmark_PK2(b *testing.B) {
  function Benchmark_PK2_orig (line 121) | func Benchmark_PK2_orig(b *testing.B) {
  function Benchmark_UUID (line 127) | func Benchmark_UUID(b *testing.B) {
  function Benchmark_UUID_orig (line 133) | func Benchmark_UUID_orig(b *testing.B) {

FILE: common/utils/map.go
  function KeysOfMap (line 22) | func KeysOfMap(m map[string]string) []string {

FILE: common/utils/md5.go
  function Md5 (line 22) | func Md5(raw string) string {

FILE: common/utils/md5_test.go
  function origMd5 (line 24) | func origMd5(raw string) string {
  function Test_Md5 (line 31) | func Test_Md5(t *testing.T) {
  function Benchmark_Md5 (line 37) | func Benchmark_Md5(b *testing.B) {
  function Benchmark_Md5_orig (line 43) | func Benchmark_Md5_orig(b *testing.B) {

FILE: common/utils/statistics.go
  function ComputeMean (line 19) | func ComputeMean(values []float64) float64 {
  function ComputeStdDeviation (line 29) | func ComputeStdDeviation(values []float64) float64 {

FILE: common/utils/tags.go
  function SortedTags (line 24) | func SortedTags(tags map[string]string) string {
  function DictedTagstring (line 69) | func DictedTagstring(s string) map[string]string {
  function SplitTagsString (line 89) | func SplitTagsString(s string) (err error, tags map[string]string) {

FILE: common/utils/tags_test.go
  function origSortedTags (line 46) | func origSortedTags(tags map[string]string) string {
  function origDictedTagstring (line 80) | func origDictedTagstring(s string) map[string]string {
  function Test_SortedTags (line 97) | func Test_SortedTags(t *testing.T) {
  function Test_DictedTagstring (line 104) | func Test_DictedTagstring(t *testing.T) {
  function Benchmark_SortedTags_1pair (line 120) | func Benchmark_SortedTags_1pair(b *testing.B) {
  function Benchmark_SortedTags_1pair_orig (line 126) | func Benchmark_SortedTags_1pair_orig(b *testing.B) {
  function Benchmark_SortedTags_2pairs (line 132) | func Benchmark_SortedTags_2pairs(b *testing.B) {
  function Benchmark_SortedTags_2pairs_orig (line 138) | func Benchmark_SortedTags_2pairs_orig(b *testing.B) {
  function Benchmark_SortedTags_3pairs (line 144) | func Benchmark_SortedTags_3pairs(b *testing.B) {
  function Benchmark_SortedTags_3pairs_orig (line 150) | func Benchmark_SortedTags_3pairs_orig(b *testing.B) {
  function Benchmark_SortedTags_4pairs (line 156) | func Benchmark_SortedTags_4pairs(b *testing.B) {
  function Benchmark_SortedTags_4pairs_orig (line 162) | func Benchmark_SortedTags_4pairs_orig(b *testing.B) {
  function Benchmark_SortedTags_5pairs (line 168) | func Benchmark_SortedTags_5pairs(b *testing.B) {
  function Benchmark_SortedTags_5pairs_orig (line 174) | func Benchmark_SortedTags_5pairs_orig(b *testing.B) {
  function Benchmark_SortedTags_6pairs (line 180) | func Benchmark_SortedTags_6pairs(b *testing.B) {
  function Benchmark_SortedTags_6pairs_orig (line 186) | func Benchmark_SortedTags_6pairs_orig(b *testing.B) {
  function Benchmark_DictedTagstring_1pair (line 192) | func Benchmark_DictedTagstring_1pair(b *testing.B) {
  function Benchmark_DictedTagstring_1pair_orig (line 198) | func Benchmark_DictedTagstring_1pair_orig(b *testing.B) {
  function Benchmark_DictedTagstring_2pairs (line 204) | func Benchmark_DictedTagstring_2pairs(b *testing.B) {
  function Benchmark_DictedTagstring_2pairs_orig (line 210) | func Benchmark_DictedTagstring_2pairs_orig(b *testing.B) {
  function Benchmark_DictedTagstring_3pairs (line 216) | func Benchmark_DictedTagstring_3pairs(b *testing.B) {
  function Benchmark_DictedTagstring_3pairs_orig (line 222) | func Benchmark_DictedTagstring_3pairs_orig(b *testing.B) {
  function Benchmark_DictedTagstring_4pairs (line 228) | func Benchmark_DictedTagstring_4pairs(b *testing.B) {
  function Benchmark_DictedTagstring_4pairs_orig (line 234) | func Benchmark_DictedTagstring_4pairs_orig(b *testing.B) {
  function Benchmark_DictedTagstring_5pairs (line 240) | func Benchmark_DictedTagstring_5pairs(b *testing.B) {
  function Benchmark_DictedTagstring_5pairs_orig (line 246) | func Benchmark_DictedTagstring_5pairs_orig(b *testing.B) {
  function Benchmark_DictedTagstring_6pairs (line 252) | func Benchmark_DictedTagstring_6pairs(b *testing.B) {
  function Benchmark_DictedTagstring_6pairs_orig (line 258) | func Benchmark_DictedTagstring_6pairs_orig(b *testing.B) {

FILE: docs/assets.js
  function require (line 16) | function require(path, parent, orig) {
  function lastIndexOf (line 161) | function lastIndexOf(arr, obj) {
  function localRequire (line 173) | function localRequire(path) {
  function jQuerySub (line 1104) | function jQuerySub( selector, context ) {
  function doScrollCheck (line 1170) | function doScrollCheck() {
  function createFlags (line 1197) | function createFlags( flags ) {
  function resolveFunc (line 1532) | function resolveFunc( i ) {
  function progressFunc (line 1540) | function progressFunc( i ) {
  function dataAttr (line 2192) | function dataAttr( elem, key, data ) {
  function isEmptyDataObject (line 2223) | function isEmptyDataObject( obj ) {
  function handleQueueMarkDefer (line 2241) | function handleQueueMarkDefer( elem, type, src ) {
  function resolve (line 2400) | function resolve() {
  function returnFalse (line 3753) | function returnFalse() {
  function returnTrue (line 3756) | function returnTrue() {
  function dirNodeCheck (line 5464) | function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
  function dirCheck (line 5497) | function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
  function isDisconnected (line 5770) | function isDisconnected( node ) {
  function winnow (line 5887) | function winnow( elements, qualifier, keep ) {
  function createSafeFragment (line 5924) | function createSafeFragment( document ) {
  function root (line 6296) | function root( elem, cur ) {
  function cloneCopyEvent (line 6303) | function cloneCopyEvent( src, dest ) {
  function cloneFixAttributes (line 6331) | function cloneFixAttributes( src, dest ) {
  function getAll (line 6476) | function getAll( elem ) {
  function fixDefaultChecked (line 6489) | function fixDefaultChecked( elem ) {
  function findInputs (line 6495) | function findInputs( elem ) {
  function shimCloneNode (line 6506) | function shimCloneNode( elem ) {
  function getWidthOrHeight (line 6997) | function getWidthOrHeight( elem, name, extra ) {
  function addToPrefiltersOrTransports (line 7238) | function addToPrefiltersOrTransports( structure ) {
  function inspectPrefiltersOrTransports (line 7274) | function inspectPrefiltersOrTransports( structure, options, originalOpti...
  function ajaxExtend (line 7316) | function ajaxExtend( target, src ) {
  function done (line 7658) | function done( status, nativeStatusText, responses, headers ) {
  function buildParams (line 7973) | function buildParams( prefix, obj, traditional, add ) {
  function ajaxHandleResponses (line 8023) | function ajaxHandleResponses( s, jqXHR, responses ) {
  function ajaxConvert (line 8088) | function ajaxConvert( s, response ) {
  function createStandardXHR (line 8353) | function createStandardXHR() {
  function createActiveXHR (line 8359) | function createActiveXHR() {
  function doAnimation (line 8698) | function doAnimation() {
  function stopQueue (line 8854) | function stopQueue( elem, data, index ) {
  function createFxNow (line 8896) | function createFxNow() {
  function clearFxNow (line 8901) | function clearFxNow() {
  function genFx (line 8906) | function genFx( type, num ) {
  function t (line 9021) | function t( gotoEnd ) {
  function defaultDisplay (line 9219) | function defaultDisplay( nodeName ) {
  function getWindow (line 9503) | function getWindow( elem ) {
  function Filter (line 9629) | function Filter(list) {

FILE: g/g.go
  function init (line 27) | func init() {
  function Bin (line 128) | func Bin(name string) string {
  function Cfg (line 133) | func Cfg(name string) string {
  function LogPath (line 138) | func LogPath(name string) string {
  function LogDir (line 143) | func LogDir(name string) string {

FILE: g/tool.go
  function HasLogfile (line 24) | func HasLogfile(name string) bool {
  function PreqOrder (line 31) | func PreqOrder(moduleArgs []string) []string {
  function Rel (line 62) | func Rel(p string) string {
  function HasCfg (line 79) | func HasCfg(name string) bool {
  function HasModule (line 86) | func HasModule(name string) bool {
  function setPid (line 90) | func setPid(name string) {
  function Pid (line 96) | func Pid(name string) string {
  function IsRunning (line 103) | func IsRunning(name string) bool {
  function RmDup (line 108) | func RmDup(args []string) []string {

FILE: g/tool_test.go
  function setup (line 24) | func setup() {
  function teardown (line 43) | func teardown() {
  function TestRel (line 48) | func TestRel(t *testing.T) {
  function TestHasCfg (line 73) | func TestHasCfg(t *testing.T) {
  function TestPreqOrder (line 92) | func TestPreqOrder(t *testing.T) {
  function TestRmDup (line 113) | func TestRmDup(t *testing.T) {
  function TestMain (line 140) | func TestMain(m *testing.M) {

FILE: main.go
  function init (line 38) | func init() {
  function main (line 51) | func main() {

FILE: modules/agent/cron/builtin.go
  function SyncBuiltinMetrics (line 26) | func SyncBuiltinMetrics() {
  function syncBuiltinMetrics (line 32) | func syncBuiltinMetrics() {

FILE: modules/agent/cron/collector.go
  function InitDataHistory (line 25) | func InitDataHistory() {
  function Collect (line 33) | func Collect() {
  function collect (line 48) | func collect(sec int64, fns []func() []*model.MetricValue) {

FILE: modules/agent/cron/ips.go
  function SyncTrustableIps (line 24) | func SyncTrustableIps() {
  function syncTrustableIps (line 30) | func syncTrustableIps() {

FILE: modules/agent/cron/plugin.go
  function SyncMinePlugins (line 31) | func SyncMinePlugins() {
  function syncMinePlugins (line 47) | func syncMinePlugins() {

FILE: modules/agent/cron/reporter.go
  function ReportAgentStatus (line 25) | func ReportAgentStatus() {
  function reportAgentStatus (line 31) | func reportAgentStatus(interval time.Duration) {

FILE: modules/agent/funcs/agent.go
  function AgentMetrics (line 21) | func AgentMetrics() []*model.MetricValue {

FILE: modules/agent/funcs/checker.go
  function CheckCollector (line 23) | func CheckCollector() {

FILE: modules/agent/funcs/common.go
  function NewMetricValue (line 22) | func NewMetricValue(metric string, val interface{}, dataType string, tag...
  function GaugeValue (line 38) | func GaugeValue(metric string, val interface{}, tags ...string) *model.M...
  function CounterValue (line 42) | func CounterValue(metric string, val interface{}, tags ...string) *model...

FILE: modules/agent/funcs/cpustat.go
  constant historyCount (line 24) | historyCount int = 2
  function UpdateCpuStat (line 32) | func UpdateCpuStat() error {
  function deltaTotal (line 48) | func deltaTotal() uint64 {
  function CpuIdle (line 55) | func CpuIdle() float64 {
  function CpuUser (line 66) | func CpuUser() float64 {
  function CpuNice (line 77) | func CpuNice() float64 {
  function CpuSystem (line 88) | func CpuSystem() float64 {
  function CpuIowait (line 99) | func CpuIowait() float64 {
  function CpuIrq (line 110) | func CpuIrq() float64 {
  function CpuSoftIrq (line 121) | func CpuSoftIrq() float64 {
  function CpuSteal (line 132) | func CpuSteal() float64 {
  function CpuGuest (line 143) | func CpuGuest() float64 {
  function CurrentCpuSwitches (line 154) | func CurrentCpuSwitches() uint64 {
  function CpuPrepared (line 160) | func CpuPrepared() bool {
  function CpuMetrics (line 166) | func CpuMetrics() []*model.MetricValue {

FILE: modules/agent/funcs/dfstat.go
  function DeviceMetrics (line 25) | func DeviceMetrics() (L []*model.MetricValue) {
  function DeviceMetricsCheck (line 95) | func DeviceMetricsCheck() bool {

FILE: modules/agent/funcs/diskstats.go
  function UpdateDiskStats (line 32) | func UpdateDiskStats() error {
  function IOReadRequests (line 47) | func IOReadRequests(arr [2]*nux.DiskStats) uint64 {
  function IOReadMerged (line 51) | func IOReadMerged(arr [2]*nux.DiskStats) uint64 {
  function IOReadSectors (line 55) | func IOReadSectors(arr [2]*nux.DiskStats) uint64 {
  function IOMsecRead (line 59) | func IOMsecRead(arr [2]*nux.DiskStats) uint64 {
  function IOWriteRequests (line 63) | func IOWriteRequests(arr [2]*nux.DiskStats) uint64 {
  function IOWriteMerged (line 67) | func IOWriteMerged(arr [2]*nux.DiskStats) uint64 {
  function IOWriteSectors (line 71) | func IOWriteSectors(arr [2]*nux.DiskStats) uint64 {
  function IOMsecWrite (line 75) | func IOMsecWrite(arr [2]*nux.DiskStats) uint64 {
  function IOMsecTotal (line 79) | func IOMsecTotal(arr [2]*nux.DiskStats) uint64 {
  function IOMsecWeightedTotal (line 83) | func IOMsecWeightedTotal(arr [2]*nux.DiskStats) uint64 {
  function TS (line 87) | func TS(arr [2]*nux.DiskStats) uint64 {
  function IODelta (line 91) | func IODelta(device string, f func([2]*nux.DiskStats) uint64) uint64 {
  function DiskIOMetrics (line 103) | func DiskIOMetrics() (L []*model.MetricValue) {
  function IOStatsMetrics (line 133) | func IOStatsMetrics() (L []*model.MetricValue) {
  function IOStatsForPage (line 178) | func IOStatsForPage() (L [][]string) {
  function ShouldHandleDevice (line 226) | func ShouldHandleDevice(device string) bool {

FILE: modules/agent/funcs/du.go
  function DuMetrics (line 35) | func DuMetrics() (L []*model.MetricValue) {

FILE: modules/agent/funcs/du_test.go
  function init (line 13) | func init() {
  function TestDuMetrics (line 23) | func TestDuMetrics(t *testing.T) {
  function TestDuMetricsPathNotExist (line 32) | func TestDuMetricsPathNotExist(t *testing.T) {
  function TestDuMetricsTimeout (line 41) | func TestDuMetricsTimeout(t *testing.T) {

FILE: modules/agent/funcs/funcs.go
  type FuncsAndInterval (line 22) | type FuncsAndInterval struct
  function BuildMappers (line 29) | func BuildMappers() {

FILE: modules/agent/funcs/gpu.go
  function GpuMetrics (line 26) | func GpuMetrics() (L []*model.MetricValue) {

FILE: modules/agent/funcs/ifstat.go
  function NetMetrics (line 24) | func NetMetrics() []*model.MetricValue {
  function CoreNetMetrics (line 28) | func CoreNetMetrics(ifacePrefix []string) []*model.MetricValue {

FILE: modules/agent/funcs/kernel.go
  function KernelMetrics (line 23) | func KernelMetrics() (L []*model.MetricValue) {

FILE: modules/agent/funcs/loadavg.go
  function LoadAvgMetrics (line 23) | func LoadAvgMetrics() []*model.MetricValue {

FILE: modules/agent/funcs/meminfo.go
  function MemMetrics (line 23) | func MemMetrics() []*model.MetricValue {

FILE: modules/agent/funcs/netstat.go
  function NetstatMetrics (line 49) | func NetstatMetrics() (L []*model.MetricValue) {

FILE: modules/agent/funcs/portstat.go
  function PortMetrics (line 26) | func PortMetrics() (L []*model.MetricValue) {

FILE: modules/agent/funcs/procs.go
  function ProcMetrics (line 25) | func ProcMetrics() (L []*model.MetricValue) {
  function is_a (line 55) | func is_a(p *nux.Proc, m map[int]string) bool {

FILE: modules/agent/funcs/snmp.go
  function UdpMetrics (line 23) | func UdpMetrics() []*model.MetricValue {

FILE: modules/agent/funcs/sockstat.go
  function SocketStatSummaryMetrics (line 23) | func SocketStatSummaryMetrics() (L []*model.MetricValue) {

FILE: modules/agent/funcs/urlstat.go
  function UrlMetrics (line 30) | func UrlMetrics() (L []*model.MetricValue) {
  function probeUrl (line 51) | func probeUrl(furl string, timeout string) (bool, error) {

FILE: modules/agent/g/cfg.go
  type PluginConfig (line 26) | type PluginConfig struct
  type HeartbeatConfig (line 33) | type HeartbeatConfig struct
  type TransferConfig (line 40) | type TransferConfig struct
  type HttpConfig (line 47) | type HttpConfig struct
  type CollectorConfig (line 53) | type CollectorConfig struct
  type GlobalConfig (line 58) | type GlobalConfig struct
  function Config (line 77) | func Config() *GlobalConfig {
  function Hostname (line 83) | func Hostname() (string, error) {
  function IP (line 101) | func IP() string {
  function ParseConfig (line 115) | func ParseConfig(cfg string) {

FILE: modules/agent/g/const.go
  function VersionMsg (line 35) | func VersionMsg() string {
  constant COLLECT_INTERVAL (line 40) | COLLECT_INTERVAL = time.Second
  constant URL_CHECK_HEALTH (line 41) | URL_CHECK_HEALTH = "url.check.health"
  constant NET_PORT_LISTEN (line 42) | NET_PORT_LISTEN  = "net.port.listen"
  constant DU_BS (line 43) | DU_BS            = "du.bs"
  constant PROC_NUM (line 44) | PROC_NUM         = "proc.num"

FILE: modules/agent/g/g.go
  function init (line 22) | func init() {

FILE: modules/agent/g/logger.go
  function InitLog (line 19) | func InitLog(level string) (err error) {

FILE: modules/agent/g/rpc.go
  type SingleConnRpcClient (line 27) | type SingleConnRpcClient struct
    method close (line 34) | func (this *SingleConnRpcClient) close() {
    method serverConn (line 41) | func (this *SingleConnRpcClient) serverConn() error {
    method Call (line 68) | func (this *SingleConnRpcClient) Call(method string, args interface{},...

FILE: modules/agent/g/tool.go
  function GetCurrPluginVersion (line 25) | func GetCurrPluginVersion() string {

FILE: modules/agent/g/transfer.go
  function SendMetrics (line 31) | func SendMetrics(metrics []*model.MetricValue, resp *model.TransferRespo...
  function initTransferClient (line 47) | func initTransferClient(addr string) *SingleConnRpcClient {
  function updateMetrics (line 59) | func updateMetrics(c *SingleConnRpcClient, metrics []*model.MetricValue,...
  function getTransferClient (line 68) | func getTransferClient(addr string) *SingleConnRpcClient {

FILE: modules/agent/g/var.go
  function InitRootDir (line 35) | func InitRootDir() {
  function lookupRootDir (line 58) | func lookupRootDir(dir string) string {
  function InitLocalIp (line 78) | func InitLocalIp() {
  function InitRpcClients (line 96) | func InitRpcClients() {
  function SendToTransfer (line 105) | func SendToTransfer(metrics []*model.MetricValue) {
  function ReportUrls (line 155) | func ReportUrls() map[string]string {
  function SetReportUrls (line 161) | func SetReportUrls(urls map[string]string) {
  function ReportPorts (line 172) | func ReportPorts() []int64 {
  function SetReportPorts (line 178) | func SetReportPorts(ports []int64) {
  function DuPaths (line 189) | func DuPaths() []string {
  function SetDuPaths (line 195) | func SetDuPaths(paths []string) {
  function ReportProcs (line 209) | func ReportProcs() map[string]map[int]string {
  function SetReportProcs (line 215) | func SetReportProcs(procs map[string]map[int]string) {
  function TrustableIps (line 226) | func TrustableIps() []string {
  function SetTrustableIps (line 232) | func SetTrustableIps(ipStr string) {
  function IsTrustable (line 239) | func IsTrustable(remoteAddr string) bool {

FILE: modules/agent/g/var_test.go
  function TestInitRootDir (line 23) | func TestInitRootDir(t *testing.T) {
  function getCurrentPath (line 39) | func getCurrentPath() string {

FILE: modules/agent/http/admin.go
  function configAdminRoutes (line 25) | func configAdminRoutes() {

FILE: modules/agent/http/cpu.go
  function configCpuRoutes (line 25) | func configCpuRoutes() {

FILE: modules/agent/http/df.go
  function configDfRoutes (line 24) | func configDfRoutes() {

FILE: modules/agent/http/health.go
  function configHealthRoutes (line 22) | func configHealthRoutes() {

FILE: modules/agent/http/http.go
  type Dto (line 25) | type Dto struct
  function init (line 30) | func init() {
  function RenderJson (line 45) | func RenderJson(w http.ResponseWriter, v interface{}) {
  function RenderDataJson (line 56) | func RenderDataJson(w http.ResponseWriter, data interface{}) {
  function RenderMsgJson (line 60) | func RenderMsgJson(w http.ResponseWriter, msg string) {
  function AutoRender (line 64) | func AutoRender(w http.ResponseWriter, data interface{}, err error) {
  function Start (line 73) | func Start() {

FILE: modules/agent/http/iostat.go
  function configIoStatRoutes (line 22) | func configIoStatRoutes() {

FILE: modules/agent/http/kernel.go
  function configKernelRoutes (line 24) | func configKernelRoutes() {

FILE: modules/agent/http/memory.go
  function configMemoryRoutes (line 22) | func configMemoryRoutes() {

FILE: modules/agent/http/page.go
  function configPageRoutes (line 25) | func configPageRoutes() {

FILE: modules/agent/http/plugin.go
  function configPluginRoutes (line 26) | func configPluginRoutes() {

FILE: modules/agent/http/push.go
  function configPushRoutes (line 24) | func configPushRoutes() {

FILE: modules/agent/http/run.go
  function configRunRoutes (line 24) | func configRunRoutes() {

FILE: modules/agent/http/system.go
  function configSystemRoutes (line 25) | func configSystemRoutes() {

FILE: modules/agent/main.go
  function main (line 27) | func main() {

FILE: modules/agent/plugins/plugins.go
  type Plugin (line 17) | type Plugin struct
  function DelNoUsePlugins (line 29) | func DelNoUsePlugins(newPlugins map[string]*Plugin) {
  function AddNewPlugins (line 38) | func AddNewPlugins(newPlugins map[string]*Plugin) {
  function ClearAllPlugins (line 51) | func ClearAllPlugins() {
  function deletePlugin (line 57) | func deletePlugin(key string) {

FILE: modules/agent/plugins/reader.go
  function ListPlugins (line 27) | func ListPlugins(script_path string) map[string]*Plugin {

FILE: modules/agent/plugins/scheduler.go
  type PluginScheduler (line 33) | type PluginScheduler struct
    method Schedule (line 46) | func (this *PluginScheduler) Schedule() {
    method Stop (line 60) | func (this *PluginScheduler) Stop() {
  function NewPluginScheduler (line 39) | func NewPluginScheduler(p *Plugin) *PluginScheduler {
  function PluginArgsParse (line 65) | func PluginArgsParse(raw_args string) []string {
  function PluginRun (line 107) | func PluginRun(plugin *Plugin) {

FILE: modules/agent/public/js/base.js
  function pulseElement (line 50) | function pulseElement(element, times, interval) {
  function isInArray (line 73) | function isInArray(array, search)

FILE: modules/agent/public/js/bootstrap.js
  function removeElement (line 108) | function removeElement() {
  function clearMenus (line 603) | function clearMenus() {
  function hideWithTransition (line 731) | function hideWithTransition() {
  function hideModal (line 744) | function hideModal( that ) {
  function backdrop (line 752) | function backdrop( callback ) {
  function removeBackdrop (line 786) | function removeBackdrop() {
  function escape (line 791) | function escape() {
  function removeWithAnimation (line 1006) | function removeWithAnimation() {
  function ScrollSpy (line 1229) | function ScrollSpy( element, options) {
  function next (line 1400) | function next() {

FILE: modules/agent/public/js/dashboard.js
  function generate_os_data (line 2) | function generate_os_data(url, element) {
  function destroy_dataTable (line 13) | function destroy_dataTable(table_id) {
  function zeroPad (line 81) | function zeroPad(num, places) {

FILE: modules/agent/public/js/jquery.js
  function cy (line 2) | function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.pa...
  function cu (line 2) | function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.cs...
  function ct (line 2) | function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),funct...
  function cs (line 2) | function cs(){cq=b}
  function cr (line 2) | function cr(){setTimeout(cs,0);return cq=f.now()}
  function ci (line 2) | function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(...
  function ch (line 2) | function ch(){try{return new a.XMLHttpRequest}catch(b){}}
  function cb (line 2) | function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.da...
  function ca (line 2) | function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i...
  function b_ (line 2) | function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a...
  function b$ (line 2) | function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d...
  function bZ (line 2) | function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],...
  function bY (line 2) | function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f...
  function bB (line 2) | function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b===...
  function bo (line 2) | function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTM...
  function bn (line 2) | function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!...
  function bm (line 2) | function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked...
  function bl (line 2) | function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getEl...
  function bk (line 2) | function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttrib...
  function bj (line 2) | function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(...
  function bi (line 2) | function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tb...
  function U (line 2) | function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.creat...
  function T (line 2) | function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d...
  function S (line 2) | function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}
  function K (line 2) | function K(){return!0}
  function J (line 2) | function J(){return!1}
  function n (line 2) | function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);...
  function m (line 2) | function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))conti...
  function l (line 2) | function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-...
  function h (line 2) | function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;...
  function J (line 2) | function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch...
  function a (line 2) | function a(b,c){return new a.fn.init(b,c)}
  function m (line 2) | function m(a){return function(b){e[a]=arguments.length>1?i.call(argument...
  function l (line 2) | function l(a){return function(c){b[a]=arguments.length>1?i.call(argument...
  function m (line 2) | function m(){--h||d.resolveWith(e,[e])}
  function x (line 3) | function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j)...
  function w (line 3) | function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j)...
  function w (line 4) | function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.ready...
  function g (line 4) | function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nod...
  function h (line 4) | function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}
  function h (line 4) | function h(a){return e.step(a)}

FILE: modules/agent/public/js/odometer.js
  function a (line 2) | function a(b){var d,e,g,h,k,l,m,n,o,p,q,r,s,t,u,v=this;if(this.options=b...

FILE: modules/aggregator/cron/computer.go
  function compute (line 23) | func compute(operands []string, operators []string, computeMode string, ...
  function compareSum (line 54) | func compareSum(sum float64, computeMode string) bool {
  function queryOperands (line 74) | func queryOperands(counters []string, endpoint string, valMap map[string...

FILE: modules/aggregator/cron/query.go
  function queryCounterLast (line 21) | func queryCounterLast(numeratorOperands, denominatorOperands, hostnames ...

FILE: modules/aggregator/cron/run.go
  function WorkerRun (line 29) | func WorkerRun(item *g.Cluster) {
  function parse (line 152) | func parse(expression string, needCompute bool) (operands []string, oper...
  function cleanParam (line 178) | func cleanParam(val string) string {
  function needCompute (line 190) | func needCompute(val string) bool {
  function expressionValid (line 194) | func expressionValid(val string) bool {
  function operatorsValid (line 233) | func operatorsValid(ops []string) bool {

FILE: modules/aggregator/cron/run_test.go
  function Test_expressionValid (line 21) | func Test_expressionValid(t *testing.T) {

FILE: modules/aggregator/cron/updater.go
  function UpdateItems (line 23) | func UpdateItems() {
  function updateItems (line 31) | func updateItems() {

FILE: modules/aggregator/cron/worker.go
  type Worker (line 25) | type Worker struct
    method Start (line 38) | func (this Worker) Start() {
    method Drop (line 66) | func (this Worker) Drop() {
  function NewWorker (line 31) | func NewWorker(ci *g.Cluster) Worker {
  function deleteNoUseWorker (line 72) | func deleteNoUseWorker(m map[string]*g.Cluster) {
  function createWorkerIfNeed (line 86) | func createWorkerIfNeed(m map[string]*g.Cluster) {

FILE: modules/aggregator/db/db.go
  function Init (line 26) | func Init() {

FILE: modules/aggregator/db/reader.go
  function ReadClusterMonitorItems (line 23) | func ReadClusterMonitorItems() (M map[string]*g.Cluster, err error) {

FILE: modules/aggregator/g/cfg.go
  type HttpConfig (line 24) | type HttpConfig struct
  type DatabaseConfig (line 29) | type DatabaseConfig struct
  type ApiConfig (line 36) | type ApiConfig struct
  type GlobalConfig (line 44) | type GlobalConfig struct
  function Config (line 57) | func Config() *GlobalConfig {
  function ParseConfig (line 63) | func ParseConfig(cfg string) {

FILE: modules/aggregator/g/g.go
  function VersionMsg (line 28) | func VersionMsg() string {
  function init (line 32) | func init() {

FILE: modules/aggregator/g/items.go
  type Cluster (line 23) | type Cluster struct
    method String (line 36) | func (this *Cluster) String() string {
  type SafeClusterMonitorItems (line 53) | type SafeClusterMonitorItems struct
    method Init (line 62) | func (this *SafeClusterMonitorItems) Init(m map[string]*Cluster) {
    method Get (line 68) | func (this *SafeClusterMonitorItems) Get() map[string]*Cluster {
  function NewClusterMonitorItems (line 58) | func NewClusterMonitorItems() *SafeClusterMonitorItems {

FILE: modules/aggregator/http/common.go
  function configCommonRoutes (line 24) | func configCommonRoutes() {

FILE: modules/aggregator/http/http.go
  type Dto (line 25) | type Dto struct
  function init (line 30) | func init() {
  function RenderJson (line 35) | func RenderJson(w http.ResponseWriter, v interface{}) {
  function RenderDataJson (line 45) | func RenderDataJson(w http.ResponseWriter, data interface{}) {
  function RenderMsgJson (line 49) | func RenderMsgJson(w http.ResponseWriter, msg string) {
  function AutoRender (line 53) | func AutoRender(w http.ResponseWriter, data interface{}, err error) {
  function Start (line 61) | func Start() {

FILE: modules/aggregator/http/proc.go
  function configProcRoutes (line 22) | func configProcRoutes() {

FILE: modules/aggregator/main.go
  function main (line 31) | func main() {

FILE: modules/aggregator/sdk/sdk.go
  function HostnamesByID (line 28) | func HostnamesByID(group_id int64) ([]string, error) {
  function QueryLastPoints (line 60) | func QueryLastPoints(endpoints, counters []string) (resp []*cmodel.Graph...

FILE: modules/aggregator/sdk/sdk_test.go
  function init (line 24) | func init() {
  function TestSDK (line 28) | func TestSDK(t *testing.T) {

FILE: modules/alarm/api/links.go
  function LinkToSMS (line 24) | func LinkToSMS(content string) (string, error) {

FILE: modules/alarm/api/portal.go
  type Action (line 28) | type Action struct
  type ActionCache (line 39) | type ActionCache struct
    method Get (line 46) | func (this *ActionCache) Get(id int) *Action {
    method Set (line 57) | func (this *ActionCache) Set(id int, action *Action) {
  function GetAction (line 63) | func GetAction(id int) *Action {
  function CurlAction (line 75) | func CurlAction(id int) *Action {

FILE: modules/alarm/api/portal_test.go
  function init (line 24) | func init() {
  function TestPortalAPI (line 28) | func TestPortalAPI(t *testing.T) {

FILE: modules/alarm/api/uic.go
  type APIGetTeamOutput (line 30) | type APIGetTeamOutput struct
  type UsersCache (line 36) | type UsersCache struct
    method Get (line 43) | func (this *UsersCache) Get(team string) []*uic.User {
    method Set (line 54) | func (this *UsersCache) Set(team string, users []*uic.User) {
  function UsersOf (line 60) | func UsersOf(team string) []*uic.User {
  function GetUsers (line 72) | func GetUsers(teams string) map[string]*uic.User {
  function ParseTeams (line 93) | func ParseTeams(teams string) ([]string, []string, []string) {
  function CurlUic (line 116) | func CurlUic(team string) []*uic.User {

FILE: modules/alarm/api/uic_test.go
  function init (line 25) | func init() {
  function TestUicAPI (line 30) | func TestUicAPI(t *testing.T) {

FILE: modules/alarm/cron/builder.go
  function BuildCommonSMSContent (line 25) | func BuildCommonSMSContent(event *model.Event) string {
  function BuildCommonIMContent (line 43) | func BuildCommonIMContent(event *model.Event) string {
  function BuildCommonMailContent (line 61) | func BuildCommonMailContent(event *model.Event) string {
  function GenerateSmsContent (line 82) | func GenerateSmsContent(event *model.Event) string {
  function GenerateMailContent (line 86) | func GenerateMailContent(event *model.Event) string {
  function GenerateIMContent (line 90) | func GenerateIMContent(event *model.Event) string {

FILE: modules/alarm/cron/callback.go
  function HandleCallback (line 31) | func HandleCallback(event *model.Event, action *api.Action) {
  function Callback (line 68) | func Callback(event *model.Event, action *api.Action) string {

FILE: modules/alarm/cron/combiner.go
  function CombineSms (line 29) | func CombineSms() {
  function CombineMail (line 37) | func CombineMail() {
  function CombineIM (line 45) | func CombineIM() {
  function combineMail (line 53) | func combineMail() {
  function combineIM (line 90) | func combineIM() {
  function combineSms (line 143) | func combineSms() {
  function popAllSmsDto (line 196) | func popAllSmsDto() []*SmsDto {
  function popAllMailDto (line 229) | func popAllMailDto() []*MailDto {
  function popAllImDto (line 262) | func popAllImDto() []*ImDto {

FILE: modules/alarm/cron/event_cleaner.go
  function CleanExpiredEvent (line 23) | func CleanExpiredEvent() {

FILE: modules/alarm/cron/event_consumer.go
  function consume (line 27) | func consume(event *cmodel.Event, isHigh bool) {
  function consumeHighEvents (line 50) | func consumeHighEvents(event *cmodel.Event, action *api.Action) {
  function consumeLowEvents (line 72) | func consumeLowEvents(event *cmodel.Event, action *api.Action) {
  function ParseUserSms (line 86) | func ParseUserSms(event *cmodel.Event, action *api.Action) {
  function ParseUserMail (line 120) | func ParseUserMail(event *cmodel.Event, action *api.Action) {
  function ParseUserIm (line 156) | func ParseUserIm(event *cmodel.Event, action *api.Action) {

FILE: modules/alarm/cron/event_reader.go
  function ReadHighEvent (line 28) | func ReadHighEvent() {
  function ReadLowEvent (line 44) | func ReadLowEvent() {
  function popEvent (line 60) | func popEvent(queues []string) (*cmodel.Event, error) {

FILE: modules/alarm/cron/im_sender.go
  function ConsumeIM (line 26) | func ConsumeIM() {
  function SendIMList (line 37) | func SendIMList(L []*model.IM) {
  function SendIM (line 44) | func SendIM(im *model.IM) {

FILE: modules/alarm/cron/init_sender.go
  function InitSenderWorker (line 27) | func InitSenderWorker() {

FILE: modules/alarm/cron/mail_sender.go
  function ConsumeMail (line 26) | func ConsumeMail() {
  function SendMailList (line 37) | func SendMailList(L []*model.Mail) {
  function SendMail (line 44) | func SendMail(mail *model.Mail) {

FILE: modules/alarm/cron/model.go
  type MailDto (line 17) | type MailDto struct
  type SmsDto (line 26) | type SmsDto struct
  type ImDto (line 34) | type ImDto struct

FILE: modules/alarm/cron/sms_sender.go
  function ConsumeSms (line 27) | func ConsumeSms() {
  function SendSmsList (line 38) | func SendSmsList(L []*model.Sms) {
  function SendSms (line 45) | func SendSms(sms *model.Sms) {

FILE: modules/alarm/g/cfg.go
  type HttpConfig (line 25) | type HttpConfig struct
  type RedisConfig (line 30) | type RedisConfig struct
  type ApiConfig (line 40) | type ApiConfig struct
  type FalconPortalConfig (line 49) | type FalconPortalConfig struct
  type WorkerConfig (line 55) | type WorkerConfig struct
  type HousekeeperConfig (line 61) | type HousekeeperConfig struct
  type GlobalConfig (line 66) | type GlobalConfig struct
  function Config (line 82) | func Config() *GlobalConfig {
  function ParseConfig (line 88) | func ParseConfig(cfg string) {

FILE: modules/alarm/g/eventdto.go
  function Link (line 22) | func Link(event *cmodel.Event) string {

FILE: modules/alarm/g/g.go
  function VersionMsg (line 28) | func VersionMsg() string {
  function init (line 32) | func init() {

FILE: modules/alarm/g/logger.go
  function InitLog (line 19) | func InitLog(level string) (err error) {

FILE: modules/alarm/g/redis.go
  function InitRedisConnPool (line 27) | func InitRedisConnPool() {
  function formatRedisAddr (line 50) | func formatRedisAddr(addrConfig string) (string, string) {
  function PingRedis (line 58) | func PingRedis(c redis.Conn, t time.Time) error {

FILE: modules/alarm/http/controller.go
  function Version (line 23) | func Version(c *gin.Context) {
  function Health (line 27) | func Health(c *gin.Context) {
  function Workdir (line 31) | func Workdir(c *gin.Context) {

FILE: modules/alarm/http/http.go
  function Start (line 23) | func Start() {

FILE: modules/alarm/main.go
  function main (line 31) | func main() {

FILE: modules/alarm/model/database.go
  function InitDatabase (line 24) | func InitDatabase() {

FILE: modules/alarm/model/event/event.go
  type EventCases (line 21) | type EventCases struct
  type Events (line 45) | type Events struct

FILE: modules/alarm/model/event/event_operation.go
  constant timeLayout (line 29) | timeLayout = "2006-01-02 15:04:05"
  function insertEvent (line 31) | func insertEvent(q orm.Ormer, eve *coommonModel.Event) (res sql.Result, ...
  function InsertEvent (line 61) | func InsertEvent(eve *coommonModel.Event) {
  function counterGen (line 185) | func counterGen(metric string, tags string) (mycounter string) {
  function DeleteEventOlder (line 193) | func DeleteEventOlder(before time.Time, limit int) {

FILE: modules/alarm/model/im.go
  type IM (line 21) | type IM struct
    method String (line 26) | func (this *IM) String() string {

FILE: modules/alarm/model/mail.go
  type Mail (line 21) | type Mail struct
    method String (line 27) | func (this *Mail) String() string {

FILE: modules/alarm/model/sms.go
  type Sms (line 21) | type Sms struct
    method String (line 26) | func (this *Sms) String() string {

FILE: modules/alarm/redi/msg_reader.go
  constant IM_QUEUE_NAME (line 26) | IM_QUEUE_NAME   = "/im"
  constant SMS_QUEUE_NAME (line 27) | SMS_QUEUE_NAME  = "/sms"
  constant MAIL_QUEUE_NAME (line 28) | MAIL_QUEUE_NAME = "/mail"
  function PopAllSms (line 31) | func PopAllSms() []*model.Sms {
  function PopAllIM (line 64) | func PopAllIM() []*model.IM {
  function PopAllMail (line 97) | func PopAllMail() []*model.Mail {

FILE: modules/alarm/redi/msg_writer.go
  function lpush (line 26) | func lpush(queue, message string) {
  function WriteSmsModel (line 35) | func WriteSmsModel(sms *model.Sms) {
  function WriteIMModel (line 50) | func WriteIMModel(im *model.IM) {
  function WriteMailModel (line 65) | func WriteMailModel(mail *model.Mail) {
  function WriteSms (line 80) | func WriteSms(tos []string, content string) {
  function WriteIM (line 89) | func WriteIM(tos []string, content string) {
  function WriteMail (line 98) | func WriteMail(tos []string, subject, content string) {

FILE: modules/falcon2p8s/g/cfg.go
  type HttpConfig (line 11) | type HttpConfig struct
  type RpcConfig (line 15) | type RpcConfig struct
  type GlobalConfig (line 19) | type GlobalConfig struct
  function Config (line 32) | func Config() *GlobalConfig {
  function ParseConfig (line 38) | func ParseConfig(cfg string) {

FILE: modules/falcon2p8s/g/const.go
  constant Gauge (line 4) | Gauge   = "GAUGE"
  constant Counter (line 5) | Counter = "COUNTER"

FILE: modules/falcon2p8s/g/g.go
  function VersionMsg (line 9) | func VersionMsg() string {

FILE: modules/falcon2p8s/g/logger.go
  function InitLog (line 5) | func InitLog(level string) (err error) {

FILE: modules/falcon2p8s/g/var.go
  type LastUpdateTimeItem (line 21) | type LastUpdateTimeItem struct
  type UncheckedCollector (line 27) | type UncheckedCollector struct
    method Describe (line 32) | func (u UncheckedCollector) Describe(_ chan<- *prometheus.Desc) {}
    method Collect (line 33) | func (u UncheckedCollector) Collect(c chan<- prometheus.Metric) {

FILE: modules/falcon2p8s/http/common.go
  function configCommonRoutes (line 8) | func configCommonRoutes() {

FILE: modules/falcon2p8s/http/cron.go
  function getqueueSize (line 16) | func getqueueSize() {
  function cleanOutdatedGaugeMetrics (line 23) | func cleanOutdatedGaugeMetrics() {
  function cleanOutdatedCounterMetrics (line 41) | func cleanOutdatedCounterMetrics() {

FILE: modules/falcon2p8s/http/helper.go
  type RespJson (line 9) | type RespJson struct
  function JSONR (line 15) | func JSONR(c *gin.Context, arg ...interface{}) (werror error) {

FILE: modules/falcon2p8s/http/http.go
  function RenderJson (line 22) | func RenderJson(w http.ResponseWriter, v interface{}) {
  function dealGaugeMetric (line 34) | func dealGaugeMetric(p8sItem *rpc.P8sItem) {
  function dealCounterMetric (line 77) | func dealCounterMetric(p8sItem *rpc.P8sItem) {
  function Start (line 144) | func Start() {
  function prometheusHandler (line 224) | func prometheusHandler() gin.HandlerFunc {

FILE: modules/falcon2p8s/main.go
  function startSignal (line 16) | func startSignal(pid int) {
  function main (line 37) | func main() {

FILE: modules/falcon2p8s/middlewares/scraping.go
  function CheckIsScraping (line 8) | func CheckIsScraping() gin.HandlerFunc {

FILE: modules/falcon2p8s/rpc/model.go
  type SimpleRpcResponse (line 5) | type SimpleRpcResponse struct
  type NullRpcRequest (line 9) | type NullRpcRequest struct
  type P8sItem (line 12) | type P8sItem struct

FILE: modules/falcon2p8s/rpc/receiver.go
  constant MetricNameChars (line 13) | MetricNameChars = "[^a-zA-Z0-9_:]"
  constant TagKeyNameChars (line 14) | TagKeyNameChars = "[^a-zA-Z0-9_]"
  function init (line 18) | func init() {
  type P8sRelay (line 23) | type P8sRelay
    method Ping (line 25) | func (this *P8sRelay) Ping(req NullRpcRequest, resp *SimpleRpcResponse...
    method Send (line 31) | func (this *P8sRelay) Send(items []*P8sItem, resp *SimpleRpcResponse) ...

FILE: modules/falcon2p8s/rpc/rpc.go
  function Start (line 11) | func Start() {

FILE: modules/falcon2p8s/utils/func.go
  function SortedTags (line 12) | func SortedTags(tags map[string]string) string {
  function PK (line 54) | func PK(metric string, tagkeys []string) string {
  function PKWithTagValue (line 68) | func PKWithTagValue(metric string, tags map[string]string) string {
  function SortedTagKVs (line 83) | func SortedTagKVs(tags map[string]string) (tagKeys, tagValues []string) {

FILE: modules/graph/api/graph.go
  type Graph (line 35) | type Graph
    method GetRrd (line 37) | func (this *Graph) GetRrd(key string, rrdfile *g.File) (err error) {
    method Ping (line 58) | func (this *Graph) Ping(req cmodel.NullRpcRequest, resp *cmodel.Simple...
    method Send (line 62) | func (this *Graph) Send(items []*cmodel.GraphItem, resp *cmodel.Simple...
    method Query (line 127) | func (this *Graph) Query(param cmodel.GraphQueryParam, resp *cmodel.Gr...
    method Delete (line 317) | func (this *Graph) Delete(params []*cmodel.GraphDeleteParam, resp *cmo...
    method Info (line 339) | func (this *Graph) Info(param cmodel.GraphInfoParam, resp *cmodel.Grap...
    method Last (line 358) | func (this *Graph) Last(param cmodel.GraphLastParam, resp *cmodel.Grap...
    method LastRaw (line 369) | func (this *Graph) LastRaw(param cmodel.GraphLastParam, resp *cmodel.G...
  function HandleItems (line 68) | func HandleItems(items []*cmodel.GraphItem) error {
  function handleItems (line 73) | func handleItems(items []*cmodel.GraphItem) {
  function GetLast (line 381) | func GetLast(endpoint, counter string) *cmodel.RRDData {
  function GetLastRaw (line 417) | func GetLastRaw(endpoint, counter string) *cmodel.RRDData {

FILE: modules/graph/api/rpc.go
  type conn_list (line 28) | type conn_list struct
    method insert (line 33) | func (l *conn_list) insert(c net.Conn) *list.Element {
    method remove (line 38) | func (l *conn_list) remove(e *list.Element) net.Conn {
  function init (line 47) | func init() {
  function Start (line 53) | func Start() {

FILE: modules/graph/cron/clean.go
  function CleanCache (line 43) | func CleanCache() {
  function DeleteInvalidItems (line 68) | func DeleteInvalidItems() int {
  function DeleteInvalidHistory (line 94) | func DeleteInvalidHistory() int {

FILE: modules/graph/g/cfg.go
  type File (line 27) | type File struct
  type HttpConfig (line 32) | type HttpConfig struct
  type RpcConfig (line 37) | type RpcConfig struct
  type RRDConfig (line 42) | type RRDConfig struct
  type DBConfig (line 46) | type DBConfig struct
  type GlobalConfig (line 51) | type GlobalConfig struct
  function Config (line 74) | func Config() *GlobalConfig {
  function ParseConfig (line 78) | func ParseConfig(cfg string) {

FILE: modules/graph/g/db.go
  function InitDB (line 32) | func InitDB() {
  function GetDbConn (line 43) | func GetDbConn(connName string) (c *sql.DB, e error) {
  function makeDbConn (line 70) | func makeDbConn() (conn *sql.DB, err error) {
  function closeDbConn (line 82) | func closeDbConn(conn *sql.DB) {

FILE: modules/graph/g/g.go
  function VersionMsg (line 47) | func VersionMsg() string {
  constant GAUGE (line 52) | GAUGE           = "GAUGE"
  constant DERIVE (line 53) | DERIVE          = "DERIVE"
  constant COUNTER (line 54) | COUNTER         = "COUNTER"
  constant DEFAULT_STEP (line 55) | DEFAULT_STEP    = 60
  constant MIN_STEP (line 56) | MIN_STEP        = 30
  constant CLEAN_CACHE (line 57) | CLEAN_CACHE     = 86400
  constant CACHE_DELAY (line 58) | CACHE_DELAY     = 1800
  constant CACHE_TIME (line 59) | CACHE_TIME      = 1800000
  constant FLUSH_DISK_STEP (line 60) | FLUSH_DISK_STEP = 1000
  constant FLUSH_MIN_COUNT (line 61) | FLUSH_MIN_COUNT = 6
  constant FLUSH_MAX_WAIT (line 62) | FLUSH_MAX_WAIT  = 86400
  constant GRAPH_F_MISS (line 66) | GRAPH_F_MISS uint32 = 1 << iota
  constant GRAPH_F_ERR (line 67) | GRAPH_F_ERR
  constant GRAPH_F_SENDING (line 68) | GRAPH_F_SENDING
  constant GRAPH_F_FETCHING (line 69) | GRAPH_F_FETCHING
  function init (line 72) | func init() {

FILE: modules/graph/g/git.go
  constant COMMIT (line 18) | COMMIT = "gitversion"

FILE: modules/graph/g/logger.go
  function InitLog (line 19) | func InitLog(level string) (err error) {

FILE: modules/graph/g/utils.go
  function RrdFileName (line 28) | func RrdFileName(baseDir string, md5 string, dsType string, step int) st...
  function IsRrdFileExist (line 34) | func IsRrdFileExist(filename string) bool {
  function FormRrdCacheKey (line 39) | func FormRrdCacheKey(md5 string, dsType string, step int) string {
  function SplitRrdCacheKey (line 42) | func SplitRrdCacheKey(ckey string) (md5 string, dsType string, step int,...
  function IsValidString (line 63) | func IsValidString(str string) bool {

FILE: modules/graph/g/utils_test.go
  function Test_RrdFileName (line 22) | func Test_RrdFileName(t *testing.T) {
  function Test_FormRrdCacheKey (line 34) | func Test_FormRrdCacheKey(t *testing.T) {
  function Benchmark_RrdFileName (line 46) | func Benchmark_RrdFileName(b *testing.B) {
  function Benchmark_RrdFileName_orig (line 52) | func Benchmark_RrdFileName_orig(b *testing.B) {
  function Benchmark_FormRrdCacheKey (line 58) | func Benchmark_FormRrdCacheKey(b *testing.B) {
  function Benchmark_FormRrdCacheKey_orig (line 64) | func Benchmark_FormRrdCacheKey_orig(b *testing.B) {
  function RrdFileName_orig (line 70) | func RrdFileName_orig(baseDir string, md5 string, dsType string, step in...
  function FormRrdCacheKey_orig (line 74) | func FormRrdCacheKey_orig(md5 string, dsType string, step int) string {

FILE: modules/graph/http/common.go
  function configCommonRoutes (line 27) | func configCommonRoutes() {

FILE: modules/graph/http/helper.go
  type RespJson (line 23) | type RespJson struct
  function JSONR (line 29) | func JSONR(c *gin.Context, arg ...interface{}) (werror error) {

FILE: modules/graph/http/http.go
  type Dto (line 31) | type Dto struct
  function init (line 39) | func init() {
  function RenderJson (line 45) | func RenderJson(w http.ResponseWriter, v interface{}) {
  function RenderDataJson (line 55) | func RenderDataJson(w http.ResponseWriter, data interface{}) {
  function RenderMsgJson (line 59) | func RenderMsgJson(w http.ResponseWriter, msg string) {
  function AutoRender (line 63) | func AutoRender(w http.ResponseWriter, data interface{}, err error) {
  type TcpKeepAliveListener (line 75) | type TcpKeepAliveListener struct
    method Accept (line 79) | func (ln TcpKeepAliveListener) Accept() (c net.Conn, err error) {
  function Start (line 89) | func Start() {

FILE: modules/graph/http/index.go
  function configIndexRoutes (line 24) | func configIndexRoutes() {

FILE: modules/graph/http/proc.go
  function configProcRoutes (line 22) | func configProcRoutes() {

FILE: modules/graph/index/cache.go
  constant DefaultMaxCacheSize (line 35) | DefaultMaxCacheSize                     = 5000000
  constant DefaultCacheProcUpdateTaskSleepInterval (line 36) | DefaultCacheProcUpdateTaskSleepInterval = time.Duration(1) * time.Second
  function InitCache (line 54) | func InitCache() {
  function GetTypeAndStep (line 59) | func GetTypeAndStep(endpoint string, counter string) (dsType string, ste...
  function GetEndpointFromCache (line 89) | func GetEndpointFromCache(endpoint string) (int64, bool) {
  function GetCounterFromCache (line 115) | func GetCounterFromCache(endpointId int64, counter string) (dsType strin...
  function startCacheProcUpdateTask (line 151) | func startCacheProcUpdateTask() {
  type IndexCacheItem (line 163) | type IndexCacheItem struct
  function NewIndexCacheItem (line 168) | func NewIndexCacheItem(uuid string, item *cmodel.GraphItem) *IndexCacheI...
  type IndexCacheBase (line 173) | type IndexCacheBase struct
    method GetMaxSize (line 183) | func (this *IndexCacheBase) GetMaxSize() int {
    method Put (line 187) | func (this *IndexCacheBase) Put(key string, item interface{}) {
    method Remove (line 193) | func (this *IndexCacheBase) Remove(key string) {
    method Get (line 199) | func (this *IndexCacheBase) Get(key string) interface{} {
    method ContainsKey (line 205) | func (this *IndexCacheBase) ContainsKey(key string) bool {
    method Size (line 211) | func (this *IndexCacheBase) Size() int {
    method Keys (line 217) | func (this *IndexCacheBase) Keys() []string {
  function NewIndexCacheBase (line 179) | func NewIndexCacheBase(max int) *IndexCacheBase {

FILE: modules/graph/index/index.go
  function Start (line 27) | func Start() {
  function ReceiveItem (line 34) | func ReceiveItem(item *cmodel.GraphItem, md5 string) {
  function RemoveItem (line 64) | func RemoveItem(item *cmodel.GraphItem) {

FILE: modules/graph/index/index_update_all_task.go
  constant DefaultUpdateStepInSec (line 34) | DefaultUpdateStepInSec     = 2 * 24 * 3600
  constant ConcurrentOfUpdateIndexAll (line 35) | ConcurrentOfUpdateIndexAll = 1
  function GetConcurrentOfUpdateIndexAll (line 44) | func GetConcurrentOfUpdateIndexAll() int {
  function UpdateIndexAllByDefaultStep (line 49) | func UpdateIndexAllByDefaultStep() {
  function UpdateIndexAll (line 52) | func UpdateIndexAll(updateStepInSec int64) {
  function UpdateIndexOne (line 78) | func UpdateIndexOne(endpoint string, metric string, tags map[string]stri...
  function updateIndexAll (line 109) | func updateIndexAll(updateStepInSec int64) int {
  function updateIndexFromOneItem (line 154) | func updateIndexFromOneItem(item *cmodel.GraphItem, conn *sql.DB) error {

FILE: modules/graph/index/index_update_incr_task.go
  constant IndexUpdateIncrTaskSleepInterval (line 30) | IndexUpdateIncrTaskSleepInterval = time.Duration(1) * time.Second
  function StartIndexUpdateIncrTask (line 38) | func StartIndexUpdateIncrTask() {
  function updateIndexIncr (line 53) | func updateIndexIncr() int {

FILE: modules/graph/main.go
  function start_signal (line 33) | func start_signal(pid int, cfg *g.GlobalConfig) {
  function main (line 67) | func main() {

FILE: modules/graph/proc/proc.go
  function GetAll (line 68) | func GetAll() []interface{} {

FILE: modules/graph/rrdtool/migrate.go
  constant _ (line 37) | _ = iota
  constant NET_TASK_M_SEND (line 38) | NET_TASK_M_SEND
  constant NET_TASK_M_QUERY (line 39) | NET_TASK_M_QUERY
  constant NET_TASK_M_PULL (line 40) | NET_TASK_M_PULL
  type Net_task_t (line 43) | type Net_task_t struct
  constant FETCH_S_SUCCESS (line 52) | FETCH_S_SUCCESS = iota
  constant FETCH_S_ERR (line 53) | FETCH_S_ERR
  constant FETCH_S_ISNOTEXIST (line 54) | FETCH_S_ISNOTEXIST
  constant SEND_S_SUCCESS (line 55) | SEND_S_SUCCESS
  constant SEND_S_ERR (line 56) | SEND_S_ERR
  constant QUERY_S_SUCCESS (line 57) | QUERY_S_SUCCESS
  constant QUERY_S_ERR (line 58) | QUERY_S_ERR
  constant CONN_S_ERR (line 59) | CONN_S_ERR
  constant CONN_S_DIAL (line 60) | CONN_S_DIAL
  constant STAT_SIZE (line 61) | STAT_SIZE
  type MigrateCounter (line 72) | type MigrateCounter struct
  function init (line 84) | func init() {
  function GetCounterV2 (line 90) | func GetCounterV2() *MigrateCounter {
  function GetCounter (line 104) | func GetCounter() (ret string) {
  function dial (line 117) | func dial(address string, timeout time.Duration) (*rpc.Client, error) {
  function migrate_start (line 132) | func migrate_start(cfg *g.GlobalConfig) {
  function net_task_worker (line 155) | func net_task_worker(idx int, ch chan *Net_task_t, client **rpc.Client, ...
  function reconnection (line 215) | func reconnection(client **rpc.Client, addr string) {
  function query_data (line 236) | func query_data(client **rpc.Client, addr string,
  function send_data (line 257) | func send_data(client **rpc.Client, key string, addr string) error {
  function fetch_rrd (line 301) | func fetch_rrd(client **rpc.Client, key string, addr string) error {
  function rpc_call (line 356) | func rpc_call(client *rpc.Client, method string, args interface{},

FILE: modules/graph/rrdtool/rrdtool.go
  type fetch_t (line 37) | type fetch_t struct
  type flushfile_t (line 46) | type flushfile_t struct
  type readfile_t (line 51) | type readfile_t struct
  function Start (line 56) | func Start() {
  constant RRA1PointCnt (line 74) | RRA1PointCnt   = 720
  constant RRA5PointCnt (line 75) | RRA5PointCnt   = 576
  constant RRA20PointCnt (line 76) | RRA20PointCnt  = 504
  constant RRA180PointCnt (line 77) | RRA180PointCnt = 766
  constant RRA720PointCnt (line 78) | RRA720PointCnt = 730
  function create (line 81) | func create(filename string, item *cmodel.GraphItem) error {
  function update (line 116) | func update(filename string, items []*cmodel.GraphItem) error {
  function flushrrd (line 137) | func flushrrd(filename string, items []*cmodel.GraphItem) error {
  function ReadFile (line 159) | func ReadFile(filename, md5 string) ([]byte, error) {
  function FlushFile (line 172) | func FlushFile(filename, md5 string, items []*cmodel.GraphItem) error {
  function Fetch (line 186) | func Fetch(filename string, md5 string, cf string, start, end int64, ste...
  function fetch (line 204) | func fetch(filename string, cf string, start, end int64, step int) ([]*c...
  function FlushAll (line 235) | func FlushAll(force bool) {
  function CommitByKey (line 247) | func CommitByKey(key string) {
  function PullByKey (line 261) | func PullByKey(key string) {
  function FlushRRD (line 290) | func FlushRRD(idx int, force bool) {
  function shouldFlush (line 314) | func shouldFlush(key string) bool {

FILE: modules/graph/rrdtool/sync_disk.go
  constant _ (line 30) | _ = iota
  constant IO_TASK_M_READ (line 31) | IO_TASK_M_READ
  constant IO_TASK_M_WRITE (line 32) | IO_TASK_M_WRITE
  constant IO_TASK_M_FLUSH (line 33) | IO_TASK_M_FLUSH
  constant IO_TASK_M_FETCH (line 34) | IO_TASK_M_FETCH
  type io_task_t (line 37) | type io_task_t struct
  function InitChannel (line 48) | func InitChannel() {
  function syncDisk (line 57) | func syncDisk() {
  function writeFile (line 78) | func writeFile(filename string, data []byte, perm os.FileMode) error {
  function ioWorker (line 93) | func ioWorker() {

FILE: modules/graph/rrdtool/utils.go
  function getIndex (line 26) | func getIndex(md5 string) (index int) {

FILE: modules/graph/store/history.go
  constant defaultHistorySize (line 24) | defaultHistorySize = 3
  function GetLastItem (line 33) | func GetLastItem(key string) *cmodel.GraphItem {
  function GetAllItems (line 47) | func GetAllItems(key string) []*cmodel.GraphItem {
  function AddItem (line 64) | func AddItem(key string, val *cmodel.GraphItem) {

FILE: modules/graph/store/linkedlist.go
  type SafeLinkedList (line 24) | type SafeLinkedList struct
    method PushFront (line 35) | func (this *SafeLinkedList) PushFront(v interface{}) *list.Element {
    method Front (line 41) | func (this *SafeLinkedList) Front() *list.Element {
    method PopBack (line 47) | func (this *SafeLinkedList) PopBack() *list.Element {
    method Back (line 59) | func (this *SafeLinkedList) Back() *list.Element {
    method Len (line 66) | func (this *SafeLinkedList) Len() int {
    method PopAll (line 75) | func (this *SafeLinkedList) PopAll() []*cmodel.GraphItem {
    method PushAll (line 96) | func (this *SafeLinkedList) PushAll(items []*cmodel.GraphItem) {
    method FetchAll (line 109) | func (this *SafeLinkedList) FetchAll() ([]*cmodel.GraphItem, uint32) {
  function NewSafeLinkedList (line 31) | func NewSafeLinkedList() *SafeLinkedList {

FILE: modules/graph/store/store.go
  type GraphItemMap (line 31) | type GraphItemMap struct
    method Get (line 37) | func (this *GraphItemMap) Get(key string) (*SafeLinkedList, bool) {
    method Remove (line 46) | func (this *GraphItemMap) Remove(key string) bool {
    method Getitems (line 59) | func (this *GraphItemMap) Getitems(idx int) map[string]*SafeLinkedList {
    method Set (line 67) | func (this *GraphItemMap) Set(key string, val *SafeLinkedList) {
    method Len (line 74) | func (this *GraphItemMap) Len() int {
    method First (line 84) | func (this *GraphItemMap) First(key string) *cmodel.GraphItem {
    method PushAll (line 101) | func (this *GraphItemMap) PushAll(key string, items []*cmodel.GraphIte...
    method GetFlag (line 113) | func (this *GraphItemMap) GetFlag(key string) (uint32, error) {
    method SetFlag (line 124) | func (this *GraphItemMap) SetFlag(key string, flag uint32) error {
    method PopAll (line 136) | func (this *GraphItemMap) PopAll(key string) []*cmodel.GraphItem {
    method FetchAll (line 147) | func (this *GraphItemMap) FetchAll(key string) ([]*cmodel.GraphItem, u...
    method PushFront (line 173) | func (this *GraphItemMap) PushFront(key string,
    method KeysByIndex (line 190) | func (this *GraphItemMap) KeysByIndex(idx int) []string {
    method Back (line 207) | func (this *GraphItemMap) Back(key string) *cmodel.GraphItem {
    method ItemCnt (line 225) | func (this *GraphItemMap) ItemCnt(key string) int {
  function hashKey (line 159) | func hashKey(key string) uint32 {
  function getWts (line 168) | func getWts(key string, now int64) int64 {
  function init (line 236) | func init() {

FILE: modules/hbs/cache/agents.go
  type SafeAgents (line 29) | type SafeAgents struct
    method Put (line 40) | func (this *SafeAgents) Put(req *model.AgentReportRequest) {
    method Get (line 60) | func (this *SafeAgents) Get(hostname string) (*model.AgentUpdateInfo, ...
    method Delete (line 67) | func (this *SafeAgents) Delete(hostname string) {
    method Keys (line 73) | func (this *SafeAgents) Keys() []string {
  function NewSafeAgents (line 36) | func NewSafeAgents() *SafeAgents {
  function DeleteStaleAgents (line 86) | func DeleteStaleAgents() {
  function deleteStaleAgents (line 94) | func deleteStaleAgents() {

FILE: modules/hbs/cache/cache.go
  function Init (line 22) | func Init() {
  function LoopInit (line 58) | func LoopInit() {

FILE: modules/hbs/cache/expressions.go
  type SafeExpressionCache (line 23) | type SafeExpressionCache struct
    method Get (line 30) | func (this *SafeExpressionCache) Get() []*model.Expression {
    method Init (line 36) | func (this *SafeExpressionCache) Init() {

FILE: modules/hbs/cache/groups.go
  type SafeHostGroupsMap (line 23) | type SafeHostGroupsMap struct
    method GetGroupIds (line 30) | func (this *SafeHostGroupsMap) GetGroupIds(hid int) ([]int, bool) {
    method Init (line 37) | func (this *SafeHostGroupsMap) Init() {

FILE: modules/hbs/cache/hosts.go
  type SafeHostMap (line 25) | type SafeHostMap struct
    method GetID (line 32) | func (this *SafeHostMap) GetID(hostname string) (int, bool) {
    method Init (line 39) | func (this *SafeHostMap) Init() {
  type SafeMonitoredHosts (line 50) | type SafeMonitoredHosts struct
    method Get (line 57) | func (this *SafeMonitoredHosts) Get() map[int]*model.Host {
    method Init (line 63) | func (this *SafeMonitoredHosts) Init() {

FILE: modules/hbs/cache/plugins.go
  type SafeGroupPlugins (line 24) | type SafeGroupPlugins struct
    method GetPlugins (line 31) | func (this *SafeGroupPlugins) GetPlugins(gid int) ([]string, bool) {
    method Init (line 38) | func (this *SafeGroupPlugins) Init() {
  function GetPlugins (line 50) | func GetPlugins(hostname string) []string {

FILE: modules/hbs/cache/strategies.go
  type SafeStrategies (line 27) | type SafeStrategies struct
    method GetMap (line 34) | func (this *SafeStrategies) GetMap() map[int]*model.Strategy {
    method Init (line 40) | func (this *SafeStrategies) Init(tpls map[int]*model.Template) {
  function GetBuiltinMetrics (line 51) | func GetBuiltinMetrics(hostname string) ([]*model.BuiltinMetric, error) {
  function ParentIds (line 103) | func ParentIds(allTpls map[int]*model.Template, tid int) (ret []int) {

FILE: modules/hbs/cache/templates.go
  type SafeGroupTemplates (line 24) | type SafeGroupTemplates struct
    method GetTemplateIds (line 31) | func (this *SafeGroupTemplates) GetTemplateIds(gid int) ([]int, bool) {
    method Init (line 38) | func (this *SafeGroupTemplates) Init() {
  type SafeTemplateCache (line 49) | type SafeTemplateCache struct
    method GetMap (line 56) | func (this *SafeTemplateCache) GetMap() map[int]*model.Template {
    method Init (line 62) | func (this *SafeTemplateCache) Init() {
  type SafeHostTemplateIds (line 73) | type SafeHostTemplateIds struct
    method GetMap (line 80) | func (this *SafeHostTemplateIds) GetMap() map[int][]int {
    method Init (line 86) | func (this *SafeHostTemplateIds) Init() {

FILE: modules/hbs/db/agent.go
  function UpdateAgent (line 24) | func UpdateAgent(agentInfo *model.AgentUpdateInfo) {

FILE: modules/hbs/db/db.go
  function Init (line 26) | func Init() {

FILE: modules/hbs/db/expression.go
  function QueryExpressions (line 24) | func QueryExpressions() (ret []*model.Expression, err error) {
  function parseExpression (line 65) | func parseExpression(exp string) (metric string, tags map[string]string,...

FILE: modules/hbs/db/group.go
  function QueryHostGroups (line 21) | func QueryHostGroups() (map[int][]int, error) {

FILE: modules/hbs/db/host.go
  function QueryHosts (line 24) | func QueryHosts() (map[string]int, error) {
  function QueryMonitoredHosts (line 53) | func QueryMonitoredHosts() (map[int]*model.Host, error) {

FILE: modules/hbs/db/plugin.go
  function QueryPlugins (line 21) | func QueryPlugins() (map[int][]string, error) {

FILE: modules/hbs/db/strategy.go
  function QueryStrategies (line 27) | func QueryStrategies(tpls map[int]*model.Template) (map[int]*model.Strat...
  function QueryBuiltinMetrics (line 90) | func QueryBuiltinMetrics(tids string) ([]*model.BuiltinMetric, error) {

FILE: modules/hbs/db/template.go
  function QueryGroupTemplates (line 22) | func QueryGroupTemplates() (map[int][]int, error) {
  function QueryTemplates (line 52) | func QueryTemplates() (map[int]*model.Template, error) {
  function QueryHostTemplateIds (line 78) | func QueryHostTemplateIds() (map[int][]int, error) {

FILE: modules/hbs/g/cfg.go
  type HttpConfig (line 24) | type HttpConfig struct
  type GlobalConfig (line 29) | type GlobalConfig struct
  function Config (line 46) | func Config() *GlobalConfig {
  function ParseConfig (line 52) | func ParseConfig(cfg string) {

FILE: modules/hbs/g/g.go
  function VersionMsg (line 34) | func VersionMsg() string {
  function init (line 38) | func init() {

FILE: modules/hbs/http/common.go
  function configCommonRoutes (line 24) | func configCommonRoutes() {

FILE: modules/hbs/http/http.go
  type Dto (line 25) | type Dto struct
  function init (line 30) | func init() {
  function RenderJson (line 35) | func RenderJson(w http.ResponseWriter, v interface{}) {
  function RenderDataJson (line 45) | func RenderDataJson(w http.ResponseWriter, data interface{}) {
  function RenderMsgJson (line 49) | func RenderMsgJson(w http.ResponseWriter, msg string) {
  function AutoRender (line 53) | func AutoRender(w http.ResponseWriter, data interface{}, err error) {
  function Start (line 61) | func Start() {

FILE: modules/hbs/http/proc.go
  function configProcRoutes (line 24) | func configProcRoutes() {

FILE: modules/hbs/main.go
  function main (line 30) | func main() {

FILE: modules/hbs/rpc/agent.go
  method MinePlugins (line 28) | func (t *Agent) MinePlugins(args model.AgentHeartbeatRequest, reply *mod...
  method ReportStatus (line 39) | func (t *Agent) ReportStatus(args *model.AgentReportRequest, reply *mode...
  method TrustableIps (line 51) | func (t *Agent) TrustableIps(args *model.NullRpcRequest, ips *string) er...
  method BuiltinMetrics (line 57) | func (t *Agent) BuiltinMetrics(args *model.AgentHeartbeatRequest, reply ...
  function DigestBuiltinMetrics (line 83) | func DigestBuiltinMetrics(items []*model.BuiltinMetric) string {

FILE: modules/hbs/rpc/hbs.go
  method GetExpressions (line 24) | func (t *Hbs) GetExpressions(req model.NullRpcRequest, reply *model.Expr...
  method GetStrategies (line 29) | func (t *Hbs) GetStrategies(req model.NullRpcRequest, reply *model.Strat...
  function Tpl2Strategies (line 86) | func Tpl2Strategies(strategies map[int]*model.Strategy) map[int][]*model...
  function CalcInheritStrategies (line 101) | func CalcInheritStrategies(allTpls map[int]*model.Template, tids []int, ...
  function slice_int_contains (line 200) | func slice_int_contains(list []int, target int) bool {
  function slice_int_eq (line 209) | func slice_int_eq(a []int, b []int) bool {
  function slice_int_lt (line 221) | func slice_int_lt(a []int, b []int) bool {

FILE: modules/hbs/rpc/rpc.go
  type Hbs (line 27) | type Hbs
  type Agent (line 28) | type Agent
  function Start (line 30) | func Start() {

FILE: modules/judge/cron/cleaner.go
  function CleanStale (line 22) | func CleanStale() {
  function cleanStale (line 29) | func cleanStale() {

FILE: modules/judge/cron/strategy.go
  function SyncStrategies (line 27) | func SyncStrategies() {
  function syncStrategies (line 37) | func syncStrategies() {
  function rebuildStrategyMap (line 48) | func rebuildStrategyMap(strategiesResponse *model.StrategiesResponse) {
  function syncExpression (line 71) | func syncExpression() {
  function rebuildExpressionMap (line 82) | func rebuildExpressionMap(expressionResponse *model.ExpressionResponse) {
  function syncFilter (line 98) | func syncFilter() {

FILE: modules/judge/g/cfg.go
  type HttpConfig (line 24) | type HttpConfig struct
  type RpcConfig (line 29) | type RpcConfig struct
  type HbsConfig (line 34) | type HbsConfig struct
  type RedisConfig (line 40) | type RedisConfig struct
  type AlarmConfig (line 48) | type AlarmConfig struct
  type GlobalConfig (line 55) | type GlobalConfig struct
  function Config (line 71) | func Config() *GlobalConfig {
  function ParseConfig (line 77) | func ParseConfig(cfg string) {

FILE: modules/judge/g/g.go
  function VersionMsg (line 33) | func VersionMsg() string {
  function init (line 37) | func init() {

FILE: modules/judge/g/redis.go
  function InitRedisConnPool (line 27) | func InitRedisConnPool() {
  function formatRedisAddr (line 60) | func formatRedisAddr(addrConfig string) (string, string) {
  function PingRedis (line 68) | func PingRedis(c redis.Conn, t time.Time) error {

FILE: modules/judge/g/rpc.go
  type SingleConnRpcClient (line 27) | type SingleConnRpcClient struct
    method close (line 35) | func (this *SingleConnRpcClient) close() {
    method insureConn (line 42) | func (this *SingleConnRpcClient) insureConn() {
    method Call (line 74) | func (this *SingleConnRpcClient) Call(method string, args interface{},...

FILE: modules/judge/g/var.go
  type SafeStrategyMap (line 24) | type SafeStrategyMap struct
    method ReInit (line 63) | func (this *SafeStrategyMap) ReInit(m map[string][]model.Strategy) {
    method Get (line 69) | func (this *SafeStrategyMap) Get() map[string][]model.Strategy {
  type SafeExpressionMap (line 30) | type SafeExpressionMap struct
    method ReInit (line 75) | func (this *SafeExpressionMap) ReInit(m map[string][]*model.Expression) {
    method Get (line 81) | func (this *SafeExpressionMap) Get() map[string][]*model.Expression {
  type SafeEventMap (line 37) | type SafeEventMap struct
    method Get (line 87) | func (this *SafeEventMap) Get(key string) (*model.Event, bool) {
    method Set (line 94) | func (this *SafeEventMap) Set(key string, event *model.Event) {
  type SafeFilterMap (line 42) | type SafeFilterMap struct
    method ReInit (line 100) | func (this *SafeFilterMap) ReInit(m map[string]string) {
    method Exists (line 106) | func (this *SafeFilterMap) Exists(key string) bool {
  function InitHbsClient (line 55) | func InitHbsClient() {

FILE: modules/judge/http/common.go
  function configCommonRoutes (line 24) | func configCommonRoutes() {

FILE: modules/judge/http/http.go
  type Dto (line 25) | type Dto struct
  function init (line 30) | func init() {
  function RenderJson (line 35) | func RenderJson(w http.ResponseWriter, v interface{}) {
  function RenderDataJson (line 45) | func RenderDataJson(w http.ResponseWriter, data interface{}) {
  function RenderMsgJson (line 49) | func RenderMsgJson(w http.ResponseWriter, msg string) {
  function AutoRender (line 53) | func AutoRender(w http.ResponseWriter, data interface{}, err error) {
  function Start (line 61) | func Start() {

FILE: modules/judge/http/info.go
  function configInfoRoutes (line 26) | func configInfoRoutes() {

FILE: modules/judge/main.go
  function main (line 28) | func main() {

FILE: modules/judge/rpc/receiver.go
  type Judge (line 25) | type Judge
    method Ping (line 27) | func (this *Judge) Ping(req model.NullRpcRequest, resp *model.SimpleRp...
    method Send (line 31) | func (this *Judge) Send(items []*model.JudgeItem, resp *model.SimpleRp...

FILE: modules/judge/rpc/rpc.go
  function Start (line 24) | func Start() {

FILE: modules/judge/store/func.go
  type Function (line 26) | type Function interface
  type MaxFunction (line 30) | type MaxFunction struct
    method Compute (line 37) | func (this MaxFunction) Compute(L *SafeLinkedList) (vs []*model.Histor...
  type MinFunction (line 55) | type MinFunction struct
    method Compute (line 62) | func (this MinFunction) Compute(L *SafeLinkedList) (vs []*model.Histor...
  type AllFunction (line 80) | type AllFunction struct
    method Compute (line 87) | func (this AllFunction) Compute(L *SafeLinkedList) (vs []*model.Histor...
  type LookupFunction (line 105) | type LookupFunction struct
    method Compute (line 113) | func (this LookupFunction) Compute(L *SafeLinkedList) (vs []*model.His...
  type SumFunction (line 134) | type SumFunction struct
    method Compute (line 141) | func (this SumFunction) Compute(L *SafeLinkedList) (vs []*model.Histor...
  type AvgFunction (line 157) | type AvgFunction struct
    method Compute (line 164) | func (this AvgFunction) Compute(L *SafeLinkedList) (vs []*model.Histor...
  type DiffFunction (line 180) | type DiffFunction struct
    method Compute (line 188) | func (this DiffFunction) Compute(L *SafeLinkedList) (vs []*model.Histo...
  type StdDeviationFunction (line 216) | type StdDeviationFunction struct
    method Compute (line 228) | func (this StdDeviationFunction) Compute(L *SafeLinkedList) (vs []*mod...
  type PDiffFunction (line 262) | type PDiffFunction struct
    method Compute (line 269) | func (this PDiffFunction) Compute(L *SafeLinkedList) (vs []*model.Hist...
  type KPDiffFunction (line 308) | type KPDiffFunction struct
    method Compute (line 316) | func (this KPDiffFunction) Compute(L *SafeLinkedList) (vs []*model.His...
  type KDiffFunction (line 347) | type KDiffFunction struct
    method Compute (line 355) | func (this KDiffFunction) Compute(L *SafeLinkedList) (vs []*model.Hist...
  function atois (line 385) | func atois(s string) (ret []int, err error) {
  function ParseFuncFromString (line 398) | func ParseFuncFromString(str string, operator string, rightValue float64...
  function checkIsTriggered (line 438) | func checkIsTriggered(leftValue float64, operator string, rightValue flo...

FILE: modules/judge/store/history.go
  type JudgeItemMap (line 23) | type JudgeItemMap struct
    method Get (line 32) | func (this *JudgeItemMap) Get(key string) (*SafeLinkedList, bool) {
    method Set (line 39) | func (this *JudgeItemMap) Set(key string, val *SafeLinkedList) {
    method Len (line 45) | func (this *JudgeItemMap) Len() int {
    method Delete (line 51) | func (this *JudgeItemMap) Delete(key string) {
    method BatchDelete (line 57) | func (this *JudgeItemMap) BatchDelete(keys []string) {
    method CleanStale (line 70) | func (this *JudgeItemMap) CleanStale(before int64) {
    method PushFrontAndMaintain (line 89) | func (this *JudgeItemMap) PushFrontAndMaintain(key string, val *model....
  function NewJudgeItemMap (line 28) | func NewJudgeItemMap() *JudgeItemMap {
  function InitHistoryBigMap (line 107) | func InitHistoryBigMap() {

FILE: modules/judge/store/judge.go
  function Judge (line 25) | func Judge(L *SafeLinkedList, firstItem *model.JudgeItem, now int64) {
  function CheckStrategy (line 30) | func CheckStrategy(L *SafeLinkedList, firstItem *model.JudgeItem, now in...
  function judgeItemWithStrategy (line 58) | func judgeItemWithStrategy(L *SafeLinkedList, strategy model.Strategy, f...
  function sendEvent (line 82) | func sendEvent(event *model.Event) {
  function CheckExpression (line 99) | func CheckExpression(L *SafeLinkedList, firstItem *model.JudgeItem, now ...
  function buildKeysFromMetricAndTags (line 126) | func buildKeysFromMetricAndTags(item *model.JudgeItem) (keys []string) {
  function filterRelatedExpressions (line 134) | func filterRelatedExpressions(expressions []*model.Expression, firstItem...
  function copyItemTags (line 169) | func copyItemTags(item *model.JudgeItem) map[string]string {
  function judgeItemWithExpression (line 180) | func judgeItemWithExpression(L *SafeLinkedList, expression *model.Expres...
  function sendEventIfNeed (line 205) | func sendEventIfNeed(historyData []*model.HistoryData, isTriggered bool,...

FILE: modules/judge/store/linkedlist.go
  type SafeLinkedList (line 23) | type SafeLinkedList struct
    method ToSlice (line 28) | func (this *SafeLinkedList) ToSlice() []*model.JudgeItem {
    method HistoryData (line 45) | func (this *SafeLinkedList) HistoryData(limit int) ([]*model.HistoryDa...
    method PushFront (line 109) | func (this *SafeLinkedList) PushFront(v interface{}) *list.Element {
    method PushFrontAndMaintain (line 116) | func (this *SafeLinkedList) PushFrontAndMaintain(v *model.JudgeItem, m...
    method Front (line 143) | func (this *SafeLinkedList) Front() *list.Element {
    method Len (line 149) | func (this *SafeLinkedList) Len() int {

FILE: modules/nodata/collector/collector.go
  function Start (line 34) | func Start() {
  function GetFirstItem (line 45) | func GetFirstItem(key string) (*DataItem, bool) {
  function AddItem (line 59) | func AddItem(key string, val *DataItem) {
  function RemoveItem (line 71) | func RemoveItem(key string) {
  type DataItem (line 76) | type DataItem struct
    method String (line 87) | func (this *DataItem) String() string {
  function NewDataItem (line 83) | func NewDataItem(ts int64, val float64, fstatus string, fts int64) *Data...

FILE: modules/nodata/collector/collector_cron.go
  function StartCollectorCron (line 39) | func StartCollectorCron() {
  function CollectDataOnce (line 57) | func CollectDataOnce() int {
  function collectDataOnce (line 61) | func collectDataOnce() int {
  function fetchItemsAndStore (line 118) | func fetchItemsAndStore(fetchKeys []string, fetchSize int) (size int, er...
  function queryLastPoints (line 158) | func queryLastPoints(param []*cmodel.GraphLastParam) (resp []*cmodel.Gra...

FILE: modules/nodata/config/config.go
  function Start (line 34) | func Start() {
  function SetNdConfigMap (line 46) | func SetNdConfigMap(val *nmap.SafeMap) {
  function Keys (line 53) | func Keys() []string {
  function Size (line 59) | func Size() int {
  function GetNdConfig (line 65) | func GetNdConfig(key string) (*cmodel.NodataConfig, bool) {

FILE: modules/nodata/config/config_cron.go
  function StartNdConfigCron (line 35) | func StartNdConfigCron() {
  function SyncNdConfigOnce (line 52) | func SyncNdConfigOnce() int {
  function syncNdConfig (line 57) | func syncNdConfig() (cnt int, errt error) {

FILE: modules/nodata/config/service/db.go
  constant dbBaseConnName (line 27) | dbBaseConnName = "db.base"
  function InitDB (line 35) | func InitDB() {
  function GetBaseConn (line 45) | func GetBaseConn() (c *sql.DB, e error) {
  function GetDbConn (line 49) | func GetDbConn(connName string) (c *sql.DB, e error) {
  function makeDbConn (line 76) | func makeDbConn() (conn *sql.DB, err error) {
  function closeDbConn (line 88) | func closeDbConn(conn *sql.DB) {

FILE: modules/nodata/config/service/host.go
  function GetHostsFromGroup (line 23) | func GetHostsFromGroup(grpName string) map[string]int {

FILE: modules/nodata/config/service/mockcfg.go
  type MockCfg (line 26) | type MockCfg struct
  function GetMockCfgFromDB (line 39) | func GetMockCfgFromDB() map[string]*cmodel.NodataConfig {
  function getEndpoint (line 100) | func getEndpoint(objType string, obj string) []string {
  function getEndpointFromHosts (line 113) | func getEndpointFromHosts(hosts string) []string {
  function getEndpointFromGroups (line 127) | func getEndpointFromGroups(grps string) []string {
  function getEndpointFromOther (line 155) | func getEndpointFromOther(other string) []string {
  function checkMockCfg (line 159) | func checkMockCfg(mc *MockCfg) error {
  function isSpuerNodataCfg (line 179) | func isSpuerNodataCfg(A *cmodel.NodataConfig, B *cmodel.NodataConfig) bo...

FILE: modules/nodata/g/cfg.go
  type HttpConfig (line 24) | type HttpConfig struct
  type PlusAPIConfig (line 29) | type PlusAPIConfig struct
  type NdConfig (line 36) | type NdConfig struct
  type CollectorConfig (line 42) | type CollectorConfig struct
  type SenderConfig (line 48) | type SenderConfig struct
  type GlobalConfig (line 56) | type GlobalConfig struct
  function Config (line 71) | func Config() *GlobalConfig {
  function ParseConfig (line 77) | func ParseConfig(cfg string) {

FILE: modules/nodata/g/g.go
  function VersionMsg (line 38) | func VersionMsg() string {
  function init (line 42) | func init() {

FILE: modules/nodata/g/git.go
  constant COMMIT (line 18) | COMMIT = "12f7b3b"

FILE: modules/nodata/g/proc.go
  function StartProc (line 48) | func StartProc() {
  function GetAllCounters (line 52) | func GetAllCounters() []interface{} {

FILE: modules/nodata/http/common.go
  function configCommonRoutes (line 27) | func configCommonRoutes() {

FILE: modules/nodata/http/debug_http.go
  function configDebugHttpRoutes (line 26) | func configDebugHttpRoutes() {

FILE: modules/nodata/http/http.go
  type Dto (line 26) | type Dto struct
  function Start (line 31) | func Start() {
  function configRoutes (line 35) | func configRoutes() {
  function startHttpServer (line 41) | func startHttpServer() {
  function RenderJson (line 62) | func RenderJson(w http.ResponseWriter, v interface{}) {
  function RenderDataJson (line 72) | func RenderDataJson(w http.ResponseWriter, data interface{}) {
  function RenderMsgJson (line 76) | func RenderMsgJson(w http.ResponseWriter, msg string) {
  function AutoRender (line 80) | func AutoRender(w http.ResponseWriter, data interface{}, err error) {

FILE: modules/nodata/http/proc_http.go
  function configProcHttpRoutes (line 27) | func configProcHttpRoutes() {

FILE: modules/nodata/judge/judge.go
  function Start (line 21) | func Start() {

FILE: modules/nodata/judge/judge_cron.go
  function StartJudgeCron (line 37) | func StartJudgeCron() {
  function judge (line 57) | func judge() {
  function genMock (line 98) | func genMock(ts int64, key string, ndcfg *cmodel.NodataConfig) {
  function genTs (line 103) | func genTs(nowTs int64, step int64) int64 {
  function getTimeout (line 111) | func getTimeout(step int64) int64 {
  constant minfloat64 (line 119) | minfloat64 = 0.000001
  function fCompare (line 121) | func fCompare(left, right float64) int {

FILE: modules/nodata/judge/status.go
  function LastTs (line 31) | func LastTs(key string) int64 {
  function TurnOk (line 47) | func TurnOk(key string, ts int64) {
  function TurnNodata (line 69) | func TurnNodata(key string, ts int64) {
  function GetNodataStatus (line 91) | func GetNodataStatus(key string) *NodataStatus {
  function GetAllNodataStatus (line 102) | func GetAllNodataStatus() []*NodataStatus {
  type NodataStatus (line 118) | type NodataStatus struct
    method String (line 129) | func (this *NodataStatus) String() string {
  function NewNodataStatus (line 125) | func NewNodataStatus(key string, status string, cnt int, ts int64) *Noda...

FILE: modules/nodata/main.go
  function main (line 29) | func main() {

FILE: modules/nodata/scripts/nodata-db-schema.sql
  type `mockcfg` (line 9) | CREATE TABLE `mockcfg` (

FILE: modules/nodata/sender/sender.go
  function AddMock (line 39) | func AddMock(key string, endpoint string, metric string, tags string, ts...
  function SendMockOnceAsync (line 44) | func SendMockOnceAsync() {
  function SendMockOnce (line 48) | func SendMockOnce() int {
  function sendMock (line 74) | func sendMock() (cnt int, errt error) {
  function sendItemsToTransfer (line 117) | func sendItemsToTransfer(items []*cmodel.JsonMetaData, size int, httpcli...

FILE: modules/transfer/g/cfg.go
  type HttpConfig (line 26) | type HttpConfig struct
  type RpcConfig (line 31) | type RpcConfig struct
  type SocketConfig (line 36) | type SocketConfig struct
  type JudgeConfig (line 42) | type JudgeConfig struct
  type GraphConfig (line 54) | type GraphConfig struct
  type TsdbConfig (line 66) | type TsdbConfig struct
  type TransferConfig (line 77) | type TransferConfig struct
  type InfluxdbConfig (line 88) | type InfluxdbConfig struct
  type P8sRelayConfig (line 101) | type P8sRelayConfig struct
  type GlobalConfig (line 114) | type GlobalConfig struct
  function Config (line 134) | func Config() *GlobalConfig {
  function ParseConfig (line 140) | func ParseConfig(cfg string) {
  type ClusterNode (line 175) | type ClusterNode struct
  function NewClusterNode (line 179) | func NewClusterNode(addrs []string) *ClusterNode {
  function formatClusterItems (line 184) | func formatClusterItems(cluster map[string]string) map[string]*ClusterNo...

FILE: modules/transfer/g/g.go
  function VersionMsg (line 40) | func VersionMsg() string {
  constant GAUGE (line 45) | GAUGE        = "GAUGE"
  constant COUNTER (line 46) | COUNTER      = "COUNTER"
  constant DERIVE (line 47) | DERIVE       = "DERIVE"
  constant DEFAULT_STEP (line 48) | DEFAULT_STEP = 60
  function init (line 51) | func init() {

FILE: modules/transfer/g/git.go
  constant COMMIT (line 18) | COMMIT = "e249d8a"

FILE: modules/transfer/http/api.go
  function api_push_datapoints (line 24) | func api_push_datapoints(rw http.ResponseWriter, req *http.Request) {
  function configApiRoutes (line 44) | func configApiRoutes() {

FILE: modules/transfer/http/common.go
  function configCommonRoutes (line 25) | func configCommonRoutes() {

FILE: modules/transfer/http/debug_http.go
  function configDebugHttpRoutes (line 24) | func configDebugHttpRoutes() {

FILE: modules/transfer/http/http.go
  type Dto (line 27) | type Dto struct
  function Start (line 32) | func Start() {
  function startHttpServer (line 36) | func startHttpServer() {
  function RenderJson (line 61) | func RenderJson(w http.ResponseWriter, v interface{}) {
  function RenderDataJson (line 71) | func RenderDataJson(w http.ResponseWriter, data interface{}) {
  function RenderMsgJson (line 75) | func RenderMsgJson(w http.ResponseWriter, msg string) {
  function AutoRender (line 79) | func AutoRender(w http.ResponseWriter, data interface{}, err error) {
  function StdRender (line 87) | func StdRender(w http.ResponseWriter, data interface{}, err error) {
  function postByJson (line 96) | func postByJson(rw http.ResponseWriter, req *http.Request, url string) {
  function postByForm (line 118) | func postByForm(rw http.ResponseWriter, req *http.Request, url string) {
  function getRequest (line 132) | func getRequest(rw http.ResponseWriter, url string) {

FILE: modules/transfer/http/proc_http.go
  function configProcHttpRoutes (line 26) | func configProcHttpRoutes() {

FILE: modules/transfer/main.go
  function main (line 28) | func main() {

FILE: modules/transfer/proc/proc.go
  function Start (line 82) | func Start() {
  function GetAll (line 86) | func GetAll() []interface{} {

FILE: modules/transfer/receiver/receiver.go
  function Start (line 22) | func Start() {

FILE: modules/transfer/receiver/rpc/rpc.go
  function StartRpc (line 25) | func StartRpc() {

FILE: modules/transfer/receiver/rpc/rpc_transfer.go
  type Transfer (line 29) | type Transfer
    method Ping (line 47) | func (this *Transfer) Ping(req cmodel.NullRpcRequest, resp *cmodel.Sim...
    method Update (line 51) | func (t *Transfer) Update(args []*cmodel.MetricValue, reply *cmodel.Tr...
  type TransferResp (line 31) | type TransferResp struct
    method String (line 38) | func (t *TransferResp) String() string {
  function RecvMetricValues (line 56) | func RecvMetricValues(args []*cmodel.MetricValue, reply *cmodel.Transfer...

FILE: modules/transfer/receiver/socket/socket.go
  function StartSocket (line 23) | func StartSocket() {

FILE: modules/transfer/receiver/socket/socket_telnet.go
  function socketTelnetHandle (line 31) | func socketTelnetHandle(conn net.Conn) {
  function convertLine2MetaData (line 102) | func convertLine2MetaData(fields []string) (item *cmodel.MetaData, err e...

FILE: modules/transfer/sender/conn_pools.go
  function initConnPools (line 23) | func initConnPools() {
  function DestroyConnPools (line 72) | func DestroyConnPools() {

FILE: modules/transfer/sender/node_rings.go
  function initNodeRings (line 23) | func initNodeRings() {

FILE: modules/transfer/sender/send_queues.go
  function initSendQueues (line 22) | func initSendQueues() {

FILE: modules/transfer/sender/send_tasks.go
  constant DefaultSendTaskSleepInterval (line 35) | DefaultSendTaskSleepInterval = time.Millisecond * 50
  function startSendTasks (line 39) | func startSendTasks() {
  function forward2JudgeTask (line 110) | func forward2JudgeTask(Q *list.SafeListLimited, node string, concurrent ...
  function forward2P8sRelayTask (line 156) | func forward2P8sRelayTask(Q *list.SafeListLimited, node string, addr str...
  function forward2GraphTask (line 196) | func forward2GraphTask(Q *list.SafeListLimited, node string, addr string...
  function forward2TsdbTask (line 241) | func forward2TsdbTask(concurrent int) {
  function forward2TransferTask (line 285) | func forward2TransferTask(Q *list.SafeListLimited, concurrent int) {
  function convert (line 352) | func convert(v *cmodel.MetaData) *cmodel.MetricValue {
  function forward2InfluxdbTask (line 364) | func forward2InfluxdbTask(concurrent int) {

FILE: modules/transfer/sender/sender.go
  constant DefaultSendQueueMaxSize (line 35) | DefaultSendQueueMaxSize = 102400
  type InfluxClient (line 80) | type InfluxClient struct
    method Send (line 105) | func (c *InfluxClient) Send(items []*cmodel.InfluxdbItem) error {
  function NewInfluxdbClient (line 86) | func NewInfluxdbClient() (*InfluxClient, error) {
  function Start (line 128) | func Start() {
  function Push2JudgeSendQueue (line 145) | func Push2JudgeSendQueue(items []*cmodel.MetaData) {
  function Push2P8sRelaySendQueue (line 179) | func Push2P8sRelaySendQueue(items []*cmodel.MetaData) {
  function Push2GraphSendQueue (line 226) | func Push2GraphSendQueue(items []*cmodel.MetaData) {
  function convert2P8sRelayItem (line 263) | func convert2P8sRelayItem(d *cmodel.MetaData) (*cmodel.P8sItem, error) {
  function convert2GraphItem (line 291) | func convert2GraphItem(d *cmodel.MetaData) (*cmodel.GraphItem, error) {
  function Push2TsdbSendQueue (line 327) | func Push2TsdbSendQueue(items []*cmodel.MetaData) {
  function convert2TsdbItem (line 339) | func convert2TsdbItem(d *cmodel.MetaData) *cmodel.TsdbItem {
  function alignTs (line 352) | func alignTs(ts int64, period int64) int64 {
  function Push2TransferSendQueue (line 356) | func Push2TransferSendQueue(items []*cmodel.MetaData) {
  function Push2InfluxdbSendQueue (line 367) | func Push2InfluxdbSendQueue(items []*cmodel.MetaData) {
  function convert2InfluxdbItem (line 378) | func convert2InfluxdbItem(d *cmodel.MetaData) *cmodel.InfluxdbItem {

FILE: modules/transfer/sender/sender_cron.go
  constant DefaultProcCronPeriod (line 28) | DefaultProcCronPeriod = time.Duration(5) * time.Second
  constant DefaultLogCronPeriod (line 29) | DefaultLogCronPeriod  = time.Duration(3600) * time.Second
  function startSenderCron (line 33) | func startSenderCron() {
  function startProcCron (line 38) | func startProcCron() {
  function startLogCron (line 45) | func startLogCron() {
  function refreshSendingCacheSize (line 52) | func refreshSendingCacheSize() {
  function calcSendCacheSize (line 69) | func calcSendCacheSize(mapList map[string]*list.SafeListLimited) int64 {
  function logConnPoolsProc (line 79) | func logConnPoolsProc() {

FILE: modules/transfer/test/rpcclient.py
  class RPCClient (line 21) | class RPCClient(object):
    method __init__ (line 23) | def __init__(self, addr, codec=json):
    method _message (line 28) | def _message(self, name, *params):
    method call (line 33) | def call(self, name, *params):
    method close (line 53) | def close(self):

FILE: scripts/mysql/db_schema/1_uic-db-schema.sql
  type `team` (line 8) | CREATE TABLE `team` (
  type `user` (line 22) | CREATE TABLE `user` (
  type `rel_team_user` (line 39) | CREATE TABLE `rel_team_user` (
  type `session` (line 49) | CREATE TABLE `session` (

FILE: scripts/mysql/db_schema/2_portal-db-schema.sql
  type host (line 12) | CREATE TABLE host
  type `grp` (line 35) | CREATE TABLE `grp` (
  type grp_host (line 50) | CREATE TABLE grp_host
  type tpl (line 67) | CREATE TABLE tpl
  type `strategy` (line 85) | CREATE TABLE `strategy` (
  type `expression` (line 107) | CREATE TABLE `expression` (
  type `grp_tpl` (line 127) | CREATE TABLE `grp_tpl` (
  type `plugin_dir` (line 138) | CREATE TABLE `plugin_dir` (
  type `action` (line 153) | CREATE TABLE `action` (
  type `mockcfg` (line 172) | CREATE TABLE `mockcfg` (
  type `cluster` (line 196) | CREATE TABLE `cluster` (
  type alert_link (line 218) | CREATE TABLE alert_link

FILE: scripts/mysql/db_schema/3_dashboard-db-schema.sql
  type `dashboard_graph` (line 31) | CREATE TABLE `dashboard_graph` (
  type `dashboard_screen` (line 54) | CREATE TABLE `dashboard_screen` (
  type `tmp_graph` (line 72) | CREATE TABLE `tmp_graph` (

FILE: scripts/mysql/db_schema/4_graph-db-schema.sql
  type `graph` (line 8) | CREATE TABLE `graph`.`endpoint` (
  type `graph` (line 19) | CREATE TABLE `graph`.`endpoint_counter` (
  type `graph` (line 33) | CREATE TABLE `graph`.`tag_endpoint` (

FILE: scripts/mysql/db_schema/5_alarms-db-schema.sql
  type event_cases (line 11) | CREATE TABLE IF NOT EXISTS event_cases(
  type events (line 44) | CREATE TABLE IF NOT EXISTS events (
  type event_note (line 63) | CREATE TABLE IF NOT EXISTS event_note (
Condensed preview — 560 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,556K chars).
[
  {
    "path": ".dockerignore",
    "chars": 45,
    "preview": "docs/\noutrun/\ntmp/\nbin/\n*.tar.gz\nopen-falcon\n"
  },
  {
    "path": ".gitignore",
    "chars": 65,
    "preview": "bin/\nout/\n*.swp\n*.swo\n*.tar.gz\ndocs/_site\n.idea\nopen-falcon\nbuild"
  },
  {
    "path": ".travis.yml",
    "chars": 845,
    "preview": "sudo: required\n\nlanguage: go\n\narch:\n  - amd64\n  - arm64\ngo:\n  - \"1.15\"\n\nenv:\n  - DB_USER=root DB_PASSWORD=test123456 DB_"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5471,
    "preview": "# Code of Conduct\n\n## 1. Purpose\n\nA primary goal of Open-Falcon is to be inclusive to the largest number of contributors"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1583,
    "preview": "### COMMUNITY\nOpen-Falcon is developed in the open. Here are some of the channels we use to communicate and contribute:\n"
  },
  {
    "path": "Dockerfile",
    "chars": 896,
    "preview": "# Build container;\nFROM openfalcon/makegcc-golang:1.15-alpine\nLABEL maintainer laiwei.ustc@gmail.com\nUSER root\n\nENV FALC"
  },
  {
    "path": "Dockerfile.module",
    "chars": 781,
    "preview": "# Build container;\nFROM openfalcon/makegcc-golang:1.15-alpine\nLABEL maintainer laiwei.ustc@gmail.com\nUSER root\n\nENV FALC"
  },
  {
    "path": "Dockerfile_arm64",
    "chars": 867,
    "preview": "FROM jimmytinsley/makegcc-golang\nLABEL maintainer laiwei.ustc@gmail.com\nUSER root\n\nENV FALCON_DIR=/open-falcon PROJ_PATH"
  },
  {
    "path": "LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "Makefile",
    "chars": 3488,
    "preview": "CMD = agent aggregator graph hbs judge nodata transfer gateway api alarm falcon2p8s\nTARGET = open-falcon\nPACKAGES ?= $(s"
  },
  {
    "path": "NOTICE",
    "chars": 462,
    "preview": "Open-Falcon\n\nCopyright (c) 2014-2017 Xiaomi, Inc. All Rights Reserved.\n\nThis product is licensed to you under the Apache"
  },
  {
    "path": "README.md",
    "chars": 5063,
    "preview": "# Falcon+\n\n![Open-Falcon](./logo.png)\n\n[![Build Status](https://travis-ci.org/open-falcon/falcon-plus.svg?branch=plus-de"
  },
  {
    "path": "VERSION",
    "chars": 6,
    "preview": "0.3.x\n"
  },
  {
    "path": "api-standard.md",
    "chars": 3529,
    "preview": "# HTTP API建议规范\n\n## 说明\n本规范参考阮一峰的《[RESTful API设计指南](http://www.ruanyifeng.com/blog/2014/05/restful_api.html)》编写,部分内容做了适应性的"
  },
  {
    "path": "cmd/check.go",
    "chars": 1433,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "cmd/monitor.go",
    "chars": 1649,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "cmd/reload.go",
    "chars": 1023,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "cmd/restart.go",
    "chars": 1480,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "cmd/start.go",
    "chars": 3146,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "cmd/stop.go",
    "chars": 1591,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/.gitignore",
    "chars": 41,
    "preview": "*.swp\n*.swo\n/var\n.DS_Store\n*.iml\n*.idea\n\n"
  },
  {
    "path": "common/LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "common/NOTICE",
    "chars": 462,
    "preview": "Open-Falcon\n\nCopyright (c) 2014-2015 Xiaomi, Inc. All Rights Reserved.\n\nThis product is licensed to you under the Apache"
  },
  {
    "path": "common/backend_pool/rpc_backends.go",
    "chars": 4592,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/backend_pool/tsdb_backends.go",
    "chars": 2806,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/db/db.go",
    "chars": 913,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/agent.go",
    "chars": 2264,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/event.go",
    "chars": 3271,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/expression.go",
    "chars": 1624,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/graph.go",
    "chars": 4337,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/host.go",
    "chars": 776,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/influxdb.go",
    "chars": 253,
    "preview": "package model\n\ntype InfluxdbItem struct {\n\tMeasurement string                 `json:\"metric\"`\n\tTags        map[string]st"
  },
  {
    "path": "common/model/judge.go",
    "chars": 1426,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/metric.go",
    "chars": 2465,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/nodata.go",
    "chars": 2037,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/prometheus.go",
    "chars": 409,
    "preview": "package model\n\n// MetricType Prometheus指标类型:GAUGE|COUNTER\ntype P8sItem struct {\n\tEndpoint   string            `json:\"end"
  },
  {
    "path": "common/model/rpc.go",
    "chars": 863,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/strategy.go",
    "chars": 1725,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/template.go",
    "chars": 1014,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/transfer.go",
    "chars": 905,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/model/tsdb.go",
    "chars": 1318,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/proc/proc.go",
    "chars": 3315,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/sdk/.gitignore",
    "chars": 318,
    "preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture spe"
  },
  {
    "path": "common/sdk/README.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "common/sdk/requests/auth_request.go",
    "chars": 1470,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/sdk/requests/post.go",
    "chars": 1006,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/sdk/sender/linkedlist.go",
    "chars": 1586,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/sdk/sender/make.go",
    "chars": 2205,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/sdk/sender/push.go",
    "chars": 1280,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/sdk/sender/sender.go",
    "chars": 1008,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/counter.go",
    "chars": 797,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/date.go",
    "chars": 719,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/formatter.go",
    "chars": 848,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/func.go",
    "chars": 2589,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/func_test.go",
    "chars": 3894,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/map.go",
    "chars": 831,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/md5.go",
    "chars": 739,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/md5_test.go",
    "chars": 1078,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/objpool.go",
    "chars": 715,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/statistics.go",
    "chars": 1332,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/tags.go",
    "chars": 2108,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "common/utils/tags_test.go",
    "chars": 6330,
    "preview": "// Copyright 2017 Xiaomi, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "config/agent.json",
    "chars": 1275,
    "preview": "{\n    \"debug\": true,\n    \"hostname\": \"%%AGENT_HOSTNAME%%\",\n    \"ip\": \"\",\n    \"plugin\": {\n        \"enabled\": false,\n     "
  },
  {
    "path": "config/aggregator.json",
    "chars": 506,
    "preview": "{\n    \"debug\": true,\n    \"http\": {\n        \"enabled\": true,\n        \"listen\": \"%%AGGREGATOR_HTTP%%\"\n    },\n    \"database"
  },
  {
    "path": "config/alarm.json",
    "chars": 1152,
    "preview": "{\n    \"log_level\": \"debug\",\n    \"http\": {\n        \"enabled\": true,\n        \"listen\": \"0.0.0.0:9912\"\n    },\n    \"redis\": "
  },
  {
    "path": "config/api.json",
    "chars": 863,
    "preview": "{\n\t\"log_level\": \"debug\",\n\t\"db\": {\n\t\t\"falcon_portal\": \"%%MYSQL%%/falcon_portal?charset=utf8&parseTime=True&loc=Local\",\n\t\t"
  },
  {
    "path": "config/confgen.sh",
    "chars": 1073,
    "preview": "#!/bin/bash\n\nconfs=(\n    '%%AGENT_HTTP%%=0.0.0.0:1988'\n    '%%AGGREGATOR_HTTP%%=0.0.0.0:6055'\n    '%%GRAPH_HTTP%%=0.0.0."
  },
  {
    "path": "config/falcon2p8s.json",
    "chars": 158,
    "preview": "{\n    \"log_level\": \"debug\",\n    \"concurrent\": 100,\n    \"http\": {\n        \"listen\": \"0.0.0.0:9090\"\n    },\n    \"rpc\": {\n  "
  },
  {
    "path": "config/gateway.json",
    "chars": 1637,
    "preview": "{\n    \"debug\": true,\n    \"minStep\": 30,\n    \"http\": {\n        \"enabled\": true,\n        \"listen\": \"0.0.0.0:16060\"\n    },\n"
  },
  {
    "path": "config/graph.json",
    "chars": 585,
    "preview": "{\n    \"debug\": false,\n    \"http\": {\n        \"enabled\": true,\n        \"listen\": \"%%GRAPH_HTTP%%\"\n    },\n    \"rpc\": {\n    "
  },
  {
    "path": "config/hbs.json",
    "chars": 271,
    "preview": "{\n    \"debug\": true,\n    \"database\": \"%%MYSQL%%/falcon_portal?loc=Local&parseTime=true\",\n    \"hosts\": \"\",\n    \"maxConns\""
  },
  {
    "path": "config/judge.json",
    "chars": 625,
    "preview": "{\n    \"debug\": true,\n    \"debugHost\": \"nil\",\n    \"remain\": 11,\n    \"http\": {\n        \"enabled\": true,\n        \"listen\": "
  },
  {
    "path": "config/nodata.json",
    "chars": 714,
    "preview": "{\n    \"debug\": true,\n    \"http\": {\n        \"enabled\": true,\n        \"listen\": \"%%NODATA_HTTP%%\"\n    },\n    \"plus_api\":{\n"
  },
  {
    "path": "config/transfer.json",
    "chars": 2051,
    "preview": "{\n    \"debug\": true,\n    \"minStep\": 30,\n    \"http\": {\n        \"enabled\": true,\n        \"listen\": \"%%TRANSFER_HTTP%%\"\n   "
  },
  {
    "path": "docker/README.md",
    "chars": 3196,
    "preview": "## Running open-falcon container\n\n`the latest version in docker hub is v0.3`\n\n##### 1. Start mysql and init the mysql ta"
  },
  {
    "path": "docker/confgen4docker.sh",
    "chars": 1000,
    "preview": "#!/bin/bash\n\nconfs=(\n    '%%AGENT_HTTP%%=0.0.0.0:1988'\n    '%%AGGREGATOR_HTTP%%=0.0.0.0:6055'\n    '%%GRAPH_HTTP%%=0.0.0."
  },
  {
    "path": "docker/ctrl.sh",
    "chars": 1523,
    "preview": "#!/bin/sh\n\nDOCKER_DIR=/open-falcon\nof_bin=$DOCKER_DIR/open-falcon\nDOCKER_HOST_IP=$(route -n | awk '/UG[ \\t]/{print $2}')"
  },
  {
    "path": "docker/k8s-cluster/Dockerfile.tpl",
    "chars": 450,
    "preview": "FROM alpine:3.7\nLABEL maintainer tabsp@qq.com\nUSER root\n\nENV FALCON_DIR=/open-falcon\n# agent\nRUN apk add --no-cache ca-c"
  },
  {
    "path": "docker/k8s-cluster/README.md",
    "chars": 395,
    "preview": "## 分布式部署 open-falcon 到 k8s 集群\n\n### 构建\n\n克隆源码:\n\n```shell\ngit clone https://github.com/open-falcon/falcon-plus.git && cd fa"
  },
  {
    "path": "docker/k8s-cluster/build.sh",
    "chars": 1190,
    "preview": "#!/bin/bash\nMODULES=(\n    'agent'\n    'aggregator'\n    'alarm'\n    'api'\n    'gateway'\n    'graph'\n    'hbs'\n    'judge'"
  },
  {
    "path": "docker/k8s-cluster/init.sh",
    "chars": 165,
    "preview": "#!/bin/sh\n\napk add --no-cache ca-certificates git bash \\\n&& make all \\\n&& make pack4docker \\\n&& tar -zxf open-falcon-v*."
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-agent.yaml",
    "chars": 1264,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-agent\n  labels:\n    app: open-falcon\nspec"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-aggregator.yaml",
    "chars": 1314,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-aggregator\n  labels:\n    app: open-falcon"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-alarm.yaml",
    "chars": 1264,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-alarm\n  labels:\n    app: open-falcon\nspec"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-api.yaml",
    "chars": 1244,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-api\n  labels:\n    app: open-falcon\nspec:\n"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-dashboard.yaml",
    "chars": 1567,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-dashboard\n  labels:\n    app: open-falcon\n"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-graph-01.yaml",
    "chars": 1733,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-graph-01\n  labels:\n    app: open-falcon\ns"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-hbs.yaml",
    "chars": 1363,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-hbs\n  labels:\n    app: open-falcon\nspec:\n"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-judge.yaml",
    "chars": 1383,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-judge\n  labels:\n    app: open-falcon\nspec"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-nodata.yaml",
    "chars": 1274,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-nodata\n  labels:\n    app: open-falcon\nspe"
  },
  {
    "path": "docker/k8s-cluster/modules/falcon-transfer.yaml",
    "chars": 1413,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  namespace: open-falcon\n  name: falcon-transfer\n  labels:\n    app: open-falcon\ns"
  },
  {
    "path": "docker/k8s-example/README.md",
    "chars": 2019,
    "preview": "## Running open-falcon in kubernetes\n\nwork on kubernetes 1.14 ,  the `kubectl version` like:\n```\nClient Version: version"
  },
  {
    "path": "docker/k8s-example/init_mysql_data.sh",
    "chars": 363,
    "preview": "#!/bin/sh\n\nmysql_pod=$(kubectl get pods | grep mysql | awk '{print $1}')\ncd /tmp && \\\n\tgit clone --depth=1 https://githu"
  },
  {
    "path": "docker/k8s-example/mysql.yaml",
    "chars": 847,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  name: mysql\n  labels:\n    app: db\nspec:\n  type: NodePort\n  ports:\n  - port: 330"
  },
  {
    "path": "docker/k8s-example/openfalcon-dashboard.yaml",
    "chars": 1332,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  name: open-falcon-dashboard\n  labels:\n    app: monitor\nspec:\n  type: NodePort\n "
  },
  {
    "path": "docker/k8s-example/openfalcon-plus.yaml",
    "chars": 5167,
    "preview": "apiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: openfalcon-configmap\ndata:\n  entrypoint.sh: |-\n    #!/bin/bash\n    /bin"
  },
  {
    "path": "docker/k8s-example/redis.yaml",
    "chars": 530,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  name: redis\n  labels:\n    app: db\nspec:\n  ports:\n    - port: 6379\n  selector:\n "
  },
  {
    "path": "docker/mysql-init/Dockerfile",
    "chars": 188,
    "preview": "from alpine:3.5\n\nenv MYSQL_HOST=mysql \\\n    MYSQL_USER=root \\\n    MYSQL_PASSWORD=test123456\n\nrun apk add --no-cache mysq"
  },
  {
    "path": "docker/mysql-init/init_mysql_data.sh",
    "chars": 396,
    "preview": "#!/bin/sh\n\nHost=${MYSQL_HOST}\nUser=${MYSQL_USER}\nPassword=${MYSQL_PASSWORD}\n\ncd /tmp && \\\n        git clone --depth=1 ht"
  },
  {
    "path": "docker/supervisord.conf",
    "chars": 3591,
    "preview": "[supervisord]\nchildlogdir = /open-falcon/logs/\nlogfile = /open-falcon/logs/supervisord.log\npidfile = /var/run/supervisor"
  },
  {
    "path": "docker-compose.yml",
    "chars": 3761,
    "preview": "version: '3.5'\n\nservices:\n  mysql:\n    container_name: falcon-mysql\n    image: mysql:5.7\n    environment:\n      MYSQL_RO"
  },
  {
    "path": "docker_test.sh",
    "chars": 1558,
    "preview": "#!/bin/bash\n\nexport DB_USER=root\nexport DB_PASSWORD=test123456\nexport DB_HOST=127.0.0.1\nexport DB_PORT=13306\nexport REDI"
  },
  {
    "path": "docs/LICENSE.md",
    "chars": 1079,
    "preview": "The MIT License (MIT)\n\nCopyright (c) [year] [fullname]\n\nPermission is hereby granted, free of charge, to any person obta"
  },
  {
    "path": "docs/Makefile",
    "chars": 419,
    "preview": "SRC = $(wildcard lib/*/*.js)\nHTML = $(wildcard lib/*/*.html)\nTEMPLATES = $(HTML:.html=.js)\nLESS = $(wildcard lib/*/*.les"
  },
  {
    "path": "docs/README.md",
    "chars": 3029,
    "preview": "## The \"What ?\" and the \"Why ?\"\n\n**Carte** is a simple Jekyll based documentation website for APIs. It is designed as a "
  },
  {
    "path": "docs/_config.yml",
    "chars": 110,
    "preview": "---\nexclude: ['README.markdown']\npermalink: ':title'\nsafe: false\ntitle: 'Falcon+ API'\nproject_name: 'Falcon+'\n"
  },
  {
    "path": "docs/_includes/nav.html",
    "chars": 516,
    "preview": "<h1>{{ site.title }}</h1>\n<ul id='links'>\n  {% for post in site.posts %}\n    {% if post.category == null %}\n    <li><a h"
  },
  {
    "path": "docs/_layouts/default.html",
    "chars": 629,
    "preview": "<!DOCTYPE html>\n<head>\n  <title>{{ site.title }}</title>\n  <meta charset='utf-8'/>\n  <meta name='description' content='D"
  },
  {
    "path": "docs/_posts/2017-01-01-authentication.md",
    "chars": 489,
    "preview": "---\ntitle: 'Auth Session'\napiurl: '/api/v1/user/auth_session'\ntype: 'GET'\nlayout: default\n---\n\n透过Session检查去判定使用者可否存取资源\n\n"
  },
  {
    "path": "docs/_posts/2017-01-01-response-status-codes.md",
    "chars": 232,
    "preview": "---\ntitle: 'Response status codes'\n\nlayout: default\n---\n\n### Success\n\n* `POST`, `GET`, `PUT`, `DELETE` returns `200` on "
  },
  {
    "path": "docs/_posts/Admin/2017-01-01-admin_change_role.md",
    "chars": 396,
    "preview": "---\ncategory: Admin\napiurl: '/api/v1/admin/change_user_role'\ntitle: \"Change User's role\"\ntype: 'PUT'\nsample_doc: 'admin."
  },
  {
    "path": "docs/_posts/Admin/2017-01-01-admin_change_user_passwd.md",
    "chars": 339,
    "preview": "---\ncategory: Admin\napiurl: '/api/v1/admin/change_user_passwd'\ntitle: \"Change User's Password\"\ntype: 'PUT'\nsample_doc: '"
  },
  {
    "path": "docs/_posts/Admin/2017-01-01-admin_delete_user.md",
    "chars": 320,
    "preview": "---\ncategory: Admin\napiurl: '/api/v1/admin/delete_user'\ntitle: 'Delete User'\ntype: 'DELETE'\nsample_doc: 'admin.html'\nlay"
  },
  {
    "path": "docs/_posts/Admin/2017-12-07-admin_login.md",
    "chars": 454,
    "preview": "---\ncategory: Admin\napiurl: '/api/v1/admin/login'\ntitle: 'Admin Login'\ntype: 'POST'\nsample_doc: 'admin.html'\nlayout: def"
  },
  {
    "path": "docs/_posts/Aggregator/2017-01-01-aggreator_create.md",
    "chars": 672,
    "preview": "---\ncategory: Aggregator\napiurl: '/api/v1/aggregator'\ntitle: \"Create Aggregator to a HostGroup\"\ntype: 'POST'\nsample_doc:"
  },
  {
    "path": "docs/_posts/Aggregator/2017-01-01-aggreator_delete.md",
    "chars": 267,
    "preview": "---\ncategory: Aggregator\napiurl: '/api/v1/aggregator/16'\ntitle: \"Delete Aggregator\"\ntype: 'DELETE'\nsample_doc: 'aggregat"
  },
  {
    "path": "docs/_posts/Aggregator/2017-01-01-aggreator_of_hostgroup.md",
    "chars": 965,
    "preview": "---\ncategory: Aggregator\napiurl: '/api/v1/hostgroup/#{hostgroup_id}/aggregators'\ntitle: \"Get Aggregator List of HostGrou"
  },
  {
    "path": "docs/_posts/Aggregator/2017-01-01-aggreator_update.md",
    "chars": 648,
    "preview": "---\ncategory: Aggregator\napiurl: '/api/v1/aggregators'\ntitle: \"Update Aggregator\"\ntype: 'PUT'\nsample_doc: 'aggregator.ht"
  },
  {
    "path": "docs/_posts/Aggregator/2017-01-01-get_aggreator_by_id.md",
    "chars": 612,
    "preview": "---\ncategory: Aggregator\napiurl: '/api/v1/aggregators'\ntitle: \"Get Aggregator Info by id\"\ntype: 'GET'\nsample_doc: 'aggre"
  },
  {
    "path": "docs/_posts/Alarm/2017-01-01-alarm_eventcases_get_by_id.md",
    "chars": 1276,
    "preview": "---\ncategory: Alarm\napiurl: '/api/v1/alarm/eventcases'\ntitle: 'Get EventCases by id'\ntype: 'GET'\nsample_doc: 'alarm.html"
  },
  {
    "path": "docs/_posts/Alarm/2017-01-01-alarm_eventcases_list.md",
    "chars": 1310,
    "preview": "---\ncategory: Alarm\napiurl: '/api/v1/alarm/eventcases'\ntitle: 'EventCases List'\ntype: 'POST'\nsample_doc: 'alarm.html'\nla"
  },
  {
    "path": "docs/_posts/Alarm/2017-01-01-alarm_eventnote_create.md",
    "chars": 622,
    "preview": "---\ncategory: Alarm\napiurl: '/api/v1/alarm/event_note'\ntitle: 'Create Event Note'\ntype: 'POST'\nsample_doc: 'alarm.html'\n"
  },
  {
    "path": "docs/_posts/Alarm/2017-01-01-alarm_eventnote_get.md",
    "chars": 1040,
    "preview": "---\ncategory: Alarm\napiurl: '/api/v1/alarm/event_note'\ntitle: 'Get Event Note by id or time range'\ntype: 'GET'\nsample_do"
  },
  {
    "path": "docs/_posts/Alarm/2017-01-01-alarm_events_create.md",
    "chars": 1020,
    "preview": "---\ncategory: Alarm\napiurl: '/api/v1/alarm/events'\ntitle: 'Create Events'\ntype: 'POST'\nsample_doc: 'alarm.html'\nlayout: "
  },
  {
    "path": "docs/_posts/DashboardGraph/2017-01-01-dashboard_graph_create.md",
    "chars": 615,
    "preview": "---\ncategory: DashboardGraph\napiurl: '/api/v1/dashboard/graph'\ntitle: 'Create User'\ntype: 'POST'\nsample_doc: 'dashboard."
  },
  {
    "path": "docs/_posts/DashboardGraph/2017-01-01-dashboard_graph_create_tmpgraph.md",
    "chars": 524,
    "preview": "---\ncategory: DashboardGraph\napiurl: '/api/v1/dashboard/tmpgraph'\ntitle: 'Create a tmpgraph'\ntype: 'POST'\nsample_doc: 'd"
  },
  {
    "path": "docs/_posts/DashboardGraph/2017-01-01-dashboard_graph_delete.md",
    "chars": 356,
    "preview": "---\ncategory: DashboardGraph\napiurl: '/api/v1/dashboard/graph/:id'\ntitle: 'Delete a DashboardGraph'\ntype: 'DELETE'\nsampl"
  },
  {
    "path": "docs/_posts/DashboardGraph/2017-01-01-dashboard_graph_get.md",
    "chars": 619,
    "preview": "---\ncategory: DashboardGraph\napiurl: '/api/v1/dashboard/graph/:id'\ntitle: 'Get DashboardGraph info by id'\ntype: 'GET'\nsa"
  },
  {
    "path": "docs/_posts/DashboardGraph/2017-01-01-dashboard_graph_get_tmpgraph_by_id.md",
    "chars": 397,
    "preview": "---\ncategory: DashboardGraph\napiurl: '/api/v1/dashboard/tmpgraph/:id'\ntitle: 'Get a tmpgraph by id'\ntype: 'GET'\nsample_d"
  },
  {
    "path": "docs/_posts/DashboardGraph/2017-01-01-dashboard_graph_update.md",
    "chars": 496,
    "preview": "---\ncategory: DashboardGraph\napiurl: '/api/v1/dashboard/graph/:id'\ntitle: 'Update a DashboardGraph'\ntype: 'PUT'\nsample_d"
  },
  {
    "path": "docs/_posts/DashboardGraph/2017-01-01-dashboard_graphs_gets_by_screenid.md",
    "chars": 1025,
    "preview": "---\ncategory: DashboardGraph\napiurl: '/api/v1/dashboard/graphs/screen/:screen_id'\ntitle: 'Gets graphs by screen id'\ntype"
  },
  {
    "path": "docs/_posts/DashboardScreen/2017-01-01-dashboard_screen_create.md",
    "chars": 479,
    "preview": "---\ncategory: DashboardScreen\napiurl: '/api/v1/dashboard/screen'\ntitle: 'Create a DashboardScreen'\ntype: 'POST'\nsample_d"
  },
  {
    "path": "docs/_posts/DashboardScreen/2017-01-01-dashboard_screen_delete.md",
    "chars": 366,
    "preview": "---\ncategory: DashboardScreen\napiurl: '/api/v1/dashboard/screen/:screen_id'\ntitle: 'Delete a DashboardScreen'\ntype: 'DEL"
  },
  {
    "path": "docs/_posts/DashboardScreen/2017-01-01-dashboard_screen_get_by_id.md",
    "chars": 391,
    "preview": "---\ncategory: DashboardScreen\napiurl: '/api/v1/dashboard/screen/:screen_id'\ntitle: 'Get a DashboardScreen by id'\ntype: '"
  },
  {
    "path": "docs/_posts/DashboardScreen/2017-01-01-dashboard_screen_gets_all.md",
    "chars": 999,
    "preview": "---\ncategory: DashboardScreen\napiurl: '/api/v1/dashboard/screens'\ntitle: 'Gets all DashboardScreens'\ntype: 'GET'\nsample_"
  },
  {
    "path": "docs/_posts/DashboardScreen/2017-01-01-dashboard_screen_gets_by_pid.md",
    "chars": 513,
    "preview": "---\ncategory: DashboardScreen\napiurl: '/api/v1/dashboard/screens/pid/:screen_pid'\ntitle: 'Gets DashboardScreens by pid'\n"
  },
  {
    "path": "docs/_posts/DashboardScreen/2017-01-01-dashboard_screen_update.md",
    "chars": 456,
    "preview": "---\ncategory: DashboardScreen\napiurl: '/api/v1/dashboard/screen/:screen_id'\ntitle: 'Update a DashboardScreen'\ntype: 'PUT"
  },
  {
    "path": "docs/_posts/Expression/2017-01-01-expression_create.md",
    "chars": 717,
    "preview": "---\ncategory: Expression\napiurl: '/api/v1/expression'\ntitle: \"Create Expression\"\ntype: 'POST'\nsample_doc: 'expression.ht"
  },
  {
    "path": "docs/_posts/Expression/2017-01-01-expression_delete.md",
    "chars": 313,
    "preview": "---\ncategory: Expression\napiurl: '/api/v1/expression/#{expression_id}'\ntitle: \"Delete Expression\"\ntype: 'DELETE'\nsample_"
  },
  {
    "path": "docs/_posts/Expression/2017-01-01-expression_info_by_id.md",
    "chars": 785,
    "preview": "---\ncategory: Expression\napiurl: '/api/v1/expression/#{expression_id}'\ntitle: \"Get Expression Info by id\"\ntype: 'GET'\nsa"
  },
  {
    "path": "docs/_posts/Expression/2017-01-01-expression_list.md",
    "chars": 1045,
    "preview": "---\ncategory: Expression\napiurl: '/api/v1/expression'\ntitle: \"Expression List\"\ntype: 'GET'\nsample_doc: 'expression.html'"
  },
  {
    "path": "docs/_posts/Expression/2017-01-01-expression_update.md",
    "chars": 753,
    "preview": "---\ncategory: Expression\napiurl: '/api/v1/expression'\ntitle: \"Update Expression\"\ntype: 'PUT'\nsample_doc: 'expression.htm"
  },
  {
    "path": "docs/_posts/Graph/2017-01-01-endpoint_counter.md",
    "chars": 613,
    "preview": "---\ncategory: Graph\napiurl: '/api/v1/graph/endpoint_counter'\ntitle: \"Get Counter of Endpoint\"\ntype: 'GET'\nsample_doc: 'g"
  },
  {
    "path": "docs/_posts/Graph/2017-01-01-endpoints.md",
    "chars": 612,
    "preview": "---\ncategory: Graph\napiurl: '/api/v1/graph/endpoint'\ntitle: \"Endpoint List\"\ntype: 'GET'\nsample_doc: 'graph.html'\nlayout:"
  },
  {
    "path": "docs/_posts/Graph/2017-01-01-grafana.md",
    "chars": 983,
    "preview": "---\ncategory: Graph\napiurl: '/v1/grafana/render'\ntitle: \"Grafan query\"\ntype: 'POST'\nlayout: default\n---\n\n* target: grafa"
  },
  {
    "path": "docs/_posts/Graph/2017-01-01-graph_histroy.md",
    "chars": 19584,
    "preview": "---\ncategory: Graph\napiurl: '/api/v1/graph/history'\ntitle: \"Graph History\"\ntype: 'POST'\nsample_doc: 'graph.html'\nlayout:"
  },
  {
    "path": "docs/_posts/Host/2017-01-01-host_maintain.md",
    "chars": 507,
    "preview": "---\ncategory: Host\napiurl: '/api/v1/host/maintain'\ntitle: \"Set host maintain by ids or hostnames\"\ntype: 'POST'\nsample_do"
  },
  {
    "path": "docs/_posts/Host/2017-01-01-host_related_hostgroup.md",
    "chars": 463,
    "preview": "---\ncategory: Host\napiurl: '/api/v1/host/#{host_id}/hostgroup'\ntitle: \"Get related HostGorup of Host\"\ntype: 'GET'\nsample"
  },
  {
    "path": "docs/_posts/Host/2017-01-01-host_related_template.md",
    "chars": 646,
    "preview": "---\ncategory: Host\napiurl: '/api/v1/host/#{host_id}/template'\ntitle: \"Get bind Template List of Host\"\ntype: 'GET'\nsample"
  },
  {
    "path": "docs/_posts/Host/2017-01-01-host_reset.md",
    "chars": 363,
    "preview": "---\ncategory: Host\napiurl: '/api/v1/host/maintain'\ntitle: \"Reset host maintain by ids or hostnames\"\ntype: 'DELETE'\nsampl"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_add_host.md",
    "chars": 452,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/host'\ntitle: \"Add Hosts to HostGroup\"\ntype: 'POST'\nsample_doc: 'hostg"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_create.md",
    "chars": 335,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup'\ntitle: \"Create HostGroup\"\ntype: 'POST'\nsample_doc: 'hostgroup.html'\n"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_delete.md",
    "chars": 343,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/#{hostgroup_id}'\ntitle: \"Delete HostGroup\"\ntype: 'DELETE'\nsample_doc:"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_get_info_by_id.md",
    "chars": 571,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/#{hostgroup_id}'\ntitle: \"Get HostGroup info by id\"\ntype: 'GET'\nsample"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_list.md",
    "chars": 451,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup'\ntitle: \"HostGroup List\"\ntype: 'GET'\nsample_doc: 'hostgroup.html'\nlay"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_template_bind.md",
    "chars": 331,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/template'\ntitle: \"Bind A Template to HostGroup\"\ntype: 'POST'\nsample_d"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_template_list.md",
    "chars": 1698,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/#{hostgroup_id}/template'\ntitle: \"Get Template List of  HostGroup\"\nty"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_template_unbind.md",
    "chars": 348,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/template'\ntitle: \"Unbind A Template of A HostGroup\"\ntype: 'PUT'\nsampl"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_unbind_host.md",
    "chars": 381,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/host'\ntitle: \"Unbind a Host on HostGroup\"\ntype: 'PUT'\nsample_doc: 'ho"
  },
  {
    "path": "docs/_posts/HostGroup/2017-01-01-hostgroup_update.md",
    "chars": 379,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/update/#{hostgroup_id}'\ntitle: \"Update HostGroup info by id\"\ntype: 'P"
  },
  {
    "path": "docs/_posts/HostGroup/2017-08-22-hostgroup_update_partial_hosts.md",
    "chars": 683,
    "preview": "---\ncategory: HostGroup\napiurl: '/api/v1/hostgroup/#{hostgroup_id}/host'\ntitle: \"Update partial hosts in HostGroup\"\ntype"
  },
  {
    "path": "docs/_posts/NoData/2017-01-01-nodata_create.md",
    "chars": 588,
    "preview": "---\ncategory: NoData\napiurl: '/api/v1/nodata/'\ntitle: \"Create Nodata\"\ntype: 'POST'\nsample_doc: 'nodata.html'\nlayout: def"
  },
  {
    "path": "docs/_posts/NoData/2017-01-01-nodata_delete.md",
    "chars": 280,
    "preview": "---\ncategory: NoData\napiurl: '/api/v1/nodata/#{nodata_id}'\ntitle: \"Delete Nodata\"\ntype: 'DELETE'\nsample_doc: 'nodata.htm"
  },
  {
    "path": "docs/_posts/NoData/2017-01-01-nodata_info_by_id.md",
    "chars": 446,
    "preview": "---\ncategory: NoData\napiurl: '/api/v1/nodata/#{nodata_id}'\ntitle: \"Get Nodata Info by id\"\ntype: 'GET'\nsample_doc: 'nodat"
  },
  {
    "path": "docs/_posts/NoData/2017-01-01-nodata_list.md",
    "chars": 428,
    "preview": "---\ncategory: NoData\napiurl: '/api/v1/nodata'\ntitle: \"Nodata List\"\ntype: 'GET'\nsample_doc: 'nodata.html'\nlayout: default"
  },
  {
    "path": "docs/_posts/NoData/2017-01-01-nodata_update.md",
    "chars": 560,
    "preview": "---\ncategory: NoData\napiurl: '/api/v1/nodata/'\ntitle: \"Update Nodata\"\ntype: 'PUT'\nsample_doc: 'nodata.html'\nlayout: defa"
  },
  {
    "path": "docs/_posts/Plugin/2017-01-01-plugin_create.md",
    "chars": 397,
    "preview": "---\ncategory: Plugin\napiurl: '/api/v1/plugin'\ntitle: \"Create A Plugin of HostGroup\"\ntype: 'POST'\nsample_doc: 'plugin.htm"
  },
  {
    "path": "docs/_posts/Plugin/2017-01-01-plugin_delete.md",
    "chars": 285,
    "preview": "---\ncategory: Plugin\napiurl: '/api/v1/plugin/#{plugin_id}'\ntitle: \"Delete Plugin\"\ntype: 'DELETE'\nsample_doc: 'plugin.htm"
  },
  {
    "path": "docs/_posts/Plugin/2017-01-01-plugin_info_by_id.md",
    "chars": 496,
    "preview": "---\ncategory: Plugin\napiurl: '/api/v1/hostgroup/#{hostgroup_id}/plugins'\ntitle: \"Get Plugin List of HostGroup\"\ntype: 'GE"
  },
  {
    "path": "docs/_posts/Strategy/2017-01-01-metric_tmplist.md",
    "chars": 527,
    "preview": "---\ncategory: Metric\napiurl: '/api/v1/metric/default_list'\ntitle: \"Get Default Builtin Metric List\"\ntype: 'GET'\nsample_d"
  },
  {
    "path": "docs/_posts/Strategy/2017-01-01-strategy_create.md",
    "chars": 700,
    "preview": "---\ncategory: Strategy\napiurl: '/api/v1/strategy'\ntitle: \"Create Strategy\"\ntype: 'POST'\nsample_doc: 'template.html'\nlayo"
  },
  {
    "path": "docs/_posts/Strategy/2017-01-01-strategy_delete.md",
    "chars": 303,
    "preview": "---\ncategory: Strategy\napiurl: '/api/v1/strategy/#{strategy_id}'\ntitle: \"Delete Strategy\"\ntype: 'DELETE'\nsample_doc: 'te"
  },
  {
    "path": "docs/_posts/Strategy/2017-01-01-strategy_info_by_id.md",
    "chars": 503,
    "preview": "---\ncategory: Strategy\napiurl: '/api/v1/strategy/#{strategy_id}'\ntitle: \"Get Strategy info by id\"\ntype: 'GET'\nsample_doc"
  },
  {
    "path": "docs/_posts/Strategy/2017-01-01-strategy_list.md",
    "chars": 1003,
    "preview": "---\ncategory: Strategy\napiurl: '/api/v1/strategy'\ntitle: \"Get Strategy List\"\ntype: 'GET'\nsample_doc: 'template.html'\nlay"
  },
  {
    "path": "docs/_posts/Strategy/2017-01-01-strategy_update.md",
    "chars": 491,
    "preview": "---\ncategory: Strategy\napiurl: '/api/v1/strategy'\ntitle: \"Update Strategy\"\ntype: 'PUT'\nsample_doc: 'template.html'\nlayou"
  },
  {
    "path": "docs/_posts/Team/2017-01-01-team_create.md",
    "chars": 398,
    "preview": "---\ncategory: Team\napiurl: '/api/v1/team'\ntitle: \"Team Create\"\ntype: 'POST'\nsample_doc: 'team.html'\nlayout: default\n---\n"
  },
  {
    "path": "docs/_posts/Team/2017-01-01-team_delete_by_id.md",
    "chars": 344,
    "preview": "---\ncategory: Team\napiurl: '/api/v1/team/#{team_id}'\ntitle: \"Delete Team By Id\"\ntype: 'DELETE'\nsample_doc: 'team.html'\nl"
  },
  {
    "path": "docs/_posts/Team/2017-01-01-team_info_by_id.md",
    "chars": 730,
    "preview": "---\ncategory: Team\napiurl: '/api/v1/team/t/#{team_id}'\ntitle: \"Get Team Info By Id\"\ntype: 'GET'\nsample_doc: 'team.html'\n"
  },
  {
    "path": "docs/_posts/Team/2017-01-01-team_info_by_name.md",
    "chars": 659,
    "preview": "---\ncategory: Team\napiurl: '/api/v1/team/name/#{team_name}'\ntitle: \"Get Team Info by name\"\ntype: 'GET'\nsample_doc: 'team"
  },
  {
    "path": "docs/_posts/Team/2017-01-01-team_list.md",
    "chars": 531,
    "preview": "---\ncategory: Team\napiurl: '/api/v1/team'\ntitle: \"Team List\"\ntype: 'GET'\nsample_doc: 'team.html'\nlayout: default\n---\n\n* "
  },
  {
    "path": "docs/_posts/Team/2017-01-01-team_update.md",
    "chars": 443,
    "preview": "---\ncategory: Team\napiurl: '/api/v1/team'\ntitle: \"Team Update\"\ntype: 'PUT'\nsample_doc: 'team.html'\nlayout: default\n---\n\n"
  },
  {
    "path": "docs/_posts/Team/2018-11-19-add-user-to-team.md",
    "chars": 365,
    "preview": "---\ncategory: Team\napiurl: '/api/v1/team/user'\ntitle: \"Add users to team\"\ntype: 'POST'\nsample_doc: ''\nlayout: default\n--"
  },
  {
    "path": "docs/_posts/Template/2017-01-01-tpl_action_create.md",
    "chars": 577,
    "preview": "---\ncategory: Template\napiurl: '/api/v1/template/action'\ntitle: \"Create Template Action\"\ntype: 'POST'\nsample_doc: 'templ"
  },
  {
    "path": "docs/_posts/Template/2017-01-01-tpl_action_update.md",
    "chars": 580,
    "preview": "---\ncategory: Template\napiurl: '/api/v1/template/action'\ntitle: \"Update Template Action\"\ntype: 'PUT'\nsample_doc: 'templa"
  },
  {
    "path": "docs/_posts/Template/2017-01-01-tpl_create.md",
    "chars": 407,
    "preview": "---\ncategory: Template\napiurl: '/api/v1/template'\ntitle: \"Create Template\"\ntype: 'POST'\nsample_doc: 'template.html'\nlayo"
  },
  {
    "path": "docs/_posts/Template/2017-01-01-tpl_delete.md",
    "chars": 321,
    "preview": "---\ncategory: Template\napiurl: '/api/v1/template/#{template_id}'\ntitle: \"Delete Template\"\ntype: 'DELETE'\nsample_doc: 'te"
  },
  {
    "path": "docs/_posts/Template/2017-01-01-tpl_hgp_list.md",
    "chars": 524,
    "preview": "---\ncategory: Template\napiurl: '/api/v1/template/#{template_id}/hostgroup'\ntitle: \"Get hostgroups list by id\"\ntype: 'GET"
  },
  {
    "path": "docs/_posts/Template/2017-01-01-tpl_info_by_id.md",
    "chars": 1756,
    "preview": "---\ncategory: Template\napiurl: '/api/v1/template/#{template_id}'\ntitle: \"Get Template Info by id\"\ntype: 'GET'\nsample_doc"
  },
  {
    "path": "docs/_posts/Template/2017-01-01-tpl_list.md",
    "chars": 714,
    "preview": "---\ncategory: Template\napiurl: '/api/v1/template'\ntitle: \"Template List\"\ntype: 'GET'\nsample_doc: 'template.html'\nlayout:"
  },
  {
    "path": "docs/_posts/Template/2017-01-01-tpl_update.md",
    "chars": 358,
    "preview": "---\ncategory: Template\napiurl: '/api/v1/template/'\ntitle: \"Update Template\"\ntype: 'PUT'\nsample_doc: 'template.html'\nlayo"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_change_password.md",
    "chars": 319,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/cgpasswd'\ntitle: 'Change Password'\ntype: 'PUT'\nsample_doc: 'user.html'\nlayout: "
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_create.md",
    "chars": 624,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/create'\ntitle: 'Create User'\ntype: 'POST'\nsample_doc: 'user.html'\nlayout: defau"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_current.md",
    "chars": 483,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/current'\ntitle: 'Current User info'\ntype: 'GET'\nsample_doc: 'user.html'\nlayout:"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_get_info_by_id.md",
    "chars": 524,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/u/#{user_id}'\ntitle: 'Get User info by id'\ntype: 'GET'\nsample_doc: 'user.html'\n"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_get_info_by_name.md",
    "chars": 571,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/name/#{user_name}'\ntitle: 'Get User info by name'\ntype: 'GET'\nsample_doc: 'user"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_get_teams.md",
    "chars": 554,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/u/:uid/teams'\ntitle: 'Get user teams'\ntype: 'GET'\nsample_doc: 'user.html'\nlayou"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_is_in_teams.md",
    "chars": 540,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/u/:uid/in_teams'\ntitle: 'Check user in teams or not'\ntype: 'GET'\nsample_doc: 'u"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_list.md",
    "chars": 695,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/users'\ntitle: 'User List'\ntype: 'GET'\nsample_doc: 'user.html'\nlayout: default\n-"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_login.md",
    "chars": 461,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/login'\ntitle: 'Login'\ntype: 'POST'\nsample_doc: 'user.html'\nlayout: default\n---\n"
  },
  {
    "path": "docs/_posts/User/2017-01-01-user_logout.md",
    "chars": 420,
    "preview": "---\ncategory: User\napiurl: '/api/v1/user/logout'\ntitle: 'Logout'\ntype: 'GET'\nsample_doc: 'user.html'\nlayout: default\n---"
  }
]

// ... and 360 more files (download for full content)

About this extraction

This page contains the full source code of the open-falcon/falcon-plus GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 560 files (2.2 MB), approximately 611.8k tokens, and a symbol index with 1284 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!