1 /** 2 * @author Brian Carlsen 3 * @version 1.0.0 4 * 5 * A logger for tracking calls to the MINDBODY API 6 */ 7 8 var fs = require( 'fs' ), 9 http = require( 'http' ); 10 11 12 /** 13 * Used to log requests to the MINDBODY server. 14 * 15 * @param {string} type The type of logger to be used. 16 * Either 'local' to log to a local file, or 17 * 'remote' to log to a remote server. 18 * 19 * @throws {Error} Throws error if an invalid type parameter is passed. 20 */ 21 function mbo_Logger( type ) { 22 if ( [ 'local', 'remote' ].indexOf( type ) === -1 ) { 23 // invalid type 24 throw new Error( 'Invalid type for mbo_Logger. Must be "local" or "remote".' ); 25 } 26 27 this.type = type; 28 this.host = undefined; 29 this.port = 80; 30 this.path = undefined; 31 } 32 33 /** 34 * Sets the host and port of the logger. Can only be used for remote loggers." 35 * 36 * @param {string} host The host for the Logger to post data to. 37 * @param {int} port The port to acces the host by. 38 * 39 * @throws {Error} If Logger type is not remote. 40 */ 41 mbo_Logger.prototype.setHost = function( host, port = 80 ) { 42 if ( this.type !== 'remote' ) { 43 throw new Error( 'mbo_Logger must be of type remote to set host.' ); 44 } 45 46 this.host = host; 47 this.port = port; 48 }; 49 50 /** 51 * Sets the path to send the log to. 52 * If a local Logger, path should point to a file to append to. 53 * If a remote Logger, the path of the host to post the data to. 54 * 55 * @param {string} path The path for the Logger to post to. 56 */ 57 mbo_Logger.prototype.setPath = function( path ) { 58 this.path = path; 59 }; 60 61 /** 62 * Creates data string to be logged. 63 * 64 * @param {object} params The parameters submitted during the call. 65 * @param {string} method The method called. 66 * @param {object} result The result of the call. 67 * 68 * @return {string} Returns the JSON stringified version of the request. 69 */ 70 mbo_Logger.prototype._createLoggerData = function( service, params, method, result ) { 71 var loggerData = { 72 service: service, 73 params: params, 74 method: method, 75 error: undefined 76 }; 77 78 var res = result[ method + 'Result' ]; 79 if ( res.ErrorCode !== 200 ) { // SOAP Fault occurred 80 loggerData.error = { 81 status: res.Status, 82 errorCode: res.ErrorCode, 83 message: res.Message 84 }; 85 } 86 87 return JSON.stringify( loggerData ); 88 }; 89 90 /** 91 * Internal function used for local logging. 92 * Writes log data to a local file. 93 * path defaults to ./mbo-api.log 94 * 95 * @param {object} params The request parameters submitted to the MINDBODY API. 96 * @param {string} method The name of the method called on the MINDBODY API. 97 * @param {object} result The result from the function call. 98 */ 99 mbo_Logger.prototype._logLocal = function( params, method, result ) { 100 var data = this._createLoggerData( params, method, result ); 101 data = '[' + ( new Date() ).toISOString() + '] ' + data + '\n'; 102 103 var path = this.path || './mbo-api.log'; 104 fs.appendFile( path, data, function( err ) { 105 if ( err ) { 106 throw err; 107 } 108 } ); 109 }; 110 111 /** 112 * Internal function used for remote logging. 113 * Posts data to the set host, port, and path. 114 * host defaults to localhost, port defaults to 80, and path defaults to /. 115 * 116 * @param {object} params The request parameters submitted to the MINDBODY API. 117 * @param {string} method The name of the method called on the MINDBODY API. 118 * @param {object} result The result from the function call. 119 */ 120 mbo_Logger.prototype._logRemote = function( params, method, result ) { 121 // check host and path are set 122 123 var loggerParams = { 124 host: this.host || 'localhost', 125 port: this.port || 80, 126 path: this.path || '/', 127 method: 'post', 128 headers: { 129 'Content-Type': 'application/json', 130 'Content-Length': undefined 131 } 132 }; 133 134 var loggerData = this._createLoggerData( params, method, result) 135 loggerParams.headers['Content-Length'] = loggerData.length; 136 137 var loggerReq = http.request( loggerParams, function( res ) { 138 var data = ''; 139 res.setEncoding( 'utf8' ); 140 141 res.on( 'data', function( chunk ) { 142 data += chunk; 143 } ); 144 145 res.on( 'end', function() { 146 if ( res.statusCode !== 200 ) { 147 console.log( "[MBO Logger Error]", data, loggerData.error ); 148 } 149 } ); 150 } ) 151 .on( 'error', function( err ) { 152 console.log( "[MBO Logger]", err ); 153 } ); 154 155 loggerReq.write( loggerData ); 156 loggerReq.end(); 157 }; 158 159 mbo_Logger.prototype.log = function( params, method, result ) { 160 switch ( this.type ) { 161 case 'local': 162 this._logLocal( params, method, result ); 163 break; 164 case 'remote': 165 this._logRemote( params, method, result ); 166 break; 167 default: 168 throw new Error( 'Invalid type property' ); 169 break; 170 }; 171 }; 172 173 module.exports = mbo_Logger;