├── .eslintignore ├── .eslintrc ├── .gitignore ├── get_alinode_version ├── get_disk_usage ├── get_node_exe ├── get_node_kill ├── get_node_processes ├── get_node_version ├── get_os_info ├── get_process_env ├── get_process_env.js ├── get_processes ├── get_processes_count ├── package.json ├── take_basic_prof ├── take_cpu_profile ├── take_diagnostic_report ├── take_gc_trace ├── take_gc_trace_verbose ├── take_heap_profile ├── take_heapdump ├── take_heaptimeline ├── upload_file └── uploader.js /.eslintignore: -------------------------------------------------------------------------------- 1 | *.debug.js 2 | *.min.js 3 | node_modules/* 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "indent": [ 4 | 2, 5 | 2 6 | ], 7 | "quotes": [ 8 | 2, 9 | "single" 10 | ], 11 | "linebreak-style": [ 12 | 2, 13 | "unix" 14 | ], 15 | "semi": [2, "always"], 16 | "strict": [2, "global"], 17 | "curly": 2, 18 | "eqeqeq": 2, 19 | "no-eval": 2, 20 | "guard-for-in": 2, 21 | "no-caller": 2, 22 | "no-else-return": 2, 23 | "no-eq-null": 2, 24 | "no-extend-native": 2, 25 | "no-extra-bind": 2, 26 | "no-floating-decimal": 2, 27 | "no-implied-eval": 2, 28 | "no-labels": 2, 29 | "no-with": 2, 30 | "no-loop-func": 1, 31 | "no-native-reassign": 2, 32 | "no-redeclare": [2, {"builtinGlobals": true}], 33 | "no-delete-var": 2, 34 | "no-shadow-restricted-names": 2, 35 | "no-undef-init": 2, 36 | "no-use-before-define": 2, 37 | "no-unused-vars": [2, {"args": "none"}], 38 | "no-undef": 2, 39 | "callback-return": [2, ["callback", "cb", "next"]], 40 | "global-require": 0, 41 | "no-console": 0, 42 | "require-yield": 0 43 | }, 44 | "env": { 45 | "es6": true, 46 | "node": true, 47 | "browser": true 48 | }, 49 | "globals": { 50 | "describe": true, 51 | "it": true, 52 | "before": true, 53 | "after": true 54 | }, 55 | "parserOptions": { 56 | "ecmaVersion": 8, 57 | "sourceType": "script", 58 | "ecmaFeatures": { 59 | "jsx": true 60 | } 61 | }, 62 | "extends": "eslint:recommended" 63 | } 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /get_alinode_version: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export ENABLE_NODE_LOG=NO 4 | 5 | DIR=$(cd "$(dirname "$0")"; pwd) 6 | GET_NODE_EXE=$DIR/get_node_exe 7 | NODE_EXE=`$GET_NODE_EXE` 8 | 9 | $NODE_EXE -p 'process.alinode' 10 | -------------------------------------------------------------------------------- /get_disk_usage: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $# != 0 ]; then 4 | df -P $@ 5 | exit 0 6 | fi 7 | 8 | IsInContainer=false 9 | 10 | CGROUP=/proc/1/cgroup 11 | SCHED=/proc/1/sched 12 | DOCKERENV=/.dockerenv 13 | 14 | if [ -f "$CGROUP" ]; then 15 | if grep /docker/ $CGROUP -qa; then 16 | IsInContainer=true 17 | elif grep /lxc/ $CGROUP -qa; then 18 | IsInContainer=true 19 | fi 20 | elif [ -f "$SCHED" ]; then 21 | if cat $SCHED | head -n 1 | grep -vqa "(1,"; then 22 | IsInContainer=true 23 | fi 24 | elif [ -f "$DOCKERENV" ]; then 25 | IsInContainer=true 26 | fi 27 | 28 | if [ "$IsInContainer" = "true" ]; then 29 | df -P / 30 | else 31 | df -P 32 | fi 33 | -------------------------------------------------------------------------------- /get_node_exe: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -x "$NODE_EXE" ] && [ -e "$NODE_EXE" ] ; then 4 | echo $NODE_EXE; 5 | elif [ -f "$HOME/.nodepath" ]; then 6 | echo `cat $HOME/.nodepath`/node; 7 | elif which node >/dev/null 2>&1; then 8 | echo `which node`; 9 | else 10 | echo "no available node"; 11 | exit 1; 12 | fi 13 | -------------------------------------------------------------------------------- /get_node_kill: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -x "$NODE_KILL" ] && [ -e "$NODE_KILL" ] ; then 4 | echo $NODE_KILL; 5 | elif [ -f "$HOME/.nodepath" ]; then 6 | echo `cat $HOME/.nodepath`/node-kill; 7 | elif which node-kill >/dev/null 2>&1; then 8 | echo `which node-kill`; 9 | else 10 | echo "no available node-kill"; 11 | exit 1; 12 | fi 13 | 14 | -------------------------------------------------------------------------------- /get_node_processes: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ps -e -o pid,args | grep -E "node |iojs |PM2 " | grep -v get_node_processes | grep -v grep 4 | -------------------------------------------------------------------------------- /get_node_version: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export ENABLE_NODE_LOG=NO 4 | 5 | DIR=$(cd "$(dirname "$0")"; pwd) 6 | GET_NODE_EXE=$DIR/get_node_exe 7 | NODE_EXE=`$GET_NODE_EXE` 8 | 9 | $NODE_EXE -v 10 | -------------------------------------------------------------------------------- /get_os_info: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export ENABLE_NODE_LOG=NO 4 | 5 | DIR=$(cd "$(dirname "$0")"; pwd) 6 | GET_NODE_EXE=$DIR/get_node_exe 7 | NODE_EXE=`$GET_NODE_EXE` 8 | 9 | $NODE_EXE -e ' 10 | var os = require("os"); 11 | console.log("%s/%s/%s/%s/%s", os.type(), os.hostname(), os.platform(), os.arch(), os.release()); 12 | ' 13 | -------------------------------------------------------------------------------- /get_process_env: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export ENABLE_NODE_LOG=NO 4 | 5 | DIR=$(cd "$(dirname "$0")"; pwd) 6 | GET_NODE_EXE=$DIR/get_node_exe 7 | NODE_EXE=`$GET_NODE_EXE` 8 | 9 | SCRIPT=$DIR/get_process_env.js 10 | 11 | #get_process_env pid 12 | $NODE_EXE "$SCRIPT" $1 13 | -------------------------------------------------------------------------------- /get_process_env.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { execSync } = require('child_process'); 4 | 5 | const argv = process.argv.slice(2); 6 | 7 | const [pid] = argv; 8 | 9 | if (!pid) { 10 | console.log('Please pass '); 11 | console.log('Usage:'); 12 | console.log(' get_process_env '); 13 | process.exit(1); 14 | } 15 | 16 | if (require('os').type() !== 'Linux') { 17 | console.log('Not support non-linux'); 18 | process.exit(1); 19 | } 20 | 21 | function getAlinodeVersion(pid) { 22 | const output = execSync(`ls -l /proc/${pid}/exe`, { 23 | encoding: 'utf8' 24 | }); 25 | // get execPath from PID 26 | // $ ls -l /proc/10532/exe 27 | // lrwxrwxrwx 1 puling.tyq users 0 Mar 8 16:54 /proc/10532/exe -> /home/puling.tyq/.tnvm/versions/node/v8.6.0/bin/node 28 | let [, execPath] = output.split('->'); 29 | execPath = execPath.trim(); 30 | if (!execPath.endsWith('bin/node')) { 31 | return ''; 32 | } 33 | 34 | const versionOutput = execSync(`${execPath} -p "process.alinode"`, { 35 | encoding: 'utf8' 36 | }); 37 | 38 | return versionOutput.trim(); 39 | } 40 | 41 | function getProcessEnv(pid) { 42 | const output = execSync(`cat /proc/${pid}/environ`, { 43 | encoding: 'utf8' 44 | }); 45 | const lines = output.split('\u0000'); 46 | 47 | var env = {ENABLE_NODE_LOG: '', NODE_LOG_DIR: '/tmp'}; 48 | var pm2_env = {}; 49 | 50 | for (var i = 0; i < lines.length; i++) { 51 | const line = lines[i]; 52 | if (line.startsWith('ENABLE_NODE_LOG')) { 53 | env.ENABLE_NODE_LOG = line.split('=')[1]; 54 | } 55 | 56 | if (line.startsWith('NODE_LOG_DIR')) { 57 | env.NODE_LOG_DIR = line.split('=')[1]; 58 | } 59 | 60 | if (line.startsWith('pm2_env=')) { 61 | try { 62 | pm2_env = JSON.parse(line.substr('pm2_env='.length)); 63 | } catch (e) { 64 | } 65 | } 66 | } 67 | 68 | env.NODE_LOG_DIR = env.NODE_LOG_DIR || pm2_env.NODE_LOG_DIR; 69 | env.ENABLE_NODE_LOG = env.ENABLE_NODE_LOG || pm2_env.ENABLE_NODE_LOG; 70 | 71 | if (!env.NODE_LOG_DIR.endsWith('/')) { 72 | env.NODE_LOG_DIR += '/'; 73 | } 74 | 75 | return env; 76 | } 77 | 78 | var env = getProcessEnv(pid); 79 | 80 | const logdir = process.env.logdir; 81 | 82 | var data = { 83 | alinode_version: getAlinodeVersion(pid), 84 | ENABLE_NODE_LOG: env.ENABLE_NODE_LOG, 85 | NODE_LOG_DIR: env.NODE_LOG_DIR, 86 | logdir: logdir 87 | }; 88 | 89 | console.log(JSON.stringify(data)); 90 | -------------------------------------------------------------------------------- /get_processes: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ps -e -o pid,args | grep "$1 " | grep -v get_processes | grep -v grep 4 | -------------------------------------------------------------------------------- /get_processes_count: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ps -e -o pid,args | grep -E "$1 |$1$" | grep -vE 'grep|get_processes_count' -c 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commandx", 3 | "version": "1.5.4", 4 | "description": "commands of alinode agentx", 5 | "scripts": {}, 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/aliyun-node/commands.git" 9 | }, 10 | "keywords": [ 11 | "alinode", 12 | "agentx", 13 | "commands" 14 | ], 15 | "author": "alinode team", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/aliyun-node/commands/issues" 19 | }, 20 | "homepage": "https://github.com/aliyun-node/commands#readme", 21 | "dependencies": { 22 | "formstream": "^1.1.0", 23 | "tunnel-agent": "^0.6.0", 24 | "urllib": "^2.22.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /take_basic_prof: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$(cd "$(dirname "$0")"; pwd) 4 | GET_NODE_KILL=$DIR/get_node_kill 5 | NODE_KILL=`$GET_NODE_KILL` 6 | 7 | $NODE_KILL --v8-options --prof --prof_cpp --pid=$1 8 | -------------------------------------------------------------------------------- /take_cpu_profile: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$(cd "$(dirname "$0")"; pwd) 4 | GET_NODE_KILL=$DIR/get_node_kill 5 | NODE_KILL=`$GET_NODE_KILL` 6 | 7 | $NODE_KILL --start_profiling $1 8 | -------------------------------------------------------------------------------- /take_diagnostic_report: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$(cd "$(dirname "$0")"; pwd) 4 | GET_NODE_KILL=$DIR/get_node_kill 5 | NODE_KILL=`$GET_NODE_KILL` 6 | 7 | $NODE_KILL --diag_report $1 8 | -------------------------------------------------------------------------------- /take_gc_trace: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$(cd "$(dirname "$0")"; pwd) 4 | GET_NODE_KILL=$DIR/get_node_kill 5 | NODE_KILL=`$GET_NODE_KILL` 6 | 7 | $NODE_KILL --v8-options --trace_gc --pid=$1 8 | -------------------------------------------------------------------------------- /take_gc_trace_verbose: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$(cd "$(dirname "$0")"; pwd) 4 | GET_NODE_KILL=$DIR/get_node_kill 5 | NODE_KILL=`$GET_NODE_KILL` 6 | 7 | $NODE_KILL --v8-options --trace_gc --trace_gc_nvp --trace_fragmentation --trace_gc_verbose --pid=$1 8 | -------------------------------------------------------------------------------- /take_heap_profile: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$(cd "$(dirname "$0")"; pwd) 4 | GET_NODE_KILL=$DIR/get_node_kill 5 | NODE_KILL=`$GET_NODE_KILL` 6 | 7 | PID=$1 8 | TIME=${2:-180}s 9 | 10 | $NODE_KILL --start_heap_profiling time=$TIME $PID 11 | -------------------------------------------------------------------------------- /take_heapdump: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$(cd "$(dirname "$0")"; pwd) 4 | GET_NODE_KILL=$DIR/get_node_kill 5 | NODE_KILL=`$GET_NODE_KILL` 6 | 7 | $NODE_KILL --heapdump $1 8 | -------------------------------------------------------------------------------- /take_heaptimeline: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DIR=$(cd "$(dirname "$0")"; pwd) 4 | GET_NODE_KILL=$DIR/get_node_kill 5 | NODE_KILL=`$GET_NODE_KILL` 6 | 7 | PID=$1 8 | TIME=${2:-30}s 9 | 10 | $NODE_KILL --start_timeline time=$TIME $PID 11 | -------------------------------------------------------------------------------- /upload_file: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export ENABLE_NODE_LOG=NO 4 | 5 | DIR=$(cd "$(dirname "$0")"; pwd) 6 | GET_NODE_EXE=$DIR/get_node_exe 7 | NODE_EXE=`$GET_NODE_EXE` 8 | 9 | FULL_PATH=$2 10 | TARGET_PATH=$2 11 | 12 | filesize=`ls -l $FULL_PATH|awk '{print $5}'` 13 | 14 | if [ "$filesize" = 0 ]; then 15 | echo '空文件' 16 | exit 1 17 | fi 18 | 19 | GZIP=`which gzip` 20 | 21 | if [ $GZIP ] && [ -f "$FULL_PATH" ]; then 22 | $GZIP -c $FULL_PATH > $FULL_PATH".gz" 23 | TARGET_PATH=$FULL_PATH".gz" 24 | fi 25 | 26 | UPLOADER=$DIR/uploader.js 27 | 28 | #uploader server filepath token id 29 | $NODE_EXE "$UPLOADER" $1 $TARGET_PATH $3 $4 $5 30 | -------------------------------------------------------------------------------- /uploader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // ./uploader server filepath token id 4 | var fs = require('fs'); 5 | var os = require('os'); 6 | var crypto = require('crypto'); 7 | var urllib = require('urllib'); 8 | var formstream = require('formstream'); 9 | var tunnel = require('tunnel-agent'); 10 | 11 | var argv = process.argv.slice(2); 12 | 13 | var server = argv[0]; 14 | var filepath = argv[1]; 15 | var token = argv[2]; 16 | var id = argv[3]; 17 | var type = argv[4]; 18 | 19 | // check args 20 | if (!server || !filepath || !token || !id) { 21 | console.log('参数错误'); 22 | console.log('\t usage: ./uploader server filepath token id'); 23 | process.exit(1); 24 | } 25 | 26 | // check filepath 27 | fs.stat(filepath, function (err, stat) { 28 | if (err) { 29 | console.log('文件不存在'); 30 | console.log(err.message); 31 | process.exit(1); 32 | return; 33 | } 34 | 35 | if (stat.size <= 0) { 36 | console.log('空文件'); 37 | process.exit(1); 38 | return; 39 | } 40 | 41 | var form = formstream(); 42 | form.file('file', filepath, filepath, stat.size); 43 | 44 | var nonce = '' + parseInt((Math.random() * 100000000000), 10); 45 | // get signature 46 | var shasum = crypto.createHash('sha1'); 47 | shasum.update([process.env.agentid || os.hostname(), token, nonce, id].join('')); 48 | var sign = shasum.digest('hex'); 49 | 50 | var url = 'http://' + server + '/files/' + id + '?nonce=' + nonce + '&sign=' + sign + '&type=' + type; 51 | 52 | var gateway = process.env.GATEWAY; 53 | if (gateway) { 54 | // upload to gateway 55 | url = 'http://' + gateway + '/file?target=' + encodeURIComponent(url); 56 | } 57 | 58 | var agent = false; 59 | if (process.env.http_proxy) { 60 | var parts = process.env.http_proxy.split(':'); 61 | agent = tunnel.httpOverHttp({ 62 | proxy: { 63 | host: parts[0], 64 | port: parts[1] 65 | } 66 | }); 67 | } 68 | 69 | var opts = { 70 | dataType: 'json', 71 | type: 'POST', 72 | timeout: 60000 * 20, // 20分钟超时 73 | headers: form.headers(), 74 | stream: form, 75 | agent: agent 76 | }; 77 | 78 | urllib.request(url, opts, function (err, data, res) { 79 | if (err) { 80 | throw err; 81 | } 82 | 83 | console.log(JSON.stringify(data)); 84 | process.exit(0); 85 | }); 86 | }); 87 | --------------------------------------------------------------------------------