Browse Source

Feature : #14 : _health and _version

pull/21/head v0.4.2
oof1lab 7 years ago
parent
commit
c0ee4166cd
  1. 63
      README.md
  2. 20
      index.js
  3. 4
      lib/util/cmd.helper.js
  4. 55
      lib/xapi.js
  5. 7
      package-lock.json
  6. 3
      package.json
  7. 66
      tests/tests.js

63
README.md

@ -85,7 +85,7 @@ Powered by popular node packages : ([express](https://github.com/expressjs/expre
* Upload single file * Upload single file
* Upload multiple files * Upload multiple files
* Download file * Download file
* Health and version apis
Use HTTP clients like [Postman](https://www.getpostman.com/) or [similar tools](https://chrome.google.com/webstore/search/http%20client?_category=apps) to invoke REST API calls Use HTTP clients like [Postman](https://www.getpostman.com/) or [similar tools](https://chrome.google.com/webstore/search/http%20client?_category=apps) to invoke REST API calls
@ -121,15 +121,16 @@ if you haven't on your system.
| GET :fire:| [/api/tableName/groupby](#group-by-having-as-api) | Group by results of column(s) | | GET :fire:| [/api/tableName/groupby](#group-by-having-as-api) | Group by results of column(s) |
| GET :fire:| [/api/tableName/ugroupby](#union-of-multiple-group-by-statements) | Multiple group by results using one call | | GET :fire:| [/api/tableName/ugroupby](#union-of-multiple-group-by-statements) | Multiple group by results using one call |
| GET :fire:| [/api/tableName/chart](#chart) | Numeric column distribution based on (min,max,step) or(step array) or (automagic)| | GET :fire:| [/api/tableName/chart](#chart) | Numeric column distribution based on (min,max,step) or(step array) or (automagic)|
| GET :fire:| [/api/tableName/autochart](#autochart) | Same as Chart but identifies which are numeric column automatically - gift for lazy while prototyping| | GET :fire:| [/api/tableName/autochart](#autochart) | Same as Chart but identifies which are numeric column automatically - gift for lazy while prototyping|
| GET :fire:| [/api/xjoin](#xjoin) | handles join | | GET :fire:| [/api/xjoin](#xjoin) | handles join |
| GET :fire:| [/dynamic](#run-dynamic-queries) | execute dynamic mysql statements with params | | GET :fire:| [/dynamic](#run-dynamic-queries) | execute dynamic mysql statements with params |
| GET :fire:| [/upload](#upload-single-file) | upload single file | | GET :fire:| [/upload](#upload-single-file) | upload single file |
| GET :fire:| [/uploads](#upload-multiple-files) | upload multiple files | | GET :fire:| [/uploads](#upload-multiple-files) | upload multiple files |
| GET :fire:| [/download](#download-file) | download a file | | GET :fire:| [/download](#download-file) | download a file |
| GET | /api/tableName/describe| describe each table for its columns | | GET | /api/tableName/describe | describe each table for its columns |
| GET | /api/tables| get all tables in database | | GET | /api/tables | get all tables in database |
| GET | [/_health](#health) | gets health of process and mysql -- details query params for more details |
| GET | [/_version](#version) | gets version of Xmysql, mysql, node|
## Relational Tables ## Relational Tables
@ -841,7 +842,55 @@ returns uploaded file names as string
http://localhost:3000/download?name=fileName http://localhost:3000/download?name=fileName
> For upload and download of files -> you can specify storage folder using -s option > For upload and download of files -> you can specify storage folder using -s option
> Upload and download apis are available only with local mysql server > Upload and download apis are available only with local mysql server
## Health
[:arrow_heading_up:](#api-overview)
http://localhost:3000/_health
```
{"process_uptime":3.858,"mysql_uptime":"2595"}
```
Shows up time of Xmysql process and mysql server
http://localhost:3000/_health?details=1
```
{"process_uptime":1.151,"mysql_uptime":"2798",
"os_total_memory":17179869184,
"os_free_memory":2516357120,
"os_load_average":[2.29931640625,2.1845703125,2.13818359375],
"v8_heap_statistics":{"total_heap_size":24735744,
"total_heap_size_executable":5242880,
"total_physical_size":23521048,
"total_available_size":1475503064,
"used_heap_size":18149064,
"heap_size_limit":1501560832,
"malloced_memory":8192,
"peak_malloced_memory":11065664,
"does_zap_garbage":0}}
```
Provides more details on process.
Infact passing any query param gives detailed health output: example below
http://localhost:3000/_health?voila
```
{"process_uptime":107.793,"mysql_uptime":"2905","os_total_memory":17179869184,"os_free_memory":2573848576,"os_load_average":[2.052734375,2.12890625,2.11767578125],"v8_heap_statistics":{"total_heap_size":24735744,"total_heap_size_executable":5242880,"total_physical_size":23735016,"total_available_size":1475411128,"used_heap_size":18454968,"heap_size_limit":1501560832,"malloced_memory":8192,"peak_malloced_memory":11065664,"does_zap_garbage":0}}
```
## Version
[:arrow_heading_up:](#api-overview)
http://localhost:3000/_version
```
{"Xmysql":"0.4.1","mysql":"5.7.15","node":"8.2.1"}
```
## When to use ? ## When to use ?
[:arrow_heading_up:](#api-overview) [:arrow_heading_up:](#api-overview)

20
index.js

@ -11,18 +11,18 @@ const dataHelp = require('./lib/util/data.helper.js');
const Xapi = require('./lib/xapi.js'); const Xapi = require('./lib/xapi.js');
const cmdargs = require('./lib/util/cmd.helper.js'); const cmdargs = require('./lib/util/cmd.helper.js');
cmdargs.handle(sqlConfig) cmdargs.handle(sqlConfig);
/**************** START : setup express ****************/ /**************** START : setup express ****************/
let app = express(); let app = express();
app.use(morgan('tiny')) app.use(morgan('tiny'));
app.use(cors()) app.use(cors());
app.use(bodyParser.json()) app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ app.use(bodyParser.urlencoded({
extended: true extended: true
})) }));
/**************** END : setup express ****************/ /**************** END : setup express ****************/
@ -43,16 +43,14 @@ let moreApis = new Xapi(sqlConfig,mysqlPool,app);
moreApis.init((err, results) => { moreApis.init((err, results) => {
app.listen(sqlConfig.portNumber,sqlConfig.ipAddress) app.listen(sqlConfig.portNumber,sqlConfig.ipAddress);
var t1 = process.hrtime(t) var t1 = process.hrtime(t);
var t2 = t1[0]+t1[1]/1000000000 var t2 = t1[0]+t1[1]/1000000000;
console.log(" Xmysql took : %d seconds",dataHelp.round(t2,1)); console.log(" Xmysql took : %d seconds",dataHelp.round(t2,1));
console.log(' '); console.log(' ');
console.log(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '); console.log(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ');
});
})
/**************** END : setup Xapi ****************/ /**************** END : setup Xapi ****************/

4
lib/util/cmd.helper.js

@ -1,6 +1,8 @@
'use strict'; 'use strict';
const program = require('commander'); const program = require('commander');
const colors = require('colors'); const colors = require('colors');
const pkginfo = require('pkginfo')(module);
program.on('--help', () => { program.on('--help', () => {
console.log('') console.log('')
@ -11,7 +13,7 @@ program.on('--help', () => {
}) })
program program
.version('0.4.1') .version(module.exports.version)
.option('-h, --host <n>', 'hostname of database / localhost by default') .option('-h, --host <n>', 'hostname of database / localhost by default')
.option('-u, --user <n>', 'username of database / root by default') .option('-u, --user <n>', 'username of database / root by default')
.option('-p, --password <n>', 'password of database / empty by default') .option('-p, --password <n>', 'password of database / empty by default')

55
lib/xapi.js

@ -3,8 +3,11 @@
var Xsql = require('./xsql.js'); var Xsql = require('./xsql.js');
var Xctrl = require('./xctrl.js'); var Xctrl = require('./xctrl.js');
var multer = require('multer'); var multer = require('multer');
var path = require('path'); const path = require('path');
const pkginfo = require('pkginfo')(module);
const v8 = require('v8'),
os = require('os');
//define class //define class
class Xapi { class Xapi {
@ -267,6 +270,12 @@ class Xapi {
this.app.get('/download', this.downloadFile.bind(this)); this.app.get('/download', this.downloadFile.bind(this));
/**************** END : multer routes ****************/ /**************** END : multer routes ****************/
/**************** START : health and version ****************/
this.app.get('/_health', this.asyncMiddleware(this.health.bind(this)));
this.app.get('/_version', this.asyncMiddleware(this.version.bind(this)));
/**************** END : health and version ****************/
stat.api += 4; stat.api += 4;
} }
@ -371,6 +380,50 @@ class Xapi {
/**************** END : files related ****************/ /**************** END : files related ****************/
/**************** START : health and version ****************/
async getMysqlUptime() {
let v = await this.mysql.exec('SHOW GLOBAL STATUS LIKE \'Uptime\';', []);
return v[0]['Value'];
}
async getMysqlHealth() {
let v = await this.mysql.exec('select version() as version', []);
return v[0]['version'];
}
async health(req, res) {
let status = {};
status['process_uptime'] = process.uptime();
status['mysql_uptime'] = await this.getMysqlUptime();
if (Object.keys(req.query).length) {
status['process_memory_usage'] = process.memoryUsage;
status['os_total_memory'] = os.totalmem();
status['os_free_memory'] = os.freemem();
status['os_load_average'] = os.loadavg();
status['v8_heap_statistics'] = v8.getHeapStatistics();
}
res.json(status);
}
async version(req, res) {
let version = {};
version['Xmysql'] = pkginfo.version;
version['mysql'] = await this.getMysqlHealth();
version['node'] = process.versions.node;
res.json(version);
}
/**************** END : health and version ****************/
} }

7
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "xmysql", "name": "xmysql",
"version": "0.4.0", "version": "0.4.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -636,6 +636,11 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
}, },
"pkginfo": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz",
"integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8="
},
"process-nextick-args": { "process-nextick-args": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",

3
package.json

@ -1,6 +1,6 @@
{ {
"name": "xmysql", "name": "xmysql",
"version": "0.4.1", "version": "0.4.2",
"description": "One command to generate REST APIs for any MySql database", "description": "One command to generate REST APIs for any MySql database",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
@ -34,6 +34,7 @@
"morgan": "^1.9.0", "morgan": "^1.9.0",
"multer": "^1.3.0", "multer": "^1.3.0",
"mysql": "^2.15.0", "mysql": "^2.15.0",
"pkginfo": "^0.4.1",
"serve-favicon": "^2.4.5" "serve-favicon": "^2.4.5"
}, },
"devDependencies": { "devDependencies": {

66
tests/tests.js

@ -8,7 +8,7 @@ var whereClause = require('../lib/util/whereClause.helper.js')
var should = require('should'); var should = require('should');
var request = require('supertest') var request = require('supertest')
const cmdargs = require('../lib/util/cmd.helper.js'); const cmdargs = require('../lib/util/cmd.helper.js');
const pkginfo = require('pkginfo')(module);
var args = {} var args = {}
var app = {} var app = {}
@ -1742,6 +1742,70 @@ describe('xmysql : tests', function () {
}); });
}); });
it('/_health should PASS', function (done) {
//post to an url with data
agent.get('/_health') //enter url
.expect(200)//200 for success 4xx for failure
.end(function (err, res) {
// Handle /api/v error
if (err) {
return done(err);
}
res.body['process_uptime'].should.be.greaterThanOrEqual(0);
res.body['mysql_uptime'].should.be.greaterThanOrEqual(0);
return done();
});
});
it('/_health?details=1 should PASS', function (done) {
//post to an url with data
agent.get('/_health?details=1') //enter url
.expect(200)//200 for success 4xx for failure
.end(function (err, res) {
// Handle /api/v error
if (err) {
return done(err);
}
res.body['process_uptime'].should.be.greaterThanOrEqual(0);
res.body['mysql_uptime'].should.be.greaterThanOrEqual(0);
res.body['os_total_memory'].should.be.greaterThanOrEqual(0);
return done();
});
});
it('/_version should PASS', function (done) {
//post to an url with data
agent.get('/_version') //enter url
.expect(200)//200 for success 4xx for failure
.end(function (err, res) {
// Handle /api/v error
if (err) {
return done(err);
}
res.body['Xmysql'].should.equals(pkginfo.version);
res.body['mysql'].should.not.equals("");
res.body['node'].should.not.equals("");
return done();
});
});
it('where clause unit ?_where=(abc,eq,1234) should PASS', function (done) { it('where clause unit ?_where=(abc,eq,1234) should PASS', function (done) {
var err = whereClause.getConditionClause('(abc,eq,1234)') var err = whereClause.getConditionClause('(abc,eq,1234)')

Loading…
Cancel
Save