├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── build-docker-image.sh ├── client ├── desktop │ ├── .gitignore │ ├── README.md │ ├── logo │ │ ├── sysmon.icns │ │ ├── sysmon.ico │ │ └── sysmon.png │ ├── main.js │ ├── package-lock.json │ ├── package.json │ ├── renderer.js │ └── scripts │ │ ├── code.sh │ │ └── compress.sh └── mobile │ ├── .gitignore │ ├── .project │ ├── README.md │ ├── index.html │ ├── manifest.json │ ├── mobile.sh │ └── unpackage │ ├── .gitkeep │ └── res │ ├── icons │ ├── 1024x1024.png │ ├── 120x120.png │ ├── 144x144.png │ ├── 152x152.png │ ├── 167x167.png │ ├── 180x180.png │ ├── 192x192.png │ ├── 20x20.png │ ├── 256x256.png │ ├── 29x29.png │ ├── 40x40.png │ ├── 48x48.png │ ├── 58x58.png │ ├── 60x60.png │ ├── 72x72.png │ ├── 76x76.png │ ├── 80x80.png │ ├── 87x87.png │ └── 96x96.png │ └── img │ └── boot-img │ └── android │ ├── boot-img-1080x1882.png │ ├── boot-img-480x762.png │ └── boot-img-720x1242.png ├── conf └── app.conf ├── controllers ├── default.go ├── info.go ├── info │ ├── all.go │ ├── cpu │ │ └── cpu.go │ ├── disk │ │ └── disk.go │ ├── mem │ │ └── mem.go │ └── net │ │ └── net.go ├── process.go ├── process │ ├── all.go │ ├── common.go │ └── details.go ├── sysInfo.go └── sysInfo │ ├── all.go │ ├── hostname.go │ ├── hw.go │ └── sw.go ├── doc ├── README-zh.md └── img │ ├── sysmon-mobile.png │ └── sysmon-resources.png ├── etc └── init │ ├── systemd │ └── sysmon.service │ └── upstart │ └── sysmon.conf ├── install.sh ├── main.go ├── pack.sh ├── routers └── router.go ├── static └── js │ └── reload.min.js ├── swagger ├── favicon-16x16.png ├── favicon-32x32.png ├── index.html ├── oauth2-redirect.html ├── swagger-ui-bundle.js ├── swagger-ui-bundle.js.map ├── swagger-ui-standalone-preset.js ├── swagger-ui-standalone-preset.js.map ├── swagger-ui.css ├── swagger-ui.css.map ├── swagger-ui.js └── swagger-ui.js.map ├── tests └── default_test.go ├── utils └── proc │ ├── buddyinfo.go │ ├── extend.go │ ├── meminfo.go │ ├── net │ ├── dev.go │ └── net.go │ ├── pid │ ├── autogroup.go │ ├── cgroup.go │ ├── cmdline.go │ ├── coredump_filter.go │ ├── cpuset.go │ ├── cwd.go │ ├── environ.go │ ├── fd.go │ ├── gid_map.go │ ├── io.go │ ├── limits.go │ ├── loginuid.go │ ├── map_files.go │ ├── mountinfo.go │ ├── mounts.go │ ├── mountstats.go │ ├── numa_maps.go │ ├── oom_adj.go │ ├── oom_score.go │ ├── oom_score_adj.go │ ├── personality.go │ ├── pid.go │ ├── projid_map.go │ ├── sched.go │ ├── schedstat.go │ ├── sessionid.go │ ├── setgroups.go │ ├── smaps.go │ ├── stack.go │ ├── stat.go │ ├── statm.go │ ├── status.go │ ├── syscall.go │ ├── task.go │ └── uid_map.go │ ├── proc.go │ ├── stat.go │ └── uptime.go ├── vendor └── github.com │ └── astaxie │ └── beego │ ├── .github │ └── ISSUE_TEMPLATE │ ├── .gitignore │ ├── .gosimpleignore │ ├── .travis.yml │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── admin.go │ ├── admin_test.go │ ├── adminui.go │ ├── app.go │ ├── beego.go │ ├── cache │ ├── README.md │ ├── cache.go │ ├── cache_test.go │ ├── conv.go │ ├── conv_test.go │ ├── file.go │ ├── memcache │ │ ├── memcache.go │ │ └── memcache_test.go │ ├── memory.go │ ├── redis │ │ ├── redis.go │ │ └── redis_test.go │ └── ssdb │ │ ├── ssdb.go │ │ └── ssdb_test.go │ ├── config.go │ ├── config │ ├── config.go │ ├── config_test.go │ ├── env │ │ ├── env.go │ │ └── env_test.go │ ├── fake.go │ ├── ini.go │ ├── ini_test.go │ ├── json.go │ ├── json_test.go │ ├── xml │ │ ├── xml.go │ │ └── xml_test.go │ └── yaml │ │ ├── yaml.go │ │ └── yaml_test.go │ ├── config_test.go │ ├── context │ ├── acceptencoder.go │ ├── acceptencoder_test.go │ ├── context.go │ ├── context_test.go │ ├── input.go │ ├── input_test.go │ ├── output.go │ ├── param │ │ ├── conv.go │ │ ├── methodparams.go │ │ ├── options.go │ │ ├── parsers.go │ │ └── parsers_test.go │ ├── renderer.go │ └── response.go │ ├── controller.go │ ├── controller_test.go │ ├── doc.go │ ├── error.go │ ├── error_test.go │ ├── filter.go │ ├── filter_test.go │ ├── flash.go │ ├── flash_test.go │ ├── grace │ ├── conn.go │ ├── grace.go │ ├── listener.go │ └── server.go │ ├── hooks.go │ ├── httplib │ ├── README.md │ ├── httplib.go │ └── httplib_test.go │ ├── log.go │ ├── logs │ ├── README.md │ ├── accesslog.go │ ├── alils │ │ ├── alils.go │ │ ├── config.go │ │ ├── log.pb.go │ │ ├── log_config.go │ │ ├── log_project.go │ │ ├── log_store.go │ │ ├── machine_group.go │ │ ├── request.go │ │ └── signature.go │ ├── color.go │ ├── color_windows.go │ ├── color_windows_test.go │ ├── conn.go │ ├── conn_test.go │ ├── console.go │ ├── console_test.go │ ├── es │ │ └── es.go │ ├── file.go │ ├── file_test.go │ ├── jianliao.go │ ├── log.go │ ├── logger.go │ ├── logger_test.go │ ├── multifile.go │ ├── multifile_test.go │ ├── slack.go │ ├── smtp.go │ └── smtp_test.go │ ├── migration │ ├── ddl.go │ ├── doc.go │ └── migration.go │ ├── mime.go │ ├── namespace.go │ ├── namespace_test.go │ ├── orm │ ├── README.md │ ├── cmd.go │ ├── cmd_utils.go │ ├── db.go │ ├── db_alias.go │ ├── db_mysql.go │ ├── db_oracle.go │ ├── db_postgres.go │ ├── db_sqlite.go │ ├── db_tables.go │ ├── db_tidb.go │ ├── db_utils.go │ ├── models.go │ ├── models_boot.go │ ├── models_fields.go │ ├── models_info_f.go │ ├── models_info_m.go │ ├── models_test.go │ ├── models_utils.go │ ├── orm.go │ ├── orm_conds.go │ ├── orm_log.go │ ├── orm_object.go │ ├── orm_querym2m.go │ ├── orm_queryset.go │ ├── orm_raw.go │ ├── orm_test.go │ ├── qb.go │ ├── qb_mysql.go │ ├── qb_tidb.go │ ├── types.go │ ├── utils.go │ └── utils_test.go │ ├── parser.go │ ├── plugins │ ├── apiauth │ │ ├── apiauth.go │ │ └── apiauth_test.go │ ├── auth │ │ └── basic.go │ ├── authz │ │ ├── authz.go │ │ ├── authz_model.conf │ │ ├── authz_policy.csv │ │ └── authz_test.go │ └── cors │ │ ├── cors.go │ │ └── cors_test.go │ ├── policy.go │ ├── router.go │ ├── router_test.go │ ├── session │ ├── README.md │ ├── couchbase │ │ └── sess_couchbase.go │ ├── ledis │ │ └── ledis_session.go │ ├── memcache │ │ └── sess_memcache.go │ ├── mysql │ │ └── sess_mysql.go │ ├── postgres │ │ └── sess_postgresql.go │ ├── redis │ │ └── sess_redis.go │ ├── sess_cookie.go │ ├── sess_cookie_test.go │ ├── sess_file.go │ ├── sess_mem.go │ ├── sess_mem_test.go │ ├── sess_test.go │ ├── sess_utils.go │ ├── session.go │ └── ssdb │ │ └── sess_ssdb.go │ ├── staticfile.go │ ├── staticfile_test.go │ ├── swagger │ └── swagger.go │ ├── template.go │ ├── template_test.go │ ├── templatefunc.go │ ├── templatefunc_test.go │ ├── testing │ ├── assertions.go │ └── client.go │ ├── toolbox │ ├── healthcheck.go │ ├── profile.go │ ├── profile_test.go │ ├── statistics.go │ ├── statistics_test.go │ ├── task.go │ └── task_test.go │ ├── tree.go │ ├── tree_test.go │ ├── unregroute_test.go │ ├── utils │ ├── caller.go │ ├── caller_test.go │ ├── captcha │ │ ├── LICENSE │ │ ├── README.md │ │ ├── captcha.go │ │ ├── image.go │ │ ├── image_test.go │ │ ├── siprng.go │ │ └── siprng_test.go │ ├── debug.go │ ├── debug_test.go │ ├── file.go │ ├── file_test.go │ ├── mail.go │ ├── mail_test.go │ ├── pagination │ │ ├── controller.go │ │ ├── doc.go │ │ ├── paginator.go │ │ └── utils.go │ ├── rand.go │ ├── rand_test.go │ ├── safemap.go │ ├── safemap_test.go │ ├── slice.go │ ├── slice_test.go │ ├── testdata │ │ └── grepe.test │ └── utils.go │ └── validation │ ├── README.md │ ├── util.go │ ├── util_test.go │ ├── validation.go │ ├── validation_test.go │ └── validators.go ├── views └── index.tpl └── web ├── .babelrc ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── design ├── boot-img.psd └── sysmon.psd ├── doc └── fonts │ └── iconfont │ ├── demo.css │ ├── demo_fontclass.html │ ├── demo_symbol.html │ ├── demo_unicode.html │ ├── iconfont.css │ ├── iconfont.eot │ ├── iconfont.js │ ├── iconfont.svg │ ├── iconfont.ttf │ └── iconfont.woff ├── index.html ├── package-lock.json ├── package.json ├── src ├── App.vue ├── assets │ └── logo.png ├── components │ ├── DrawerLeft.vue │ ├── HelloWorld.vue │ ├── Init.vue │ ├── Layout.vue │ ├── Toolbar.vue │ ├── common │ │ ├── Doughnut.js │ │ ├── about.vue │ │ ├── confirmBtns.vue │ │ ├── selection.vue │ │ └── serverInputField.vue │ ├── content │ │ ├── FS.vue │ │ ├── Processes.vue │ │ ├── Resources.vue │ │ ├── Setting.vue │ │ ├── fs │ │ │ └── diskCard.vue │ │ ├── processes │ │ │ ├── detailsLimits.vue │ │ │ ├── detailsNumaMaps.vue │ │ │ ├── detailsOther.vue │ │ │ ├── detailsSmaps.vue │ │ │ ├── detailsStack.vue │ │ │ └── processList.vue │ │ └── resources │ │ │ ├── LineChart.js │ │ │ ├── chartHdr.vue │ │ │ ├── chartLegend.vue │ │ │ ├── chartLegendBar.vue │ │ │ ├── cpu.vue │ │ │ ├── cpuLineChart.vue │ │ │ ├── disk.vue │ │ │ ├── diskLineChart.vue │ │ │ ├── mem.vue │ │ │ ├── memLineChart.vue │ │ │ ├── net.vue │ │ │ └── netLineChart.vue │ ├── header │ │ ├── clearSetting.vue │ │ └── serverInfo.vue │ └── more.vue ├── css │ ├── app.css │ └── resources.css ├── js │ ├── common │ │ ├── backendAPI.js │ │ ├── dataDef.js │ │ ├── fmtSize.js │ │ ├── fs.js │ │ ├── index.js │ │ ├── processes.js │ │ ├── resources.js │ │ ├── serverAPI.js │ │ └── sysInfo.js │ └── tips │ │ ├── index.js │ │ ├── processes.js │ │ └── resources.js ├── main.js ├── router │ └── index.js └── static │ └── icon │ └── iconfont.js └── static ├── .gitkeep ├── PWA └── manifest.json └── img ├── 192x192.png ├── 48x48.png ├── 96x96.png └── drawerLeft └── material.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | sysmon 2 | swagger/swagger.json 3 | swagger/swagger.yml 4 | routers/commentsRouter_controllers.go 5 | routers/commentsRouter____controllers.go 6 | lastupdate.tmp 7 | 8 | sysmon*.tar.gz 9 | sysmon*.tar.xz 10 | 11 | .project 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.7 2 | 3 | # Godep for vendoring 4 | RUN mkdir /opt 5 | ADD sysmon-latest.tar.xz /opt/ 6 | RUN sed -i 's/runmode = dev/runmode = prod/g' /opt/sysmon/conf/app.conf && echo 'procfs = /hproc' >> /opt/sysmon/conf/app.conf 7 | 8 | RUN echo "#!/bin/sh" > /opt/run.sh && echo "cd /opt/sysmon && ./sysmon > /var/log/sysmon.log &" >> /opt/run.sh && echo "/bin/sh" >> /opt/run.sh && chmod a+x /opt/run.sh 9 | 10 | WORKDIR /opt 11 | ENTRYPOINT [ "/opt/run.sh" ] 12 | 13 | EXPOSE 2048 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 何培勤 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build-docker-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | ./pack.sh 5 | docker build -t sysmon . 6 | 7 | if [[ $? -eq 0 ]]; then 8 | echo "=================== success ===================" 9 | echo "Start dockerized sysmon:" 10 | echo "docker run --name sysmon --restart=always -d -p 4096:2048 -v /proc:/hproc --privileged -it sysmon" 11 | echo "Visit web UI from localhost:4096 in browser" 12 | else 13 | echo "=================== failed ===================" 14 | echo build image failed... 15 | fi 16 | -------------------------------------------------------------------------------- /client/desktop/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build-* 3 | 4 | index.html 5 | static 6 | -------------------------------------------------------------------------------- /client/desktop/README.md: -------------------------------------------------------------------------------- 1 | # 说明 2 | 当前目录下的工具可以使用 ../../web/dist 中的静态 web app 来构建各个桌面平台的客户端 3 | 4 | ## 支持的平台和架构 5 | 6 |
7 | 8 | # 安装构建以来的工具 9 | ``` 10 | apt-get install wine p7zip-full 11 | ``` 12 | 13 |
14 | 15 | # 构建 sysmon 客户端 16 | 在当前目录执行: 17 | ``` 18 | npm run build 19 | -- 构建当前平台和硬件架构的客户端 20 | 21 | npm run build -- --all 22 | -- 构建全部支持的平台和硬件架构的客户端 23 | ``` 24 | 构建成功之后会将生成的客户端放在 build 目录下的对应目录中,build 下的目录以 sysmon-$平台-$架构 命名。 25 | 26 | 注意:在构建 sysmon 的客户端之前需要确保 ../../web/dist 目录是最新生成的 web app,如果不是,请先进入 ../../web 目录执行 "npm run build" 以生成最新的 web app。 27 | 28 |
29 | 30 | # 打包 31 | 上面的步骤只是生成了应用,每个应用放在 build/sysmon-$平台-$架构 目录下,并没有版本信息,也没有打包成单个文件,下面的命令可以将 build 下的应用根据当前版本来打包为压缩包。 32 | 33 | ``` 34 | npm run compress 35 | ``` 36 | -------------------------------------------------------------------------------- /client/desktop/logo/sysmon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/desktop/logo/sysmon.icns -------------------------------------------------------------------------------- /client/desktop/logo/sysmon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/desktop/logo/sysmon.ico -------------------------------------------------------------------------------- /client/desktop/logo/sysmon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/desktop/logo/sysmon.png -------------------------------------------------------------------------------- /client/desktop/main.js: -------------------------------------------------------------------------------- 1 | // Modules to control application life and create native browser window 2 | const {app, BrowserWindow} = require('electron') 3 | 4 | // Keep a global reference of the window object, if you don't, the window will 5 | // be closed automatically when the JavaScript object is garbage collected. 6 | let mainWindow 7 | 8 | function createWindow () { 9 | // Create the browser window. 10 | mainWindow = new BrowserWindow({width: 1000, height: 680}) 11 | 12 | // and load the index.html of the app. 13 | mainWindow.loadFile('index.html') 14 | 15 | // Open the DevTools. 16 | // mainWindow.webContents.openDevTools() 17 | 18 | // Emitted when the window is closed. 19 | mainWindow.on('closed', function () { 20 | // Dereference the window object, usually you would store windows 21 | // in an array if your app supports multi windows, this is the time 22 | // when you should delete the corresponding element. 23 | mainWindow = null 24 | }) 25 | } 26 | 27 | // This method will be called when Electron has finished 28 | // initialization and is ready to create browser windows. 29 | // Some APIs can only be used after this event occurs. 30 | app.on('ready', createWindow) 31 | 32 | // Quit when all windows are closed. 33 | app.on('window-all-closed', function () { 34 | // On OS X it is common for applications and their menu bar 35 | // to stay active until the user quits explicitly with Cmd + Q 36 | if (process.platform !== 'darwin') { 37 | app.quit() 38 | } 39 | }) 40 | 41 | app.on('activate', function () { 42 | // On OS X it's common to re-create a window in the app when the 43 | // dock icon is clicked and there are no other windows open. 44 | if (mainWindow === null) { 45 | createWindow() 46 | } 47 | }) 48 | 49 | // In this file you can include the rest of your app's specific main process 50 | // code. You can also put them in separate files and require them here. 51 | -------------------------------------------------------------------------------- /client/desktop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sysmon-client", 3 | "version": "1.1.0", 4 | "description": "A system monitor for linux", 5 | "main": "main.js", 6 | "scripts": { 7 | "start": "electron .", 8 | "build": "electron-packager . --icon=logo/sysmon.icns --out=build --overwrite", 9 | "compress": "./scripts/compress.sh", 10 | "gencode": "./scripts/code.sh gen", 11 | "clean": "./scripts/code.sh clean" 12 | }, 13 | "keywords": [ 14 | "sysmon", 15 | "system monitor", 16 | "Electron" 17 | ], 18 | "author": "hepeiqin", 19 | "license": "MIT", 20 | "devDependencies": { 21 | "electron": "^2.0.8", 22 | "electron-packager": "^12.1.1" 23 | }, 24 | "dependencies": {} 25 | } 26 | -------------------------------------------------------------------------------- /client/desktop/renderer.js: -------------------------------------------------------------------------------- 1 | // This file is required by the index.html file and will 2 | // be executed in the renderer process for that window. 3 | // All of the Node.js APIs are available in this process. 4 | -------------------------------------------------------------------------------- /client/desktop/scripts/compress.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | VER=$(git tag | tail -n1) 6 | 7 | cd build 8 | list=$(ls) 9 | for d in $list; do 10 | echo Working on $d 11 | name=${d}-${VER} 12 | mv $d $name 13 | if [ "$d" = "sysmon-client-win32-ia32" ] || [ "$d" = "sysmon-client-win32-x64" ]; then 14 | out_name=$name.7x 15 | echo Compressing $d 7z to $out_name 16 | if [ -f "$out_name" ]; then 17 | continue 18 | fi 19 | 7z a $name.7z $name -mx=9 20 | else 21 | out_name=$name.tar.xz 22 | echo Compressing $d to $out_name 23 | if [ -f "$out_name" ]; then 24 | continue 25 | fi 26 | tar --checkpoint=100 --checkpoint-action=dot --totals -Jcf $name.tar.xz $name 27 | fi 28 | done 29 | 30 | cd .. 31 | echo Moving build to build-$VER 32 | mv build build-$VER 33 | 34 | -------------------------------------------------------------------------------- /client/mobile/.gitignore: -------------------------------------------------------------------------------- 1 | static 2 | backup-* 3 | unpackage/release 4 | unpackage/.confirmed_dependencies 5 | unpackage/.dependencies 6 | -------------------------------------------------------------------------------- /client/mobile/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | sysmon-mobile 4 | Create By HBuilder 5 | 6 | 7 | 8 | 9 | com.pandora.projects.ui.MKeyBuilder 10 | 11 | 12 | 13 | 14 | com.aptana.ide.core.unifiedBuilder 15 | 16 | 17 | 18 | 19 | 20 | com.pandora.projects.ui.MKeyNature 21 | com.aptana.projects.webnature 22 | 23 | 24 | 25 | 1535356236144 26 | 27 | 10 28 | 29 | org.eclipse.ui.ide.orFilterMatcher 30 | 31 | 32 | org.eclipse.ui.ide.multiFilter 33 | 1.0-projectRelativePath-matches-false-false-bin 34 | 35 | 36 | org.eclipse.ui.ide.multiFilter 37 | 1.0-projectRelativePath-matches-false-false-setting 38 | 39 | 40 | 41 | 42 | 43 | 1535446245987 44 | 45 | 26 46 | 47 | org.eclipse.ui.ide.multiFilter 48 | 1.0-name-matches-false-false-node_modules 49 | 50 | 51 | 52 | 1535446245988 53 | 54 | 26 55 | 56 | org.eclipse.ui.ide.multiFilter 57 | 1.0-name-matches-false-false-node_modules 58 | 59 | 60 | 61 | 1535544852397 62 | 63 | 26 64 | 65 | org.eclipse.ui.ide.multiFilter 66 | 1.0-name-matches-false-false-node_modules 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /client/mobile/README.md: -------------------------------------------------------------------------------- 1 | # 关于 2 | 当前目录下的文件是用于生成移动客户端的,移动客户端目前覆盖 Android 和 IOS,通过 HBuilder 直接使用 web app 来生成移动客户端。web app 是 server 端自带的由 vue 实现的客户端(位于 sysmon/web 下)。 3 | 4 |
5 | 6 | # 构建步骤 7 | ## 1. 生成 web app 8 | 在 sysmon/web 下执行: 9 | ``` 10 | npm run build 11 | ``` 12 | 执行成功的话,生成的 sysmon/web 目录即为所需的 web app 13 | 14 | Note: 如果是首次执行,则需要先在 sysmon/web 下执行 "npm install" 安装依赖。 15 | 16 | 17 | ## 2. 生成 HBuilder 移动 APP 18 | 在当前目录下(sysmon/client/mobile)执行: 19 | ``` 20 | ./mobile.sh gen 21 | ``` 22 | 执行成功的话,可以生成构建移动 APP 所需的全部文件 23 | 24 | ## 3. 构建移动 APP 25 | 通过 HBuilder 客户端打开当前目录,即可作为一个移动 APP 项目来生成移动 APP。 26 | -------------------------------------------------------------------------------- /client/mobile/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /client/mobile/unpackage/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/.gitkeep -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/1024x1024.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/120x120.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/144x144.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/152x152.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/167x167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/167x167.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/180x180.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/192x192.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/20x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/20x20.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/256x256.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/29x29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/29x29.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/40x40.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/48x48.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/58x58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/58x58.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/60x60.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/72x72.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/76x76.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/80x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/80x80.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/87x87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/87x87.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/icons/96x96.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/img/boot-img/android/boot-img-1080x1882.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/img/boot-img/android/boot-img-1080x1882.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/img/boot-img/android/boot-img-480x762.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/img/boot-img/android/boot-img-480x762.png -------------------------------------------------------------------------------- /client/mobile/unpackage/res/img/boot-img/android/boot-img-720x1242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/client/mobile/unpackage/res/img/boot-img/android/boot-img-720x1242.png -------------------------------------------------------------------------------- /conf/app.conf: -------------------------------------------------------------------------------- 1 | appname = sysmon 2 | httpport = 2048 3 | EnableGzip = true 4 | runmode = dev 5 | 6 | EnableDocs = true 7 | 8 | -------------------------------------------------------------------------------- /controllers/default.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "github.com/astaxie/beego" 5 | ) 6 | 7 | type MainController struct { 8 | beego.Controller 9 | } 10 | 11 | // @Title index.tpl 12 | // @Description get all objects 13 | // @Success 200 {object} models.Object 14 | // @Failure 403 :objectId is empty 15 | // @router / [get] 16 | func (c *MainController) Get() { 17 | c.TplName = "index.tpl" 18 | } -------------------------------------------------------------------------------- /controllers/info.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | // "fmt" 5 | 6 | "github.com/Lt0/sysmon/controllers/info" 7 | "github.com/Lt0/sysmon/controllers/info/disk" 8 | "github.com/astaxie/beego" 9 | ) 10 | 11 | type InfoController struct { 12 | beego.Controller 13 | } 14 | 15 | // @Title System Info 16 | // @Description Get all system info 17 | // @Success 200 {object} models.Object 18 | // @Failure 403 :objectId is empty 19 | // @router /all [get] 20 | func (c *InfoController) GetSysInfo() { 21 | // fmt.Println("GetSysInfo") 22 | handler := &info.AllInfo{Controller: &c.Controller} 23 | c.Data["json"] = handler.Do() 24 | c.ServeJSON() 25 | } 26 | 27 | // @Title System Disk Info 28 | // @Description Get system disk info 29 | // @Success 200 {object} models.Object 30 | // @Failure 403 :objectId is empty 31 | // @router /disk [get] 32 | func (c *InfoController) GetSysDiskInfo() { 33 | // fmt.Println("GetSysInfo") 34 | //handler := &disk.AllInfo{Controller: &c.Controller} 35 | c.Data["json"] = disk.AllInfo() 36 | c.ServeJSON() 37 | } -------------------------------------------------------------------------------- /controllers/info/all.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | // "fmt" 5 | "time" 6 | 7 | "github.com/Lt0/sysmon/controllers/info/cpu" 8 | "github.com/Lt0/sysmon/controllers/info/mem" 9 | "github.com/Lt0/sysmon/controllers/info/net" 10 | "github.com/Lt0/sysmon/controllers/info/disk" 11 | "github.com/astaxie/beego" 12 | ) 13 | 14 | type AllInfo struct { 15 | Controller *beego.Controller 16 | 17 | allInfo SysInfo 18 | } 19 | 20 | type SysInfo struct { 21 | TimeStamp time.Time 22 | Cpu cpu.CpuInfo 23 | Mem mem.MemInfo 24 | Net net.NetInfo 25 | Disk disk.DiskInfo 26 | 27 | // HWInfo struct 28 | // SWInfo struct 29 | } 30 | 31 | func (p *AllInfo) Do() interface{} { 32 | var si SysInfo 33 | 34 | // fmt.Println("do all info") 35 | 36 | si.TimeStamp = time.Now(); 37 | // fmt.Println("TimeStamp:", si.TimeStamp); 38 | 39 | si.Cpu = cpu.GetCpuInfo() 40 | si.Mem = mem.All() 41 | si.Net = net.GetNetInfo() 42 | si.Disk = disk.AllInfo() 43 | // fmt.Println("si.Cpu: ", si.Cpu) 44 | // fmt.Println("si.Mem: ", si.Mem) 45 | // fmt.Println("si.Net: ", si.Net) 46 | // fmt.Println("si.Disk: ", si.Disk) 47 | 48 | return si 49 | } 50 | -------------------------------------------------------------------------------- /controllers/info/net/net.go: -------------------------------------------------------------------------------- 1 | package net 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "os/exec" 7 | "strconv" 8 | ) 9 | 10 | type Context struct { 11 | Procfs string 12 | } 13 | 14 | var Ctx Context 15 | 16 | type NetInfo struct { 17 | NicNum int // 网卡数量 18 | Nics []NicInfo // 每个网卡的状态信息 19 | } 20 | 21 | type NicInfo struct { 22 | Name string 23 | 24 | RBytes int 25 | RPackets int 26 | RErrs int 27 | RDrop int 28 | RFifo int 29 | RFrame int 30 | RComporessed int 31 | RMulticast int 32 | 33 | TBytes int 34 | TPackets int 35 | TErrs int 36 | TDrop int 37 | TFifo int 38 | TFrame int 39 | TComporessed int 40 | TMulticast int 41 | } 42 | 43 | func GetNetInfo() NetInfo { 44 | var ni NetInfo 45 | 46 | cmd := fmt.Sprintf("cat %s/net/dev | tail -n +3 | sed 's/^\\s*//g' | sed 's/\\s\\+/|/g'", Ctx.Procfs) 47 | out, err := exec.Command("sh", "-c", cmd).Output() 48 | //out, err := exec.Command("sh", "-c", `cat /proc/net/dev | tail -n +3 | sed 's/^\s*//g' | sed 's/\s\+/|/g'`).Output() 49 | if err != nil { 50 | fmt.Println("GetCoresInfo", err) 51 | } 52 | 53 | for _, v := range(strings.Split(string(out), "\n")) { 54 | if v == "" {continue} 55 | NicStrs := strings.Split(v, ":") 56 | infos := strings.Split(NicStrs[1], "|") 57 | 58 | if len(infos) < 17 { 59 | fmt.Println("infos is too short, could not get NIC info") 60 | return ni 61 | } 62 | RBytes, _ := strconv.Atoi(infos[1]) 63 | RPackets, _ := strconv.Atoi(infos[2]) 64 | RErrs, _ := strconv.Atoi(infos[3]) 65 | RDrop, _ := strconv.Atoi(infos[4]) 66 | RFifo, _ := strconv.Atoi(infos[5]) 67 | RFrame, _ := strconv.Atoi(infos[6]) 68 | RComporessed, _ := strconv.Atoi(infos[7]) 69 | RMulticast, _ := strconv.Atoi(infos[8]) 70 | 71 | TBytes, _ := strconv.Atoi(infos[9]) 72 | TPackets, _ := strconv.Atoi(infos[10]) 73 | TErrs, _ := strconv.Atoi(infos[11]) 74 | TDrop, _ := strconv.Atoi(infos[12]) 75 | TFifo, _ := strconv.Atoi(infos[13]) 76 | TFrame, _ := strconv.Atoi(infos[14]) 77 | TComporessed, _ := strconv.Atoi(infos[15]) 78 | TMulticast, _ := strconv.Atoi(infos[16]) 79 | ni.Nics = append(ni.Nics, NicInfo{NicStrs[0], RBytes, RPackets, RErrs, RDrop, RFifo, RFrame, RComporessed, RMulticast, TBytes, TPackets, TErrs, TDrop, TFifo, TFrame, TComporessed, TMulticast}) 80 | } 81 | 82 | return ni 83 | } -------------------------------------------------------------------------------- /controllers/process.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "github.com/Lt0/sysmon/controllers/process" 5 | "github.com/astaxie/beego" 6 | ) 7 | 8 | type ProcessController struct { 9 | beego.Controller 10 | } 11 | 12 | // @Title All Processes Status 13 | // @Description Get All Processes Status 14 | // @Success 200 {object} models.Object 15 | // @Failure 403 :objectId is empty 16 | // @router /all [get] 17 | func (c *ProcessController) AllProcess() { 18 | handler := &process.AllProcessCtrl{Controller: &c.Controller} 19 | c.Data["json"] = handler.Do() 20 | c.ServeJSON() 21 | } 22 | 23 | // @Title Process Details 24 | // @Description Get Process Details 25 | // @Param pid query string true "which process to get" 26 | // @Success 200 {object} models.Object 27 | // @Failure 403 :objectId is empty 28 | // @router /details [get] 29 | func (c *ProcessController) Details() { 30 | handler := &process.DetailsCtrl{Controller: &c.Controller} 31 | c.Data["json"] = handler.Do() 32 | c.ServeJSON() 33 | } -------------------------------------------------------------------------------- /controllers/process/all.go: -------------------------------------------------------------------------------- 1 | package process 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/Lt0/sysmon/utils/proc" 7 | "github.com/astaxie/beego" 8 | ) 9 | 10 | type AllProcessCtrl struct { 11 | Controller *beego.Controller 12 | } 13 | 14 | type AllProcess struct { 15 | TimeStamp int64 16 | CoreNum int // 设备的内核总数 17 | Cores []proc.CPU // 每个 CPU 核心的信息 18 | UpTime proc.UpTimeInfo // 系统启动时间和 idle 时间 19 | Processes []Process // 所有的线程信息 20 | } 21 | 22 | func (p *AllProcessCtrl) Do() interface{} { 23 | var ap AllProcess 24 | 25 | t := time.Now() 26 | ap.TimeStamp = t.UnixNano() 27 | p.AllPidInfo(&ap) 28 | ap.Cores, ap.CoreNum = coresInfo() 29 | ap.UpTime = uptimeInfo() 30 | 31 | return ap 32 | } 33 | 34 | func (p *AllProcessCtrl) AllPidInfo(ap *AllProcess) { 35 | for _, v := range(proc.AllPids()) { 36 | info, err := PidInfo(v) 37 | if err != nil { 38 | // fmt.Printf("not add %v cause by: %v\n", v, err) 39 | continue 40 | } 41 | ap.Processes = append(ap.Processes, info) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /controllers/sysInfo.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | // "fmt" 5 | 6 | "github.com/Lt0/sysmon/controllers/sysInfo" 7 | "github.com/astaxie/beego" 8 | ) 9 | 10 | type SysInfoController struct { 11 | beego.Controller 12 | } 13 | 14 | // @Title Static System Global Info 15 | // @Description Get all static system global info 16 | // @Success 200 {object} models.Object 17 | // @Failure 403 :objectId is empty 18 | // @router /all [get] 19 | func (c *SysInfoController) GetSysInfo() { 20 | // fmt.Println("GetSysInfo") 21 | handler := &sysInfo.AllInfo{Controller: &c.Controller} 22 | c.Data["json"] = handler.Do() 23 | c.ServeJSON() 24 | } 25 | 26 | // @Title Hostname 27 | // @Description Get hostname reported by the kernel. 28 | // @Success 200 {object} models.Object 29 | // @Failure 403 :objectId is empty 30 | // @router /hostname [get] 31 | func (c *SysInfoController) GetHostname() { 32 | handler := &sysInfo.Hostname{} 33 | c.Data["json"] = handler.Do() 34 | c.ServeJSON() 35 | } -------------------------------------------------------------------------------- /controllers/sysInfo/all.go: -------------------------------------------------------------------------------- 1 | package sysInfo 2 | 3 | import ( 4 | "github.com/astaxie/beego" 5 | ) 6 | 7 | type AllInfo struct { 8 | Controller *beego.Controller 9 | 10 | allSysInfo SysInfo 11 | } 12 | 13 | type SysInfo struct { 14 | HW HWInfo 15 | SW SWInfo 16 | } 17 | 18 | func (p *AllInfo) Do() interface{} { 19 | var si SysInfo 20 | si.HW = getHWInfo() 21 | return si 22 | } 23 | -------------------------------------------------------------------------------- /controllers/sysInfo/hostname.go: -------------------------------------------------------------------------------- 1 | package sysInfo 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "github.com/astaxie/beego" 7 | ) 8 | 9 | type Hostname struct { 10 | Controller *beego.Controller 11 | } 12 | 13 | func (p *Hostname) Do() interface{} { 14 | fmt.Println("hostname:", os.Hostname) 15 | hostname, err := os.Hostname() 16 | if err != nil { 17 | return "unknown" 18 | } 19 | return hostname 20 | } -------------------------------------------------------------------------------- /controllers/sysInfo/hw.go: -------------------------------------------------------------------------------- 1 | package sysInfo 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | 7 | "github.com/Lt0/sysmon/utils/proc" 8 | ) 9 | 10 | type Memory struct { 11 | PhySize uint64 12 | SWapSize uint64 13 | } 14 | 15 | type HWInfo struct { 16 | Mem Memory 17 | Lshw string 18 | } 19 | 20 | // GHW is global hardware info 21 | var GHW HWInfo 22 | var initedGlobalHW bool 23 | 24 | func getHWInfo() HWInfo { 25 | if initedGlobalHW { 26 | return GHW 27 | } 28 | 29 | // GHW.Lshw = lshwStr() 30 | 31 | initedGlobalHW = true 32 | 33 | mi, _ := proc.GetMeminfo() 34 | GHW.Mem.PhySize = mi.MemTotal 35 | GHW.Mem.SWapSize = mi.SwapTotal 36 | 37 | return GHW 38 | } 39 | 40 | func lshwStr() string { 41 | cmd := fmt.Sprintf("lshw") 42 | out, err := exec.Command("sh", "-c", cmd).Output() 43 | if err != nil { 44 | fmt.Println("lshw:", err) 45 | } 46 | // fmt.Println("out:", out) 47 | return string(out) 48 | } -------------------------------------------------------------------------------- /controllers/sysInfo/sw.go: -------------------------------------------------------------------------------- 1 | package sysInfo 2 | 3 | type SWInfo struct { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /doc/img/sysmon-mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/doc/img/sysmon-mobile.png -------------------------------------------------------------------------------- /doc/img/sysmon-resources.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/doc/img/sysmon-resources.png -------------------------------------------------------------------------------- /etc/init/systemd/sysmon.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=sysmon - system monitor by lightimehpq@gmail.com 3 | [Service] 4 | Environment= 5 | WorkingDirectory=APP_PATH 6 | ExecStart=APP_PATH/sysmon 7 | ExecReload=/bin/kill -HUP $MAINPID 8 | KillMode=process 9 | Restart=on-failure 10 | RestartSec=10s 11 | [Install] 12 | WantedBy=multi-user.target 13 | Alias=sysmon.target 14 | -------------------------------------------------------------------------------- /etc/init/upstart/sysmon.conf: -------------------------------------------------------------------------------- 1 | description "sysmon(system monitor) daemon start on boot" 2 | author "Peiqin He" 3 | 4 | start on runlevel [2345] 5 | stop on runlevel [!2345] 6 | 7 | respawn 8 | respawn limit 10 5 9 | 10 | script 11 | APP_PATH="/opt/sysmon" 12 | exec /bin/sh -c "cd $APP_PATH && ./sysmon" 13 | end script 14 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SCRIPTS_ROOT=etc/init 4 | APP_PATH=$PWD 5 | INIT_TYPE="" 6 | 7 | 8 | get_init_type() { 9 | comm=$(cat /proc/1/comm) 10 | if [ "$comm" = "systemd" ]; then 11 | INIT_TYPE="systemd" 12 | return 13 | elif [ "$comm" = "init" ]; then 14 | ver=$(/sbin/init --version 2>/dev/null | grep upstart) 15 | if [ -n "$ver" ]; then 16 | INIT_TYPE="upstart" 17 | return 18 | fi 19 | fi 20 | 21 | INIT_TYPE="sysvinit" 22 | } 23 | 24 | install() { 25 | case $INIT_TYPE in 26 | "systemd" ) 27 | echo install in systemd init 28 | if [ -d /usr/lib/systemd/system ]; then 29 | dst_path="/usr/lib/systemd/system" 30 | elif [ -d /lib/systemd/system ]; then 31 | dst_path="/lib/systemd/system" 32 | else 33 | dst_path="/etc/systemd/system" 34 | fi 35 | cp $SCRIPTS_ROOT/systemd/sysmon.service $dst_path/ 36 | sed -i "s|APP_PATH|$APP_PATH|g" $dst_path/sysmon.service 37 | systemctl daemon-reload 38 | systemctl enable sysmon 39 | systemctl start sysmon 40 | ;; 41 | "upstart" ) 42 | echo install in upstart init 43 | cp $SCRIPTS_ROOT/upstart/sysmon.conf /etc/init/sysmon.conf 44 | sed -i "s|APP_PATH=.*|APP_PATH=\"$APP_PATH\"|g" /etc/init/sysmon.conf 45 | service sysmon start 46 | ;; 47 | "sysvinit" ) 48 | echo install in sysvinit init 49 | ;; 50 | * ) 51 | echo install in unknown init 52 | ;; 53 | esac 54 | } 55 | 56 | uninstall() { 57 | case $INIT_TYPE in 58 | "systemd" ) 59 | echo uninstall sysmon from systemd init 60 | systemctl stop sysmon 61 | rm -rvf /lib/systemd/system/sysmon.service 62 | find /etc/systemd/system -name "sysmon.*" | xargs rm -vf 63 | systemctl daemon-reload 64 | ;; 65 | "upstart" ) 66 | rm -rvf /etc/init/sysmon.conf 67 | echo uninstall sysmon from upstart init 68 | ;; 69 | "sysvinit" ) 70 | echo uninstall sysmon from sysvinit init 71 | ;; 72 | * ) 73 | echo uninstall sysmon from unknown init 74 | ;; 75 | esac 76 | } 77 | 78 | get_init_type 79 | case $1 in 80 | u | -u | --uninstall ) 81 | uninstall 82 | ;; 83 | h | -h | --help ) 84 | show_help 85 | ;; 86 | * ) 87 | install 88 | ;; 89 | esac 90 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "github.com/Lt0/sysmon/routers" 5 | "github.com/astaxie/beego" 6 | "github.com/astaxie/beego/plugins/cors" 7 | 8 | "github.com/Lt0/sysmon/controllers/info/cpu" 9 | "github.com/Lt0/sysmon/controllers/info/disk" 10 | "github.com/Lt0/sysmon/controllers/info/net" 11 | 12 | proc "github.com/Lt0/sysmon/utils/proc" 13 | ppid "github.com/Lt0/sysmon/utils/proc/pid" 14 | pnet "github.com/Lt0/sysmon/utils/proc/net" 15 | ) 16 | 17 | func main() { 18 | setCORS() 19 | initStaticDir() 20 | initProcfs() 21 | 22 | beego.Run() 23 | } 24 | 25 | func initStaticDir(){ 26 | beego.BConfig.WebConfig.DirectoryIndex = true 27 | beego.BConfig.WebConfig.StaticDir["/web"] = "web" 28 | beego.BConfig.WebConfig.StaticDir["/static"] = "web/dist/static" 29 | if beego.BConfig.RunMode == "dev" { 30 | beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger" 31 | } 32 | } 33 | 34 | func initProcfs() { 35 | procfs := beego.AppConfig.String("procfs") 36 | if procfs == "" { 37 | procfs = "/proc" 38 | } 39 | 40 | cpu.Ctx.Procfs = procfs 41 | disk.Ctx.Procfs = procfs 42 | net.Ctx.Procfs = procfs 43 | 44 | proc.Ctx.Procfs = procfs 45 | ppid.Ctx.Procfs = procfs 46 | pnet.Ctx.Procfs = procfs 47 | } 48 | 49 | func setCORS() { 50 | beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{ 51 | AllowOrigins: []string{"*"}, 52 | AllowMethods: []string{"GET", "PUT", "PATCH"}, 53 | AllowHeaders: []string{"Origin"}, 54 | ExposeHeaders: []string{"Content-Length"}, 55 | AllowCredentials: true,})) 56 | } 57 | -------------------------------------------------------------------------------- /pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | ARCH=$1 6 | HOST_ARCH="" 7 | SUPP_ARCH="amd64 386 arm64 arm mips64 mips" 8 | VER=$(git tag | tail -n1) 9 | WS=$PWD 10 | 11 | get_host_arch() { 12 | ARCH_RAW=$(uname -m) 13 | if [ "$ARCH_RAW" = "x86_64" ]; then 14 | HOST_ARCH="amd64" 15 | elif [ "$ARCH_RAW" = "i386" ] || [ "$ARCH_RAW" = "i486" ] || [ "$ARCH_RAW" = "i586" ] || [ "$ARCH_RAW" = "i686" ]; then 16 | HOST_ARCH="386" 17 | elif [ "$ARCH_RAW" = "aarch64" ]; then 18 | HOST_ARCH="arm64" 19 | elif [ "$ARCH_RAW" = "armv6l" ] || [ "$ARCH_RAW" = "armv7l" ]; then 20 | HOST_ARCH="arm" 21 | else 22 | HOST_ARCH="unknown" 23 | fi 24 | } 25 | 26 | 27 | #cd web 28 | #npm install 29 | #npm run build 30 | #cd $WS 31 | 32 | build_binary_local() { 33 | echo "build binary with musl-gcc..." 34 | export CC="musl-gcc" 35 | go build -o sysmon -ldflags '-linkmode "external" -extldflags "-static"' 36 | } 37 | 38 | build_binary_cross() { 39 | echo "cross build binary for $arch ...." 40 | 41 | arch=$1 42 | export GOARCH="$arch" 43 | 44 | # only support building all ARCH on amd64 platform and installed docker 45 | if [ "$HOST_ARCH" = "amd64" ]; then 46 | if [ "$arch" = "arm" ] || [ "$arch" = "mips" ]; then 47 | docker run --rm -v $PWD:$PWD -e GOPATH="/vob/golang" -w $PWD -e GOARCH=$arch -it lightimehpq/golang-386 go build 48 | else 49 | go build 50 | fi 51 | fi 52 | } 53 | 54 | build_binary() { 55 | arch=$1 56 | if [ "$arch" = "$HOST_ARCH" ]; then 57 | build_binary_local 58 | else 59 | build_binary_cross $arch 60 | fi 61 | } 62 | 63 | pack() { 64 | echo "Packing..." 65 | arch=$1 66 | 67 | DST=$(mktemp -d) 68 | mkdir $DST/sysmon 69 | DST=$DST/sysmon 70 | cp -rf sysmon views conf web/dist install.sh etc $DST 71 | mkdir $DST/web 72 | mv $DST/dist $DST/web/ 73 | sed -i 's/runmode = dev/runmode = prod/g' $DST/conf/app.conf 74 | cd $DST/../ && tar Jcf $WS/sysmon-server-${arch}-${VER}.tar.xz * 75 | cd $WS 76 | } 77 | 78 | build_pack_all() { 79 | for arch in $SUPP_ARCH; do 80 | echo "###### Building all - $arch ######" 81 | build_binary $arch 82 | pack $arch 83 | done 84 | } 85 | 86 | get_host_arch 87 | if [ -z "$ARCH" ]; then 88 | build_binary $HOST_ARCH 89 | pack $HOST_ARCH 90 | elif [ "$ARCH" = "all" ]; then 91 | build_pack_all 92 | else 93 | build_binary $ARCH 94 | pack $ARCH 95 | fi 96 | -------------------------------------------------------------------------------- /routers/router.go: -------------------------------------------------------------------------------- 1 | // @APIVersion 1.0.0 2 | // @Title System Monitor API 3 | // @Description System Monitor API 4 | // @Contact lightimehpq@gmail.com 5 | package routers 6 | 7 | import ( 8 | "github.com/Lt0/sysmon/controllers" 9 | "github.com/astaxie/beego" 10 | ) 11 | 12 | func init() { 13 | beego.Router("/", &controllers.MainController{}) 14 | ns := beego.NewNamespace("/v1", 15 | beego.NSNamespace("/process", 16 | beego.NSInclude( 17 | &controllers.ProcessController{}, 18 | ), 19 | ), 20 | beego.NSNamespace("/info", 21 | beego.NSInclude( 22 | &controllers.InfoController{}, 23 | ), 24 | ), 25 | beego.NSNamespace("/sysInfo", 26 | beego.NSInclude( 27 | &controllers.SysInfoController{}, 28 | ), 29 | ), 30 | ) 31 | 32 | beego.AddNamespace(ns) 33 | } 34 | -------------------------------------------------------------------------------- /static/js/reload.min.js: -------------------------------------------------------------------------------- 1 | function b(a){var c=new WebSocket(a);c.onclose=function(){setTimeout(function(){b(a)},2E3)};c.onmessage=function(){location.reload()}}try{if(window.WebSocket)try{b("ws://localhost:12450/reload")}catch(a){console.error(a)}else console.log("Your browser does not support WebSockets.")}catch(a){console.error("Exception during connecting to Reload:",a)}; 2 | -------------------------------------------------------------------------------- /swagger/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/swagger/favicon-16x16.png -------------------------------------------------------------------------------- /swagger/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/swagger/favicon-32x32.png -------------------------------------------------------------------------------- /swagger/oauth2-redirect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 54 | -------------------------------------------------------------------------------- /swagger/swagger-ui-bundle.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AAyTA;;;;;;AAoIA;AAi7FA;AAmtCA;AAi0IA;AA0oJA;AAgwFA;AAyrGA;AA0lFA;AA4nFA;AA+9CA;AA+gDA;AAwrCA;AA60EA;;;;;AA6oCA;AAsyJA;;;;;;;;;;;;;;AA64EA;AA4mIA;AAquJA;AA2qHA;AA2mGA;AAiiEA;AAq4DA;AAg3DA;AAoPA;;;;;;AAk7FA;AA07FA;;;;;AAi8CA;AAgsFA;AAs2CA;AAglCA;AAu9CA;AAy8EA;AAsiCA;AA+yFA;;;;;;;;;AAgkDA;AA2zIA;AAu7FA;AAmrFA;AAu0EA","sourceRoot":""} -------------------------------------------------------------------------------- /swagger/swagger-ui-standalone-preset.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA8QA;AAmvGA;AAuxFA;;;;;;AAocA;AAkvFA;AAu+CA;AAo+CA;AAgrCA;AAuyEA","sourceRoot":""} -------------------------------------------------------------------------------- /swagger/swagger-ui.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"swagger-ui.css","sources":[],"mappings":"","sourceRoot":""} -------------------------------------------------------------------------------- /swagger/swagger-ui.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA0yCA;AAoyHA;AAmyHA;AAykGA;AA+9BA;AA6iCA;AAojCA;AAu5BA","sourceRoot":""} -------------------------------------------------------------------------------- /tests/default_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | "runtime" 8 | "path/filepath" 9 | _ "github.com/Lt0/sysmon/routers" 10 | 11 | "github.com/astaxie/beego" 12 | . "github.com/smartystreets/goconvey/convey" 13 | ) 14 | 15 | func init() { 16 | _, file, _, _ := runtime.Caller(1) 17 | apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".." + string(filepath.Separator)))) 18 | beego.TestBeegoInit(apppath) 19 | } 20 | 21 | 22 | // TestBeego is a sample to run an endpoint test 23 | func TestBeego(t *testing.T) { 24 | r, _ := http.NewRequest("GET", "/", nil) 25 | w := httptest.NewRecorder() 26 | beego.BeeApp.Handlers.ServeHTTP(w, r) 27 | 28 | beego.Trace("testing", "TestBeego", "Code[%d]\n%s", w.Code, w.Body.String()) 29 | 30 | Convey("Subject: Test Station Endpoint\n", t, func() { 31 | Convey("Status Code Should Be 200", func() { 32 | So(w.Code, ShouldEqual, 200) 33 | }) 34 | Convey("The Result Should Not Be Empty", func() { 35 | So(w.Body.Len(), ShouldBeGreaterThan, 0) 36 | }) 37 | }) 38 | } 39 | 40 | -------------------------------------------------------------------------------- /utils/proc/buddyinfo.go: -------------------------------------------------------------------------------- 1 | package proc 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | "path/filepath" 7 | "io/ioutil" 8 | ) 9 | 10 | type BuddyInfoInfo struct { 11 | Zones []BuddyInfoZone 12 | } 13 | 14 | type BuddyInfoZone struct { 15 | Node string 16 | Type string 17 | Pages []uint64 // Linux 通过 buddy 算法,把所有空闲的内存,以2的幂次方的形式,分成 11 个块链表, 18 | // 分别对应为 1、2、4、8、16、32、64、128、256、512、1024 个页块的链表(比如最后一个链表中记录的是所有可用的连续 1024 页的内存)。 19 | } 20 | 21 | func BuddyInfo() (BuddyInfoInfo, error) { 22 | var info BuddyInfoInfo 23 | 24 | buf, err := ioutil.ReadFile(filepath.Join(Ctx.Procfs, "buddyinfo")) 25 | if err != nil { 26 | return info, err 27 | } 28 | 29 | lines := strings.Split(string(buf), "\n") 30 | for _, s := range(lines) { 31 | var zone BuddyInfoZone 32 | vs := strings.Fields(s) 33 | if len(vs) < 15 { 34 | continue 35 | } 36 | 37 | zone.Node = vs[0] + " " + vs[1][:len(vs[1])-1] 38 | zone.Type = vs[3] 39 | zone.Pages = parseUint64List(vs[4:]) 40 | info.Zones = append(info.Zones, zone) 41 | } 42 | 43 | return info, nil 44 | } 45 | 46 | func parseUint64List(strs []string) []uint64 { 47 | var nums []uint64 48 | for _, v := range(strs) { 49 | num, _ := strconv.ParseUint(strings.TrimSpace(v), 10, 64) 50 | nums = append(nums, num) 51 | } 52 | return nums 53 | } -------------------------------------------------------------------------------- /utils/proc/extend.go: -------------------------------------------------------------------------------- 1 | package proc 2 | 3 | import ( 4 | "path/filepath" 5 | "os" 6 | "fmt" 7 | "strconv" 8 | ) 9 | 10 | // return all pids in Ctx.Procfs 11 | func AllPids() []string { 12 | return pids(Ctx.Procfs) 13 | } 14 | 15 | func AllThreadPids(pid string) []string { 16 | return pids(filepath.Join(Ctx.Procfs, pid, "task")) 17 | } 18 | 19 | func pids(path string) []string { 20 | p, err := os.Open(path) 21 | if err != nil { 22 | fmt.Println("can not open", path) 23 | return nil 24 | } 25 | 26 | defer p.Close() 27 | 28 | var files []string 29 | files, err = p.Readdirnames(0) 30 | if err != nil { 31 | fmt.Printf("Readdirnames %v failed\n", path) 32 | return nil 33 | } 34 | 35 | var pids []string 36 | for _, v := range(files) { 37 | if pid, _ := strconv.Atoi(v); pid != 0 { 38 | pids = append(pids, v) 39 | } 40 | } 41 | return pids 42 | } -------------------------------------------------------------------------------- /utils/proc/net/net.go: -------------------------------------------------------------------------------- 1 | // various net pseudo-files, all of which give the status of some part of the networking layer. 2 | // These files contain ASCII structures and are, therefore, readable with cat(1). 3 | // However, the standard netstat(8) suite provides much cleaner access to these files. 4 | package net 5 | 6 | 7 | var netfs = "net" 8 | 9 | type Context struct { 10 | Procfs string 11 | } 12 | var Ctx Context 13 | 14 | func init() { 15 | Ctx.Procfs = "/proc" 16 | } 17 | -------------------------------------------------------------------------------- /utils/proc/pid/autogroup.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func AutoGroupRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "autogroup")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/cgroup.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func CGroupRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "cgroup")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/cmdline.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "bufio" 7 | "path/filepath" 8 | "bytes" 9 | ) 10 | 11 | // comment for /proc/pid/cmdline 12 | // This read-only file holds the complete command line for the process, unless the process is a zombie. In the latter 13 | // case, there is nothing in this file: that is, a read on this file will return 0 characters. The command-line argu‐ 14 | // ments appear in this file as a set of strings separated by null bytes ('\0'), with a further null byte after the 15 | // last string. 16 | 17 | type CmdlineInfo struct { 18 | Cmdline string 19 | } 20 | 21 | func Cmdline(pid string) (CmdlineInfo, error) { 22 | var ci CmdlineInfo 23 | 24 | f, err := os.Open(filepath.Join(Ctx.Procfs, pid, "cmdline")) 25 | if err != nil { 26 | return ci, fmt.Errorf("Cmdline: open %v/%v/cmdline failed: %v\n", Ctx.Procfs, pid, err) 27 | } 28 | defer f.Close() 29 | 30 | r := bufio.NewReader(f) 31 | cmdline, _ := r.ReadBytes('\n') 32 | if len(cmdline) > 1 { 33 | cmdline := bytes.Replace(cmdline[:len(cmdline)-1], []byte{0}, []byte{' '}, -1) 34 | 35 | ci.Cmdline = string(cmdline) 36 | } 37 | 38 | return ci, nil 39 | } 40 | -------------------------------------------------------------------------------- /utils/proc/pid/cpuset.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func CPUSetRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "cpuset")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/cwd.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | func CWD(pid string) string { 10 | path, err := os.Readlink(filepath.Join(Ctx.Procfs, pid, "cwd")) 11 | if err != nil { 12 | return fmt.Sprint(err) 13 | } 14 | 15 | return path 16 | } -------------------------------------------------------------------------------- /utils/proc/pid/environ.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | "bytes" 7 | ) 8 | 9 | func EnvironRawData(pid string) string { 10 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "environ")) 11 | buf = bytes.Replace(buf, []byte{0}, []byte{'\n'}, -1) 12 | return string(buf) 13 | } -------------------------------------------------------------------------------- /utils/proc/pid/fd.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "path/filepath" 7 | ) 8 | 9 | type FDInfo struct { 10 | FDs []FDItem 11 | } 12 | 13 | type FDItem struct { 14 | Name string 15 | File string 16 | } 17 | 18 | func FD(pid string) FDInfo { 19 | var info FDInfo 20 | 21 | path := filepath.Join(Ctx.Procfs, pid, "fd") 22 | p, err := os.Open(path) 23 | if err != nil { 24 | fmt.Println("can not open", path) 25 | return info 26 | } 27 | 28 | defer p.Close() 29 | 30 | var files []string 31 | files, err = p.Readdirnames(0) 32 | if err != nil { 33 | fmt.Printf("Readdirnames %v failed\n", path) 34 | return info 35 | } 36 | 37 | for _, v := range(files) { 38 | var item FDItem 39 | item.Name = v 40 | file, err := os.Readlink(filepath.Join(path, v)) 41 | if err != nil { 42 | item.File = fmt.Sprint(err) 43 | } else { 44 | item.File = file 45 | } 46 | 47 | info.FDs = append(info.FDs, item) 48 | } 49 | 50 | return info 51 | } -------------------------------------------------------------------------------- /utils/proc/pid/gid_map.go: -------------------------------------------------------------------------------- 1 | // http://man7.org/linux/man-pages/man7/user_namespaces.7.html 2 | // 除了把 uid 改为 gid,所有地方和 uid_map 的相同 3 | package pid 4 | 5 | import ( 6 | "io/ioutil" 7 | "path/filepath" 8 | ) 9 | 10 | func GidMapRawData(pid string) string { 11 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "gid_map")) 12 | return string(buf) 13 | } -------------------------------------------------------------------------------- /utils/proc/pid/limits.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "bufio" 5 | // "fmt" 6 | "io" 7 | "io/ioutil" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | ) 12 | 13 | // containe all info of /proc/[pid]/statm 14 | type LimitsInfo struct { 15 | Limits []limitsItem 16 | } 17 | 18 | type limitsItem struct { 19 | Limit string 20 | SoftLimit string 21 | HardLimit string 22 | Units string 23 | } 24 | 25 | func Limits(pid string) (LimitsInfo, error) { 26 | var info LimitsInfo 27 | 28 | f, err := os.Open(filepath.Join(Ctx.Procfs, pid, "limits")) 29 | if err != nil { 30 | return info, err 31 | } 32 | defer f.Close() 33 | 34 | r := bufio.NewReader(f) 35 | for { 36 | b, err := r.ReadBytes('\n') 37 | if err == io.EOF { 38 | break 39 | } 40 | 41 | l := string(b) 42 | vs := strings.Fields(l) 43 | if vs[0] == "Limit" { 44 | continue 45 | } 46 | 47 | var item limitsItem 48 | item.Limit = strings.TrimSpace(l[:25]) 49 | item.SoftLimit = strings.TrimSpace(l[25:46]) 50 | item.HardLimit = strings.TrimSpace(l[46:67]) 51 | item.Units = strings.TrimSpace(l[67:]) 52 | info.Limits = append(info.Limits, item) 53 | } 54 | 55 | return info, nil 56 | } 57 | 58 | 59 | func LimitsRawData(pid string) string { 60 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "limits")) 61 | return string(buf) 62 | } -------------------------------------------------------------------------------- /utils/proc/pid/loginuid.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func LoginUidRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "loginuid")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/map_files.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "path/filepath" 7 | ) 8 | 9 | type MapFilesInfo struct { 10 | Mappings []MapFilesItem 11 | } 12 | 13 | type MapFilesItem struct { 14 | AddrRange string 15 | File string 16 | } 17 | 18 | func MapFiles(pid string) MapFilesInfo { 19 | var info MapFilesInfo 20 | 21 | path := filepath.Join(Ctx.Procfs, pid, "map_files") 22 | p, err := os.Open(path) 23 | if err != nil { 24 | fmt.Println("can not open", path) 25 | return info 26 | } 27 | 28 | defer p.Close() 29 | 30 | var files []string 31 | files, err = p.Readdirnames(0) 32 | if err != nil { 33 | fmt.Printf("Readdirnames %v failed\n", path) 34 | return info 35 | } 36 | 37 | for _, v := range(files) { 38 | var item MapFilesItem 39 | item.AddrRange = v 40 | file, err := os.Readlink(filepath.Join(path, v)) 41 | if err != nil { 42 | item.File = fmt.Sprint(err) 43 | } else { 44 | item.File = file 45 | } 46 | 47 | info.Mappings = append(info.Mappings, item) 48 | } 49 | 50 | return info 51 | } -------------------------------------------------------------------------------- /utils/proc/pid/mountinfo.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func MountInfoRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "mountinfo")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/mounts.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func MountsRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "mounts")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/mountstats.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func MountStatsRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "mountstats")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/oom_adj.go: -------------------------------------------------------------------------------- 1 | // This file can be used to adjust the score used to select which process should be killed in an out-of-memory (OOM) situation. 2 | // The kernel uses this value for a bit-shift operation of the process's oom_score value: 3 | // valid values are in the range -16 to +15, plus the special value -17, which disables OOM-killing altogether for this process. 4 | // A positive score increases the likelihood of this process being killed by the OOM-killer; a negative score decreases the likelihood. 5 | // The default value for this file is 0; a new process inherits its parent's oom_adj setting. A process must be privileged (CAP_SYS_RESOURCE) to update this file. 6 | // Since Linux 2.6.36, use of this file is deprecated in favor of /proc/[pid]/oom_score_adj. 7 | 8 | // 在内存不足(OOM)的情况下,系统根据各个进程的该文件的值来权衡要杀死的进程。 9 | // 内核使用这个进行进程的 oom_score 值的位移操作:有效值在 -16 到 +15 的范围内,再加上特殊值 -17,它会为此进程完全禁用OOM查杀。 10 | // 正分会增加这个过程被 OOM 杀手杀死的可能性; 负分数降低了可能性。 11 | // 该文件的默认值为0; 新进程继承其父进程的oom_adj设置。 进程必须具有特权(CAP_SYS_RESOURCE)才能更新此文件。 12 | // 从Linux 2.6.36开始,不推荐使用此文件,而使用/ proc / [pid] / oom_score_adj。 13 | package pid 14 | 15 | import ( 16 | "strconv" 17 | "path/filepath" 18 | "io/ioutil" 19 | ) 20 | 21 | func OOMAdj(pid string) int { 22 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "oom_adj")) 23 | score, _ := strconv.Atoi(string(buf)) 24 | return score 25 | } -------------------------------------------------------------------------------- /utils/proc/pid/oom_score.go: -------------------------------------------------------------------------------- 1 | // This file displays the current score that the kernel gives to this process for the purpose of selecting a process 2 | // for the OOM-killer. A higher score means that the process is more likely to be selected by the OOM-killer. The 3 | // basis for this score is the amount of memory used by the process, with increases (+) or decreases (-) for factors 4 | // including: 5 | // 6 | // * whether the process creates a lot of children using fork(2) (+); 7 | // 8 | // * whether the process has been running a long time, or has used a lot of CPU time (-); 9 | // 10 | // * whether the process has a low nice value (i.e., > 0) (+); 11 | // 12 | // * whether the process is privileged (-); and 13 | // 14 | // * whether the process is making direct hardware access (-). 15 | // 16 | // The oom_score also reflects the adjustment specified by the oom_score_adj or oom_adj setting for the process. 17 | 18 | 19 | // 此文件显示内核为此进程提供的当前分数,以便为OOM杀手选择进程。 得分越高意味着OOM杀手更有可能选择该过程。 此分数的取决于进程运行过程使用的内存量,决策因素如下: 20 | // 1. 该进程是否使用fork(2)(+)创建了很多子进程; 21 | // 2. 进程是否已运行很长时间,或者是否占用了大量CPU时间( - ); 22 | // 3. 该进程是否具有低的 nice 值(即> 0)(+); 23 | // 4. 流程是否具有特权( - ); 和 24 | // 5. 该进程是否进行直接硬件访问( - )。 25 | // oom_score还反映了进程的oom_score_adj或oom_adj设置指定的调整。 26 | 27 | package pid 28 | 29 | import ( 30 | "strconv" 31 | "path/filepath" 32 | "io/ioutil" 33 | ) 34 | 35 | func OOMScore(pid string) int { 36 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "oom_score")) 37 | score, _ := strconv.Atoi(string(buf)) 38 | return score 39 | } -------------------------------------------------------------------------------- /utils/proc/pid/personality.go: -------------------------------------------------------------------------------- 1 | // 该只读文件公开进程的执行域,由 personality(2) 设置。 该值以十六进制表示法显示。 2 | // 访问该文件的权限由 ptrace 访问模式 PTRACE_MODE_ATTACH_FSCREDS 检查控制; 见ptrace(2)。 3 | package pid 4 | 5 | import ( 6 | "io/ioutil" 7 | "path/filepath" 8 | ) 9 | 10 | func PersonalityRawData(pid string) string { 11 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "personality")) 12 | return string(buf) 13 | } -------------------------------------------------------------------------------- /utils/proc/pid/pid.go: -------------------------------------------------------------------------------- 1 | // There is a numerical subdirectory for each running process; the subdirectory is named by the process ID. 2 | // Each such subdirectory contains the following pseudo-files and directories. 3 | package pid 4 | 5 | type Context struct { 6 | Procfs string // proc filesystem mount point, default is /proc 7 | } 8 | var Ctx Context 9 | 10 | func init() { 11 | Ctx.Procfs = "/proc" 12 | } -------------------------------------------------------------------------------- /utils/proc/pid/projid_map.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func ProjidMapRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "projid_map")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/schedstat.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "strconv" 5 | "fmt" 6 | "io/ioutil" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | type SchedStatInfo struct { 12 | SumExecRuntime uint64 // time spent on the cpu, task->se.sum_exec_runtime, 累计运行的物理时间时间, se.sum_exec_runtime 13 | WaitSum uint64 // io 等待时间, se.wait_sum 14 | Switches uint64 // 主动切换和被动切换的累计次数, se->nr_switches 15 | } 16 | 17 | func SchedStat(pid string) (SchedStatInfo, error) { 18 | var info SchedStatInfo 19 | 20 | buf, err := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "schedstat")) 21 | if err != nil { 22 | return info, err 23 | } 24 | 25 | vs := strings.Fields(string(buf)) 26 | if len(vs) < 3 { 27 | return info, fmt.Errorf("invalid schedstat file: %v\n", string(buf)) 28 | } 29 | 30 | info.SumExecRuntime, _ = strconv.ParseUint(vs[0], 10, 64) 31 | info.WaitSum, _ = strconv.ParseUint(vs[1], 10, 64) 32 | info.Switches, _ = strconv.ParseUint(strings.TrimSpace(vs[2]), 10, 64) 33 | 34 | return info, nil 35 | } -------------------------------------------------------------------------------- /utils/proc/pid/sessionid.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func SessionIDRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "sessionid")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/setgroups.go: -------------------------------------------------------------------------------- 1 | // allow: 允许包含进程pid的用户命名空间中的进程使用setgroups(2)系统调用 2 | // deny: 在该用户命名空间中不允许setgroups(2) 3 | // 请注意,如果没有设置 /proc/[pid]/gid_map,则无论该文件的值是什么,都不允许调用setgroups(2) 4 | package pid 5 | 6 | import ( 7 | "io/ioutil" 8 | "path/filepath" 9 | ) 10 | 11 | func SetGroupRawData(pid string) string { 12 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "setgroups")) 13 | return string(buf) 14 | } -------------------------------------------------------------------------------- /utils/proc/pid/stack.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "path/filepath" 9 | "strings" 10 | ) 11 | 12 | // containe all info of /proc/[pid]/statm 13 | type StackInfo struct { 14 | Stacks []stackItem 15 | } 16 | 17 | type stackItem struct { 18 | Address string 19 | Name string 20 | } 21 | 22 | func Stack(pid string) (StackInfo, error) { 23 | var info StackInfo 24 | 25 | f, err := os.Open(filepath.Join(Ctx.Procfs, pid, "stack")) 26 | if err != nil { 27 | return info, err 28 | } 29 | defer f.Close() 30 | 31 | r := bufio.NewReader(f) 32 | for { 33 | b, err := r.ReadBytes('\n') 34 | if err == io.EOF { 35 | break 36 | } 37 | 38 | l := string(b) 39 | vs := strings.Fields(l) 40 | 41 | if len(vs) < 2 { 42 | return info, fmt.Errorf("Invalid string slice: %v\n", vs) 43 | } 44 | 45 | var item stackItem 46 | item.Address = vs[0] 47 | item.Address = item.Address[2:len(item.Address)-2] 48 | item.Name = vs[1] 49 | info.Stacks = append(info.Stacks, item) 50 | } 51 | 52 | return info, nil 53 | } -------------------------------------------------------------------------------- /utils/proc/pid/statm.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "strconv" 5 | "bufio" 6 | "fmt" 7 | "io" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | ) 12 | 13 | // containe all info of /proc/[pid]/statm 14 | type StatmInfo struct { 15 | // 1. total program size (same as VmSize in /proc/[pid]/status) 16 | Size uint64 17 | 18 | // 2. resident set size (same as VmRSS in /proc/[pid]/status) 19 | Resident uint64 20 | 21 | // 3. shared pages (i.e., backed by a file) 22 | Share uint64 23 | 24 | // 4. text (code) 25 | Text uint64 26 | 27 | // 5. library (unused in Linux 2.6) 28 | Lib uint64 29 | 30 | // 6. data + stack 31 | Data uint64 32 | 33 | // 7. dirty pages (unused in Linux 2.6) 34 | Dt uint64 35 | } 36 | 37 | // get statm info from /proc/[pid]/statm. 38 | func Statm(pid string) (StatmInfo, error) { 39 | var statm StatmInfo 40 | 41 | f, err := os.Open(filepath.Join(Ctx.Procfs, pid, "statm")) 42 | if err != nil { 43 | return statm, fmt.Errorf("Statm: Open %v/%v/statm failed: %v\n", Ctx.Procfs, pid, err) 44 | } 45 | defer f.Close() 46 | 47 | r := bufio.NewReader(f) 48 | for i := 1; ; i++ { 49 | b, err := r.ReadBytes(' ') 50 | if err == io.EOF { 51 | break 52 | } 53 | s := strings.TrimSpace(string(b)) 54 | 55 | switch i { 56 | case 1: 57 | statm.Size, _ = strconv.ParseUint(s, 10, 64) 58 | case 2: 59 | statm.Resident, _ = strconv.ParseUint(s, 10, 64) 60 | case 3: 61 | statm.Share, _ = strconv.ParseUint(s, 10, 64) 62 | case 4: 63 | statm.Text, _ = strconv.ParseUint(s, 10, 64) 64 | case 5: 65 | statm.Lib, _ = strconv.ParseUint(s, 10, 64) 66 | case 6: 67 | statm.Data, _ = strconv.ParseUint(s, 10, 64) 68 | case 7: 69 | statm.Dt, _ = strconv.ParseUint(s, 10, 64) 70 | default: 71 | // fmt.Println("unknow value in statm:", s) 72 | } 73 | } 74 | 75 | return statm, nil 76 | } 77 | -------------------------------------------------------------------------------- /utils/proc/pid/syscall.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | ) 7 | 8 | func SyscallRawData(pid string) string { 9 | buf, _ := ioutil.ReadFile(filepath.Join(Ctx.Procfs, pid, "syscall")) 10 | return string(buf) 11 | } -------------------------------------------------------------------------------- /utils/proc/pid/task.go: -------------------------------------------------------------------------------- 1 | package pid 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "path/filepath" 7 | ) 8 | 9 | type TaskInfo []string 10 | 11 | func Task(pid string) TaskInfo { 12 | t, err := os.Open(filepath.Join(Ctx.Procfs, pid, "task")) 13 | if err != nil { 14 | fmt.Println("can not open", Ctx.Procfs) 15 | return nil 16 | } 17 | 18 | defer t.Close() 19 | 20 | var tasks TaskInfo 21 | tasks, err = t.Readdirnames(0) 22 | if err != nil { 23 | fmt.Println("Readdirnames failed") 24 | return nil 25 | } 26 | return tasks 27 | } -------------------------------------------------------------------------------- /utils/proc/proc.go: -------------------------------------------------------------------------------- 1 | // The proc filesystem is a pseudo-filesystem which provides an interface to kernel data structures. 2 | // It is commonly mounted at /proc. Most of it is read-only, but some files allow kernel variables to be changed. 3 | package proc 4 | 5 | import ( 6 | //"fmt" 7 | ) 8 | 9 | type Context struct { 10 | Procfs string 11 | } 12 | var Ctx Context 13 | 14 | func init() { 15 | Ctx.Procfs = "/proc" 16 | } 17 | -------------------------------------------------------------------------------- /utils/proc/uptime.go: -------------------------------------------------------------------------------- 1 | package proc 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "bufio" 7 | "strings" 8 | "strconv" 9 | "path/filepath" 10 | ) 11 | 12 | type UpTimeInfo struct { 13 | Uptime float64 // the uptime of the system (seconds) 14 | IdleTime float64 // the amount of time spent in idle process (seconds) 15 | } 16 | 17 | func UpTime() (UpTimeInfo, error) { 18 | var ut UpTimeInfo 19 | f, err := os.Open(filepath.Join(Ctx.Procfs, "uptime")) 20 | if err != nil { 21 | return ut, err 22 | } 23 | defer f.Close() 24 | 25 | r := bufio.NewReader(f) 26 | b, _ := r.ReadBytes('\n') 27 | s := strings.TrimSpace(string(b)) 28 | vs := strings.Split(s, " ") 29 | if len(vs) < 2 { 30 | return ut, fmt.Errorf("splited strings read from %v/uptime incorrect. len(vs): %v\n", Ctx.Procfs, len(vs)) 31 | } 32 | ut.Uptime, err = strconv.ParseFloat(vs[0], 10) 33 | if err != nil { 34 | return ut, err 35 | } 36 | 37 | ut.IdleTime, err = strconv.ParseFloat(vs[1], 10) 38 | if err != nil { 39 | return ut, err 40 | } 41 | return ut, nil 42 | } -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/.github/ISSUE_TEMPLATE: -------------------------------------------------------------------------------- 1 | Please answer these questions before submitting your issue. Thanks! 2 | 3 | 1. What version of Go and beego are you using (`bee version`)? 4 | 5 | 6 | 2. What operating system and processor architecture are you using (`go env`)? 7 | 8 | 9 | 3. What did you do? 10 | If possible, provide a recipe for reproducing the error. 11 | A complete runnable program is good. 12 | 13 | 14 | 4. What did you expect to see? 15 | 16 | 17 | 5. What did you see instead? -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | .DS_Store 4 | *.swp 5 | *.swo 6 | beego.iml 7 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/.gosimpleignore: -------------------------------------------------------------------------------- 1 | github.com/astaxie/beego/*/*:S1012 2 | github.com/astaxie/beego/*:S1012 3 | github.com/astaxie/beego/*/*:S1007 4 | github.com/astaxie/beego/*:S1007 -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.7.5 5 | - 1.8.5 6 | - 1.9.2 7 | services: 8 | - redis-server 9 | - mysql 10 | - postgresql 11 | - memcached 12 | env: 13 | - ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db 14 | - ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable" 15 | before_install: 16 | - git clone git://github.com/ideawu/ssdb.git 17 | - cd ssdb 18 | - make 19 | - cd .. 20 | install: 21 | - go get github.com/lib/pq 22 | - go get github.com/go-sql-driver/mysql 23 | - go get github.com/mattn/go-sqlite3 24 | - go get github.com/bradfitz/gomemcache/memcache 25 | - go get github.com/garyburd/redigo/redis 26 | - go get github.com/beego/x2j 27 | - go get github.com/couchbase/go-couchbase 28 | - go get github.com/beego/goyaml2 29 | - go get github.com/belogik/goes 30 | - go get github.com/siddontang/ledisdb/config 31 | - go get github.com/siddontang/ledisdb/ledis 32 | - go get github.com/ssdb/gossdb/ssdb 33 | - go get github.com/cloudflare/golz4 34 | - go get github.com/gogo/protobuf/proto 35 | - go get github.com/Knetic/govaluate 36 | - go get github.com/casbin/casbin 37 | - go get -u honnef.co/go/tools/cmd/gosimple 38 | - go get -u github.com/mdempsky/unconvert 39 | - go get -u github.com/gordonklaus/ineffassign 40 | - go get -u github.com/golang/lint/golint 41 | before_script: 42 | - psql --version 43 | - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi" 44 | - sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi" 45 | - sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi" 46 | - sh -c "if [ $(go version) == *1.[5-9]* ]; then go get github.com/golang/lint/golint; golint ./...; fi" 47 | - sh -c "if [ $(go version) == *1.[5-9]* ]; then go tool vet .; fi" 48 | - mkdir -p res/var 49 | - ./ssdb/ssdb-server ./ssdb/ssdb.conf -d 50 | after_script: 51 | -killall -w ssdb-server 52 | - rm -rf ./res/var/* 53 | script: 54 | - go test -v ./... 55 | - gosimple -ignore "$(cat .gosimpleignore)" $(go list ./... | grep -v /vendor/) 56 | - unconvert $(go list ./... | grep -v /vendor/) 57 | - ineffassign . 58 | - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s 59 | - golint ./... 60 | addons: 61 | postgresql: "9.4" 62 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to beego 2 | 3 | beego is an open source project. 4 | 5 | It is the work of hundreds of contributors. We appreciate your help! 6 | 7 | Here are instructions to get you started. They are probably not perfect, 8 | please let us know if anything feels wrong or incomplete. 9 | 10 | ## Contribution guidelines 11 | 12 | ### Pull requests 13 | 14 | First of all. beego follow the gitflow. So please send you pull request 15 | to **develop** branch. We will close the pull request to master branch. 16 | 17 | We are always happy to receive pull requests, and do our best to 18 | review them as fast as possible. Not sure if that typo is worth a pull 19 | request? Do it! We will appreciate it. 20 | 21 | If your pull request is not accepted on the first try, don't be 22 | discouraged! Sometimes we can make a mistake, please do more explaining 23 | for us. We will appreciate it. 24 | 25 | We're trying very hard to keep beego simple and fast. We don't want it 26 | to do everything for everybody. This means that we might decide against 27 | incorporating a new feature. But we will give you some advice on how to 28 | do it in other way. 29 | 30 | ### Create issues 31 | 32 | Any significant improvement should be documented as [a GitHub 33 | issue](https://github.com/astaxie/beego/issues) before anybody 34 | starts working on it. 35 | 36 | Also when filing an issue, make sure to answer these five questions: 37 | 38 | - What version of beego are you using (bee version)? 39 | - What operating system and processor architecture are you using? 40 | - What did you do? 41 | - What did you expect to see? 42 | - What did you see instead? 43 | 44 | ### but check existing issues and docs first! 45 | 46 | Please take a moment to check that an issue doesn't already exist 47 | documenting your bug report or improvement proposal. If it does, it 48 | never hurts to add a quick "+1" or "I have this problem too". This will 49 | help prioritize the most common problems and requests. 50 | 51 | Also if you don't know how to use it. please make sure you have read though 52 | the docs in http://beego.me/docs -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014 astaxie 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/README.md: -------------------------------------------------------------------------------- 1 | # Beego [![Build Status](https://travis-ci.org/astaxie/beego.svg?branch=master)](https://travis-ci.org/astaxie/beego) [![GoDoc](http://godoc.org/github.com/astaxie/beego?status.svg)](http://godoc.org/github.com/astaxie/beego) [![Foundation](https://img.shields.io/badge/Golang-Foundation-green.svg)](http://golangfoundation.org) [![Go Report Card](https://goreportcard.com/badge/github.com/astaxie/beego)](https://goreportcard.com/report/github.com/astaxie/beego) 2 | 3 | 4 | beego is used for rapid development of RESTful APIs, web apps and backend services in Go. 5 | It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct embedding. 6 | 7 | ###### More info at [beego.me](http://beego.me). 8 | 9 | ## Quick Start 10 | 11 | #### Download and install 12 | 13 | go get github.com/astaxie/beego 14 | 15 | #### Create file `hello.go` 16 | ```go 17 | package main 18 | 19 | import "github.com/astaxie/beego" 20 | 21 | func main(){ 22 | beego.Run() 23 | } 24 | ``` 25 | #### Build and run 26 | 27 | go build hello.go 28 | ./hello 29 | 30 | #### Go to [http://localhost:8080](http://localhost:8080) 31 | 32 | Congratulations! You've just built your first **beego** app. 33 | 34 | ###### Please see [Documentation](http://beego.me/docs) for more. 35 | 36 | ## Features 37 | 38 | * RESTful support 39 | * MVC architecture 40 | * Modularity 41 | * Auto API documents 42 | * Annotation router 43 | * Namespace 44 | * Powerful development tools 45 | * Full stack for Web & API 46 | 47 | ## Documentation 48 | 49 | * [English](http://beego.me/docs/intro/) 50 | * [中文文档](http://beego.me/docs/intro/) 51 | * [Русский](http://beego.me/docs/intro/) 52 | 53 | ## Community 54 | 55 | * [http://beego.me/community](http://beego.me/community) 56 | * Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited from [here](https://github.com/beego/beedoc/issues/232) 57 | 58 | ## License 59 | 60 | beego source code is licensed under the Apache Licence, Version 2.0 61 | (http://www.apache.org/licenses/LICENSE-2.0.html). 62 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/cache/README.md: -------------------------------------------------------------------------------- 1 | ## cache 2 | cache is a Go cache manager. It can use many cache adapters. The repo is inspired by `database/sql` . 3 | 4 | 5 | ## How to install? 6 | 7 | go get github.com/astaxie/beego/cache 8 | 9 | 10 | ## What adapters are supported? 11 | 12 | As of now this cache support memory, Memcache and Redis. 13 | 14 | 15 | ## How to use it? 16 | 17 | First you must import it 18 | 19 | import ( 20 | "github.com/astaxie/beego/cache" 21 | ) 22 | 23 | Then init a Cache (example with memory adapter) 24 | 25 | bm, err := cache.NewCache("memory", `{"interval":60}`) 26 | 27 | Use it like this: 28 | 29 | bm.Put("astaxie", 1, 10 * time.Second) 30 | bm.Get("astaxie") 31 | bm.IsExist("astaxie") 32 | bm.Delete("astaxie") 33 | 34 | 35 | ## Memory adapter 36 | 37 | Configure memory adapter like this: 38 | 39 | {"interval":60} 40 | 41 | interval means the gc time. The cache will check at each time interval, whether item has expired. 42 | 43 | 44 | ## Memcache adapter 45 | 46 | Memcache adapter use the [gomemcache](http://github.com/bradfitz/gomemcache) client. 47 | 48 | Configure like this: 49 | 50 | {"conn":"127.0.0.1:11211"} 51 | 52 | 53 | ## Redis adapter 54 | 55 | Redis adapter use the [redigo](http://github.com/garyburd/redigo) client. 56 | 57 | Configure like this: 58 | 59 | {"conn":":6039"} 60 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/config/config_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package config 16 | 17 | import ( 18 | "os" 19 | "testing" 20 | ) 21 | 22 | func TestExpandValueEnv(t *testing.T) { 23 | 24 | testCases := []struct { 25 | item string 26 | want string 27 | }{ 28 | {"", ""}, 29 | {"$", "$"}, 30 | {"{", "{"}, 31 | {"{}", "{}"}, 32 | {"${}", ""}, 33 | {"${|}", ""}, 34 | {"${}", ""}, 35 | {"${{}}", ""}, 36 | {"${{||}}", "}"}, 37 | {"${pwd||}", ""}, 38 | {"${pwd||}", ""}, 39 | {"${pwd||}", ""}, 40 | {"${pwd||}}", "}"}, 41 | {"${pwd||{{||}}}", "{{||}}"}, 42 | {"${GOPATH}", os.Getenv("GOPATH")}, 43 | {"${GOPATH||}", os.Getenv("GOPATH")}, 44 | {"${GOPATH||root}", os.Getenv("GOPATH")}, 45 | {"${GOPATH_NOT||root}", "root"}, 46 | {"${GOPATH_NOT||||root}", "||root"}, 47 | } 48 | 49 | for _, c := range testCases { 50 | if got := ExpandValueEnv(c.item); got != c.want { 51 | t.Errorf("expand value error, item %q want %q, got %q", c.item, c.want, got) 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/config/env/env_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // Copyright 2017 Faissal Elamraoui. All Rights Reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | package env 16 | 17 | import ( 18 | "os" 19 | "testing" 20 | ) 21 | 22 | func TestEnvGet(t *testing.T) { 23 | gopath := Get("GOPATH", "") 24 | if gopath != os.Getenv("GOPATH") { 25 | t.Error("expected GOPATH not empty.") 26 | } 27 | 28 | noExistVar := Get("NOEXISTVAR", "foo") 29 | if noExistVar != "foo" { 30 | t.Errorf("expected NOEXISTVAR to equal foo, got %s.", noExistVar) 31 | } 32 | } 33 | 34 | func TestEnvMustGet(t *testing.T) { 35 | gopath, err := MustGet("GOPATH") 36 | if err != nil { 37 | t.Error(err) 38 | } 39 | 40 | if gopath != os.Getenv("GOPATH") { 41 | t.Errorf("expected GOPATH to be the same, got %s.", gopath) 42 | } 43 | 44 | _, err = MustGet("NOEXISTVAR") 45 | if err == nil { 46 | t.Error("expected error to be non-nil") 47 | } 48 | } 49 | 50 | func TestEnvSet(t *testing.T) { 51 | Set("MYVAR", "foo") 52 | myVar := Get("MYVAR", "bar") 53 | if myVar != "foo" { 54 | t.Errorf("expected MYVAR to equal foo, got %s.", myVar) 55 | } 56 | } 57 | 58 | func TestEnvMustSet(t *testing.T) { 59 | err := MustSet("FOO", "bar") 60 | if err != nil { 61 | t.Error(err) 62 | } 63 | 64 | fooVar := os.Getenv("FOO") 65 | if fooVar != "bar" { 66 | t.Errorf("expected FOO variable to equal bar, got %s.", fooVar) 67 | } 68 | } 69 | 70 | func TestEnvGetAll(t *testing.T) { 71 | envMap := GetAll() 72 | if len(envMap) == 0 { 73 | t.Error("expected environment not empty.") 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/context/context_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package context 16 | 17 | import ( 18 | "net/http" 19 | "net/http/httptest" 20 | "testing" 21 | ) 22 | 23 | func TestXsrfReset_01(t *testing.T) { 24 | r := &http.Request{} 25 | c := NewContext() 26 | c.Request = r 27 | c.ResponseWriter = &Response{} 28 | c.ResponseWriter.reset(httptest.NewRecorder()) 29 | c.Output.Reset(c) 30 | c.Input.Reset(c) 31 | c.XSRFToken("key", 16) 32 | if c._xsrfToken == "" { 33 | t.FailNow() 34 | } 35 | token := c._xsrfToken 36 | c.Reset(&Response{ResponseWriter: httptest.NewRecorder()}, r) 37 | if c._xsrfToken != "" { 38 | t.FailNow() 39 | } 40 | c.XSRFToken("key", 16) 41 | if c._xsrfToken == "" { 42 | t.FailNow() 43 | } 44 | if token == c._xsrfToken { 45 | t.FailNow() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/context/param/methodparams.go: -------------------------------------------------------------------------------- 1 | package param 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | //MethodParam keeps param information to be auto passed to controller methods 9 | type MethodParam struct { 10 | name string 11 | in paramType 12 | required bool 13 | defaultValue string 14 | } 15 | 16 | type paramType byte 17 | 18 | const ( 19 | param paramType = iota 20 | path 21 | body 22 | header 23 | ) 24 | 25 | //New creates a new MethodParam with name and specific options 26 | func New(name string, opts ...MethodParamOption) *MethodParam { 27 | return newParam(name, nil, opts) 28 | } 29 | 30 | func newParam(name string, parser paramParser, opts []MethodParamOption) (param *MethodParam) { 31 | param = &MethodParam{name: name} 32 | for _, option := range opts { 33 | option(param) 34 | } 35 | return 36 | } 37 | 38 | //Make creates an array of MethodParmas or an empty array 39 | func Make(list ...*MethodParam) []*MethodParam { 40 | if len(list) > 0 { 41 | return list 42 | } 43 | return nil 44 | } 45 | 46 | func (mp *MethodParam) String() string { 47 | options := []string{} 48 | result := "param.New(\"" + mp.name + "\"" 49 | if mp.required { 50 | options = append(options, "param.IsRequired") 51 | } 52 | switch mp.in { 53 | case path: 54 | options = append(options, "param.InPath") 55 | case body: 56 | options = append(options, "param.InBody") 57 | case header: 58 | options = append(options, "param.InHeader") 59 | } 60 | if mp.defaultValue != "" { 61 | options = append(options, fmt.Sprintf(`param.Default("%s")`, mp.defaultValue)) 62 | } 63 | if len(options) > 0 { 64 | result += ", " 65 | } 66 | result += strings.Join(options, ", ") 67 | result += ")" 68 | return result 69 | } 70 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/context/param/options.go: -------------------------------------------------------------------------------- 1 | package param 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // MethodParamOption defines a func which apply options on a MethodParam 8 | type MethodParamOption func(*MethodParam) 9 | 10 | // IsRequired indicates that this param is required and can not be omitted from the http request 11 | var IsRequired MethodParamOption = func(p *MethodParam) { 12 | p.required = true 13 | } 14 | 15 | // InHeader indicates that this param is passed via an http header 16 | var InHeader MethodParamOption = func(p *MethodParam) { 17 | p.in = header 18 | } 19 | 20 | // InPath indicates that this param is part of the URL path 21 | var InPath MethodParamOption = func(p *MethodParam) { 22 | p.in = path 23 | } 24 | 25 | // InBody indicates that this param is passed as an http request body 26 | var InBody MethodParamOption = func(p *MethodParam) { 27 | p.in = body 28 | } 29 | 30 | // Default provides a default value for the http param 31 | func Default(defaultValue interface{}) MethodParamOption { 32 | return func(p *MethodParam) { 33 | if defaultValue != nil { 34 | p.defaultValue = fmt.Sprint(defaultValue) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/context/renderer.go: -------------------------------------------------------------------------------- 1 | package context 2 | 3 | // Renderer defines an http response renderer 4 | type Renderer interface { 5 | Render(ctx *Context) 6 | } 7 | 8 | type rendererFunc func(ctx *Context) 9 | 10 | func (f rendererFunc) Render(ctx *Context) { 11 | f(ctx) 12 | } 13 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/context/response.go: -------------------------------------------------------------------------------- 1 | package context 2 | 3 | import ( 4 | "strconv" 5 | 6 | "net/http" 7 | ) 8 | 9 | const ( 10 | //BadRequest indicates http error 400 11 | BadRequest StatusCode = http.StatusBadRequest 12 | 13 | //NotFound indicates http error 404 14 | NotFound StatusCode = http.StatusNotFound 15 | ) 16 | 17 | // StatusCode sets the http response status code 18 | type StatusCode int 19 | 20 | func (s StatusCode) Error() string { 21 | return strconv.Itoa(int(s)) 22 | } 23 | 24 | // Render sets the http status code 25 | func (s StatusCode) Render(ctx *Context) { 26 | ctx.Output.SetStatus(int(s)) 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package beego provide a MVC framework 3 | beego: an open-source, high-performance, modular, full-stack web framework 4 | 5 | It is used for rapid development of RESTful APIs, web apps and backend services in Go. 6 | beego is inspired by Tornado, Sinatra and Flask with the added benefit of some Go-specific features such as interfaces and struct embedding. 7 | 8 | package main 9 | import "github.com/astaxie/beego" 10 | 11 | func main() { 12 | beego.Run() 13 | } 14 | 15 | more information: http://beego.me 16 | */ 17 | package beego 18 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/filter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package beego 16 | 17 | import "github.com/astaxie/beego/context" 18 | 19 | // FilterFunc defines a filter function which is invoked before the controller handler is executed. 20 | type FilterFunc func(*context.Context) 21 | 22 | // FilterRouter defines a filter operation which is invoked before the controller handler is executed. 23 | // It can match the URL against a pattern, and execute a filter function 24 | // when a request with a matching URL arrives. 25 | type FilterRouter struct { 26 | filterFunc FilterFunc 27 | tree *Tree 28 | pattern string 29 | returnOnOutput bool 30 | resetParams bool 31 | } 32 | 33 | // ValidRouter checks if the current request is matched by this filter. 34 | // If the request is matched, the values of the URL parameters defined 35 | // by the filter pattern are also returned. 36 | func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool { 37 | isOk := f.tree.Match(url, ctx) 38 | if isOk != nil { 39 | if b, ok := isOk.(bool); ok { 40 | return b 41 | } 42 | } 43 | return false 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/filter_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package beego 16 | 17 | import ( 18 | "net/http" 19 | "net/http/httptest" 20 | "testing" 21 | 22 | "github.com/astaxie/beego/context" 23 | ) 24 | 25 | var FilterUser = func(ctx *context.Context) { 26 | ctx.Output.Body([]byte("i am " + ctx.Input.Param(":last") + ctx.Input.Param(":first"))) 27 | } 28 | 29 | func TestFilter(t *testing.T) { 30 | r, _ := http.NewRequest("GET", "/person/asta/Xie", nil) 31 | w := httptest.NewRecorder() 32 | handler := NewControllerRegister() 33 | handler.InsertFilter("/person/:last/:first", BeforeRouter, FilterUser) 34 | handler.Add("/person/:last/:first", &TestController{}) 35 | handler.ServeHTTP(w, r) 36 | if w.Body.String() != "i am astaXie" { 37 | t.Errorf("user define func can't run") 38 | } 39 | } 40 | 41 | var FilterAdminUser = func(ctx *context.Context) { 42 | ctx.Output.Body([]byte("i am admin")) 43 | } 44 | 45 | // Filter pattern /admin/:all 46 | // all url like /admin/ /admin/xie will all get filter 47 | 48 | func TestPatternTwo(t *testing.T) { 49 | r, _ := http.NewRequest("GET", "/admin/", nil) 50 | w := httptest.NewRecorder() 51 | handler := NewControllerRegister() 52 | handler.InsertFilter("/admin/?:all", BeforeRouter, FilterAdminUser) 53 | handler.ServeHTTP(w, r) 54 | if w.Body.String() != "i am admin" { 55 | t.Errorf("filter /admin/ can't run") 56 | } 57 | } 58 | 59 | func TestPatternThree(t *testing.T) { 60 | r, _ := http.NewRequest("GET", "/admin/astaxie", nil) 61 | w := httptest.NewRecorder() 62 | handler := NewControllerRegister() 63 | handler.InsertFilter("/admin/:all", BeforeRouter, FilterAdminUser) 64 | handler.ServeHTTP(w, r) 65 | if w.Body.String() != "i am admin" { 66 | t.Errorf("filter /admin/astaxie can't run") 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/flash_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package beego 16 | 17 | import ( 18 | "net/http" 19 | "net/http/httptest" 20 | "strings" 21 | "testing" 22 | ) 23 | 24 | type TestFlashController struct { 25 | Controller 26 | } 27 | 28 | func (t *TestFlashController) TestWriteFlash() { 29 | flash := NewFlash() 30 | flash.Notice("TestFlashString") 31 | flash.Store(&t.Controller) 32 | // we choose to serve json because we don't want to load a template html file 33 | t.ServeJSON(true) 34 | } 35 | 36 | func TestFlashHeader(t *testing.T) { 37 | // create fake GET request 38 | r, _ := http.NewRequest("GET", "/", nil) 39 | w := httptest.NewRecorder() 40 | 41 | // setup the handler 42 | handler := NewControllerRegister() 43 | handler.Add("/", &TestFlashController{}, "get:TestWriteFlash") 44 | handler.ServeHTTP(w, r) 45 | 46 | // get the Set-Cookie value 47 | sc := w.Header().Get("Set-Cookie") 48 | // match for the expected header 49 | res := strings.Contains(sc, "BEEGO_FLASH=%00notice%23BEEGOFLASH%23TestFlashString%00") 50 | // validate the assertion 51 | if !res { 52 | t.Errorf("TestFlashHeader() unable to validate flash message") 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/grace/conn.go: -------------------------------------------------------------------------------- 1 | package grace 2 | 3 | import ( 4 | "errors" 5 | "net" 6 | "sync" 7 | ) 8 | 9 | type graceConn struct { 10 | net.Conn 11 | server *Server 12 | m sync.Mutex 13 | closed bool 14 | } 15 | 16 | func (c *graceConn) Close() (err error) { 17 | defer func() { 18 | if r := recover(); r != nil { 19 | switch x := r.(type) { 20 | case string: 21 | err = errors.New(x) 22 | case error: 23 | err = x 24 | default: 25 | err = errors.New("Unknown panic") 26 | } 27 | } 28 | }() 29 | 30 | c.m.Lock() 31 | if c.closed { 32 | c.m.Unlock() 33 | return 34 | } 35 | c.server.wg.Done() 36 | c.closed = true 37 | c.m.Unlock() 38 | return c.Conn.Close() 39 | } 40 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/grace/listener.go: -------------------------------------------------------------------------------- 1 | package grace 2 | 3 | import ( 4 | "net" 5 | "os" 6 | "syscall" 7 | "time" 8 | ) 9 | 10 | type graceListener struct { 11 | net.Listener 12 | stop chan error 13 | stopped bool 14 | server *Server 15 | } 16 | 17 | func newGraceListener(l net.Listener, srv *Server) (el *graceListener) { 18 | el = &graceListener{ 19 | Listener: l, 20 | stop: make(chan error), 21 | server: srv, 22 | } 23 | go func() { 24 | <-el.stop 25 | el.stopped = true 26 | el.stop <- el.Listener.Close() 27 | }() 28 | return 29 | } 30 | 31 | func (gl *graceListener) Accept() (c net.Conn, err error) { 32 | tc, err := gl.Listener.(*net.TCPListener).AcceptTCP() 33 | if err != nil { 34 | return 35 | } 36 | 37 | tc.SetKeepAlive(true) 38 | tc.SetKeepAlivePeriod(3 * time.Minute) 39 | 40 | c = &graceConn{ 41 | Conn: tc, 42 | server: gl.server, 43 | } 44 | 45 | gl.server.wg.Add(1) 46 | return 47 | } 48 | 49 | func (gl *graceListener) Close() error { 50 | if gl.stopped { 51 | return syscall.EINVAL 52 | } 53 | gl.stop <- nil 54 | return <-gl.stop 55 | } 56 | 57 | func (gl *graceListener) File() *os.File { 58 | // returns a dup(2) - FD_CLOEXEC flag *not* set 59 | tl := gl.Listener.(*net.TCPListener) 60 | fl, _ := tl.File() 61 | return fl 62 | } 63 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/README.md: -------------------------------------------------------------------------------- 1 | ## logs 2 | logs is a Go logs manager. It can use many logs adapters. The repo is inspired by `database/sql` . 3 | 4 | 5 | ## How to install? 6 | 7 | go get github.com/astaxie/beego/logs 8 | 9 | 10 | ## What adapters are supported? 11 | 12 | As of now this logs support console, file,smtp and conn. 13 | 14 | 15 | ## How to use it? 16 | 17 | First you must import it 18 | 19 | import ( 20 | "github.com/astaxie/beego/logs" 21 | ) 22 | 23 | Then init a Log (example with console adapter) 24 | 25 | log := NewLogger(10000) 26 | log.SetLogger("console", "") 27 | 28 | > the first params stand for how many channel 29 | 30 | Use it like this: 31 | 32 | log.Trace("trace") 33 | log.Info("info") 34 | log.Warn("warning") 35 | log.Debug("debug") 36 | log.Critical("critical") 37 | 38 | 39 | ## File adapter 40 | 41 | Configure file adapter like this: 42 | 43 | log := NewLogger(10000) 44 | log.SetLogger("file", `{"filename":"test.log"}`) 45 | 46 | 47 | ## Conn adapter 48 | 49 | Configure like this: 50 | 51 | log := NewLogger(1000) 52 | log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`) 53 | log.Info("info") 54 | 55 | 56 | ## Smtp adapter 57 | 58 | Configure like this: 59 | 60 | log := NewLogger(10000) 61 | log.SetLogger("smtp", `{"username":"beegotest@gmail.com","password":"xxxxxxxx","host":"smtp.gmail.com:587","sendTos":["xiemengjun@gmail.com"]}`) 62 | log.Critical("sendmail critical") 63 | time.Sleep(time.Second * 30) 64 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/alils/config.go: -------------------------------------------------------------------------------- 1 | package alils 2 | 3 | const ( 4 | version = "0.5.0" // SDK version 5 | signatureMethod = "hmac-sha1" // Signature method 6 | 7 | // OffsetNewest stands for the log head offset, i.e. the offset that will be 8 | // assigned to the next message that will be produced to the shard. 9 | OffsetNewest = "end" 10 | // OffsetOldest stands for the oldest offset available on the logstore for a 11 | // shard. 12 | OffsetOldest = "begin" 13 | ) 14 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/alils/log_config.go: -------------------------------------------------------------------------------- 1 | package alils 2 | 3 | // InputDetail define log detail 4 | type InputDetail struct { 5 | LogType string `json:"logType"` 6 | LogPath string `json:"logPath"` 7 | FilePattern string `json:"filePattern"` 8 | LocalStorage bool `json:"localStorage"` 9 | TimeFormat string `json:"timeFormat"` 10 | LogBeginRegex string `json:"logBeginRegex"` 11 | Regex string `json:"regex"` 12 | Keys []string `json:"key"` 13 | FilterKeys []string `json:"filterKey"` 14 | FilterRegex []string `json:"filterRegex"` 15 | TopicFormat string `json:"topicFormat"` 16 | } 17 | 18 | // OutputDetail define the output detail 19 | type OutputDetail struct { 20 | Endpoint string `json:"endpoint"` 21 | LogStoreName string `json:"logstoreName"` 22 | } 23 | 24 | // LogConfig define Log Config 25 | type LogConfig struct { 26 | Name string `json:"configName"` 27 | InputType string `json:"inputType"` 28 | InputDetail InputDetail `json:"inputDetail"` 29 | OutputType string `json:"outputType"` 30 | OutputDetail OutputDetail `json:"outputDetail"` 31 | 32 | CreateTime uint32 33 | LastModifyTime uint32 34 | 35 | project *LogProject 36 | } 37 | 38 | // GetAppliedMachineGroup returns applied machine group of this config. 39 | func (c *LogConfig) GetAppliedMachineGroup(confName string) (groupNames []string, err error) { 40 | groupNames, err = c.project.GetAppliedMachineGroups(c.Name) 41 | return 42 | } 43 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/alils/machine_group.go: -------------------------------------------------------------------------------- 1 | package alils 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "net/http/httputil" 9 | ) 10 | 11 | // MachineGroupAttribute define the Attribute 12 | type MachineGroupAttribute struct { 13 | ExternalName string `json:"externalName"` 14 | TopicName string `json:"groupTopic"` 15 | } 16 | 17 | // MachineGroup define the machine Group 18 | type MachineGroup struct { 19 | Name string `json:"groupName"` 20 | Type string `json:"groupType"` 21 | MachineIDType string `json:"machineIdentifyType"` 22 | MachineIDList []string `json:"machineList"` 23 | 24 | Attribute MachineGroupAttribute `json:"groupAttribute"` 25 | 26 | CreateTime uint32 27 | LastModifyTime uint32 28 | 29 | project *LogProject 30 | } 31 | 32 | // Machine define the Machine 33 | type Machine struct { 34 | IP string 35 | UniqueID string `json:"machine-uniqueid"` 36 | UserdefinedID string `json:"userdefined-id"` 37 | } 38 | 39 | // MachineList define the Machine List 40 | type MachineList struct { 41 | Total int 42 | Machines []*Machine 43 | } 44 | 45 | // ListMachines returns machine list of this machine group. 46 | func (m *MachineGroup) ListMachines() (ms []*Machine, total int, err error) { 47 | h := map[string]string{ 48 | "x-sls-bodyrawsize": "0", 49 | } 50 | 51 | uri := fmt.Sprintf("/machinegroups/%v/machines", m.Name) 52 | r, err := request(m.project, "GET", uri, h, nil) 53 | if err != nil { 54 | return 55 | } 56 | 57 | buf, err := ioutil.ReadAll(r.Body) 58 | if err != nil { 59 | return 60 | } 61 | 62 | if r.StatusCode != http.StatusOK { 63 | errMsg := &errorMessage{} 64 | err = json.Unmarshal(buf, errMsg) 65 | if err != nil { 66 | err = fmt.Errorf("failed to remove config from machine group") 67 | dump, _ := httputil.DumpResponse(r, true) 68 | fmt.Println(dump) 69 | return 70 | } 71 | err = fmt.Errorf("%v:%v", errMsg.Code, errMsg.Message) 72 | return 73 | } 74 | 75 | body := &MachineList{} 76 | err = json.Unmarshal(buf, body) 77 | if err != nil { 78 | return 79 | } 80 | 81 | ms = body.Machines 82 | total = body.Total 83 | 84 | return 85 | } 86 | 87 | // GetAppliedConfigs returns applied configs of this machine group. 88 | func (m *MachineGroup) GetAppliedConfigs() (confNames []string, err error) { 89 | confNames, err = m.project.GetAppliedConfigs(m.Name) 90 | return 91 | } 92 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/alils/request.go: -------------------------------------------------------------------------------- 1 | package alils 2 | 3 | import ( 4 | "bytes" 5 | "crypto/md5" 6 | "fmt" 7 | "net/http" 8 | ) 9 | 10 | // request sends a request to SLS. 11 | func request(project *LogProject, method, uri string, headers map[string]string, 12 | body []byte) (resp *http.Response, err error) { 13 | 14 | // The caller should provide 'x-sls-bodyrawsize' header 15 | if _, ok := headers["x-sls-bodyrawsize"]; !ok { 16 | err = fmt.Errorf("Can't find 'x-sls-bodyrawsize' header") 17 | return 18 | } 19 | 20 | // SLS public request headers 21 | headers["Host"] = project.Name + "." + project.Endpoint 22 | headers["Date"] = nowRFC1123() 23 | headers["x-sls-apiversion"] = version 24 | headers["x-sls-signaturemethod"] = signatureMethod 25 | if body != nil { 26 | bodyMD5 := fmt.Sprintf("%X", md5.Sum(body)) 27 | headers["Content-MD5"] = bodyMD5 28 | 29 | if _, ok := headers["Content-Type"]; !ok { 30 | err = fmt.Errorf("Can't find 'Content-Type' header") 31 | return 32 | } 33 | } 34 | 35 | // Calc Authorization 36 | // Authorization = "SLS :" 37 | digest, err := signature(project, method, uri, headers) 38 | if err != nil { 39 | return 40 | } 41 | auth := fmt.Sprintf("SLS %v:%v", project.AccessKeyID, digest) 42 | headers["Authorization"] = auth 43 | 44 | // Initialize http request 45 | reader := bytes.NewReader(body) 46 | urlStr := fmt.Sprintf("http://%v.%v%v", project.Name, project.Endpoint, uri) 47 | req, err := http.NewRequest(method, urlStr, reader) 48 | if err != nil { 49 | return 50 | } 51 | for k, v := range headers { 52 | req.Header.Add(k, v) 53 | } 54 | 55 | // Get ready to do request 56 | resp, err = http.DefaultClient.Do(req) 57 | if err != nil { 58 | return 59 | } 60 | 61 | return 62 | } 63 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/color.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +build !windows 16 | 17 | package logs 18 | 19 | import "io" 20 | 21 | type ansiColorWriter struct { 22 | w io.Writer 23 | mode outputMode 24 | } 25 | 26 | func (cw *ansiColorWriter) Write(p []byte) (int, error) { 27 | return cw.w.Write(p) 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/conn_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package logs 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestConn(t *testing.T) { 22 | log := NewLogger(1000) 23 | log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`) 24 | log.Informational("informational") 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/console_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package logs 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | // Try each log level in decreasing order of priority. 22 | func testConsoleCalls(bl *BeeLogger) { 23 | bl.Emergency("emergency") 24 | bl.Alert("alert") 25 | bl.Critical("critical") 26 | bl.Error("error") 27 | bl.Warning("warning") 28 | bl.Notice("notice") 29 | bl.Informational("informational") 30 | bl.Debug("debug") 31 | } 32 | 33 | // Test console logging by visually comparing the lines being output with and 34 | // without a log level specification. 35 | func TestConsole(t *testing.T) { 36 | log1 := NewLogger(10000) 37 | log1.EnableFuncCallDepth(true) 38 | log1.SetLogger("console", "") 39 | testConsoleCalls(log1) 40 | 41 | log2 := NewLogger(100) 42 | log2.SetLogger("console", `{"level":3}`) 43 | testConsoleCalls(log2) 44 | } 45 | 46 | // Test console without color 47 | func TestConsoleNoColor(t *testing.T) { 48 | log := NewLogger(100) 49 | log.SetLogger("console", `{"color":false}`) 50 | testConsoleCalls(log) 51 | } 52 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/es/es.go: -------------------------------------------------------------------------------- 1 | package es 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "net" 8 | "net/url" 9 | "time" 10 | 11 | "github.com/astaxie/beego/logs" 12 | "github.com/belogik/goes" 13 | ) 14 | 15 | // NewES return a LoggerInterface 16 | func NewES() logs.Logger { 17 | cw := &esLogger{ 18 | Level: logs.LevelDebug, 19 | } 20 | return cw 21 | } 22 | 23 | type esLogger struct { 24 | *goes.Connection 25 | DSN string `json:"dsn"` 26 | Level int `json:"level"` 27 | } 28 | 29 | // {"dsn":"http://localhost:9200/","level":1} 30 | func (el *esLogger) Init(jsonconfig string) error { 31 | err := json.Unmarshal([]byte(jsonconfig), el) 32 | if err != nil { 33 | return err 34 | } 35 | if el.DSN == "" { 36 | return errors.New("empty dsn") 37 | } else if u, err := url.Parse(el.DSN); err != nil { 38 | return err 39 | } else if u.Path == "" { 40 | return errors.New("missing prefix") 41 | } else if host, port, err := net.SplitHostPort(u.Host); err != nil { 42 | return err 43 | } else { 44 | conn := goes.NewConnection(host, port) 45 | el.Connection = conn 46 | } 47 | return nil 48 | } 49 | 50 | // WriteMsg will write the msg and level into es 51 | func (el *esLogger) WriteMsg(when time.Time, msg string, level int) error { 52 | if level > el.Level { 53 | return nil 54 | } 55 | 56 | vals := make(map[string]interface{}) 57 | vals["@timestamp"] = when.Format(time.RFC3339) 58 | vals["@msg"] = msg 59 | d := goes.Document{ 60 | Index: fmt.Sprintf("%04d.%02d.%02d", when.Year(), when.Month(), when.Day()), 61 | Type: "logs", 62 | Fields: vals, 63 | } 64 | _, err := el.Index(d, nil) 65 | return err 66 | } 67 | 68 | // Destroy is a empty method 69 | func (el *esLogger) Destroy() { 70 | 71 | } 72 | 73 | // Flush is a empty method 74 | func (el *esLogger) Flush() { 75 | 76 | } 77 | 78 | func init() { 79 | logs.Register(logs.AdapterEs, NewES) 80 | } 81 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/jianliao.go: -------------------------------------------------------------------------------- 1 | package logs 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | "net/url" 8 | "time" 9 | ) 10 | 11 | // JLWriter implements beego LoggerInterface and is used to send jiaoliao webhook 12 | type JLWriter struct { 13 | AuthorName string `json:"authorname"` 14 | Title string `json:"title"` 15 | WebhookURL string `json:"webhookurl"` 16 | RedirectURL string `json:"redirecturl,omitempty"` 17 | ImageURL string `json:"imageurl,omitempty"` 18 | Level int `json:"level"` 19 | } 20 | 21 | // newJLWriter create jiaoliao writer. 22 | func newJLWriter() Logger { 23 | return &JLWriter{Level: LevelTrace} 24 | } 25 | 26 | // Init JLWriter with json config string 27 | func (s *JLWriter) Init(jsonconfig string) error { 28 | return json.Unmarshal([]byte(jsonconfig), s) 29 | } 30 | 31 | // WriteMsg write message in smtp writer. 32 | // it will send an email with subject and only this message. 33 | func (s *JLWriter) WriteMsg(when time.Time, msg string, level int) error { 34 | if level > s.Level { 35 | return nil 36 | } 37 | 38 | text := fmt.Sprintf("%s %s", when.Format("2006-01-02 15:04:05"), msg) 39 | 40 | form := url.Values{} 41 | form.Add("authorName", s.AuthorName) 42 | form.Add("title", s.Title) 43 | form.Add("text", text) 44 | if s.RedirectURL != "" { 45 | form.Add("redirectUrl", s.RedirectURL) 46 | } 47 | if s.ImageURL != "" { 48 | form.Add("imageUrl", s.ImageURL) 49 | } 50 | 51 | resp, err := http.PostForm(s.WebhookURL, form) 52 | if err != nil { 53 | return err 54 | } 55 | defer resp.Body.Close() 56 | if resp.StatusCode != http.StatusOK { 57 | return fmt.Errorf("Post webhook failed %s %d", resp.Status, resp.StatusCode) 58 | } 59 | return nil 60 | } 61 | 62 | // Flush implementing method. empty. 63 | func (s *JLWriter) Flush() { 64 | } 65 | 66 | // Destroy implementing method. empty. 67 | func (s *JLWriter) Destroy() { 68 | } 69 | 70 | func init() { 71 | Register(AdapterJianLiao, newJLWriter) 72 | } 73 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/logger_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package logs 16 | 17 | import ( 18 | "bytes" 19 | "testing" 20 | "time" 21 | ) 22 | 23 | func TestFormatHeader_0(t *testing.T) { 24 | tm := time.Now() 25 | if tm.Year() >= 2100 { 26 | t.FailNow() 27 | } 28 | dur := time.Second 29 | for { 30 | if tm.Year() >= 2100 { 31 | break 32 | } 33 | h, _ := formatTimeHeader(tm) 34 | if tm.Format("2006/01/02 15:04:05.999 ") != string(h) { 35 | t.Log(tm) 36 | t.FailNow() 37 | } 38 | tm = tm.Add(dur) 39 | dur *= 2 40 | } 41 | } 42 | 43 | func TestFormatHeader_1(t *testing.T) { 44 | tm := time.Now() 45 | year := tm.Year() 46 | dur := time.Second 47 | for { 48 | if tm.Year() >= year+1 { 49 | break 50 | } 51 | h, _ := formatTimeHeader(tm) 52 | if tm.Format("2006/01/02 15:04:05.999 ") != string(h) { 53 | t.Log(tm) 54 | t.FailNow() 55 | } 56 | tm = tm.Add(dur) 57 | } 58 | } 59 | 60 | func TestNewAnsiColor1(t *testing.T) { 61 | inner := bytes.NewBufferString("") 62 | w := NewAnsiColorWriter(inner) 63 | if w == inner { 64 | t.Errorf("Get %#v, want %#v", w, inner) 65 | } 66 | } 67 | 68 | func TestNewAnsiColor2(t *testing.T) { 69 | inner := bytes.NewBufferString("") 70 | w1 := NewAnsiColorWriter(inner) 71 | w2 := NewAnsiColorWriter(w1) 72 | if w1 != w2 { 73 | t.Errorf("Get %#v, want %#v", w1, w2) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/multifile_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package logs 16 | 17 | import ( 18 | "bufio" 19 | "os" 20 | "strconv" 21 | "strings" 22 | "testing" 23 | ) 24 | 25 | func TestFiles_1(t *testing.T) { 26 | log := NewLogger(10000) 27 | log.SetLogger("multifile", `{"filename":"test.log","separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]}`) 28 | log.Debug("debug") 29 | log.Informational("info") 30 | log.Notice("notice") 31 | log.Warning("warning") 32 | log.Error("error") 33 | log.Alert("alert") 34 | log.Critical("critical") 35 | log.Emergency("emergency") 36 | fns := []string{""} 37 | fns = append(fns, levelNames[0:]...) 38 | name := "test" 39 | suffix := ".log" 40 | for _, fn := range fns { 41 | 42 | file := name + suffix 43 | if fn != "" { 44 | file = name + "." + fn + suffix 45 | } 46 | f, err := os.Open(file) 47 | if err != nil { 48 | t.Fatal(err) 49 | } 50 | b := bufio.NewReader(f) 51 | lineNum := 0 52 | lastLine := "" 53 | for { 54 | line, _, err := b.ReadLine() 55 | if err != nil { 56 | break 57 | } 58 | if len(line) > 0 { 59 | lastLine = string(line) 60 | lineNum++ 61 | } 62 | } 63 | var expected = 1 64 | if fn == "" { 65 | expected = LevelDebug + 1 66 | } 67 | if lineNum != expected { 68 | t.Fatal(file, "has", lineNum, "lines not "+strconv.Itoa(expected)+" lines") 69 | } 70 | if lineNum == 1 { 71 | if !strings.Contains(lastLine, fn) { 72 | t.Fatal(file + " " + lastLine + " not contains the log msg " + fn) 73 | } 74 | } 75 | os.Remove(file) 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/slack.go: -------------------------------------------------------------------------------- 1 | package logs 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | "net/url" 8 | "time" 9 | ) 10 | 11 | // SLACKWriter implements beego LoggerInterface and is used to send jiaoliao webhook 12 | type SLACKWriter struct { 13 | WebhookURL string `json:"webhookurl"` 14 | Level int `json:"level"` 15 | } 16 | 17 | // newSLACKWriter create jiaoliao writer. 18 | func newSLACKWriter() Logger { 19 | return &SLACKWriter{Level: LevelTrace} 20 | } 21 | 22 | // Init SLACKWriter with json config string 23 | func (s *SLACKWriter) Init(jsonconfig string) error { 24 | return json.Unmarshal([]byte(jsonconfig), s) 25 | } 26 | 27 | // WriteMsg write message in smtp writer. 28 | // it will send an email with subject and only this message. 29 | func (s *SLACKWriter) WriteMsg(when time.Time, msg string, level int) error { 30 | if level > s.Level { 31 | return nil 32 | } 33 | 34 | text := fmt.Sprintf("{\"text\": \"%s %s\"}", when.Format("2006-01-02 15:04:05"), msg) 35 | 36 | form := url.Values{} 37 | form.Add("payload", text) 38 | 39 | resp, err := http.PostForm(s.WebhookURL, form) 40 | if err != nil { 41 | return err 42 | } 43 | defer resp.Body.Close() 44 | if resp.StatusCode != http.StatusOK { 45 | return fmt.Errorf("Post webhook failed %s %d", resp.Status, resp.StatusCode) 46 | } 47 | return nil 48 | } 49 | 50 | // Flush implementing method. empty. 51 | func (s *SLACKWriter) Flush() { 52 | } 53 | 54 | // Destroy implementing method. empty. 55 | func (s *SLACKWriter) Destroy() { 56 | } 57 | 58 | func init() { 59 | Register(AdapterSlack, newSLACKWriter) 60 | } 61 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/logs/smtp_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package logs 16 | 17 | import ( 18 | "testing" 19 | "time" 20 | ) 21 | 22 | func TestSmtp(t *testing.T) { 23 | log := NewLogger(10000) 24 | log.SetLogger("smtp", `{"username":"beegotest@gmail.com","password":"xxxxxxxx","host":"smtp.gmail.com:587","sendTos":["xiemengjun@gmail.com"]}`) 25 | log.Critical("sendmail critical") 26 | time.Sleep(time.Second * 30) 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/migration/doc.go: -------------------------------------------------------------------------------- 1 | // Package migration enables you to generate migrations back and forth. It generates both migrations. 2 | // 3 | // //Creates a table 4 | // m.CreateTable("tablename","InnoDB","utf8"); 5 | // 6 | // //Alter a table 7 | // m.AlterTable("tablename") 8 | // 9 | // Standard Column Methods 10 | // * SetDataType 11 | // * SetNullable 12 | // * SetDefault 13 | // * SetUnsigned (use only on integer types unless produces error) 14 | // 15 | // //Sets a primary column, multiple calls allowed, standard column methods available 16 | // m.PriCol("id").SetAuto(true).SetNullable(false).SetDataType("INT(10)").SetUnsigned(true) 17 | // 18 | // //UniCol Can be used multiple times, allows standard Column methods. Use same "index" string to add to same index 19 | // m.UniCol("index","column") 20 | // 21 | // //Standard Column Initialisation, can call .Remove() after NewCol("") on alter to remove 22 | // m.NewCol("name").SetDataType("VARCHAR(255) COLLATE utf8_unicode_ci").SetNullable(false) 23 | // m.NewCol("value").SetDataType("DOUBLE(8,2)").SetNullable(false) 24 | // 25 | // //Rename Columns , only use with Alter table, doesn't works with Create, prefix standard column methods with "Old" to 26 | // //create a true reversible migration eg: SetOldDataType("DOUBLE(12,3)") 27 | // m.RenameColumn("from","to")... 28 | // 29 | // //Foreign Columns, single columns are only supported, SetOnDelete & SetOnUpdate are available, call appropriately. 30 | // //Supports standard column methods, automatic reverse. 31 | // m.ForeignCol("local_col","foreign_col","foreign_table") 32 | package migration 33 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/orm/db_tidb.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 TiDB Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package orm 16 | 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | // mysql dbBaser implementation. 22 | type dbBaseTidb struct { 23 | dbBase 24 | } 25 | 26 | var _ dbBaser = new(dbBaseTidb) 27 | 28 | // get mysql operator. 29 | func (d *dbBaseTidb) OperatorSQL(operator string) string { 30 | return mysqlOperators[operator] 31 | } 32 | 33 | // get mysql table field types. 34 | func (d *dbBaseTidb) DbTypes() map[string]string { 35 | return mysqlTypes 36 | } 37 | 38 | // show table sql for mysql. 39 | func (d *dbBaseTidb) ShowTablesQuery() string { 40 | return "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema = DATABASE()" 41 | } 42 | 43 | // show columns sql of table for mysql. 44 | func (d *dbBaseTidb) ShowColumnsQuery(table string) string { 45 | return fmt.Sprintf("SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE FROM information_schema.columns "+ 46 | "WHERE table_schema = DATABASE() AND table_name = '%s'", table) 47 | } 48 | 49 | // execute sql to check index exist. 50 | func (d *dbBaseTidb) IndexExists(db dbQuerier, table string, name string) bool { 51 | row := db.QueryRow("SELECT count(*) FROM information_schema.statistics "+ 52 | "WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?", table, name) 53 | var cnt int 54 | row.Scan(&cnt) 55 | return cnt > 0 56 | } 57 | 58 | // create new mysql dbBaser. 59 | func newdbBaseTidb() dbBaser { 60 | b := new(dbBaseTidb) 61 | b.ins = b 62 | return b 63 | } 64 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/orm/qb.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package orm 16 | 17 | import "errors" 18 | 19 | // QueryBuilder is the Query builder interface 20 | type QueryBuilder interface { 21 | Select(fields ...string) QueryBuilder 22 | ForUpdate() QueryBuilder 23 | From(tables ...string) QueryBuilder 24 | InnerJoin(table string) QueryBuilder 25 | LeftJoin(table string) QueryBuilder 26 | RightJoin(table string) QueryBuilder 27 | On(cond string) QueryBuilder 28 | Where(cond string) QueryBuilder 29 | And(cond string) QueryBuilder 30 | Or(cond string) QueryBuilder 31 | In(vals ...string) QueryBuilder 32 | OrderBy(fields ...string) QueryBuilder 33 | Asc() QueryBuilder 34 | Desc() QueryBuilder 35 | Limit(limit int) QueryBuilder 36 | Offset(offset int) QueryBuilder 37 | GroupBy(fields ...string) QueryBuilder 38 | Having(cond string) QueryBuilder 39 | Update(tables ...string) QueryBuilder 40 | Set(kv ...string) QueryBuilder 41 | Delete(tables ...string) QueryBuilder 42 | InsertInto(table string, fields ...string) QueryBuilder 43 | Values(vals ...string) QueryBuilder 44 | Subquery(sub string, alias string) string 45 | String() string 46 | } 47 | 48 | // NewQueryBuilder return the QueryBuilder 49 | func NewQueryBuilder(driver string) (qb QueryBuilder, err error) { 50 | if driver == "mysql" { 51 | qb = new(MySQLQueryBuilder) 52 | } else if driver == "tidb" { 53 | qb = new(TiDBQueryBuilder) 54 | } else if driver == "postgres" { 55 | err = errors.New("postgres query builder is not supported yet") 56 | } else if driver == "sqlite" { 57 | err = errors.New("sqlite query builder is not supported yet") 58 | } else { 59 | err = errors.New("unknown driver for query builder") 60 | } 61 | return 62 | } 63 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/orm/utils_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package orm 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestCamelString(t *testing.T) { 22 | snake := []string{"pic_url", "hello_world_", "hello__World", "_HelLO_Word", "pic_url_1", "pic_url__1"} 23 | camel := []string{"PicUrl", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "PicUrl1"} 24 | 25 | answer := make(map[string]string) 26 | for i, v := range snake { 27 | answer[v] = camel[i] 28 | } 29 | 30 | for _, v := range snake { 31 | res := camelString(v) 32 | if res != answer[v] { 33 | t.Error("Unit Test Fail:", v, res, answer[v]) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/plugins/apiauth/apiauth_test.go: -------------------------------------------------------------------------------- 1 | package apiauth 2 | 3 | import ( 4 | "net/url" 5 | "testing" 6 | ) 7 | 8 | func TestSignature(t *testing.T) { 9 | appsecret := "beego secret" 10 | method := "GET" 11 | RequestURL := "http://localhost/test/url" 12 | params := make(url.Values) 13 | params.Add("arg1", "hello") 14 | params.Add("arg2", "beego") 15 | 16 | signature := "mFdpvLh48ca4mDVEItE9++AKKQ/IVca7O/ZyyB8hR58=" 17 | if Signature(appsecret, method, params, RequestURL) != signature { 18 | t.Error("Signature error") 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/plugins/authz/authz_model.conf: -------------------------------------------------------------------------------- 1 | [request_definition] 2 | r = sub, obj, act 3 | 4 | [policy_definition] 5 | p = sub, obj, act 6 | 7 | [role_definition] 8 | g = _, _ 9 | 10 | [policy_effect] 11 | e = some(where (p.eft == allow)) 12 | 13 | [matchers] 14 | m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*") -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/plugins/authz/authz_policy.csv: -------------------------------------------------------------------------------- 1 | p, alice, /dataset1/*, GET 2 | p, alice, /dataset1/resource1, POST 3 | p, bob, /dataset2/resource1, * 4 | p, bob, /dataset2/resource2, GET 5 | p, bob, /dataset2/folder1/*, POST 6 | p, dataset1_admin, /dataset1/*, * 7 | g, cathy, dataset1_admin -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/session/sess_mem_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package session 16 | 17 | import ( 18 | "encoding/json" 19 | "net/http" 20 | "net/http/httptest" 21 | "strings" 22 | "testing" 23 | ) 24 | 25 | func TestMem(t *testing.T) { 26 | config := `{"cookieName":"gosessionid","gclifetime":10, "enableSetCookie":true}` 27 | conf := new(ManagerConfig) 28 | if err := json.Unmarshal([]byte(config), conf); err != nil { 29 | t.Fatal("json decode error", err) 30 | } 31 | globalSessions, _ := NewManager("memory", conf) 32 | go globalSessions.GC() 33 | r, _ := http.NewRequest("GET", "/", nil) 34 | w := httptest.NewRecorder() 35 | sess, err := globalSessions.SessionStart(w, r) 36 | if err != nil { 37 | t.Fatal("set error,", err) 38 | } 39 | defer sess.SessionRelease(w) 40 | err = sess.Set("username", "astaxie") 41 | if err != nil { 42 | t.Fatal("set error,", err) 43 | } 44 | if username := sess.Get("username"); username != "astaxie" { 45 | t.Fatal("get username error") 46 | } 47 | if cookiestr := w.Header().Get("Set-Cookie"); cookiestr == "" { 48 | t.Fatal("setcookie error") 49 | } else { 50 | parts := strings.Split(strings.TrimSpace(cookiestr), ";") 51 | for k, v := range parts { 52 | nameval := strings.Split(v, "=") 53 | if k == 0 && nameval[0] != "gosessionid" { 54 | t.Fatal("error") 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/staticfile_test.go: -------------------------------------------------------------------------------- 1 | package beego 2 | 3 | import ( 4 | "bytes" 5 | "compress/gzip" 6 | "compress/zlib" 7 | "io" 8 | "io/ioutil" 9 | "os" 10 | "path/filepath" 11 | "testing" 12 | ) 13 | 14 | var currentWorkDir, _ = os.Getwd() 15 | var licenseFile = filepath.Join(currentWorkDir, "LICENSE") 16 | 17 | func testOpenFile(encoding string, content []byte, t *testing.T) { 18 | fi, _ := os.Stat(licenseFile) 19 | b, n, sch, err := openFile(licenseFile, fi, encoding) 20 | if err != nil { 21 | t.Log(err) 22 | t.Fail() 23 | } 24 | 25 | t.Log("open static file encoding "+n, b) 26 | 27 | assetOpenFileAndContent(sch, content, t) 28 | } 29 | func TestOpenStaticFile_1(t *testing.T) { 30 | file, _ := os.Open(licenseFile) 31 | content, _ := ioutil.ReadAll(file) 32 | testOpenFile("", content, t) 33 | } 34 | 35 | func TestOpenStaticFileGzip_1(t *testing.T) { 36 | file, _ := os.Open(licenseFile) 37 | var zipBuf bytes.Buffer 38 | fileWriter, _ := gzip.NewWriterLevel(&zipBuf, gzip.BestCompression) 39 | io.Copy(fileWriter, file) 40 | fileWriter.Close() 41 | content, _ := ioutil.ReadAll(&zipBuf) 42 | 43 | testOpenFile("gzip", content, t) 44 | } 45 | func TestOpenStaticFileDeflate_1(t *testing.T) { 46 | file, _ := os.Open(licenseFile) 47 | var zipBuf bytes.Buffer 48 | fileWriter, _ := zlib.NewWriterLevel(&zipBuf, zlib.BestCompression) 49 | io.Copy(fileWriter, file) 50 | fileWriter.Close() 51 | content, _ := ioutil.ReadAll(&zipBuf) 52 | 53 | testOpenFile("deflate", content, t) 54 | } 55 | 56 | func assetOpenFileAndContent(sch *serveContentHolder, content []byte, t *testing.T) { 57 | t.Log(sch.size, len(content)) 58 | if sch.size != int64(len(content)) { 59 | t.Log("static content file size not same") 60 | t.Fail() 61 | } 62 | bs, _ := ioutil.ReadAll(sch) 63 | for i, v := range content { 64 | if v != bs[i] { 65 | t.Log("content not same") 66 | t.Fail() 67 | } 68 | } 69 | if len(staticFileMap) == 0 { 70 | t.Log("men map is empty") 71 | t.Fail() 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/testing/assertions.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package testing 16 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/testing/client.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package testing 16 | 17 | import ( 18 | "github.com/astaxie/beego/config" 19 | "github.com/astaxie/beego/httplib" 20 | ) 21 | 22 | var port = "" 23 | var baseURL = "http://localhost:" 24 | 25 | // TestHTTPRequest beego test request client 26 | type TestHTTPRequest struct { 27 | httplib.BeegoHTTPRequest 28 | } 29 | 30 | func getPort() string { 31 | if port == "" { 32 | config, err := config.NewConfig("ini", "../conf/app.conf") 33 | if err != nil { 34 | return "8080" 35 | } 36 | port = config.String("httpport") 37 | return port 38 | } 39 | return port 40 | } 41 | 42 | // Get returns test client in GET method 43 | func Get(path string) *TestHTTPRequest { 44 | return &TestHTTPRequest{*httplib.Get(baseURL + getPort() + path)} 45 | } 46 | 47 | // Post returns test client in POST method 48 | func Post(path string) *TestHTTPRequest { 49 | return &TestHTTPRequest{*httplib.Post(baseURL + getPort() + path)} 50 | } 51 | 52 | // Put returns test client in PUT method 53 | func Put(path string) *TestHTTPRequest { 54 | return &TestHTTPRequest{*httplib.Put(baseURL + getPort() + path)} 55 | } 56 | 57 | // Delete returns test client in DELETE method 58 | func Delete(path string) *TestHTTPRequest { 59 | return &TestHTTPRequest{*httplib.Delete(baseURL + getPort() + path)} 60 | } 61 | 62 | // Head returns test client in HEAD method 63 | func Head(path string) *TestHTTPRequest { 64 | return &TestHTTPRequest{*httplib.Head(baseURL + getPort() + path)} 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/toolbox/healthcheck.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package toolbox healthcheck 16 | // 17 | // type DatabaseCheck struct { 18 | // } 19 | // 20 | // func (dc *DatabaseCheck) Check() error { 21 | // if dc.isConnected() { 22 | // return nil 23 | // } else { 24 | // return errors.New("can't connect database") 25 | // } 26 | // } 27 | // 28 | // AddHealthCheck("database",&DatabaseCheck{}) 29 | // 30 | // more docs: http://beego.me/docs/module/toolbox.md 31 | package toolbox 32 | 33 | // AdminCheckList holds health checker map 34 | var AdminCheckList map[string]HealthChecker 35 | 36 | // HealthChecker health checker interface 37 | type HealthChecker interface { 38 | Check() error 39 | } 40 | 41 | // AddHealthCheck add health checker with name string 42 | func AddHealthCheck(name string, hc HealthChecker) { 43 | AdminCheckList[name] = hc 44 | } 45 | 46 | func init() { 47 | AdminCheckList = make(map[string]HealthChecker) 48 | } 49 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/toolbox/profile_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package toolbox 16 | 17 | import ( 18 | "os" 19 | "testing" 20 | ) 21 | 22 | func TestProcessInput(t *testing.T) { 23 | ProcessInput("lookup goroutine", os.Stdout) 24 | ProcessInput("lookup heap", os.Stdout) 25 | ProcessInput("lookup threadcreate", os.Stdout) 26 | ProcessInput("lookup block", os.Stdout) 27 | ProcessInput("gc summary", os.Stdout) 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/toolbox/statistics_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package toolbox 16 | 17 | import ( 18 | "encoding/json" 19 | "testing" 20 | "time" 21 | ) 22 | 23 | func TestStatics(t *testing.T) { 24 | StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(2000)) 25 | StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(120000)) 26 | StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(13000)) 27 | StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(14000)) 28 | StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(12000)) 29 | StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(13000)) 30 | StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400)) 31 | t.Log(StatisticsMap.GetMap()) 32 | 33 | data := StatisticsMap.GetMapData() 34 | b, err := json.Marshal(data) 35 | if err != nil { 36 | t.Errorf(err.Error()) 37 | } 38 | 39 | t.Log(string(b)) 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/toolbox/task_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package toolbox 16 | 17 | import ( 18 | "fmt" 19 | "sync" 20 | "testing" 21 | "time" 22 | ) 23 | 24 | func TestParse(t *testing.T) { 25 | tk := NewTask("taska", "0/30 * * * * *", func() error { fmt.Println("hello world"); return nil }) 26 | err := tk.Run() 27 | if err != nil { 28 | t.Fatal(err) 29 | } 30 | AddTask("taska", tk) 31 | StartTask() 32 | time.Sleep(6 * time.Second) 33 | StopTask() 34 | } 35 | 36 | func TestSpec(t *testing.T) { 37 | wg := &sync.WaitGroup{} 38 | wg.Add(2) 39 | tk1 := NewTask("tk1", "0 12 * * * *", func() error { fmt.Println("tk1"); return nil }) 40 | tk2 := NewTask("tk2", "0,10,20 * * * * *", func() error { fmt.Println("tk2"); wg.Done(); return nil }) 41 | tk3 := NewTask("tk3", "0 10 * * * *", func() error { fmt.Println("tk3"); wg.Done(); return nil }) 42 | 43 | AddTask("tk1", tk1) 44 | AddTask("tk2", tk2) 45 | AddTask("tk3", tk3) 46 | StartTask() 47 | defer StopTask() 48 | 49 | select { 50 | case <-time.After(200 * time.Second): 51 | t.FailNow() 52 | case <-wait(wg): 53 | } 54 | } 55 | 56 | func wait(wg *sync.WaitGroup) chan bool { 57 | ch := make(chan bool) 58 | go func() { 59 | wg.Wait() 60 | ch <- true 61 | }() 62 | return ch 63 | } 64 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/caller.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "reflect" 19 | "runtime" 20 | ) 21 | 22 | // GetFuncName get function name 23 | func GetFuncName(i interface{}) string { 24 | return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/caller_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "strings" 19 | "testing" 20 | ) 21 | 22 | func TestGetFuncName(t *testing.T) { 23 | name := GetFuncName(TestGetFuncName) 24 | t.Log(name) 25 | if !strings.HasSuffix(name, ".TestGetFuncName") { 26 | t.Error("get func name error") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/captcha/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2014 Dmitry Chestnykh 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/captcha/README.md: -------------------------------------------------------------------------------- 1 | # Captcha 2 | 3 | an example for use captcha 4 | 5 | ``` 6 | package controllers 7 | 8 | import ( 9 | "github.com/astaxie/beego" 10 | "github.com/astaxie/beego/cache" 11 | "github.com/astaxie/beego/utils/captcha" 12 | ) 13 | 14 | var cpt *captcha.Captcha 15 | 16 | func init() { 17 | // use beego cache system store the captcha data 18 | store := cache.NewMemoryCache() 19 | cpt = captcha.NewWithFilter("/captcha/", store) 20 | } 21 | 22 | type MainController struct { 23 | beego.Controller 24 | } 25 | 26 | func (this *MainController) Get() { 27 | this.TplName = "index.tpl" 28 | } 29 | 30 | func (this *MainController) Post() { 31 | this.TplName = "index.tpl" 32 | 33 | this.Data["Success"] = cpt.VerifyReq(this.Ctx.Request) 34 | } 35 | ``` 36 | 37 | template usage 38 | 39 | ``` 40 | {{.Success}} 41 |
42 | {{create_captcha}} 43 | 44 |
45 | ``` 46 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/captcha/image_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package captcha 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/astaxie/beego/utils" 21 | ) 22 | 23 | type byteCounter struct { 24 | n int64 25 | } 26 | 27 | func (bc *byteCounter) Write(b []byte) (int, error) { 28 | bc.n += int64(len(b)) 29 | return len(b), nil 30 | } 31 | 32 | func BenchmarkNewImage(b *testing.B) { 33 | b.StopTimer() 34 | d := utils.RandomCreateBytes(challengeNums, defaultChars...) 35 | b.StartTimer() 36 | for i := 0; i < b.N; i++ { 37 | NewImage(d, stdWidth, stdHeight) 38 | } 39 | } 40 | 41 | func BenchmarkImageWriteTo(b *testing.B) { 42 | b.StopTimer() 43 | d := utils.RandomCreateBytes(challengeNums, defaultChars...) 44 | b.StartTimer() 45 | counter := &byteCounter{} 46 | for i := 0; i < b.N; i++ { 47 | img := NewImage(d, stdWidth, stdHeight) 48 | img.WriteTo(counter) 49 | b.SetBytes(counter.n) 50 | counter.n = 0 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/captcha/siprng_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package captcha 16 | 17 | import "testing" 18 | 19 | func TestSiphash(t *testing.T) { 20 | good := uint64(0xe849e8bb6ffe2567) 21 | cur := siphash(0, 0, 0) 22 | if cur != good { 23 | t.Fatalf("siphash: expected %x, got %x", good, cur) 24 | } 25 | } 26 | 27 | func BenchmarkSiprng(b *testing.B) { 28 | b.SetBytes(8) 29 | p := &siprng{} 30 | for i := 0; i < b.N; i++ { 31 | p.Uint64() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/debug_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | type mytype struct { 22 | next *mytype 23 | prev *mytype 24 | } 25 | 26 | func TestPrint(t *testing.T) { 27 | Display("v1", 1, "v2", 2, "v3", 3) 28 | } 29 | 30 | func TestPrintPoint(t *testing.T) { 31 | var v1 = new(mytype) 32 | var v2 = new(mytype) 33 | 34 | v1.prev = nil 35 | v1.next = v2 36 | 37 | v2.prev = v1 38 | v2.next = nil 39 | 40 | Display("v1", v1, "v2", v2) 41 | } 42 | 43 | func TestPrintString(t *testing.T) { 44 | str := GetDisplayString("v1", 1, "v2", 2) 45 | println(str) 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/file_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "path/filepath" 19 | "reflect" 20 | "testing" 21 | ) 22 | 23 | var noExistedFile = "/tmp/not_existed_file" 24 | 25 | func TestSelfPath(t *testing.T) { 26 | path := SelfPath() 27 | if path == "" { 28 | t.Error("path cannot be empty") 29 | } 30 | t.Logf("SelfPath: %s", path) 31 | } 32 | 33 | func TestSelfDir(t *testing.T) { 34 | dir := SelfDir() 35 | t.Logf("SelfDir: %s", dir) 36 | } 37 | 38 | func TestFileExists(t *testing.T) { 39 | if !FileExists("./file.go") { 40 | t.Errorf("./file.go should exists, but it didn't") 41 | } 42 | 43 | if FileExists(noExistedFile) { 44 | t.Errorf("Weird, how could this file exists: %s", noExistedFile) 45 | } 46 | } 47 | 48 | func TestSearchFile(t *testing.T) { 49 | path, err := SearchFile(filepath.Base(SelfPath()), SelfDir()) 50 | if err != nil { 51 | t.Error(err) 52 | } 53 | t.Log(path) 54 | 55 | _, err = SearchFile(noExistedFile, ".") 56 | if err == nil { 57 | t.Errorf("err shouldnt be nil, got path: %s", SelfDir()) 58 | } 59 | } 60 | 61 | func TestGrepFile(t *testing.T) { 62 | _, err := GrepFile("", noExistedFile) 63 | if err == nil { 64 | t.Error("expect file-not-existed error, but got nothing") 65 | } 66 | 67 | path := filepath.Join(".", "testdata", "grepe.test") 68 | lines, err := GrepFile(`^\s*[^#]+`, path) 69 | if err != nil { 70 | t.Error(err) 71 | } 72 | if !reflect.DeepEqual(lines, []string{"hello", "world"}) { 73 | t.Errorf("expect [hello world], but receive %v", lines) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/mail_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import "testing" 18 | 19 | func TestMail(t *testing.T) { 20 | config := `{"username":"astaxie@gmail.com","password":"astaxie","host":"smtp.gmail.com","port":587}` 21 | mail := NewEMail(config) 22 | if mail.Username != "astaxie@gmail.com" { 23 | t.Fatal("email parse get username error") 24 | } 25 | if mail.Password != "astaxie" { 26 | t.Fatal("email parse get password error") 27 | } 28 | if mail.Host != "smtp.gmail.com" { 29 | t.Fatal("email parse get host error") 30 | } 31 | if mail.Port != 587 { 32 | t.Fatal("email parse get port error") 33 | } 34 | mail.To = []string{"xiemengjun@gmail.com"} 35 | mail.From = "astaxie@gmail.com" 36 | mail.Subject = "hi, just from beego!" 37 | mail.Text = "Text Body is, of course, supported!" 38 | mail.HTML = "

Fancy Html is supported, too!

" 39 | mail.AttachFile("/Users/astaxie/github/beego/beego.go") 40 | mail.Send() 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/pagination/controller.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pagination 16 | 17 | import ( 18 | "github.com/astaxie/beego/context" 19 | ) 20 | 21 | // SetPaginator Instantiates a Paginator and assigns it to context.Input.Data("paginator"). 22 | func SetPaginator(context *context.Context, per int, nums int64) (paginator *Paginator) { 23 | paginator = NewPaginator(context.Request, per, nums) 24 | context.Input.SetData("paginator", &paginator) 25 | return 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/pagination/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package pagination provides utilities to setup a paginator within the 3 | context of a http request. 4 | 5 | Usage 6 | 7 | In your beego.Controller: 8 | 9 | package controllers 10 | 11 | import "github.com/astaxie/beego/utils/pagination" 12 | 13 | type PostsController struct { 14 | beego.Controller 15 | } 16 | 17 | func (this *PostsController) ListAllPosts() { 18 | // sets this.Data["paginator"] with the current offset (from the url query param) 19 | postsPerPage := 20 20 | paginator := pagination.SetPaginator(this.Ctx, postsPerPage, CountPosts()) 21 | 22 | // fetch the next 20 posts 23 | this.Data["posts"] = ListPostsByOffsetAndLimit(paginator.Offset(), postsPerPage) 24 | } 25 | 26 | 27 | In your view templates: 28 | 29 | {{if .paginator.HasPages}} 30 | 51 | {{end}} 52 | 53 | See also 54 | 55 | http://beego.me/docs/mvc/view/page.md 56 | 57 | */ 58 | package pagination 59 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/pagination/utils.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pagination 16 | 17 | import ( 18 | "fmt" 19 | "reflect" 20 | ) 21 | 22 | // ToInt64 convert any numeric value to int64 23 | func toInt64(value interface{}) (d int64, err error) { 24 | val := reflect.ValueOf(value) 25 | switch value.(type) { 26 | case int, int8, int16, int32, int64: 27 | d = val.Int() 28 | case uint, uint8, uint16, uint32, uint64: 29 | d = int64(val.Uint()) 30 | default: 31 | err = fmt.Errorf("ToInt64 need numeric not `%T`", value) 32 | } 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/rand.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "crypto/rand" 19 | r "math/rand" 20 | "time" 21 | ) 22 | 23 | var alphaNum = []byte(`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`) 24 | 25 | // RandomCreateBytes generate random []byte by specify chars. 26 | func RandomCreateBytes(n int, alphabets ...byte) []byte { 27 | if len(alphabets) == 0 { 28 | alphabets = alphaNum 29 | } 30 | var bytes = make([]byte, n) 31 | var randBy bool 32 | if num, err := rand.Read(bytes); num != n || err != nil { 33 | r.Seed(time.Now().UnixNano()) 34 | randBy = true 35 | } 36 | for i, b := range bytes { 37 | if randBy { 38 | bytes[i] = alphabets[r.Intn(len(alphabets))] 39 | } else { 40 | bytes[i] = alphabets[b%byte(len(alphabets))] 41 | } 42 | } 43 | return bytes 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/rand_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import "testing" 18 | 19 | func TestRand_01(t *testing.T) { 20 | bs0 := RandomCreateBytes(16) 21 | bs1 := RandomCreateBytes(16) 22 | 23 | t.Log(string(bs0), string(bs1)) 24 | if string(bs0) == string(bs1) { 25 | t.FailNow() 26 | } 27 | 28 | bs0 = RandomCreateBytes(4, []byte(`a`)...) 29 | 30 | if string(bs0) != "aaaa" { 31 | t.FailNow() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/slice_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 beego Author. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestInSlice(t *testing.T) { 22 | sl := []string{"A", "b"} 23 | if !InSlice("A", sl) { 24 | t.Error("should be true") 25 | } 26 | if InSlice("B", sl) { 27 | t.Error("should be false") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/testdata/grepe.test: -------------------------------------------------------------------------------- 1 | # empty lines 2 | 3 | 4 | 5 | hello 6 | # comment 7 | world 8 | -------------------------------------------------------------------------------- /vendor/github.com/astaxie/beego/utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "runtime" 7 | "strings" 8 | ) 9 | 10 | // GetGOPATHs returns all paths in GOPATH variable. 11 | func GetGOPATHs() []string { 12 | gopath := os.Getenv("GOPATH") 13 | if gopath == "" && strings.Compare(runtime.Version(), "go1.8") >= 0 { 14 | gopath = defaultGOPATH() 15 | } 16 | return filepath.SplitList(gopath) 17 | } 18 | 19 | func defaultGOPATH() string { 20 | env := "HOME" 21 | if runtime.GOOS == "windows" { 22 | env = "USERPROFILE" 23 | } else if runtime.GOOS == "plan9" { 24 | env = "home" 25 | } 26 | if home := os.Getenv(env); home != "" { 27 | return filepath.Join(home, "go") 28 | } 29 | return "" 30 | } 31 | -------------------------------------------------------------------------------- /views/index.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /web/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /web/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /web/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | # web 2 | 3 | sysmon frontend is a web application based on vue and vuetify. It use vicon project for icons. 4 | 5 | ## Build Setup 6 | Note: If your network is slow when connecting to npm repository, please use cnpm instead of npm(check https://npm.taobao.org/ for how to use cnpm). 7 | 8 | ``` bash 9 | # install dependencies 10 | npm install 11 | 12 | # serve with hot reload at 0.0.0.0:2047, if you have run server and the server has served on 0.0.0.0:208, you can visit 0.0.0.0:2047 on browser to debug. 13 | npm run dev 14 | 15 | # build for production with minification 16 | npm run build 17 | 18 | # build for production and view the bundle analyzer report 19 | npm run build --report 20 | ``` 21 | 22 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 23 | -------------------------------------------------------------------------------- /web/build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /web/build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /web/build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/build/logo.png -------------------------------------------------------------------------------- /web/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /web/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | 12 | 13 | module.exports = { 14 | context: path.resolve(__dirname, '../'), 15 | entry: { 16 | app: './src/main.js' 17 | }, 18 | output: { 19 | path: config.build.assetsRoot, 20 | filename: '[name].js', 21 | publicPath: process.env.NODE_ENV === 'production' 22 | ? config.build.assetsPublicPath 23 | : config.dev.assetsPublicPath 24 | }, 25 | resolve: { 26 | extensions: ['.js', '.vue', '.json'], 27 | alias: { 28 | 'vue$': 'vue/dist/vue.esm.js', 29 | '@': resolve('src'), 30 | } 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /\.vue$/, 36 | loader: 'vue-loader', 37 | options: vueLoaderConfig 38 | }, 39 | { 40 | test: /\.js$/, 41 | loader: 'babel-loader', 42 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 43 | }, 44 | { 45 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 46 | loader: 'url-loader', 47 | options: { 48 | limit: 10000, 49 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 50 | } 51 | }, 52 | { 53 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 54 | loader: 'url-loader', 55 | options: { 56 | limit: 10000, 57 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 58 | } 59 | }, 60 | { 61 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 62 | loader: 'url-loader', 63 | options: { 64 | limit: 10000, 65 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 66 | } 67 | } 68 | ] 69 | }, 70 | node: { 71 | // prevent webpack from injecting useless setImmediate polyfill because Vue 72 | // source contains it (although only uses it if it's native). 73 | setImmediate: false, 74 | // prevent webpack from injecting mocks to Node native modules 75 | // that does not make sense for the client 76 | dgram: 'empty', 77 | fs: 'empty', 78 | net: 'empty', 79 | tls: 'empty', 80 | child_process: 'empty' 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /web/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /web/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.3.1 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: '0.0.0.0', // can be overwritten by process.env.HOST 17 | port: 2047, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true, 37 | 38 | // API Proxying During Development 39 | proxyTable: { 40 | '*': { 41 | target: 'http://localhost:2048', 42 | changeOrigin: true, 43 | }, 44 | }, 45 | }, 46 | 47 | build: { 48 | // Template for index.html 49 | index: path.resolve(__dirname, '../dist/index.html'), 50 | 51 | // Paths 52 | assetsRoot: path.resolve(__dirname, '../dist'), 53 | assetsSubDirectory: 'static', 54 | assetsPublicPath: '/', 55 | 56 | /** 57 | * Source Maps 58 | */ 59 | 60 | productionSourceMap: true, 61 | // https://webpack.js.org/configuration/devtool/#production 62 | devtool: '#source-map', 63 | 64 | // Gzip off by default as many popular static hosts such as 65 | // Surge or Netlify already gzip all static assets for you. 66 | // Before setting to `true`, make sure to: 67 | // npm install --save-dev compression-webpack-plugin 68 | productionGzip: false, 69 | productionGzipExtensions: ['js', 'css'], 70 | 71 | // Run the build command with an extra argument to 72 | // View the bundle analyzer report after build finishes: 73 | // `npm run build --report` 74 | // Set to `true` or `false` to always turn it on or off 75 | bundleAnalyzerReport: process.env.npm_config_report 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /web/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /web/design/boot-img.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/design/boot-img.psd -------------------------------------------------------------------------------- /web/design/sysmon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/design/sysmon.psd -------------------------------------------------------------------------------- /web/doc/fonts/iconfont/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/doc/fonts/iconfont/iconfont.eot -------------------------------------------------------------------------------- /web/doc/fonts/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/doc/fonts/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /web/doc/fonts/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/doc/fonts/iconfont/iconfont.woff -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sysmon 7 | 8 | 9 | 10 | 11 | 49 | 50 | 51 |
52 | 53 | 54 |
55 |
56 | Loading APP... 57 |
58 | 59 |
60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web", 3 | "version": "1.0.0", 4 | "description": "sysmon frontend", 5 | "author": "lightime ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "axios": "^0.18.0", 14 | "chart.js": "^2.7.2", 15 | "material-design-icons-iconfont": "^3.0.3", 16 | "vicon": "^1.0.4", 17 | "vue": "^2.5.2", 18 | "vue-chartjs": "^3.3.1", 19 | "vue-router": "^3.0.1", 20 | "vuetify": "^1.0.17" 21 | }, 22 | "devDependencies": { 23 | "autoprefixer": "^7.1.2", 24 | "babel-core": "^6.22.1", 25 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 26 | "babel-loader": "^7.1.1", 27 | "babel-plugin-syntax-jsx": "^6.18.0", 28 | "babel-plugin-transform-runtime": "^6.22.0", 29 | "babel-plugin-transform-vue-jsx": "^3.5.0", 30 | "babel-preset-env": "^1.3.2", 31 | "babel-preset-stage-2": "^6.22.0", 32 | "chalk": "^2.0.1", 33 | "copy-webpack-plugin": "^4.0.1", 34 | "css-loader": "^0.28.0", 35 | "extract-text-webpack-plugin": "^3.0.0", 36 | "file-loader": "^1.1.4", 37 | "friendly-errors-webpack-plugin": "^1.6.1", 38 | "html-webpack-plugin": "^2.30.1", 39 | "node-notifier": "^5.1.2", 40 | "optimize-css-assets-webpack-plugin": "^3.2.0", 41 | "ora": "^1.2.0", 42 | "portfinder": "^1.0.13", 43 | "postcss-import": "^11.0.0", 44 | "postcss-loader": "^2.0.8", 45 | "postcss-url": "^7.2.1", 46 | "rimraf": "^2.6.0", 47 | "semver": "^5.3.0", 48 | "shelljs": "^0.7.6", 49 | "uglifyjs-webpack-plugin": "^1.1.1", 50 | "url-loader": "^0.5.8", 51 | "vue-loader": "^13.3.0", 52 | "vue-style-loader": "^3.0.1", 53 | "vue-template-compiler": "^2.5.2", 54 | "webpack": "^3.6.0", 55 | "webpack-bundle-analyzer": "^2.9.0", 56 | "webpack-dev-server": "^2.9.1", 57 | "webpack-merge": "^4.1.0" 58 | }, 59 | "engines": { 60 | "node": ">= 6.0.0", 61 | "npm": ">= 3.0.0" 62 | }, 63 | "browserslist": [ 64 | "> 1%", 65 | "last 2 versions", 66 | "not ie <= 8" 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /web/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 24 | -------------------------------------------------------------------------------- /web/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/src/assets/logo.png -------------------------------------------------------------------------------- /web/src/components/Init.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 59 | 60 | -------------------------------------------------------------------------------- /web/src/components/Toolbar.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /web/src/components/common/Doughnut.js: -------------------------------------------------------------------------------- 1 | import { Doughnut, mixins } from 'vue-chartjs' 2 | const { reactiveProp } = mixins 3 | 4 | export default { 5 | extends: Doughnut, 6 | mixins: [reactiveProp], 7 | props: ['options'], 8 | mounted () { 9 | // this.chartData is created in the mixin 10 | this.renderChart(this.chartData, this.options) 11 | } 12 | } -------------------------------------------------------------------------------- /web/src/components/common/about.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 45 | -------------------------------------------------------------------------------- /web/src/components/common/confirmBtns.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 50 | 51 | -------------------------------------------------------------------------------- /web/src/components/common/serverInputField.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 63 | 64 | -------------------------------------------------------------------------------- /web/src/components/content/FS.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 68 | 69 | 70 | 75 | -------------------------------------------------------------------------------- /web/src/components/content/Setting.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /web/src/components/content/processes/detailsLimits.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | <> 61 | -------------------------------------------------------------------------------- /web/src/components/content/resources/LineChart.js: -------------------------------------------------------------------------------- 1 | import { Line, mixins } from 'vue-chartjs' 2 | const { reactiveProp } = mixins 3 | 4 | export default { 5 | extends: Line, 6 | mixins: [reactiveProp], 7 | props: ['options'], 8 | mounted () { 9 | // this.chartData is created in the mixin 10 | this.renderChart(this.chartData, this.options) 11 | } 12 | } -------------------------------------------------------------------------------- /web/src/components/content/resources/chartHdr.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 30 | 31 | 43 | -------------------------------------------------------------------------------- /web/src/components/content/resources/chartLegendBar.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 40 | 41 | 46 | 47 | -------------------------------------------------------------------------------- /web/src/components/content/resources/cpu.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 43 | -------------------------------------------------------------------------------- /web/src/components/content/resources/disk.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 49 | 50 | 53 | 54 | -------------------------------------------------------------------------------- /web/src/components/content/resources/mem.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 41 | -------------------------------------------------------------------------------- /web/src/components/content/resources/net.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 59 | 60 | -------------------------------------------------------------------------------- /web/src/components/header/clearSetting.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 30 | 31 | -------------------------------------------------------------------------------- /web/src/components/header/serverInfo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | 15 | -------------------------------------------------------------------------------- /web/src/components/more.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 46 | 47 | 52 | -------------------------------------------------------------------------------- /web/src/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("resources.css"); -------------------------------------------------------------------------------- /web/src/css/resources.css: -------------------------------------------------------------------------------- 1 | .rsc-chart{ 2 | padding-top: 2em; 3 | } 4 | 5 | 6 | .rsc-legend-bar{ 7 | padding-top: 0.2em; 8 | } 9 | 10 | .rsc-line-chart-container { 11 | position: relative; 12 | margin: auto; 13 | width: 99%; 14 | } -------------------------------------------------------------------------------- /web/src/js/common/backendAPI.js: -------------------------------------------------------------------------------- 1 | const ver = "v1" 2 | 3 | let path = { 4 | infoAll: "/" + ver + "/info/all", 5 | infoDisk: "/" + ver + "/info/disk", 6 | 7 | processAll: "/" + ver + "/process/all", 8 | processDetails: "/" + ver + "/process/details", 9 | 10 | sysInfoAll: "/" + ver + "/sysInfo/all", 11 | sysInfoHostname: "/" + ver + "/sysInfo/hostname", 12 | } 13 | 14 | var activeServer = localStorage.getItem("activeServer") 15 | if(!activeServer) { 16 | activeServer = "" 17 | } 18 | 19 | const infoAll = activeServer + path.infoAll; 20 | const infoDisk = activeServer + path.infoDisk; 21 | 22 | const processAll = activeServer + path.processAll; 23 | const processDetails = activeServer + path.processDetails; 24 | 25 | const sysInfoAll = activeServer + path.sysInfoAll; 26 | const sysInfoHostname = activeServer + path.sysInfoHostname; 27 | 28 | exports.path = path; 29 | 30 | exports.infoAll = infoAll; 31 | exports.infoDisk = infoDisk; 32 | 33 | exports.processAll = processAll; 34 | exports.processDetails = processDetails; 35 | 36 | exports.sysInfoAll = sysInfoAll; 37 | exports.sysInfoHostname = sysInfoHostname; -------------------------------------------------------------------------------- /web/src/js/common/dataDef.js: -------------------------------------------------------------------------------- 1 | function remoteData(err, obj){ 2 | this.err = err; 3 | this.obj = obj; 4 | } 5 | 6 | exports.remoteData = remoteData; -------------------------------------------------------------------------------- /web/src/js/common/fs.js: -------------------------------------------------------------------------------- 1 | var axios = require('axios'); 2 | var bapi = require('./backendAPI'); 3 | 4 | let updater = null; 5 | let interval = 1000; 6 | 7 | function runUpdater(self) { 8 | axios.get(bapi.infoDisk).then(function(res){ 9 | self.info = res.data 10 | //console.log(self.rsc); 11 | updater = setTimeout(runUpdater, interval, self); 12 | }).catch(function(err){ 13 | console.log("get disk info failed: " + err); 14 | self.infoErr = err; 15 | updater = setTimeout(runUpdater, interval, self); 16 | }) 17 | } 18 | function startUpdater(self){ 19 | if (updater) { 20 | console.log("fs updater already updated before."); 21 | return; 22 | } 23 | console.log("start fs updater"); 24 | interval = self.interval; 25 | runUpdater(self); 26 | } 27 | 28 | function stopUpdater(){ 29 | console.log("stop fs updater."); 30 | clearTimeout(updater); 31 | updater = null; 32 | } 33 | 34 | exports.startUpdater = startUpdater; 35 | exports.stopUpdater = stopUpdater; -------------------------------------------------------------------------------- /web/src/js/common/index.js: -------------------------------------------------------------------------------- 1 | var rsc = require('./resources') 2 | var process = require('./processes') 3 | var fs = require('./fs') 4 | var fmtSize = require('./fmtSize') 5 | var sysInfo = require('./sysInfo') 6 | var bapi = require('./backendAPI') 7 | import sapi from './serverAPI' 8 | 9 | export default { 10 | bus: null, 11 | 12 | rsc: rsc, 13 | process: process, 14 | fmtSize: fmtSize, 15 | fs: fs, 16 | sysInfo: sysInfo, 17 | bapi: bapi, 18 | sapi: sapi, 19 | } -------------------------------------------------------------------------------- /web/src/js/common/processes.js: -------------------------------------------------------------------------------- 1 | var axios = require('axios'); 2 | var bapi = require('./backendAPI'); 3 | var dd = require('./dataDef'); 4 | 5 | let interval = 1000; 6 | 7 | function runUpdater(ctrl, api) { 8 | // console.log("api: " + api); 9 | axios.get(api).then(function(res){ 10 | ctrl.info = res.data 11 | //console.log(ctrl.rsc); 12 | ctrl.updater = setTimeout(runUpdater, interval, ctrl, api); 13 | // console.log(ctrl.type, ctrl.pid + " updater: ", ctrl.updater); 14 | }).catch(function(err){ 15 | console.log("get info all failed: " + err); 16 | ctrl.infoErr = err; 17 | ctrl.updater = setTimeout(runUpdater, interval, ctrl, api); 18 | }) 19 | } 20 | function startUpdater(ctrl){ 21 | if (ctrl.updater) { 22 | console.log("processes updater of this ctrl already updated before."); 23 | return; 24 | } 25 | 26 | if(ctrl.interval) { 27 | interval = ctrl.interval; 28 | } 29 | 30 | switch (ctrl.type){ 31 | case "all": 32 | console.log("run updater for all processes"); 33 | runUpdater(ctrl, bapi.processAll); 34 | break; 35 | case "details": 36 | console.log("run updater for process details of ", ctrl.pid); 37 | runUpdater(ctrl, bapi.processDetails + "?pid=" + ctrl.pid); 38 | break; 39 | default: 40 | console.log("runUPdater: unknow type: " + type); 41 | break; 42 | } 43 | } 44 | 45 | function stopUpdater(ctrl){ 46 | if(!ctrl.updater) { 47 | console.log("updater of this ctrl already stoped before."); 48 | return; 49 | } 50 | 51 | console.log("stop processes updater"); 52 | clearTimeout(ctrl.updater); 53 | ctrl.updater = null; 54 | } 55 | 56 | exports.startUpdater = startUpdater; 57 | exports.stopUpdater = stopUpdater; -------------------------------------------------------------------------------- /web/src/js/common/sysInfo.js: -------------------------------------------------------------------------------- 1 | var axios = require('axios'); 2 | var bapi = require('./backendAPI'); 3 | 4 | // sysInfo 包含系统静态信息,一般首次打开应用时更新一次即可 5 | 6 | // let SysInfo = {}; 7 | 8 | function getSysInfo(serverInfo) { 9 | console.log("updateSysInfoAll"); 10 | axios.get(bapi.sysInfoAll).then(function(res){ 11 | serverInfo.SysInfo = res.data 12 | }).catch(function(err){ 13 | console.log("get SysInfo all failed: " + err); 14 | }) 15 | } 16 | 17 | // 获取当前连接的 server (activeServer)的 hostname,保存到 self 参数的 hostname 属性中 18 | function getHostname(self) { 19 | console.log("getHostname"); 20 | axios.get(bapi.sysInfoHostname).then(function(res){ 21 | console.log("hostname: ", res.data) 22 | self.hostname = res.data; 23 | }).catch(function(err){ 24 | console.log("get SysInfo all failed: " + err); 25 | }) 26 | } 27 | 28 | exports.getSysInfo = getSysInfo; 29 | exports.getHostname = getHostname; -------------------------------------------------------------------------------- /web/src/js/tips/index.js: -------------------------------------------------------------------------------- 1 | var resources = require('./resources') 2 | var processes = require('./processes') 3 | 4 | export default { 5 | resources: resources, 6 | processes: processes, 7 | } -------------------------------------------------------------------------------- /web/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import Vuetify from 'vuetify' 7 | import 'vuetify/dist/vuetify.min.css' 8 | 9 | import cm from './js/common' 10 | import './css/app.css' 11 | import 'material-design-icons-iconfont/dist/material-design-icons.css' 12 | 13 | import icon from 'vicon' 14 | import './static/icon/iconfont' 15 | 16 | Vue.config.productionTip = false 17 | 18 | Vue.use(Vuetify); 19 | Vue.component('icon', icon) 20 | 21 | cm.bus = new Vue(); 22 | 23 | /* eslint-disable no-new */ 24 | new Vue({ 25 | el: '#app', 26 | router, 27 | components: { App }, 28 | template: '' 29 | }) 30 | -------------------------------------------------------------------------------- /web/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | import Layout from '@/components/Layout' 5 | import Init from '@/components/Init' 6 | import Resources from '@/components/content/Resources' 7 | import Processes from '@/components/content/Processes' 8 | import FS from '@/components/content/FS.vue' 9 | import Setting from '@/components/content/Setting.vue' 10 | 11 | Vue.use(Router) 12 | 13 | export default new Router({ 14 | routes: [ 15 | { 16 | path: '/', 17 | redirect: Init, 18 | }, 19 | { 20 | path: '/init', 21 | name: 'Init', 22 | component: Init, 23 | }, 24 | { 25 | path: '/main', 26 | name: 'Main', 27 | component: Layout, 28 | redirect: Resources, 29 | children: [ 30 | { 31 | path: 'resources', 32 | name: 'Resources', 33 | component: Resources, 34 | }, 35 | { 36 | path: 'processes', 37 | name: 'Processes', 38 | component: Processes, 39 | }, 40 | { 41 | path: 'fs', 42 | name: 'FS', 43 | component: FS, 44 | }, 45 | { 46 | path: 'setting', 47 | name: 'Setting', 48 | component: Setting, 49 | }, 50 | ], 51 | } 52 | ] 53 | }) 54 | -------------------------------------------------------------------------------- /web/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/static/.gitkeep -------------------------------------------------------------------------------- /web/static/PWA/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Sysmon", 3 | "name": "System Monitor", 4 | "icons": [ 5 | { 6 | "src": "../../static/img/48x48.png", 7 | "type": "image/png", 8 | "sizes": "48x48" 9 | }, 10 | { 11 | "src": "../../static/img/96x96.png", 12 | "type": "image/png", 13 | "sizes": "96x96" 14 | }, 15 | { 16 | "src": "../../static/img/192x192.png", 17 | "type": "image/png", 18 | "sizes": "192x192" 19 | } 20 | ], 21 | "start_url": "../../index.html", 22 | "background_color": "#ffffff", 23 | "theme_color": "#ffffff", 24 | "display": "standalone" 25 | } 26 | -------------------------------------------------------------------------------- /web/static/img/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/static/img/192x192.png -------------------------------------------------------------------------------- /web/static/img/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/static/img/48x48.png -------------------------------------------------------------------------------- /web/static/img/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/static/img/96x96.png -------------------------------------------------------------------------------- /web/static/img/drawerLeft/material.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lt0/sysmon/51b6c18cc8745c00458ee48b45a6cb3315bc4108/web/static/img/drawerLeft/material.jpg --------------------------------------------------------------------------------