Authored by 姜枫

add influxdb

@@ -84,7 +84,7 @@ class Build { @@ -84,7 +84,7 @@ class Build {
84 _cloneCode(branch) { 84 _cloneCode(branch) {
85 var self = this; 85 var self = this;
86 this._state('cloning_code'); 86 this._state('cloning_code');
87 - let clone_script = `git clone -b ${branch} --progress ${this.project.gitlab}`; 87 + let clone_script = `git clone -b ${branch} ${this.project.gitlab}`;
88 this._log(`>>>>>>>>> ${clone_script} >>>>>>>>>>>`); 88 this._log(`>>>>>>>>> ${clone_script} >>>>>>>>>>>`);
89 89
90 return new Promise((reslove, reject) => { 90 return new Promise((reslove, reject) => {
@@ -52,18 +52,16 @@ class Deploy { @@ -52,18 +52,16 @@ class Deploy {
52 } catch (e) { 52 } catch (e) {
53 self._state('fail'); 53 self._state('fail');
54 self._log(e); 54 self._log(e);
55 - console.error(e);  
56 } 55 }
57 }).on('error', (err) => { 56 }).on('error', (err) => {
58 self._state('fail'); 57 self._state('fail');
59 self._log(err); 58 self._log(err);
60 - console.log(err);  
61 }).connect(serverInfo); 59 }).connect(serverInfo);
62 } 60 }
63 61
64 _preDeploy(conn) { 62 _preDeploy(conn) {
65 let self = this; 63 let self = this;
66 - return new Promise((reslove, reject) => { 64 + return new Promise((resolve, reject) => {
67 let script = `mkdir -p ${self.remoteWorkDir} && mkdir -p ${self.remoteDist}`; 65 let script = `mkdir -p ${self.remoteWorkDir} && mkdir -p ${self.remoteDist}`;
68 self._state('preparing'); 66 self._state('preparing');
69 self._log(`>>>>>>>>> ${script} >>>>>>>>`); 67 self._log(`>>>>>>>>> ${script} >>>>>>>>`);
@@ -72,8 +70,7 @@ class Deploy { @@ -72,8 +70,7 @@ class Deploy {
72 reject(err); 70 reject(err);
73 } else { 71 } else {
74 stream.on('exit', (code) => { 72 stream.on('exit', (code) => {
75 - console.log(`mkdir code = ${code}`);  
76 - reslove(); 73 + resolve();
77 }); 74 });
78 } 75 }
79 76
@@ -83,14 +80,11 @@ class Deploy { @@ -83,14 +80,11 @@ class Deploy {
83 80
84 _scp(conn) { 81 _scp(conn) {
85 let self = this; 82 let self = this;
86 - console.log(`localFile : ${this.localFile}`);  
87 - console.log(`remoteFIle : ${this.remoteFile}`);  
88 83
89 - return new Promise((reslove, reject) => { 84 + return new Promise((resolve, reject) => {
90 self._state('uploading'); 85 self._state('uploading');
91 self._log(`>>>> uploading ${self.localFile} ==> ${self.remoteFile}`); 86 self._log(`>>>> uploading ${self.localFile} ==> ${self.remoteFile}`);
92 conn.sftp((err, sftp) => { 87 conn.sftp((err, sftp) => {
93 - console.log('open sftp');  
94 if (err) { 88 if (err) {
95 reject(err); 89 reject(err);
96 } else { 90 } else {
@@ -102,7 +96,7 @@ class Deploy { @@ -102,7 +96,7 @@ class Deploy {
102 } else { 96 } else {
103 self._log(' uploaded success!'); 97 self._log(' uploaded success!');
104 self._state('uploaded'); 98 self._state('uploaded');
105 - reslove(); 99 + resolve();
106 } 100 }
107 }); 101 });
108 } 102 }
@@ -112,9 +106,9 @@ class Deploy { @@ -112,9 +106,9 @@ class Deploy {
112 106
113 _unzip(conn) { 107 _unzip(conn) {
114 let self = this; 108 let self = this;
115 - return new Promise((reslove, reject) => { 109 + return new Promise((resolve, reject) => {
116 self._state('unziping'); 110 self._state('unziping');
117 - let script = `tar -zxvf ${self.remoteFile} -C ${self.remoteWorkDir}`; 111 + let script = `tar -zxvf ${self.remoteFile} -C ${self.remoteWorkDir} && rm -rf ${self.remoteDist}`;
118 self._log(`>>>> unziping ${self.remoteFile} ==> ${self.remoteWorkDir}`); 112 self._log(`>>>> unziping ${self.remoteFile} ==> ${self.remoteWorkDir}`);
119 conn.exec(script, (err, stream) => { 113 conn.exec(script, (err, stream) => {
120 if (err) { 114 if (err) {
@@ -128,9 +122,8 @@ class Deploy { @@ -128,9 +122,8 @@ class Deploy {
128 }); 122 });
129 stream.on('exit', (code) => { 123 stream.on('exit', (code) => {
130 if (code === 0) { 124 if (code === 0) {
131 - console.log('unzip success');  
132 self._state('unziped'); 125 self._state('unziped');
133 - reslove(); 126 + resolve();
134 } else { 127 } else {
135 reject('unzip fail: ' + script); 128 reject('unzip fail: ' + script);
136 } 129 }
@@ -143,7 +136,7 @@ class Deploy { @@ -143,7 +136,7 @@ class Deploy {
143 _startup(conn) { 136 _startup(conn) {
144 let self = this; 137 let self = this;
145 let startup = this.project.scripts.start; 138 let startup = this.project.scripts.start;
146 - return new Promise((reslove, reject) => { 139 + return new Promise((resolve, reject) => {
147 self._state('starting'); 140 self._state('starting');
148 self._log(`>>>> ${startup}`); 141 self._log(`>>>> ${startup}`);
149 conn.exec(`cd ${self.remoteRunningDir} && ${startup}`, (err, stream) => { 142 conn.exec(`cd ${self.remoteRunningDir} && ${startup}`, (err, stream) => {
@@ -158,9 +151,8 @@ class Deploy { @@ -158,9 +151,8 @@ class Deploy {
158 }); 151 });
159 stream.on('exit', (code) => { 152 stream.on('exit', (code) => {
160 if (code === 0) { 153 if (code === 0) {
161 - console.log('startup!');  
162 self._state('running'); 154 self._state('running');
163 - reslove(); 155 + resolve();
164 } else { 156 } else {
165 reject('startup fail'); 157 reject('startup fail');
166 } 158 }
@@ -169,7 +161,7 @@ class Deploy { @@ -169,7 +161,7 @@ class Deploy {
169 }); 161 });
170 }); 162 });
171 } 163 }
172 - 164 +
173 async _state(state) { 165 async _state(state) {
174 ws.broadcast(`/deploy/${this.project._id}`, { 166 ws.broadcast(`/deploy/${this.project._id}`, {
175 host: this.info.host, 167 host: this.info.host,
  1 +/**
  2 + *
  3 + * @author: jiangfeng<jeff.jiang@yoho.cn>
  4 + * @date: 2016/7/29
  5 + */
  6 +
  7 +const influx = require('influx');
  8 +
  9 +let client = influx({
  10 + hosts: [{
  11 + host: '54.222.219.223',
  12 + port: 8086,
  13 + protocol: 'http'
  14 + }],
  15 + database: 'udp'
  16 +});
  17 +
  18 +client.getSeriesNames((err, dbs) => {
  19 + console.log(err);
  20 + console.log(JSON.stringify(dbs));
  21 +});
  22 +
  23 +client.query('select * from test_point limit 10', function(err, results) {
  24 + console.log(results);
  25 +});
  26 +
  27 +const db = {
  28 + client: client,
  29 + query: (query) => {
  30 + return new Promise((resolve, reject) => {
  31 + client.query(query, (err, result) => {
  32 + if (err) {
  33 + reject(err);
  34 + } else {
  35 + resolve(result);
  36 + }
  37 + });
  38 + });
  39 + }
  40 +};
  41 +
  42 +module.exports = db;
  1 +/**
  2 + * 跟踪监控工具, 将监控数据写入influxdb
  3 + *
  4 + * @usage:
  5 + * <code>
  6 + * let trace = new Trace({
  7 + * host: '54.222.219.223',
  8 + * port: 4444
  9 + * });
  10 + *
  11 + * let testTrace = trace.trace('test_key'); // createOrChoose a measurement
  12 + *
  13 + * // testTrace(someTags, someFields);
  14 + * testTrace({ foo: 'bar', foobar: 'baz2'}, {value: 123, value2: 'aaa 123', value3: 1.3, value4: false});
  15 + *
  16 + * </code>
  17 + *
  18 + * @author: jiangfeng<jeff.jiang@yoho.cn>
  19 + * @date: 16/8/1
  20 + */
  21 +
  22 +'use strict';
  23 +
  24 +const dgram = require('dgram');
  25 +const influx = require('influx');
  26 +const _ = require('lodash');
  27 +
  28 +class Trace {
  29 +
  30 + /**
  31 + * influxdb connection config
  32 + *
  33 + * @param options
  34 + */
  35 + constructor(options) {
  36 + this.options = options;
  37 + }
  38 +
  39 + /**
  40 + * create or choose a measurement to write point in.
  41 + * @param name {string} the measurement name
  42 + * @param options {object} some options. the protocol of influxdb connection.
  43 + * @returns {function()} a point write function
  44 + */
  45 + trace(name, options) {
  46 + options = _.assign({
  47 + protocol: 'udp'
  48 + }, options);
  49 +
  50 + let self = this;
  51 +
  52 + if (options.protocol === 'udp') {
  53 + return (key, fields) => {
  54 + return self.udpTrace(name, options, key, fields);
  55 + };
  56 + } else if (options.protocol === 'http') {
  57 + return (key, fields) => {
  58 + return self.httpTrace(name, options, key, fields);
  59 + };
  60 + }
  61 + }
  62 +
  63 + /**
  64 + * write point into influxdb by UDP
  65 + *
  66 + * @param name {string} the measurement name
  67 + * @param options {object}
  68 + * @param key {object} some keys of data
  69 + * @param fields {object} some fields of data
  70 + * @returns {Promise}
  71 + */
  72 + udpTrace(name, options, key, fields) {
  73 +
  74 + if (_.isArray(key)) {
  75 + key.forEach(p => {
  76 + let line = `${this._escape(name)},${this._makeLine(p)}`;
  77 +
  78 + return this._updPostLine(line);
  79 + });
  80 + } else {
  81 + let line = `${this._escape(name)},${this._makeLine(key, false)} ${this._makeLine(fields, true)}`;
  82 +
  83 + return this._updPostLine(line);
  84 + }
  85 + }
  86 +
  87 + /**
  88 + * upd send.
  89 + * @param line {string} @see infulxdb's line protocol
  90 + * @returns {Promise}
  91 + * @private
  92 + */
  93 + _updPostLine(line) {
  94 + let self = this;
  95 +
  96 + return new Promise((resolve, reject) => {
  97 + let socket = dgram.createSocket("udp4");
  98 + let buff = new Buffer(line);
  99 +
  100 +
  101 + socket.send(buff, 0, buff.length, self.options.port, self.options.host, (err, rp) => {
  102 + socket.close();
  103 +
  104 + console.log(rp);
  105 + if (err) {
  106 + reject(err);
  107 + } else {
  108 + resolve();
  109 + }
  110 + });
  111 + });
  112 + }
  113 +
  114 + /**
  115 + * make the data with influxdb's line protocol.
  116 + * @see https://docs.influxdata.com/influxdb/v0.13/write_protocols/line/
  117 + *
  118 + * @param data {object}
  119 + * @param withNoQuote {boolean}
  120 + * @returns {string}
  121 + * @private
  122 + */
  123 + _makeLine(data, withNoQuote) {
  124 + if (_.isObject(data)) {
  125 + return Object.keys(data).map(key => {
  126 + return key + '=' + this._escape(data[key], withNoQuote);
  127 + }).join(',');
  128 + } else if (_.isArray(data)) {
  129 + return data.map(d => {
  130 + return this._makeLine(d, escape);
  131 + }).join(' ');
  132 + } else if (!_.isNil(data)) {
  133 + return 'value=' + this._escape(data, withNoQuote);
  134 + } else {
  135 + return '';
  136 + }
  137 + }
  138 +
  139 + /**
  140 + * data escape with influxdb's line protocol.
  141 + *
  142 + * @param value {*}
  143 + * @param withQuote {boolean}
  144 + * @returns {*}
  145 + * @private
  146 + */
  147 + _escape(value, withQuote) {
  148 + if (_.isString(value)) {
  149 + value = _.replace(value, /,/g, '\\,');
  150 + value = _.replace(value, /=/g, '\\=');
  151 +
  152 + if (withQuote) {
  153 + value = '"' + value + '"';
  154 + } else {
  155 + value = _.replace(value, /\s/g, '\\ ');
  156 + }
  157 + } else if (_.isInteger(value)) {
  158 + if (withQuote) {
  159 + value = value + 'i';
  160 + }
  161 + }
  162 +
  163 + return value;
  164 + }
  165 +
  166 + /**
  167 + * write point into influxdb by HTTP. use the open source node-influx module.
  168 + * @see https://github.com/node-influx/node-influx
  169 + *
  170 + * @param name {string} the measurement name
  171 + * @param options {object}
  172 + * @param key {object} some keys of data
  173 + * @param fields {object} some fields of data
  174 + * @returns {Promise}
  175 + */
  176 + httpTrace(name, options, key, fields) {
  177 + let client = this.getHttpClient();
  178 +
  179 + return new Promise((resolve, reject) => {
  180 + if (_.isArray(key)) {
  181 + client.writePoints(name, key, options, (err, rp) => {
  182 + if (err) {
  183 + reject(err);
  184 + } else {
  185 + resolve(rp)
  186 + }
  187 + });
  188 + } else {
  189 + client.writePoint(name, fields, key, options, (err, rp) => {
  190 + if (err) {
  191 + reject(err);
  192 + } else {
  193 + resolve(rp)
  194 + }
  195 + });
  196 + }
  197 + });
  198 + }
  199 +
  200 + /**
  201 + * the singleton http client.
  202 + *
  203 + * @returns {*}
  204 + */
  205 + getHttpClient() {
  206 + if (!this.httpClient) {
  207 + this.httpClient = influx(this.options);
  208 + }
  209 +
  210 + return this.httpClient;
  211 + }
  212 +}
  213 +
  214 +
  215 +module.exports = Trace;
@@ -6,9 +6,6 @@ import { @@ -6,9 +6,6 @@ import {
6 Server 6 Server
7 } from '../../models'; 7 } from '../../models';
8 8
9 -  
10 -  
11 -  
12 const r = new Router; 9 const r = new Router;
13 10
14 const envs = { 11 const envs = {
@@ -43,7 +40,7 @@ const servers = { @@ -43,7 +40,7 @@ const servers = {
43 port: port, 40 port: port,
44 env: env, 41 env: env,
45 deployDir: deployDir 42 deployDir: deployDir
46 - } 43 + };
47 if (_id) { 44 if (_id) {
48 await Server.update({ 45 await Server.update({
49 _id: _id 46 _id: _id
@@ -38,6 +38,7 @@ @@ -38,6 +38,7 @@
38 "fs-promise": "^0.5.0", 38 "fs-promise": "^0.5.0",
39 "fstream": "^1.0.9", 39 "fstream": "^1.0.9",
40 "handlebars": "^4.0.5", 40 "handlebars": "^4.0.5",
  41 + "influx": "^4.2.1",
41 "koa": "^2.0.0", 42 "koa": "^2.0.0",
42 "koa-body": "^1.4.0", 43 "koa-body": "^1.4.0",
43 "koa-convert": "^1.2.0", 44 "koa-convert": "^1.2.0",