@@ -17,16 +17,37 @@ var api = require('./api'),
1717 params . unshift ( level ) ;
1818 return this . log . apply ( this , params ) ;
1919 } ,
20+ // Determine whether or not an API key has been specified. If not, then APP_DETAILS will not exist.
21+ appDetailsExist ,
22+ hasAppDetails = function ( ) {
23+ if ( appDetailsExist === undefined ) {
24+ appDetailsExist = undefined !== CONFIG . APP_DETAILS ;
25+
26+ if ( ! appDetailsExist ) {
27+ debug . write ( '*** A valid Stackify API key has not been specified ***' ) ;
28+ }
29+ }
30+
31+ return appDetailsExist ;
32+ } ,
2033
2134 /* handler for sending logs, accepts callback function and boolean variable
2235 indicating if we should run process.exit() after the callback
2336 */
2437 sendLogs = function ( cb , shutdown ) {
38+
39+ // If Stackify Application details have not been received, skip logging.
40+ if ( ! hasAppDetails ( ) ) {
41+ cb && cb ( ) ;
42+
43+ return ;
44+ }
45+
2546 var length = storage . length , // number of the messages in the iteration
2647 chunk = Math . min ( length , CONFIG . MSG . MAX_BATCH_SIZE ) ,
2748 data = storage . slice ( 0 , chunk ) ,
2849
29- /* if request is succesful remove messages from the queue,
50+ /* if request is successful remove messages from the queue,
3051 send another batch (if there are enough messages in the queue)
3152 */
3253 success = function ( response ) {
@@ -41,11 +62,11 @@ var api = require('./api'),
4162 api . methods . postLogs ( data , success , shutdown ) ;
4263 } else {
4364 // full batch is sent, set timeout for the next request
65+ sendingLogsInProgress = false ;
4466 if ( cb ) {
4567 // if exception is caught run next middleware or check if we need to shutdown the server
4668 cb ( ) ;
4769 } else {
48- sendingLogsInProgress = false ;
4970 timeout = setTimeout ( sendLogs , delay ) ;
5071 }
5172 }
@@ -61,135 +82,162 @@ var api = require('./api'),
6182
6283 if ( data . length && CONFIG . APP_DETAILS ) {
6384 // queue has messages and the app is authorized - set the flag, post data
64- api . methods . postLogs ( data , success , shutdown ) ;
6585 sendingLogsInProgress = true ;
86+ api . methods . postLogs ( data , success , shutdown ) ;
6687 } else {
6788 // queue is empty or app is not authorized, set timeout for the next request, switch the flag
68- timeout = setTimeout ( sendLogs , delay ) ;
6989 sendingLogsInProgress = false ;
90+ timeout = setTimeout ( sendLogs , delay ) ;
7091 }
7192 } ;
7293
73- module . exports . storage = storage ;
74-
75- module . exports . methods = {
76- // create the message object, push it to the queue if the queue cap isn't exceeded
77- push : function push ( level , msg , meta , req , err ) {
78- var stackError = err || new Error ( ) ,
79- getStack = error . getStackTraceItem ( stackError , err ) ,
80- messageObject = {
81- Msg : msg ,
82- Level : level . toUpperCase ( ) ,
83- EpochMs : Date . now ( ) ,
84- SrcMethod : getStack . SrcMethod ,
85- SrcLine : getStack . SrcLine
86- } ,
87- data ;
88-
89- // handle properly metadata object and create exception object if needed
90- if ( meta . length ) {
91- if ( level . toLowerCase ( ) === 'error' ) {
92- data = helpers . parseMeta ( meta , true ) ;
93- // if duplicate errors cap per minute isn't exceeded and error object is passed, create an exception
94- if ( data . ex ) {
95- messageObject . Ex = error . formatEx ( data . ex , req ) ;
96- if ( ! error . checkErrorLimitMessage ( messageObject . Ex ) ) {
97- delete messageObject . Ex ;
98- }
99- }
100- } else {
101- data = helpers . parseMeta ( meta ) ;
102- }
94+ //module.exports.storage = storage;
10395
104- if ( data . result ) {
105- messageObject . Data = data . result ;
106- }
107- }
96+ module . exports = {
10897
109- // if error object isn't passed with message & duplicate errors cap per minute isn't exceeded, create a string exception
110- if ( level . toLowerCase ( ) === 'error' && ! messageObject . Ex ) {
111- messageObject . Ex = error . formatEx ( stackError , null , msg ) ;
98+ size : function ( ) {
99+ return storage ? storage . length : 0 ;
100+ } ,
112101
113- if ( ! error . checkErrorLimitMessage ( messageObject . Ex ) ) {
114- delete messageObject . Ex ;
115- }
102+ get : function ( index ) {
103+ if ( index >= 0 && storage && storage . length ) {
104+ return storage [ index ] ;
116105 }
117106
118- storage . push ( messageObject ) ;
107+ return null ;
108+ } ,
109+
110+ hasAppDetails : hasAppDetails ,
119111
120- // remove the earliest message from the queue if message cap is exceeded
121- if ( storage . length === CONFIG . MSG . QUEUE_CAP ) {
122- storage . shift ( ) ;
112+ /**
113+ * A function to clear the logs.
114+ */
115+ flushLogs : function ( ) {
116+ if ( storage && storage . length ) {
117+ storage . length = 0 ;
123118 }
124119 } ,
125120
126- // start sending logs after IdentifyApp call is done
127- start : function start ( ) {
128- timeout = setTimeout ( sendLogs , delay ) ;
129- } ,
121+ methods : {
122+ // create the message object, push it to the queue if the queue cap isn't exceeded
123+ push : function push ( level , msg , meta , req , err ) {
124+ var stackError = err || new Error ( ) ,
125+ getStack = error . getStackTraceItem ( stackError , err ) ,
126+ messageObject = {
127+ Msg : msg ,
128+ Level : level . toUpperCase ( ) ,
129+ EpochMs : Date . now ( ) ,
130+ SrcMethod : getStack . SrcMethod ,
131+ SrcLine : getStack . SrcLine
132+ } ,
133+ data ;
134+
135+ // handle properly metadata object and create exception object if needed
136+ if ( meta . length ) {
137+ if ( level . toLowerCase ( ) === 'error' ) {
138+ data = helpers . parseMeta ( meta , true ) ;
139+ // if duplicate errors cap per minute isn't exceeded and error object is passed, create an exception
140+ if ( data . ex ) {
141+ messageObject . Ex = error . formatEx ( data . ex , req ) ;
142+ if ( ! error . checkErrorLimitMessage ( messageObject . Ex ) ) {
143+ delete messageObject . Ex ;
144+ }
145+ }
146+ } else {
147+ data = helpers . parseMeta ( meta ) ;
148+ }
130149
131- // reset current delay schedule, push exception to the queue, send data and run the callback
132- sendException : function sendException ( err , req , cb ) {
133- // check if messages are being sent right now
134- var check = function check ( ) {
150+ if ( data . result ) {
151+ messageObject . Data = data . result ;
152+ }
153+ }
135154
136- if ( sendingLogsInProgress ) {
137- setTimeout ( check , 500 ) ;
138- } else {
139- sendLogs ( cb , true ) ;
155+ // if error object isn't passed with message & duplicate errors cap per minute isn't exceeded, create a string exception
156+ if ( level . toLowerCase ( ) === 'error' && ! messageObject . Ex ) {
157+ messageObject . Ex = error . formatEx ( stackError , null , msg ) ;
158+
159+ if ( ! error . checkErrorLimitMessage ( messageObject . Ex ) ) {
160+ delete messageObject . Ex ;
161+ }
140162 }
141- } ;
142163
143- debug . write ( 'Exception caught' ) ;
164+ storage . push ( messageObject ) ;
144165
145- clearTimeout ( timeout ) ;
146- this . push ( 'error' , err . message , [ err ] , req , err ) ;
147- check ( ) ;
148- } ,
149- // drain the queue and send the messages before server closes
150- drain : function drain ( ) {
151- if ( storage . length ) {
152- api . methods . postLogsSync ( storage ) ;
153- } else {
154- debug . close ( ) ;
155- }
156- } ,
166+ // remove the earliest message from the queue if message cap is exceeded
167+ if ( storage . length === CONFIG . MSG . QUEUE_CAP ) {
168+ storage . shift ( ) ;
169+ }
170+ } ,
157171
158- // basic logging method
159- log : function log ( level , msg ) {
160- var meta = Array . prototype . slice . call ( arguments , 2 ) ;
161- var levels = [ 'error' , 'debug' , 'warn' , 'info' , 'trace' ] ;
172+ // start sending logs after IdentifyApp call is done
173+ start : function start ( ) {
174+ appDetailsExist = undefined ; // Reset to allow for logging after receiving successful application details.
175+ timeout = setTimeout ( sendLogs , delay ) ;
176+ } ,
162177
163- // check the message level
164- if ( levels . indexOf ( level . toLowerCase ( ) ) < 0 ) {
165- debug . write ( level + ' level doesn\'t exist' ) ;
166- throw new TypeError ( level + ' level doesn\'t exist' ) ;
167- }
168- // check the message itself
169- if ( typeof msg !== 'string' ) {
170- debug . write ( 'Message must be a string' ) ;
171- throw new TypeError ( 'Message must be a string' ) ;
172- }
173- this . push ( level , msg , meta ) ;
174- } ,
178+ // reset current delay schedule, push exception to the queue, send data and run the callback
179+ sendException : function sendException ( err , req , cb ) {
180+ // check if messages are being sent right now
181+ var check = function check ( ) {
175182
176- /*
177- Shortcut functions for logging message of certain level. Every function takes the same params as log function except the level.
178- */
183+ if ( sendingLogsInProgress ) {
184+ setTimeout ( check , CONFIG . DELAY . ONE_SECOND_DELAY ) ;
185+ } else {
186+ sendLogs ( cb , true ) ;
187+ }
188+ } ;
179189
180- trace : function trace ( ) {
181- getShortcut . call ( this , arguments , 'trace' ) ;
182- } ,
183- debug : function debug ( ) {
184- getShortcut . call ( this , arguments , 'debug' ) ;
185- } ,
186- info : function info ( ) {
187- getShortcut . call ( this , arguments , 'info' ) ;
188- } ,
189- warn : function warn ( ) {
190- getShortcut . call ( this , arguments , 'warn' ) ;
191- } ,
192- error : function error ( ) {
193- getShortcut . call ( this , arguments , 'error' ) ;
190+ debug . write ( 'Exception caught' ) ;
191+
192+ clearTimeout ( timeout ) ;
193+ this . push ( 'error' , err . message , [ err ] , req , err ) ;
194+ check ( ) ;
195+ } ,
196+ // drain the queue and send the messages before server closes
197+ drain : function drain ( ) {
198+ if ( storage . length ) {
199+ api . methods . postLogsSync ( storage ) ;
200+ } else {
201+ debug . close ( ) ;
202+ }
203+ } ,
204+
205+ // basic logging method
206+ log : function log ( level , msg ) {
207+ var meta = Array . prototype . slice . call ( arguments , 2 ) ;
208+ var levels = [ 'error' , 'debug' , 'warn' , 'info' , 'trace' ] ;
209+
210+ // check the message level
211+ if ( levels . indexOf ( level . toLowerCase ( ) ) < 0 ) {
212+ debug . write ( level + ' level doesn\'t exist' ) ;
213+ throw new TypeError ( level + ' level doesn\'t exist' ) ;
214+ }
215+ // check the message itself
216+ if ( typeof msg !== 'string' ) {
217+ debug . write ( 'Message must be a string' ) ;
218+ throw new TypeError ( 'Message must be a string' ) ;
219+ }
220+ this . push ( level , msg , meta ) ;
221+ } ,
222+
223+ /*
224+ Shortcut functions for logging message of certain level. Every function takes the same params as log function except the level.
225+ */
226+
227+ trace : function trace ( ) {
228+ getShortcut . call ( this , arguments , 'trace' ) ;
229+ } ,
230+ debug : function debug ( ) {
231+ getShortcut . call ( this , arguments , 'debug' ) ;
232+ } ,
233+ info : function info ( ) {
234+ getShortcut . call ( this , arguments , 'info' ) ;
235+ } ,
236+ warn : function warn ( ) {
237+ getShortcut . call ( this , arguments , 'warn' ) ;
238+ } ,
239+ error : function error ( ) {
240+ getShortcut . call ( this , arguments , 'error' ) ;
241+ }
194242 }
195243} ;
0 commit comments