├── .project ├── LICENSE ├── README.md ├── lib ├── cronTrigger.js ├── cronTriggerDecoder.js ├── job.js ├── priorityQueue.js ├── schedule.js └── simpleTrigger.js ├── node_modules └── log4js │ ├── .npmignore │ ├── .project │ ├── .travis.yml │ ├── README.md │ ├── example-connect-logger.js │ ├── example-socket.js │ ├── example.js │ ├── lib │ ├── appenders │ │ ├── console.js │ │ ├── file.js │ │ ├── gelf.js │ │ ├── hookio.js │ │ ├── logLevelFilter.js │ │ ├── multiprocess.js │ │ └── smtp.js │ ├── connect-logger.js │ ├── date_format.js │ ├── layouts.js │ ├── levels.js │ ├── log4js.js │ ├── log4js.json │ └── streams.js │ ├── log-rolling.js │ ├── memory-test.js │ ├── node_modules │ ├── async │ │ ├── .gitmodules │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── deps │ │ │ ├── nodeunit.css │ │ │ └── nodeunit.js │ │ ├── dist │ │ │ └── async.min.js │ │ ├── index.js │ │ ├── lib │ │ │ └── async.js │ │ ├── nodelint.cfg │ │ ├── package.json │ │ └── test │ │ │ ├── test-async.js │ │ │ └── test.html │ └── compress-buffer │ │ ├── .lock-wscript │ │ ├── .npmignore │ │ ├── CHANGELOG │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── build │ │ ├── .wafpickle-7 │ │ ├── Release │ │ │ ├── compress-buffer-bindings.node │ │ │ └── src │ │ │ │ └── compress-buffer_1.o │ │ ├── c4che │ │ │ ├── Release.cache.py │ │ │ └── build.config.py │ │ └── config.log │ │ ├── index.js │ │ ├── package.json │ │ ├── src │ │ ├── compress-buffer.cc │ │ └── compress-buffer.cc- │ │ ├── t │ │ ├── t.c │ │ ├── t.plist │ │ ├── test.csv │ │ ├── test.gz │ │ ├── test │ │ └── node-compress-buffer-test.js │ │ └── wscript │ ├── package.json │ └── test │ ├── bufferedStream.js │ ├── date_format.js │ ├── fileAppender.js │ ├── gelfAppender.js │ ├── hookioAppender.js │ ├── layouts.js │ ├── levels.js │ ├── log4js.json │ ├── logLevelFilter.js │ ├── logging.js │ ├── multiprocessAppender.js │ ├── rollingFileStream.js │ ├── smtpAppender.js │ ├── test-connect-logger.js │ ├── test-global-log-level.js │ ├── test-log-abspath.js │ ├── test-nolog.js │ ├── test-rolling-file-stream │ ├── test-rolling-file-stream-write │ ├── test-rolling-file-stream-write-less │ ├── test-rolling-file-stream-write-more │ ├── test-rolling-file-stream-write-more.1 │ ├── with-log-rolling.json │ └── with-logLevelFilter.json ├── package.json └── test ├── cronTriggerTest.js ├── priorityQueueTest.js ├── scheduleTest.js └── test.js /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | schedule 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2012 Netease, Inc. and other pomelo contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pomelo-scheduler 2 | pomelo-schedule is a schedule tool for nodejs, it's purpose is to provide a product level schedule module which is high efficient and can support large number job schedule.You can 3 | 4 | As a schedule tool, it support two kinds of trigger: A simple trigger which use a js object and a Cron time trigger which use a Cron time string. 5 | ##Installation 6 | ``` 7 | npm install pomelo-schedule 8 | ``` 9 | ##Schedule simple Job 10 | Simple job will receive a object as a trigger, which take three attributes, a JS function as object, and an object as the parameters in the job. 11 | 12 | ###Simple trigge example 13 | ``` javascript 14 | //Fire 10000ms after now, and run 10 times with a 1000ms interval. 15 | var trigger1 = { 16 | start : Date.now() + 10000, //Start time, use the time in date object 17 | period : 1000, //Fire interval, the precision is millisecond 18 | count : 10 //Fire times, in this case the trigger will fire 10 times. 19 | } 20 | 21 | //Fire right now, and run 10 times with 1000ms interval. 22 | var trigger2 = { 23 | period : 1000, 24 | count : 10 25 | } 26 | 27 | //Fire right now, and run for ever with 1000ms interval. 28 | var trigger3 = { 29 | period : 1000 30 | } 31 | 32 | //Fire 3000ms after right now, run only once. 33 | var trigger4 = { 34 | start : Date.now() + 3000; 35 | } 36 | 37 | //The job will fire right now, run only once. 38 | var trigger5 = { 39 | } 40 | 41 | //Illegal! The 'count' attribute cannot used alone without 'period'. 42 | var trigger6 = { 43 | count : 10; 44 | } 45 | ``` 46 | 47 | ###Simple job example 48 | ``` javascript 49 | var schedule = require('../lib/schedule'); 50 | 51 | var simpleJob = function(data){ 52 | console.log("run Job :" + data.name); 53 | } 54 | 55 | schedule.scheduleJob({start:Date.now(), period:3000, count: 10}, simpleJob, {name: 'simpleJobExample'}); 56 | ``` 57 | ##Schedule cron Job 58 | Cron job is the job that use cron trigger, it is just like the simple job, only use the cron trigger instead of simple trigger. 59 | 60 | ###Cron job example 61 | ``` javascript 62 | var schedule = require('../lib/schedule'); 63 | 64 | var cronJob = function(data){ 65 | console.log("run Job :" + data.name); 66 | } 67 | 68 | schedule.scheduleJob("0 0/15 8 * * *", cronJob, {name:'cronJobExample'}); 69 | ``` 70 | ###Cron Trigger syntax 71 | Cron trigger has 7 fiels, the format is very like the cronTab in linux, only add a second field in the head. The fields and the boundary is as follow: 72 |
 73 | *     *     *     *   *    *        command to be executed
 74 | -     -     -     -   -    -
 75 | |     |     |     |   |    |
 76 | |     |     |     |   |    +----- day of week (0 - 6) (Sunday=0)
 77 | |     |     |     |   +------- month (1 - 12)
 78 | |     |     |     +--------- day of month (1 - 31)
 79 | |     |     +----------- hour (0 - 23)
 80 | |     +------------- min (0 - 59)
 81 | +------------- second (0 - 59)
 82 | 
83 | ###Exampe of cron tirggers 84 | 85 | "0/2 0 8 * * 6" Fire at every Satuaday at every even seconds of 08:00 86 | "0 30 10 1 4 *" Fire at 10:30 on 1st of March 87 | "15 15 15 10 10 *" Fire at Octorber 10th, at 15:15:15. 88 | 89 | ###Special characters 90 | Pomelo-schedule allow three kinds of spechial characters, they are '-', '/' and '.'. 91 | 92 | -: '-' means range. For example, 1-3 in the second field means the seconds 1, 2 and 3 93 | 94 | /: means increasement. For exapmle, 1/20 in the second field means 1, 21 and 41 second, and 1/2 means for every odd seconds as 1, 3, 5 ... ... 95 | 96 | ,: means additional values. For example, 1, 10, 15 in the second field means 1, 10 and 15 second. You can use '-', and '/' with ',', for example, 11,20-22,0/2 in the second filed means 11, 21 and all the even seconds. 97 | 98 | ##Cancel Job 99 | ``` javascript 100 | var schedule = require('../lib/schedule'); 101 | 102 | var simpleJob = function(){ 103 | console.log("run simple Job "); 104 | } 105 | 106 | //Add a simple job and save the id 107 | var id = schedule.scheduleJob({period: 1000}, simpleJob, {}); 108 | 109 | /** 110 | * Do some thing else 111 | */ 112 | 113 | //CancelJob 114 | schedule.cancelJob(id); 115 | ``` 116 | When you cancel a job, it will stop schedule immidiatelly, and delete the job. 117 | -------------------------------------------------------------------------------- /lib/cronTrigger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the trigger used to decode the cronTimer and calculate the next excution time of the cron Trigger. 3 | */ 4 | var logger = require('log4js').getLogger(__filename); 5 | 6 | var SECOND = 0; 7 | var MIN = 1; 8 | var HOUR = 2; 9 | var DOM = 3; 10 | var MONTH = 4; 11 | var DOW = 5; 12 | 13 | var Limit = [ 14 | [0, 59], 15 | [0, 59], 16 | [0, 24], 17 | [1, 31], 18 | [0, 11], 19 | [0, 6] 20 | ]; 21 | 22 | /** 23 | * The constructor of the CronTrigger 24 | * @param trigger The trigger str used to build the cronTrigger instance 25 | */ 26 | var CronTrigger = function(trigger, job) { 27 | this.trigger = this.decodeTrigger(trigger); 28 | 29 | this.nextTime = this.nextExcuteTime(Date.now()); 30 | 31 | this.job = job; 32 | }; 33 | 34 | var pro = CronTrigger.prototype; 35 | 36 | /** 37 | * Get the current excuteTime of trigger 38 | */ 39 | pro.excuteTime = function() { 40 | return this.nextTime; 41 | }; 42 | 43 | /** 44 | * Caculate the next valid cronTime after the given time 45 | * @param The given time point 46 | * @return The nearest valid time after the given time point 47 | */ 48 | pro.nextExcuteTime = function(time) { 49 | //add 1s to the time so it must be the next time 50 | time = !!time ? time : this.nextTime; 51 | time += 1000; 52 | 53 | var cronTrigger = this.trigger; 54 | var date = new Date(time); 55 | date.setMilliseconds(0); 56 | 57 | outmost: while (true) { 58 | if (date.getFullYear() > 2999) { 59 | logger.error("Can't compute the next time, exceed the limit"); 60 | return null; 61 | } 62 | if (!timeMatch(date.getMonth(), cronTrigger[MONTH])) { 63 | var nextMonth = nextCronTime(date.getMonth(), cronTrigger[MONTH]); 64 | 65 | if (nextMonth == null) 66 | return null; 67 | 68 | if (nextMonth <= date.getMonth()) { 69 | date.setYear(date.getFullYear() + 1); 70 | date.setMonth(0); 71 | date.setDate(1); 72 | date.setHours(0); 73 | date.setMinutes(0); 74 | date.setSeconds(0); 75 | continue; 76 | } 77 | 78 | date.setDate(1); 79 | date.setMonth(nextMonth); 80 | date.setHours(0); 81 | date.setMinutes(0); 82 | date.setSeconds(0); 83 | } 84 | 85 | if (!timeMatch(date.getDate(), cronTrigger[DOM]) || !timeMatch(date.getDay(), cronTrigger[DOW])) { 86 | var domLimit = getDomLimit(date.getFullYear(), date.getMonth()); 87 | 88 | do { 89 | var nextDom = nextCronTime(date.getDate(), cronTrigger[DOM]); 90 | if (nextDom == null) 91 | return null; 92 | 93 | //If the date is in the next month, add month 94 | if (nextDom <= date.getDate() || nextDom > domLimit) { 95 | date.setDate(1); 96 | date.setMonth(date.getMonth() + 1); 97 | date.setHours(0); 98 | date.setMinutes(0); 99 | date.setSeconds(0); 100 | continue outmost; 101 | } 102 | 103 | date.setDate(nextDom); 104 | } while (!timeMatch(date.getDay(), cronTrigger[DOW])); 105 | 106 | date.setHours(0); 107 | date.setMinutes(0); 108 | date.setSeconds(0); 109 | } 110 | 111 | if (!timeMatch(date.getHours(), cronTrigger[HOUR])) { 112 | var nextHour = nextCronTime(date.getHours(), cronTrigger[HOUR]); 113 | 114 | if (nextHour <= date.getHours()) { 115 | date.setDate(date.getDate() + 1); 116 | date.setHours(nextHour); 117 | date.setMinutes(0); 118 | date.setSeconds(0); 119 | continue; 120 | } 121 | 122 | date.setHours(nextHour); 123 | date.setMinutes(0); 124 | date.setSeconds(0); 125 | } 126 | 127 | if (!timeMatch(date.getMinutes(), cronTrigger[MIN])) { 128 | var nextMinute = nextCronTime(date.getMinutes(), cronTrigger[MIN]); 129 | 130 | if (nextMinute <= date.getMinutes()) { 131 | date.setHours(date.getHours() + 1); 132 | date.setMinutes(nextMinute); 133 | date.setSeconds(0); 134 | continue; 135 | } 136 | 137 | date.setMinutes(nextMinute); 138 | date.setSeconds(0); 139 | } 140 | 141 | if (!timeMatch(date.getSeconds(), cronTrigger[SECOND])) { 142 | var nextSecond = nextCronTime(date.getSeconds(), cronTrigger[SECOND]); 143 | 144 | if (nextSecond <= date.getSeconds()) { 145 | date.setMinutes(date.getMinutes() + 1); 146 | date.setSeconds(nextSecond); 147 | continue; 148 | } 149 | 150 | date.setSeconds(nextSecond); 151 | } 152 | break; 153 | } 154 | 155 | this.nextTime = date.getTime(); 156 | return this.nextTime; 157 | }; 158 | 159 | /** 160 | * return the next match time of the given value 161 | * @param value The time value 162 | * @param cronTime The cronTime need to match 163 | * @return The match value or null if unmatch(it offten means an error occur). 164 | */ 165 | function nextCronTime(value, cronTime) { 166 | value += 1; 167 | 168 | if (typeof(cronTime) == 'number') { 169 | if (cronTime == -1) 170 | return value; 171 | else 172 | return cronTime; 173 | } else if (typeof(cronTime) == 'object' && cronTime instanceof Array) { 174 | if (value <= cronTime[0] || value > cronTime[cronTime.length - 1]) 175 | return cronTime[0]; 176 | 177 | for (var i = 0; i < cronTime.length; i++) 178 | if (value <= cronTime[i]) 179 | return cronTime[i]; 180 | } 181 | 182 | logger.warn('Compute next Time error! value :' + value + ' cronTime : ' + cronTime); 183 | return null; 184 | } 185 | 186 | /** 187 | * Match the given value to the cronTime 188 | * @param value The given value 189 | * @param cronTime The cronTime 190 | * @return The match result 191 | */ 192 | function timeMatch(value, cronTime) { 193 | if (typeof(cronTime) == 'number') { 194 | if (cronTime == -1) 195 | return true; 196 | if (value == cronTime) 197 | return true; 198 | return false; 199 | } else if (typeof(cronTime) == 'object' && cronTime instanceof Array) { 200 | if (value < cronTime[0] || value > cronTime[cronTime.length - 1]) 201 | return false; 202 | 203 | for (var i = 0; i < cronTime.length; i++) 204 | if (value == cronTime[i]) 205 | return true; 206 | 207 | return false; 208 | } 209 | 210 | return null; 211 | } 212 | 213 | /** 214 | * Decude the cronTrigger string to arrays 215 | * @param cronTimeStr The cronTimeStr need to decode, like "0 12 * * * 3" 216 | * @return The array to represent the cronTimer 217 | */ 218 | pro.decodeTrigger = function(cronTimeStr) { 219 | cronTimeStr = cronTimeStr.trim(); 220 | var cronTimes = cronTimeStr.split(/\s+/); 221 | 222 | if (cronTimes.length != 6) { 223 | console.log('error'); 224 | return null; 225 | } 226 | 227 | for (var i = 0; i < cronTimes.length; i++) { 228 | cronTimes[i] = (this.decodeTimeStr(cronTimes[i], i)); 229 | 230 | if (!checkNum(cronTimes[i], Limit[i][0], Limit[i][1])) { 231 | logger.error('Decode crontime error, value exceed limit!' + 232 | JSON.stringify({ 233 | cronTime: cronTimes[i], 234 | limit: Limit[i] 235 | })); 236 | return null; 237 | } 238 | } 239 | 240 | return cronTimes; 241 | } 242 | 243 | /** 244 | * Decode the cron Time string 245 | * @param timeStr The cron time string, like: 1,2 or 1-3 246 | * @return A sorted array, like [1,2,3] 247 | */ 248 | pro.decodeTimeStr = function(timeStr, type) { 249 | var result = {}; 250 | var arr = []; 251 | 252 | if (timeStr == '*') { 253 | return -1; 254 | } else if (timeStr.search(',') > 0) { 255 | var timeArr = timeStr.split(','); 256 | for (var i = 0; i < timeArr.length; i++) { 257 | var time = timeArr[i]; 258 | if (time.match(/^\d+-\d+$/)) { 259 | decodeRangeTime(result, time); 260 | } else if (time.match(/^\d+\/\d+/)) { 261 | decodePeriodTime(result, time, type); 262 | } else if (!isNaN(time)) { 263 | var num = Number(time); 264 | result[num] = num; 265 | } else 266 | return null; 267 | } 268 | } else if (timeStr.match(/^\d+-\d+$/)) { 269 | decodeRangeTime(result, timeStr); 270 | } else if (timeStr.match(/^\d+\/\d+/)) { 271 | decodePeriodTime(result, timeStr, type); 272 | } else if (!isNaN(timeStr)) { 273 | var num = Number(timeStr); 274 | result[num] = num; 275 | } else { 276 | return null; 277 | } 278 | 279 | for (var key in result) { 280 | arr.push(result[key]); 281 | } 282 | 283 | arr.sort(function(a, b) { 284 | return a - b; 285 | }); 286 | 287 | return arr; 288 | } 289 | 290 | /** 291 | * Decode time range 292 | * @param map The decode map 293 | * @param timeStr The range string, like 2-5 294 | */ 295 | function decodeRangeTime(map, timeStr) { 296 | var times = timeStr.split('-'); 297 | 298 | times[0] = Number(times[0]); 299 | times[1] = Number(times[1]); 300 | if (times[0] > times[1]) { 301 | console.log("Error time range"); 302 | return null; 303 | } 304 | 305 | for (var i = times[0]; i <= times[1]; i++) { 306 | map[i] = i; 307 | } 308 | } 309 | 310 | /** 311 | * Compute the period timer 312 | */ 313 | function decodePeriodTime(map, timeStr, type) { 314 | var times = timeStr.split('/'); 315 | var min = Limit[type][0]; 316 | var max = Limit[type][1]; 317 | 318 | var remind = Number(times[0]); 319 | var period = Number(times[1]); 320 | 321 | if (period == 0) 322 | return; 323 | 324 | for (var i = remind; i <= max; i += period) { 325 | // if (i % period == remind) 326 | map[i] = i; 327 | // } 328 | } 329 | } 330 | 331 | /** 332 | * Check if the numbers are valid 333 | * @param nums The numbers array need to check 334 | * @param min Minimus value 335 | * @param max Maximam value 336 | * @return If all the numbers are in the data range 337 | */ 338 | function checkNum(nums, min, max) { 339 | if (nums == null) 340 | return false; 341 | 342 | if (nums == -1) 343 | return true; 344 | 345 | for (var i = 0; i < nums.length; i++) { 346 | if (nums[i] < min || nums[i] > max) 347 | return false; 348 | } 349 | 350 | return true; 351 | } 352 | 353 | /** 354 | * Get the date limit of given month 355 | * @param The given year 356 | * @month The given month 357 | * @return The date count of given month 358 | */ 359 | function getDomLimit(year, month) { 360 | var date = new Date(year, month + 1, 0); 361 | 362 | return date.getDate(); 363 | } 364 | 365 | /** 366 | * Create cronTrigger 367 | * @param trigger The Cron Trigger string 368 | * @return The Cron trigger 369 | */ 370 | function createTrigger(trigger, job) { 371 | return new CronTrigger(trigger, job); 372 | } 373 | 374 | module.exports.createTrigger = createTrigger; -------------------------------------------------------------------------------- /lib/cronTriggerDecoder.js: -------------------------------------------------------------------------------- 1 | var decoder = module.exports; 2 | decoder.decodeCronTime = decodeCronTime; 3 | 4 | var timer = { 5 | second: -1, 6 | min: -1, 7 | hour: -1, 8 | dom: -1, 9 | month: -1, 10 | dow: -1, 11 | executeTime: -1 12 | } 13 | 14 | var limit = [[0,59],[0,59],[0,24],[1,31],[1,12],[0,6]]; 15 | 16 | function nexExcuteTime(time, timer){ 17 | //add 1s to the time so it must be the next time 18 | time += 1000; 19 | var date = new Date(time); 20 | var nextTime = new Date(time); 21 | 22 | outmost: 23 | while(true){ 24 | if(!timeMatch(date.getMonth(), timer.month)){ 25 | var nextMonth = nextTime(date.getMonth(), timer.month); 26 | if(nextMonth < date.getMonth()){ 27 | date.setYear(date.getYear()+1); 28 | } 29 | date.setMonth(nextMonth); 30 | 31 | date.setDate(1); 32 | date.setHours(0); 33 | date.setMinutes(0); 34 | date.setSeconds(0); 35 | } 36 | 37 | if(!timeMatch(date.getDate(), timer.dom)){ 38 | do{ 39 | var nextDom = nextTime(date.getDate(), timer.dom); 40 | 41 | //If the date is in the next month, add month 42 | if(nextDom <= date.getDate()){ 43 | date.setMonth(date.getMonth() + 1); 44 | continue outmost; 45 | } 46 | 47 | //If the date exceed the limit, add month 48 | var domLimit = getDomLimit(); 49 | if(nexDom > domLimit){ 50 | date.setMonth(date.getMonth() + 1); 51 | continue outmost; 52 | } 53 | 54 | date.setDate(nextDom); 55 | }while(!timeMatch(date.getDay(), timer.dow)); 56 | 57 | date.setHours(0); 58 | date.setMinutes(0); 59 | date.setSeconds(0); 60 | } 61 | 62 | if(!timeMatch(date.getHours(), timer.hour)){ 63 | var nextHour = nextTime(date.getHours(), timer.hour); 64 | 65 | if(nextHour <= date.getHours()){ 66 | date.setDate(date.getDate() + 1); 67 | continue; 68 | } 69 | 70 | date.setHours(nextHour); 71 | date.setMinutes(0); 72 | date.setSeconds(0); 73 | } 74 | 75 | if(!timeMatch(date.getMinutes(), timer.minute)){ 76 | var nextMinute = nextTime(date.getMinutes(), timer.minute); 77 | 78 | if(nextMinute <= date.getMinutes()){ 79 | date.setHours(date.getHours() + 1); 80 | continue; 81 | } 82 | 83 | date.setMinutes(nextMinute); 84 | date.setSeconds(0); 85 | } 86 | 87 | if(!timeMatch(date.getSeconds(), timer.seconde)){ 88 | var nextSecond = nextTime(date.getSeconds(), timer.seconde); 89 | 90 | if(nextSecond <= date.getSeconds()){ 91 | date.setMinutes()(date.getMinutes() + 1); 92 | continue; 93 | } 94 | 95 | date.setSeconds(nextSecond); 96 | } 97 | 98 | break; 99 | } 100 | 101 | return date.getTime(); 102 | } 103 | 104 | /** 105 | * return the next match time of the given value 106 | */ 107 | function nextTime(value, cronTime){ 108 | if(typeof(cronTime) == 'number'){ 109 | if(cronTime == -1) 110 | return value + 1; 111 | else 112 | return cronTime; 113 | }else if(typeof(cronTime) == 'array'){ 114 | if(value < arr[0] || value > arr[arr.length -1]) 115 | return arr[0]; 116 | 117 | for(var i = 0; i < arr.length; i++) 118 | if(value < arr[i]) 119 | return arr[i]; 120 | } 121 | 122 | return null; 123 | } 124 | 125 | function timeMatch(value, cronTime){ 126 | if(tyeof(cronTime) == 'number'){ 127 | if(cronTime == -1) 128 | return true; 129 | if(value == cronTime) 130 | return true; 131 | return false; 132 | }else if(typeof(cronTime) == 'array'){ 133 | if(value < arr[0] || value > arr[arr.length -1]) 134 | return false; 135 | 136 | for(var i = 0; i < arr.length; i++) 137 | if(value == arr[i]) 138 | return true; 139 | 140 | return false; 141 | } 142 | 143 | return null; 144 | } 145 | 146 | function getDomLimit(year, month){ 147 | var date = new Date(year, month, 0); 148 | 149 | return date.getDate(); 150 | } 151 | 152 | function decodeCronTime(cronTime){ 153 | var timers = cronTime.split(/\s+/); 154 | 155 | if(timers.length != 6){ 156 | return null; 157 | } 158 | 159 | for(var i = 0; i < timers.length; i++){ 160 | timers[i] = (decodeTimeStr(timers[i])); 161 | 162 | if(!checkNum(timers[i], limit[i][0], limit[i][1])){ 163 | return null; 164 | } 165 | } 166 | 167 | return timers; 168 | } 169 | 170 | function decodeTimeStr(timeStr){ 171 | var result = {}; 172 | var arr = []; 173 | 174 | if(timeStr=='*'){ 175 | return -1; 176 | }else if(timeStr.search(',')>0){ 177 | var timeStrArray = timeStr.split(','); 178 | for(var i = 0; i < timeStrArray.length; i++){ 179 | var time = timeStrArray[i]; 180 | if(time.match(/^\d+-\d+$/)){ 181 | decodeRangeTime(result, time); 182 | }else if(!isNaN(timeStrArray[i])) 183 | result[i] = time; 184 | else 185 | return null; 186 | } 187 | }else if(timeStr.match(/^\d+-\d+$/)){ 188 | decodeRangeTime(result, time); 189 | }else if(!isNaN(timeStr)){ 190 | result[timeStr] = timeStr; 191 | }else{ 192 | return null; 193 | } 194 | 195 | for(var key in result) 196 | arr.push(result[key]); 197 | 198 | arr.sort(); 199 | 200 | return arr; 201 | } 202 | 203 | function decodeRangeTime(map, timeStr){ 204 | var times = timeStr.split('-'); 205 | 206 | if(times[0] > times[1]) 207 | return null; 208 | for(var i = times[0]; i <= times[1]; i++) 209 | map[i] = i; 210 | } 211 | 212 | function checkNum(nums, min, max){ 213 | if(nums == null) 214 | return false; 215 | 216 | if(nums == -1) 217 | return true; 218 | 219 | for(var i = 0; i < nums.length; i++){ 220 | if(nums[i]max) 221 | return false; 222 | } 223 | 224 | return true; 225 | } -------------------------------------------------------------------------------- /lib/job.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the class of the job used in schedule module 3 | */ 4 | var cronTrigger = require('./cronTrigger'); 5 | var simpleTrigger = require('./simpleTrigger'); 6 | 7 | var jobId = 1; 8 | 9 | var SIMPLE_JOB = 1; 10 | var CRON_JOB = 2; 11 | var jobCount = 0; 12 | 13 | var warnLimit = 500; 14 | 15 | var logger = require('log4js').getLogger(__filename); 16 | 17 | 18 | //For test 19 | var lateCount = 0; 20 | 21 | var Job = function(trigger, jobFunc, jobData){ 22 | this.data = (!!jobData)?jobData:null; 23 | this.func = jobFunc; 24 | 25 | if(typeof(trigger) == 'string'){ 26 | this.type = CRON_JOB; 27 | this.trigger = cronTrigger.createTrigger(trigger, this); 28 | }else if(typeof(trigger) == 'object'){ 29 | this.type = SIMPLE_JOB; 30 | this.trigger = simpleTrigger.createTrigger(trigger, this); 31 | } 32 | 33 | this.id = jobId++; 34 | this.runTime = 0; 35 | }; 36 | 37 | var pro = Job.prototype; 38 | 39 | /** 40 | * Run the job code 41 | */ 42 | pro.run = function(){ 43 | try{ 44 | jobCount++; 45 | this.runTime++; 46 | var late = Date.now() - this.excuteTime(); 47 | if(late>warnLimit) 48 | logger.warn('run Job count ' + jobCount + ' late :' + late + ' lateCount ' + (++lateCount)); 49 | this.func(this.data); 50 | }catch(e){ 51 | logger.error("Job run error for exception ! " + e.stack); 52 | } 53 | }; 54 | 55 | /** 56 | * Compute the next excution time 57 | */ 58 | pro.nextTime = function(){ 59 | return this.trigger.nextExcuteTime(); 60 | }; 61 | 62 | pro.excuteTime = function(){ 63 | return this.trigger.excuteTime(); 64 | }; 65 | 66 | /** 67 | * The Interface to create Job 68 | * @param trigger The trigger to use 69 | * @param jobFunc The function the job to run 70 | * @param jobDate The date the job use 71 | * @return The new instance of the give job or null if fail 72 | */ 73 | function createJob(trigger, jobFunc, jobData){ 74 | return new Job(trigger, jobFunc, jobData); 75 | } 76 | 77 | module.exports.createJob = createJob; -------------------------------------------------------------------------------- /lib/priorityQueue.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The PriorityQeueu class 3 | */ 4 | var PriorityQueue = function(comparator){ 5 | this.init(comparator); 6 | } 7 | 8 | var pro = PriorityQueue.prototype; 9 | 10 | pro.init = function(comparator){ 11 | this._comparator = typeof(comparator)=='function'?comparator:this._defaultComparator; 12 | 13 | this._queue = []; 14 | this._tailPos = 0; 15 | } 16 | 17 | /** 18 | * Return the size of the pirority queue 19 | * @return PirorityQueue size 20 | */ 21 | pro.size = function(){ 22 | return this._tailPos; 23 | }; 24 | 25 | /** 26 | * Insert an element to the queue 27 | * @param element The element to insert 28 | */ 29 | pro.offer = function(element){ 30 | var queue = this._queue; 31 | var compare = this._comparator; 32 | 33 | queue[this._tailPos++] = element; 34 | 35 | var pos = this._tailPos-1; 36 | 37 | while(pos > 0){ 38 | var parentPos = (pos%2==0)?(pos/2-1):(pos-1)/2; 39 | if(compare(queue[parentPos], element)){ 40 | queue[pos] = queue[parentPos]; 41 | queue[parentPos] = element; 42 | 43 | pos = parentPos; 44 | }else{ 45 | break; 46 | } 47 | } 48 | }; 49 | 50 | /** 51 | * Get and remove the first element in the queue 52 | * @return The first element 53 | */ 54 | pro.pop = function(){ 55 | var queue = this._queue; 56 | var compare = this._comparator; 57 | 58 | if(this._tailPos == 0) 59 | return null; 60 | 61 | 62 | var headNode = queue[0]; 63 | 64 | var tail = queue[this._tailPos - 1]; 65 | 66 | var pos = 0; 67 | var left = pos*2 + 1; 68 | var right = left + 1; 69 | queue[pos] = tail; 70 | this._tailPos--; 71 | 72 | while(left < this._tailPos){ 73 | if(right b; 106 | } 107 | 108 | module.exports.createPriorityQueue = function(comparator){ 109 | return new PriorityQueue(comparator); 110 | } -------------------------------------------------------------------------------- /lib/schedule.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The main class and interface of the schedule module 3 | */ 4 | var PriorityQueue = require('./priorityQueue'); 5 | var Job = require('./job.js'); 6 | var timerCount = 0; 7 | 8 | var logger = require('log4js').getLogger(__filename); 9 | 10 | var map = {}; 11 | var queue = PriorityQueue.createPriorityQueue(comparator); 12 | 13 | var jobId = 0; 14 | var timer; 15 | 16 | //The accuracy of the scheduler, it will affect the performance when the schedule tasks are 17 | //crowded together 18 | var accuracy = 10; 19 | 20 | /** 21 | * Schedule a new Job 22 | */ 23 | function scheduleJob(trigger, jobFunc, jobData){ 24 | var job = Job.createJob(trigger, jobFunc, jobData); 25 | var excuteTime = job.excuteTime(); 26 | var id = job.id; 27 | 28 | map[id] = job; 29 | var element = { 30 | id : id, 31 | time : excuteTime 32 | }; 33 | 34 | var curJob = queue.peek(); 35 | if(!curJob || excuteTime < curJob.time){ 36 | queue.offer(element); 37 | setTimer(job); 38 | 39 | return job.id; 40 | } 41 | 42 | queue.offer(element); 43 | return job.id; 44 | } 45 | 46 | /** 47 | * Cancel Job 48 | */ 49 | function cancelJob(id){ 50 | var curJob = queue.peek(); 51 | if(curJob && id === curJob.id){ // to avoid queue.peek() is null 52 | queue.pop(); 53 | delete map[id]; 54 | 55 | clearTimeout(timer); 56 | excuteJob(); 57 | } 58 | delete map[id]; 59 | return true; 60 | } 61 | 62 | /** 63 | * Clear last timeout and schedule the next job, it will automaticly run the job that 64 | * need to run now 65 | * @param job The job need to schedule 66 | * @return void 67 | */ 68 | function setTimer(job){ 69 | clearTimeout(timer); 70 | 71 | timer = setTimeout(excuteJob, job.excuteTime()-Date.now()); 72 | } 73 | 74 | /** 75 | * The function used to ran the schedule job, and setTimeout for next running job 76 | */ 77 | function excuteJob(){ 78 | var job = peekNextJob(); 79 | var nextJob; 80 | 81 | while(!!job && (job.excuteTime()-Date.now()) 0); 117 | 118 | return (!!job)?job:null; 119 | } 120 | 121 | /** 122 | * Return and remove the next valid job 123 | * @return Next valid job 124 | */ 125 | function getNextJob(){ 126 | var job = null; 127 | 128 | while(!job && queue.size() > 0){ 129 | var id = queue.pop().id; 130 | job = map[id]; 131 | } 132 | 133 | return (!!job)?job:null; 134 | } 135 | 136 | function comparator(e1, e2){ 137 | return e1.time > e2.time; 138 | } 139 | 140 | module.exports.scheduleJob = scheduleJob; 141 | module.exports.cancelJob = cancelJob; 142 | -------------------------------------------------------------------------------- /lib/simpleTrigger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the tirgger that use an object as trigger. 3 | */ 4 | var SKIP_OLD_JOB = false; 5 | 6 | /** 7 | * The constructor of simple trigger 8 | */ 9 | var SimpleTrigger = function(trigger, job){ 10 | this.nextTime = (!!trigger.start)?trigger.start:Date.now(); 11 | 12 | //The rec 13 | this.period = (!!trigger.period)?trigger.period:-1; 14 | 15 | //The running count of the job, -1 means no limit 16 | this.count = (!!trigger.count)?trigger.count:-1; 17 | 18 | this.job = job; 19 | }; 20 | 21 | var pro = SimpleTrigger.prototype; 22 | 23 | /** 24 | * Get the current excuteTime of rigger 25 | */ 26 | pro.excuteTime = function(){ 27 | return this.nextTime; 28 | }; 29 | 30 | /** 31 | * Get the next excuteTime of the trigger, and set the trigger's excuteTime 32 | * @return Next excute time 33 | */ 34 | pro.nextExcuteTime = function(){ 35 | var period = this.period; 36 | 37 | if((this.count > 0 && this.count <= this.job.runTime) || period <= 0) 38 | return null; 39 | 40 | this.nextTime += period; 41 | 42 | if(SKIP_OLD_JOB && this.nextTime < Date.now()){ 43 | this.nextTime += Math.floor((Date.now()-this.nextTime)/period) * period; 44 | } 45 | 46 | return this.nextTime; 47 | }; 48 | 49 | /** 50 | * Create Simple trigger 51 | */ 52 | function createTrigger(trigger, job){ 53 | return new SimpleTrigger(trigger, job); 54 | } 55 | 56 | module.exports.createTrigger = createTrigger; -------------------------------------------------------------------------------- /node_modules/log4js/.npmignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.log?? 3 | -------------------------------------------------------------------------------- /node_modules/log4js/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | log4js 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /node_modules/log4js/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.4 4 | - 0.5 5 | - 0.6 6 | -------------------------------------------------------------------------------- /node_modules/log4js/example-connect-logger.js: -------------------------------------------------------------------------------- 1 | var log4js = require('./lib/log4js'); 2 | log4js.addAppender(log4js.fileAppender('cheese.log'), 'cheese'); 3 | 4 | var logger = log4js.getLogger('cheese'); 5 | logger.setLevel('INFO'); 6 | 7 | var app = require('express').createServer(); 8 | app.configure(function() { 9 | app.use(log4js.connectLogger(logger, { level: log4js.levels.INFO })); 10 | }); 11 | app.get('*', function(req,res) { 12 | res.send('hello world\n cheese\n'); 13 | }); 14 | app.listen(5000); 15 | -------------------------------------------------------------------------------- /node_modules/log4js/example-socket.js: -------------------------------------------------------------------------------- 1 | var log4js = require('./lib/log4js') 2 | , cluster = require('cluster') 3 | , numCPUs = require('os').cpus().length 4 | , i = 0; 5 | 6 | if (cluster.isMaster) { 7 | log4js.configure({ 8 | appenders: [ 9 | { 10 | type: "multiprocess", 11 | mode: "master", 12 | appender: { 13 | type: "console" 14 | } 15 | } 16 | ] 17 | }); 18 | 19 | console.info("Master creating %d workers", numCPUs); 20 | for (i=0; i < numCPUs; i++) { 21 | cluster.fork(); 22 | } 23 | 24 | cluster.on('death', function(worker) { 25 | console.info("Worker %d died.", worker.pid); 26 | // cluster.fork(); 27 | }); 28 | } else { 29 | log4js.configure({ 30 | appenders: [ 31 | { 32 | type: "multiprocess", 33 | mode: "worker" 34 | } 35 | ] 36 | }); 37 | function logSomething(i) { 38 | return function() { 39 | console.info("Worker %d - logging something %d", process.pid, i); 40 | } 41 | } 42 | 43 | console.info("Worker %d started.", process.pid); 44 | for (i=0; i < 1000; i++) { 45 | process.nextTick(logSomething(i)); 46 | } 47 | } 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /node_modules/log4js/example.js: -------------------------------------------------------------------------------- 1 | var log4js = require('./lib/log4js'); 2 | //log the cheese logger messages to a file, and the console ones as well. 3 | log4js.addAppender(log4js.fileAppender('cheese.log'), 'cheese', 'console'); 4 | 5 | var logger = log4js.getLogger('cheese'); 6 | //only errors and above get logged. 7 | logger.setLevel('ERROR'); 8 | 9 | //console logging methds have been replaced with log4js ones. 10 | console.error("AAArgh! Something went wrong", { some: "otherObject", useful_for: "debug purposes" }); 11 | 12 | //these will not appear (logging level beneath error) 13 | logger.trace('Entering cheese testing'); 14 | logger.debug('Got cheese.'); 15 | logger.info('Cheese is Gouda.'); 16 | logger.warn('Cheese is quite smelly.'); 17 | //these end up on the console and in cheese.log 18 | logger.error('Cheese %s is too ripe!', "gouda"); 19 | logger.fatal('Cheese was breeding ground for listeria.'); 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/appenders/console.js: -------------------------------------------------------------------------------- 1 | var layouts = require('../layouts'), 2 | consoleLog = console.log; 3 | 4 | function consoleAppender (layout) { 5 | layout = layout || layouts.colouredLayout; 6 | return function(loggingEvent) { 7 | consoleLog(layout(loggingEvent)); 8 | }; 9 | } 10 | 11 | function configure(config) { 12 | var layout; 13 | if (config.layout) { 14 | layout = layouts.layout(config.layout.type, config.layout); 15 | } 16 | return consoleAppender(layout); 17 | } 18 | 19 | exports.name = "console"; 20 | exports.appender = consoleAppender; 21 | exports.configure = configure; 22 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/appenders/file.js: -------------------------------------------------------------------------------- 1 | var layouts = require('../layouts') 2 | , path = require('path') 3 | , fs = require('fs') 4 | , streams = require('../streams'); 5 | 6 | /** 7 | * File Appender writing the logs to a text file. Supports rolling of logs by size. 8 | * 9 | * @param file file log messages will be written to 10 | * @param layout a function that takes a logevent and returns a string (defaults to basicLayout). 11 | * @param logSize - the maximum size (in bytes) for a log file, if not provided then logs won't be rotated. 12 | * @param numBackups - the number of log files to keep after logSize has been reached (default 5) 13 | */ 14 | function fileAppender (file, layout, logSize, numBackups) { 15 | var bytesWritten = 0; 16 | file = path.normalize(file); 17 | layout = layout || layouts.basicLayout; 18 | numBackups = numBackups === undefined ? 5 : numBackups; 19 | //there has to be at least one backup if logSize has been specified 20 | numBackups = numBackups === 0 ? 1 : numBackups; 21 | 22 | function openTheStream(file, fileSize, numFiles) { 23 | var stream; 24 | if (fileSize) { 25 | stream = new streams.BufferedWriteStream( 26 | new streams.RollingFileStream( 27 | file, 28 | fileSize, 29 | numFiles 30 | ) 31 | ); 32 | } else { 33 | stream = new streams.BufferedWriteStream(fs.createWriteStream(file, { encoding: "utf8", mode: 0644, flags: 'a' })); 34 | } 35 | stream.on("error", function (err) { 36 | console.error("log4js.fileAppender - Writing to file %s, error happened ", file, err); 37 | }); 38 | return stream; 39 | } 40 | 41 | var logFile = openTheStream(file, logSize, numBackups); 42 | 43 | //close the file on process exit. 44 | process.on('exit', function() { 45 | logFile.end(); 46 | }); 47 | 48 | return function(loggingEvent) { 49 | logFile.write(layout(loggingEvent)+'\n', "utf8"); 50 | }; 51 | } 52 | 53 | function configure(config) { 54 | var layout; 55 | if (config.layout) { 56 | layout = layouts.layout(config.layout.type, config.layout); 57 | } 58 | return fileAppender(config.filename, layout, config.maxLogSize, config.backups); 59 | } 60 | 61 | exports.name = "file"; 62 | exports.appender = fileAppender; 63 | exports.configure = configure; 64 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/appenders/gelf.js: -------------------------------------------------------------------------------- 1 | var compress = require('compress-buffer').compress; 2 | var layouts = require('../layouts'); 3 | var levels = require('../levels'); 4 | var dgram = require('dgram'); 5 | var util = require('util'); 6 | 7 | var LOG_EMERG=0; // system is unusable 8 | var LOG_ALERT=1; // action must be taken immediately 9 | var LOG_CRIT=2; // critical conditions 10 | var LOG_ERR=3; // error conditions 11 | var LOG_ERROR=3; // because people WILL typo 12 | var LOG_WARNING=4; // warning conditions 13 | var LOG_NOTICE=5; // normal, but significant, condition 14 | var LOG_INFO=6; // informational message 15 | var LOG_DEBUG=7; // debug-level message 16 | 17 | var levelMapping = {}; 18 | levelMapping[levels.ALL] = LOG_DEBUG; 19 | levelMapping[levels.TRACE] = LOG_DEBUG; 20 | levelMapping[levels.DEBUG] = LOG_DEBUG; 21 | levelMapping[levels.INFO] = LOG_INFO; 22 | levelMapping[levels.WARN] = LOG_WARNING; 23 | levelMapping[levels.ERROR] = LOG_ERR; 24 | levelMapping[levels.FATAL] = LOG_CRIT; 25 | 26 | /** 27 | * GELF appender that supports sending UDP packets to a GELF compatible server such as Graylog 28 | * 29 | * @param layout a function that takes a logevent and returns a string (defaults to none). 30 | * @param host - host to which to send logs (default:localhost) 31 | * @param port - port at which to send logs to (default:12201) 32 | * @param hostname - hostname of the current host (default:os hostname) 33 | * @param facility - facility to log to (default:nodejs-server) 34 | */ 35 | function gelfAppender (layout, host, port, hostname, facility) { 36 | 37 | host = host || 'localhost'; 38 | port = port || 12201; 39 | hostname = hostname || require('os').hostname(); 40 | facility = facility || 'nodejs-server'; 41 | layout = layout || layouts.messagePassThroughLayout; 42 | 43 | var client = dgram.createSocket("udp4"); 44 | 45 | process.on('exit', function() { 46 | if (client) client.close(); 47 | }); 48 | 49 | function preparePacket(loggingEvent) { 50 | var msg = {}; 51 | msg.full_message = layout(loggingEvent); 52 | msg.short_message = msg.full_message; 53 | 54 | msg.version="1.0"; 55 | msg.timestamp = msg.timestamp || new Date().getTime() / 1000 >> 0; 56 | msg.host = hostname; 57 | msg.level = levelMapping[loggingEvent.level || levels.DEBUG]; 58 | msg.facility = facility; 59 | return msg; 60 | } 61 | 62 | function sendPacket(packet) { 63 | try { 64 | client.send(packet, 0, packet.length, port, host); 65 | } catch(e) {} 66 | } 67 | 68 | return function(loggingEvent) { 69 | var message = preparePacket(loggingEvent); 70 | var packet = compress(new Buffer(JSON.stringify(message))); 71 | if (packet.length > 8192) { 72 | util.debug("Message packet length (" + packet.length + ") is larger than 8k. Not sending"); 73 | } else { 74 | sendPacket(packet); 75 | } 76 | }; 77 | } 78 | 79 | function configure(config) { 80 | var layout; 81 | if (config.layout) { 82 | layout = layouts.layout(config.layout.type, config.layout); 83 | } 84 | return gelfAppender(layout, config.host, config.port, config.hostname, config.facility); 85 | } 86 | 87 | exports.name = "gelf"; 88 | exports.appender = gelfAppender; 89 | exports.configure = configure; 90 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/appenders/hookio.js: -------------------------------------------------------------------------------- 1 | var log4js = require('../log4js'); 2 | var layouts = require('../layouts'); 3 | var Hook = require('hook.io').Hook; 4 | var util = require('util'); 5 | 6 | var Logger = function createLogger(options) { 7 | var self = this; 8 | var actualAppender = options.actualAppender; 9 | Hook.call(self, options); 10 | self.on('hook::ready', function hookReady() { 11 | self.on('*::' + options.name + '::log', function log(loggingEvent) { 12 | deserializeLoggingEvent(loggingEvent); 13 | actualAppender(loggingEvent); 14 | }); 15 | }); 16 | } 17 | util.inherits(Logger, Hook); 18 | 19 | function deserializeLoggingEvent(loggingEvent) { 20 | loggingEvent.startTime = new Date(loggingEvent.startTime); 21 | loggingEvent.level.toString = function levelToString() { 22 | return loggingEvent.level.levelStr; 23 | }; 24 | } 25 | 26 | function initHook(hookioOptions) { 27 | var loggerHook; 28 | if (hookioOptions.mode === 'master') { 29 | // Start the master hook, handling the actual logging 30 | loggerHook = new Logger(hookioOptions); 31 | } else { 32 | // Start a worker, just emitting events for a master 33 | loggerHook = new Hook(hookioOptions); 34 | } 35 | loggerHook.start(); 36 | return loggerHook; 37 | } 38 | 39 | function getBufferedHook(hook, eventName) { 40 | var hookBuffer = []; 41 | var hookReady = false; 42 | hook.on('hook::ready', function emptyBuffer() { 43 | hookBuffer.forEach(function logBufferItem(loggingEvent) { 44 | hook.emit(eventName, loggingEvent); 45 | }) 46 | hookReady = true; 47 | }); 48 | 49 | return function log(loggingEvent) { 50 | if (hookReady) { 51 | hook.emit(eventName, loggingEvent); 52 | } else { 53 | hookBuffer.push(loggingEvent); 54 | } 55 | } 56 | } 57 | 58 | function createAppender(hookioOptions) { 59 | var loggerHook = initHook(hookioOptions); 60 | var loggerEvent = hookioOptions.name + '::log'; 61 | return getBufferedHook(loggerHook, loggerEvent); 62 | } 63 | 64 | function configure(config) { 65 | var actualAppender; 66 | if (config.appender && config.mode === 'master') { 67 | log4js.loadAppender(config.appender.type); 68 | actualAppender = log4js.appenderMakers[config.appender.type](config.appender); 69 | config.actualAppender = actualAppender; 70 | } 71 | return createAppender(config); 72 | } 73 | 74 | exports.name = 'hookio'; 75 | exports.appender = createAppender; 76 | exports.configure = configure; 77 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/appenders/logLevelFilter.js: -------------------------------------------------------------------------------- 1 | var levels = require('../levels'); 2 | var log4js = require('../log4js'); 3 | 4 | function logLevelFilter (levelString, appender) { 5 | var level = levels.toLevel(levelString); 6 | return function(logEvent) { 7 | if (logEvent.level.isGreaterThanOrEqualTo(level)) { 8 | appender(logEvent); 9 | } 10 | } 11 | } 12 | 13 | function configure(config) { 14 | log4js.loadAppender(config.appender.type); 15 | var appender = log4js.appenderMakers[config.appender.type](config.appender); 16 | return logLevelFilter(config.level, appender); 17 | } 18 | 19 | exports.name = "logLevelFilter"; 20 | exports.appender = logLevelFilter; 21 | exports.configure = configure; 22 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/appenders/multiprocess.js: -------------------------------------------------------------------------------- 1 | var log4js = require('../log4js'); 2 | var layouts = require('../layouts'); 3 | var net = require('net'); 4 | var util = require('util'); 5 | 6 | var LogServer = function createLogServer(config) { 7 | var actualAppender = config.actualAppender; 8 | var server = net.createServer(function serverCreated(clientSocket) { 9 | clientSocket.on('connect', function clientConnected() { 10 | var logMessage = ''; 11 | clientSocket.on('data', function chunkReceived(chunk) { 12 | logMessage += chunk; 13 | }); 14 | clientSocket.on('end', function gotChunks() { 15 | try { 16 | var loggingEvent = JSON.parse(logMessage); 17 | deserializeLoggingEvent(loggingEvent); 18 | actualAppender(loggingEvent); 19 | } catch (e) { 20 | // JSON.parse failed, just log the contents probably a naughty. 21 | actualAppender(createLoggingEvent('ERROR', 'Unable to parse log: ' + logMessage)); 22 | } 23 | }); 24 | }); 25 | }); 26 | server.listen(config.loggerPort || 5000, config.loggerHost || 'localhost'); 27 | } 28 | 29 | function createLoggingEvent(level, message) { 30 | return { 31 | startTime: new Date(), 32 | categoryName: 'log4js', 33 | level: { toString: function () { 34 | return level; 35 | }}, 36 | data: [ message ] 37 | }; 38 | } 39 | 40 | function deserializeLoggingEvent(loggingEvent) { 41 | loggingEvent.startTime = new Date(loggingEvent.startTime); 42 | loggingEvent.level.toString = function levelToString() { 43 | return loggingEvent.level.levelStr; 44 | }; 45 | } 46 | 47 | function workerAppender(config) { 48 | return function log(loggingEvent) { 49 | var socket = net.createConnection(config.loggerPort || 5000, config.loggerHost || 'localhost'); 50 | socket.on('connect', function socketConnected() { 51 | socket.end(JSON.stringify(loggingEvent), 'utf8'); 52 | }); 53 | }; 54 | } 55 | 56 | function createAppender(config) { 57 | if (config.mode === 'master') { 58 | var server = new LogServer(config); 59 | return config.actualAppender; 60 | } else { 61 | return workerAppender(config); 62 | } 63 | } 64 | 65 | function configure(config) { 66 | var actualAppender; 67 | if (config.appender && config.mode === 'master') { 68 | log4js.loadAppender(config.appender.type); 69 | actualAppender = log4js.appenderMakers[config.appender.type](config.appender); 70 | config.actualAppender = actualAppender; 71 | } 72 | return createAppender(config); 73 | } 74 | 75 | exports.name = 'multiprocess'; 76 | exports.appender = createAppender; 77 | exports.configure = configure; 78 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/appenders/smtp.js: -------------------------------------------------------------------------------- 1 | var layouts = require("../layouts"), 2 | mailer = require("nodemailer"); 3 | 4 | /** 5 | * SMTP Appender. Sends logging events using SMTP protocol. 6 | * It can either send an email on each event or group several logging events gathered during specified interval. 7 | * 8 | * @param recipients comma separated list of email recipients 9 | * @param sender sender of all emails (defaults to SMTP user) 10 | * @param subject subject of all email messages (defaults to first event's message) 11 | * @param layout a function that takes a logevent and returns a string (defaults to basicLayout). 12 | * @param smtpConfig SMTP configuration for 'nodemailer' 13 | * @param sendInterval the time in seconds between sending attempts (defaults to 0); 14 | * all events are buffered and sent in one email during this time; if 0 than every event sends an email 15 | */ 16 | function smtpAppender(recipients, sender, subject, layout, smtpConfig, sendInterval) { 17 | sender = sender || smtpConfig.user; 18 | layout = layout || layouts.basicLayout; 19 | subjectLayout = layouts.messagePassThroughLayout; 20 | mailer.SMTP = smtpConfig; 21 | sendInterval = sendInterval*1000 || 0; 22 | 23 | var logEventBuffer = []; 24 | var sendTimer; 25 | 26 | function sendBuffer() { 27 | if (logEventBuffer.length == 0) 28 | return; 29 | 30 | var firstEvent = logEventBuffer[0]; 31 | var body = ""; 32 | while (logEventBuffer.length > 0) { 33 | body += layout(logEventBuffer.shift()) + "\n"; 34 | } 35 | 36 | var msg = { 37 | sender: sender, 38 | to: recipients, 39 | subject: subject || subjectLayout(firstEvent), 40 | body: body 41 | }; 42 | mailer.send_mail(msg, function(error, success) { 43 | if (error) { 44 | console.error("log4js.smtpAppender - Error happened ", error); 45 | } 46 | }); 47 | } 48 | 49 | function scheduleSend() { 50 | if (!sendTimer) 51 | sendTimer = setTimeout(function() { 52 | sendTimer = null; 53 | sendBuffer(); 54 | }, sendInterval); 55 | } 56 | 57 | return function(loggingEvent) { 58 | logEventBuffer.push(loggingEvent); 59 | if (sendInterval > 0) 60 | scheduleSend(); 61 | else 62 | sendBuffer(); 63 | }; 64 | } 65 | 66 | function configure(config) { 67 | var layout; 68 | if (config.layout) { 69 | layout = layouts.layout(config.layout.type, config.layout); 70 | } 71 | return smtpAppender(config.recipients, config.sender, config.subject, layout, config.smtp, config.sendInterval); 72 | } 73 | 74 | exports.name = "smtp"; 75 | exports.appender = smtpAppender; 76 | exports.configure = configure; 77 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/connect-logger.js: -------------------------------------------------------------------------------- 1 | var levels = require("./levels"); 2 | /** 3 | * Log requests with the given `options` or a `format` string. 4 | * 5 | * Options: 6 | * 7 | * - `format` Format string, see below for tokens 8 | * - `level` A log4js levels instance. 9 | * 10 | * Tokens: 11 | * 12 | * - `:req[header]` ex: `:req[Accept]` 13 | * - `:res[header]` ex: `:res[Content-Length]` 14 | * - `:http-version` 15 | * - `:response-time` 16 | * - `:remote-addr` 17 | * - `:date` 18 | * - `:method` 19 | * - `:url` 20 | * - `:referrer` 21 | * - `:user-agent` 22 | * - `:status` 23 | * 24 | * @param {String|Function|Object} format or options 25 | * @return {Function} 26 | * @api public 27 | */ 28 | 29 | function getLogger(logger4js, options) { 30 | if ('object' == typeof options) { 31 | options = options || {}; 32 | } else if (options) { 33 | options = { format: options }; 34 | } else { 35 | options = {}; 36 | } 37 | 38 | var thislogger = logger4js 39 | , level = levels.toLevel(options.level, levels.INFO) 40 | , fmt = options.format || ':remote-addr - - ":method :url HTTP/:http-version" :status :content-length ":referrer" ":user-agent"' 41 | , nolog = options.nolog ? createNoLogCondition(options.nolog) : null; 42 | 43 | return function (req, res, next) { 44 | 45 | // mount safety 46 | if (req._logging) return next(); 47 | 48 | // nologs 49 | if(nolog && nolog.test(req.originalUrl)) return next(); 50 | 51 | if (thislogger.isLevelEnabled(level)) { 52 | 53 | var start = +new Date 54 | , statusCode 55 | , writeHead = res.writeHead 56 | , end = res.end 57 | , url = req.originalUrl; 58 | 59 | // flag as logging 60 | req._logging = true; 61 | 62 | // proxy for statusCode. 63 | res.writeHead = function(code, headers){ 64 | res.writeHead = writeHead; 65 | res.writeHead(code, headers); 66 | res.__statusCode = statusCode = code; 67 | res.__headers = headers || {}; 68 | }; 69 | 70 | // proxy end to output a line to the provided logger. 71 | res.end = function(chunk, encoding) { 72 | res.end = end; 73 | res.end(chunk, encoding); 74 | res.responseTime = +new Date - start; 75 | if ('function' == typeof fmt) { 76 | var line = fmt(req, res, function(str){ return format(str, req, res); }); 77 | if (line) thislogger.log(level, line); 78 | } else { 79 | thislogger.log(level, format(fmt, req, res)); 80 | } 81 | }; 82 | } 83 | 84 | //ensure next gets always called 85 | next(); 86 | }; 87 | } 88 | 89 | /** 90 | * Return formatted log line. 91 | * 92 | * @param {String} str 93 | * @param {IncomingMessage} req 94 | * @param {ServerResponse} res 95 | * @return {String} 96 | * @api private 97 | */ 98 | 99 | function format(str, req, res) { 100 | return str 101 | .replace(':url', req.originalUrl) 102 | .replace(':method', req.method) 103 | .replace(':status', res.__statusCode || res.statusCode) 104 | .replace(':response-time', res.responseTime) 105 | .replace(':date', new Date().toUTCString()) 106 | .replace(':referrer', req.headers['referer'] || req.headers['referrer'] || '') 107 | .replace(':http-version', req.httpVersionMajor + '.' + req.httpVersionMinor) 108 | .replace(':remote-addr', req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress))) 109 | .replace(':user-agent', req.headers['user-agent'] || '') 110 | .replace(':content-length', (res._headers && res._headers['content-length']) || (res.__headers && res.__headers['Content-Length']) || '-') 111 | .replace(/:req\[([^\]]+)\]/g, function(_, field){ return req.headers[field.toLowerCase()]; }) 112 | .replace(/:res\[([^\]]+)\]/g, function(_, field){ 113 | return res._headers 114 | ? (res._headers[field.toLowerCase()] || res.__headers[field]) 115 | : (res.__headers && res.__headers[field]); 116 | }); 117 | } 118 | 119 | /** 120 | * Return RegExp Object about nolog 121 | * 122 | * @param {String} nolog 123 | * @return {RegExp} 124 | * @api private 125 | */ 126 | 127 | /** 128 | * syntax 129 | * 1. String 130 | * 1.1 "\\.gif" 131 | * NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga 132 | * LOGGING http://example.com/hoge.agif 133 | * 1.2 in "\\.gif|\\.jpg$" 134 | * NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga and http://example.com/hoge.jpg?fuga 135 | * LOGGING http://example.com/hoge.agif, http://example.com/hoge.ajpg and http://example.com/hoge.jpg?hoge 136 | * 1.3 in "\\.(gif|jpe?g|png)$" 137 | * NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.jpeg 138 | * LOGGING http://example.com/hoge.gif?uid=2 and http://example.com/hoge.jpg?pid=3 139 | * 2. RegExp 140 | * 2.1 in /\.(gif|jpe?g|png)$/ 141 | * SAME AS 1.3 142 | * 3. Array 143 | * 3.1 ["\\.jpg$", "\\.png", "\\.gif"] 144 | * SAME AS "\\.jpg|\\.png|\\.gif" 145 | */ 146 | function createNoLogCondition(nolog, type) { 147 | if(!nolog) return null; 148 | type = type || ''; 149 | 150 | if(nolog instanceof RegExp){ 151 | if(type === 'string') 152 | return nolog.source; 153 | return nolog; 154 | } else if(typeof nolog === 'string'){ 155 | if(type === 'string') 156 | return nolog; 157 | try{ 158 | return new RegExp(nolog); 159 | } catch (ex) { 160 | return null; 161 | } 162 | } else if(nolog instanceof Array){ 163 | var regexps = nolog.map(function(o){ return createNoLogCondition(o, 'string')}); 164 | return new RegExp(regexps.join('|')); 165 | } 166 | } 167 | 168 | exports.connectLogger = getLogger; -------------------------------------------------------------------------------- /node_modules/log4js/lib/date_format.js: -------------------------------------------------------------------------------- 1 | exports.ISO8601_FORMAT = "yyyy-MM-dd hh:mm:ss.SSS"; 2 | exports.ISO8601_WITH_TZ_OFFSET_FORMAT = "yyyy-MM-ddThh:mm:ssO"; 3 | exports.DATETIME_FORMAT = "dd MM yyyy hh:mm:ss.SSS"; 4 | exports.ABSOLUTETIME_FORMAT = "hh:mm:ss.SSS"; 5 | 6 | exports.asString = function(/*format,*/ date) { 7 | var format = exports.ISO8601_FORMAT; 8 | if (typeof(date) === "string") { 9 | format = arguments[0]; 10 | date = arguments[1]; 11 | } 12 | 13 | var vDay = addZero(date.getDate()); 14 | var vMonth = addZero(date.getMonth()+1); 15 | var vYearLong = addZero(date.getFullYear()); 16 | var vYearShort = addZero(date.getFullYear().toString().substring(3,4)); 17 | var vYear = (format.indexOf("yyyy") > -1 ? vYearLong : vYearShort); 18 | var vHour = addZero(date.getHours()); 19 | var vMinute = addZero(date.getMinutes()); 20 | var vSecond = addZero(date.getSeconds()); 21 | var vMillisecond = padWithZeros(date.getMilliseconds(), 3); 22 | var vTimeZone = offset(date); 23 | var formatted = format 24 | .replace(/dd/g, vDay) 25 | .replace(/MM/g, vMonth) 26 | .replace(/y{1,4}/g, vYear) 27 | .replace(/hh/g, vHour) 28 | .replace(/mm/g, vMinute) 29 | .replace(/ss/g, vSecond) 30 | .replace(/SSS/g, vMillisecond) 31 | .replace(/O/g, vTimeZone); 32 | return formatted; 33 | 34 | function padWithZeros(vNumber, width) { 35 | var numAsString = vNumber + ""; 36 | while (numAsString.length < width) { 37 | numAsString = "0" + numAsString; 38 | } 39 | return numAsString; 40 | } 41 | 42 | function addZero(vNumber) { 43 | return padWithZeros(vNumber, 2); 44 | } 45 | 46 | /** 47 | * Formats the TimeOffest 48 | * Thanks to http://www.svendtofte.com/code/date_format/ 49 | * @private 50 | */ 51 | function offset(date) { 52 | // Difference to Greenwich time (GMT) in hours 53 | var os = Math.abs(date.getTimezoneOffset()); 54 | var h = String(Math.floor(os/60)); 55 | var m = String(os%60); 56 | h.length == 1? h = "0"+h:1; 57 | m.length == 1? m = "0"+m:1; 58 | return date.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/layouts.js: -------------------------------------------------------------------------------- 1 | var dateFormat = require('./date_format') 2 | , util = require('util') 3 | , replacementRegExp = /%[sdj]/g 4 | , layoutMakers = { 5 | "messagePassThrough": function() { return messagePassThroughLayout; } 6 | , "basic": function() { return basicLayout; } 7 | , "colored": function() { return colouredLayout; } 8 | , "coloured": function() { return colouredLayout; } 9 | , "pattern": function (config) { 10 | var pattern = config.pattern || undefined; 11 | return patternLayout(pattern); 12 | } 13 | } 14 | , colours = { 15 | ALL: "grey" 16 | , TRACE: "blue" 17 | , DEBUG: "cyan" 18 | , INFO: "green" 19 | , WARN: "yellow" 20 | , ERROR: "red" 21 | , FATAL: "magenta" 22 | , OFF: "grey" 23 | }; 24 | 25 | 26 | function formatLogData(logData) { 27 | var output = "" 28 | , data = Array.isArray(logData) ? logData.slice() : Array.prototype.slice.call(arguments) 29 | , format = data.shift(); 30 | 31 | if (typeof format === "string") { 32 | output = format.replace(replacementRegExp, function(match) { 33 | switch (match) { 34 | case "%s": return new String(data.shift()); 35 | case "%d": return new Number(data.shift()); 36 | case "%j": return JSON.stringify(data.shift()); 37 | default: 38 | return match; 39 | }; 40 | }); 41 | } else { 42 | //put it back, it's not a format string 43 | data.unshift(format); 44 | } 45 | 46 | data.forEach(function (item) { 47 | if (output) { 48 | output += ' '; 49 | } 50 | if (item && item.stack) { 51 | output += item.stack; 52 | } else { 53 | output += util.inspect(item); 54 | } 55 | }); 56 | 57 | return output; 58 | } 59 | 60 | /** 61 | * Taken from masylum's fork (https://github.com/masylum/log4js-node) 62 | */ 63 | function colorize (str, style) { 64 | var styles = { 65 | //styles 66 | 'bold' : [1, 22], 67 | 'italic' : [3, 23], 68 | 'underline' : [4, 24], 69 | 'inverse' : [7, 27], 70 | //grayscale 71 | 'white' : [37, 39], 72 | 'grey' : [90, 39], 73 | 'black' : [90, 39], 74 | //colors 75 | 'blue' : [34, 39], 76 | 'cyan' : [36, 39], 77 | 'green' : [32, 39], 78 | 'magenta' : [35, 39], 79 | 'red' : [31, 39], 80 | 'yellow' : [33, 39] 81 | }; 82 | return style ? '\033[' + styles[style][0] + 'm' + str + 83 | '\033[' + styles[style][1] + 'm' : str; 84 | } 85 | 86 | function timestampLevelAndCategory(loggingEvent, colour) { 87 | var output = colorize( 88 | formatLogData( 89 | '[%s] [%s] %s - ' 90 | , dateFormat.asString(loggingEvent.startTime) 91 | , loggingEvent.level 92 | , loggingEvent.categoryName 93 | ) 94 | , colour 95 | ); 96 | return output; 97 | } 98 | 99 | /** 100 | * BasicLayout is a simple layout for storing the logs. The logs are stored 101 | * in following format: 102 | *
103 |  * [startTime] [logLevel] categoryName - message\n
104 |  * 
105 | * 106 | * @author Stephan Strittmatter 107 | */ 108 | function basicLayout (loggingEvent) { 109 | return timestampLevelAndCategory(loggingEvent) + formatLogData(loggingEvent.data); 110 | } 111 | 112 | /** 113 | * colouredLayout - taken from masylum's fork. 114 | * same as basicLayout, but with colours. 115 | */ 116 | function colouredLayout (loggingEvent) { 117 | return timestampLevelAndCategory(loggingEvent, colours[loggingEvent.level.toString()]) + formatLogData(loggingEvent.data); 118 | } 119 | 120 | function messagePassThroughLayout (loggingEvent) { 121 | return formatLogData(loggingEvent.data); 122 | } 123 | 124 | /** 125 | * PatternLayout 126 | * Format for specifiers is %[padding].[truncation][field]{[format]} 127 | * e.g. %5.10p - left pad the log level by 5 characters, up to a max of 10 128 | * Fields can be any of: 129 | * - %r time in toLocaleTimeString format 130 | * - %p log level 131 | * - %c log category 132 | * - %m log data 133 | * - %d date in various formats 134 | * - %% % 135 | * - %n newline 136 | * Takes a pattern string and returns a layout function. 137 | * @author Stephan Strittmatter 138 | */ 139 | function patternLayout (pattern) { 140 | var TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n"; 141 | var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([cdmnpr%])(\{([^\}]+)\})?|([^%]+)/; 142 | 143 | pattern = pattern || TTCC_CONVERSION_PATTERN; 144 | 145 | return function(loggingEvent) { 146 | var formattedString = ""; 147 | var result; 148 | var searchString = pattern; 149 | 150 | while ((result = regex.exec(searchString))) { 151 | var matchedString = result[0]; 152 | var padding = result[1]; 153 | var truncation = result[2]; 154 | var conversionCharacter = result[3]; 155 | var specifier = result[5]; 156 | var text = result[6]; 157 | 158 | // Check if the pattern matched was just normal text 159 | if (text) { 160 | formattedString += "" + text; 161 | } else { 162 | // Create a raw replacement string based on the conversion 163 | // character and specifier 164 | var replacement = ""; 165 | switch(conversionCharacter) { 166 | case "c": 167 | var loggerName = loggingEvent.categoryName; 168 | if (specifier) { 169 | var precision = parseInt(specifier, 10); 170 | var loggerNameBits = loggingEvent.categoryName.split("."); 171 | if (precision >= loggerNameBits.length) { 172 | replacement = loggerName; 173 | } else { 174 | replacement = loggerNameBits.slice(loggerNameBits.length - precision).join("."); 175 | } 176 | } else { 177 | replacement = loggerName; 178 | } 179 | break; 180 | case "d": 181 | var format = dateFormat.ISO8601_FORMAT; 182 | if (specifier) { 183 | format = specifier; 184 | // Pick up special cases 185 | if (format == "ISO8601") { 186 | format = dateFormat.ISO8601_FORMAT; 187 | } else if (format == "ABSOLUTE") { 188 | format = dateFormat.ABSOLUTETIME_FORMAT; 189 | } else if (format == "DATE") { 190 | format = dateFormat.DATETIME_FORMAT; 191 | } 192 | } 193 | // Format the date 194 | replacement = dateFormat.asString(format, loggingEvent.startTime); 195 | break; 196 | case "m": 197 | replacement = formatLogData(loggingEvent.data); 198 | break; 199 | case "n": 200 | replacement = "\n"; 201 | break; 202 | case "p": 203 | replacement = loggingEvent.level.toString(); 204 | break; 205 | case "r": 206 | replacement = "" + loggingEvent.startTime.toLocaleTimeString(); 207 | break; 208 | case "%": 209 | replacement = "%"; 210 | break; 211 | default: 212 | replacement = matchedString; 213 | break; 214 | } 215 | // Format the replacement according to any padding or 216 | // truncation specified 217 | 218 | var len; 219 | 220 | // First, truncation 221 | if (truncation) { 222 | len = parseInt(truncation.substr(1), 10); 223 | replacement = replacement.substring(0, len); 224 | } 225 | // Next, padding 226 | if (padding) { 227 | if (padding.charAt(0) == "-") { 228 | len = parseInt(padding.substr(1), 10); 229 | // Right pad with spaces 230 | while (replacement.length < len) { 231 | replacement += " "; 232 | } 233 | } else { 234 | len = parseInt(padding, 10); 235 | // Left pad with spaces 236 | while (replacement.length < len) { 237 | replacement = " " + replacement; 238 | } 239 | } 240 | } 241 | formattedString += replacement; 242 | } 243 | searchString = searchString.substr(result.index + result[0].length); 244 | } 245 | return formattedString; 246 | }; 247 | 248 | }; 249 | 250 | 251 | module.exports = { 252 | basicLayout: basicLayout 253 | , messagePassThroughLayout: messagePassThroughLayout 254 | , patternLayout: patternLayout 255 | , colouredLayout: colouredLayout 256 | , coloredLayout: colouredLayout 257 | , layout: function(name, config) { 258 | return layoutMakers[name] && layoutMakers[name](config); 259 | } 260 | }; -------------------------------------------------------------------------------- /node_modules/log4js/lib/levels.js: -------------------------------------------------------------------------------- 1 | function Level(level, levelStr) { 2 | this.level = level; 3 | this.levelStr = levelStr; 4 | } 5 | 6 | /** 7 | * converts given String to corresponding Level 8 | * @param {String} sArg String value of Level 9 | * @param {Log4js.Level} defaultLevel default Level, if no String representation 10 | * @return Level object 11 | * @type Log4js.Level 12 | */ 13 | function toLevel(sArg, defaultLevel) { 14 | 15 | if (sArg === null) { 16 | return defaultLevel; 17 | } 18 | 19 | if (typeof sArg == "string") { 20 | var s = sArg.toUpperCase(); 21 | if (module.exports[s]) { 22 | return module.exports[s]; 23 | } 24 | } 25 | return defaultLevel; 26 | }; 27 | 28 | Level.prototype.toString = function() { 29 | return this.levelStr; 30 | }; 31 | 32 | Level.prototype.isLessThanOrEqualTo = function(otherLevel) { 33 | if (typeof otherLevel === "string") { 34 | otherLevel = toLevel(otherLevel); 35 | } 36 | return this.level <= otherLevel.level; 37 | }; 38 | 39 | Level.prototype.isGreaterThanOrEqualTo = function(otherLevel) { 40 | if (typeof otherLevel === "string") { 41 | otherLevel = toLevel(otherLevel); 42 | } 43 | return this.level >= otherLevel.level; 44 | }; 45 | 46 | module.exports = { 47 | ALL: new Level(Number.MIN_VALUE, "ALL") 48 | , TRACE: new Level(5000, "TRACE") 49 | , DEBUG: new Level(10000, "DEBUG") 50 | , INFO: new Level(20000, "INFO") 51 | , WARN: new Level(30000, "WARN") 52 | , ERROR: new Level(40000, "ERROR") 53 | , FATAL: new Level(50000, "FATAL") 54 | , OFF: new Level(Number.MAX_VALUE, "OFF") 55 | , toLevel: toLevel 56 | }; 57 | -------------------------------------------------------------------------------- /node_modules/log4js/lib/log4js.json: -------------------------------------------------------------------------------- 1 | { 2 | "appenders": [ 3 | { 4 | "type": "console" 5 | } 6 | ] 7 | } -------------------------------------------------------------------------------- /node_modules/log4js/lib/streams.js: -------------------------------------------------------------------------------- 1 | var util = require('util'), 2 | fs = require('fs'), 3 | path = require('path'), 4 | events = require('events'), 5 | async = require('async'); 6 | 7 | function debug(message) { 8 | util.debug(message); 9 | // console.log(message); 10 | } 11 | 12 | function BufferedWriteStream(stream) { 13 | var that = this; 14 | this.stream = stream; 15 | this.buffer = []; 16 | this.canWrite = false; 17 | this.bytes = 0; 18 | 19 | this.stream.on("open", function() { 20 | that.canWrite = true; 21 | that.flushBuffer(); 22 | }); 23 | 24 | this.stream.on("error", function (err) { 25 | that.emit("error", err); 26 | }); 27 | 28 | this.stream.on("drain", function() { 29 | that.canWrite = true; 30 | that.flushBuffer(); 31 | }); 32 | } 33 | 34 | util.inherits(BufferedWriteStream, events.EventEmitter); 35 | 36 | Object.defineProperty( 37 | BufferedWriteStream.prototype, 38 | "fd", 39 | { 40 | get: function() { return this.stream.fd; }, 41 | set: function(newFd) { 42 | this.stream.fd = newFd; 43 | this.bytes = 0; 44 | } 45 | } 46 | ); 47 | 48 | Object.defineProperty( 49 | BufferedWriteStream.prototype, 50 | "bytesWritten", 51 | { 52 | get: function() { return this.bytes; } 53 | } 54 | ); 55 | 56 | BufferedWriteStream.prototype.write = function(data, encoding) { 57 | this.buffer.push({ data: data, encoding: encoding }); 58 | this.flushBuffer(); 59 | }; 60 | 61 | BufferedWriteStream.prototype.end = function(data, encoding) { 62 | if (data) { 63 | this.buffer.push({ data: data, encoding: encoding }); 64 | } 65 | this.flushBufferEvenIfCannotWrite(); 66 | }; 67 | 68 | BufferedWriteStream.prototype.writeToStream = function(toWrite) { 69 | this.bytes += toWrite.data.length; 70 | this.canWrite = this.stream.write(toWrite.data, toWrite.encoding); 71 | }; 72 | 73 | BufferedWriteStream.prototype.flushBufferEvenIfCannotWrite = function() { 74 | while (this.buffer.length > 0) { 75 | this.writeToStream(this.buffer.shift()); 76 | } 77 | }; 78 | 79 | BufferedWriteStream.prototype.flushBuffer = function() { 80 | while (this.buffer.length > 0 && this.canWrite) { 81 | this.writeToStream(this.buffer.shift()); 82 | } 83 | }; 84 | 85 | function BaseRollingFileStream(filename, options) { 86 | this.filename = filename; 87 | this.options = options || { encoding: 'utf8', mode: 0644, flags: 'a' }; 88 | this.rolling = false; 89 | this.writesWhileRolling = []; 90 | this.currentSize = 0; 91 | 92 | function currentFileSize(file) { 93 | var fileSize = 0; 94 | try { 95 | fileSize = fs.statSync(file).size; 96 | } catch (e) { 97 | // file does not exist 98 | } 99 | return fileSize; 100 | } 101 | 102 | function throwErrorIfArgumentsAreNotValid() { 103 | if (!filename) { 104 | throw new Error("You must specify a filename"); 105 | } 106 | } 107 | 108 | throwErrorIfArgumentsAreNotValid(); 109 | 110 | BaseRollingFileStream.super_.call(this, this.filename, this.options); 111 | this.currentSize = currentFileSize(this.filename); 112 | } 113 | util.inherits(BaseRollingFileStream, fs.FileWriteStream); 114 | 115 | BaseRollingFileStream.prototype.initRolling = function() { 116 | var that = this; 117 | 118 | function emptyRollingQueue() { 119 | debug("emptying the rolling queue"); 120 | var toWrite; 121 | while ((toWrite = that.writesWhileRolling.shift())) { 122 | BaseRollingFileStream.super_.prototype.write.call(that, toWrite.data, toWrite.encoding); 123 | that.currentSize += toWrite.data.length; 124 | if (that.shouldRoll()) { 125 | that.flush(); 126 | return true; 127 | } 128 | } 129 | that.flush(); 130 | return false; 131 | } 132 | 133 | this.rolling = true; 134 | this.roll(this.filename, function() { 135 | that.currentSize = 0; 136 | that.rolling = emptyRollingQueue(); 137 | if (that.rolling) { 138 | process.nextTick(function() { that.initRolling(); }); 139 | } 140 | }); 141 | }; 142 | 143 | BaseRollingFileStream.prototype.write = function(data, encoding) { 144 | if (this.rolling) { 145 | this.writesWhileRolling.push({ data: data, encoding: encoding }); 146 | return false; 147 | } else { 148 | var canWrite = BaseRollingFileStream.super_.prototype.write.call(this, data, encoding); 149 | this.currentSize += data.length; 150 | debug('current size = ' + this.currentSize); 151 | if (this.shouldRoll()) { 152 | this.initRolling(); 153 | } 154 | return canWrite; 155 | } 156 | }; 157 | 158 | BaseRollingFileStream.prototype.shouldRoll = function() { 159 | return false; // default behaviour is never to roll 160 | }; 161 | 162 | BaseRollingFileStream.prototype.roll = function(filename, callback) { 163 | callback(); // default behaviour is not to do anything 164 | }; 165 | 166 | 167 | function RollingFileStream (filename, size, backups, options) { 168 | this.size = size; 169 | this.backups = backups || 1; 170 | 171 | function throwErrorIfArgumentsAreNotValid() { 172 | if (!filename || !size || size <= 0) { 173 | throw new Error("You must specify a filename and file size"); 174 | } 175 | } 176 | 177 | throwErrorIfArgumentsAreNotValid(); 178 | 179 | RollingFileStream.super_.call(this, filename, options); 180 | } 181 | util.inherits(RollingFileStream, BaseRollingFileStream); 182 | 183 | RollingFileStream.prototype.shouldRoll = function() { 184 | return this.currentSize >= this.size; 185 | }; 186 | 187 | RollingFileStream.prototype.roll = function(filename, callback) { 188 | var that = this, 189 | nameMatcher = new RegExp('^' + path.basename(filename)); 190 | 191 | function justTheseFiles (item) { 192 | return nameMatcher.test(item); 193 | } 194 | 195 | function index(filename_) { 196 | return parseInt(filename_.substring((path.basename(filename) + '.').length), 10) || 0; 197 | } 198 | 199 | function byIndex(a, b) { 200 | if (index(a) > index(b)) { 201 | return 1; 202 | } else if (index(a) < index(b) ) { 203 | return -1; 204 | } else { 205 | return 0; 206 | } 207 | } 208 | 209 | function increaseFileIndex (fileToRename, cb) { 210 | var idx = index(fileToRename); 211 | debug('Index of ' + fileToRename + ' is ' + idx); 212 | if (idx < that.backups) { 213 | //on windows, you can get a EEXIST error if you rename a file to an existing file 214 | //so, we'll try to delete the file we're renaming to first 215 | fs.unlink(filename + '.' + (idx+1), function (err) { 216 | //ignore err: if we could not delete, it's most likely that it doesn't exist 217 | debug('Renaming ' + fileToRename + ' -> ' + filename + '.' + (idx+1)); 218 | fs.rename(path.join(path.dirname(filename), fileToRename), filename + '.' + (idx + 1), cb); 219 | }); 220 | } else { 221 | cb(); 222 | } 223 | } 224 | 225 | function renameTheFiles(cb) { 226 | //roll the backups (rename file.n to file.n+1, where n <= numBackups) 227 | debug("Renaming the old files"); 228 | fs.readdir(path.dirname(filename), function (err, files) { 229 | async.forEachSeries( 230 | files.filter(justTheseFiles).sort(byIndex).reverse(), 231 | increaseFileIndex, 232 | cb 233 | ); 234 | }); 235 | } 236 | 237 | function openANewFile(cb) { 238 | debug("Opening a new file"); 239 | fs.open( 240 | filename, 241 | that.options.flags, 242 | that.options.mode, 243 | function (err, fd) { 244 | debug("opened new file"); 245 | var oldLogFileFD = that.fd; 246 | that.fd = fd; 247 | that.writable = true; 248 | fs.close(oldLogFileFD, cb); 249 | } 250 | ); 251 | } 252 | 253 | debug("Starting roll"); 254 | debug("Queueing up data until we've finished rolling"); 255 | debug("Flushing underlying stream"); 256 | this.flush(); 257 | 258 | async.series([ 259 | renameTheFiles, 260 | openANewFile 261 | ], callback); 262 | 263 | }; 264 | 265 | 266 | exports.BaseRollingFileStream = BaseRollingFileStream; 267 | exports.RollingFileStream = RollingFileStream; 268 | exports.BufferedWriteStream = BufferedWriteStream; 269 | -------------------------------------------------------------------------------- /node_modules/log4js/log-rolling.js: -------------------------------------------------------------------------------- 1 | var log4js = require('./lib/log4js') 2 | , log 3 | , i = 0; 4 | log4js.configure({ 5 | "appenders": [ 6 | { 7 | type: "console" 8 | , category: "console" 9 | }, 10 | { 11 | "type": "file", 12 | "filename": "tmp-test.log", 13 | "maxLogSize": 1024, 14 | "backups": 3, 15 | "category": "test" 16 | } 17 | ] 18 | }); 19 | log = log4js.getLogger("test"); 20 | 21 | function doTheLogging(x) { 22 | log.info("Logging something %d", x); 23 | } 24 | 25 | for ( ; i < 5000; i++) { 26 | doTheLogging(i); 27 | } -------------------------------------------------------------------------------- /node_modules/log4js/memory-test.js: -------------------------------------------------------------------------------- 1 | var log4js = require('./lib/log4js') 2 | , logger 3 | , usage 4 | , i; 5 | 6 | log4js.configure( 7 | { 8 | appenders: [ 9 | { 10 | category: "memory-test" 11 | , type: "file" 12 | , filename: "memory-test.log" 13 | }, 14 | { 15 | type: "console" 16 | , category: "memory-usage" 17 | }, 18 | { 19 | type: "file" 20 | , filename: "memory-usage.log" 21 | , category: "memory-usage" 22 | , layout: { 23 | type: "messagePassThrough" 24 | } 25 | } 26 | ] 27 | } 28 | ); 29 | logger = log4js.getLogger("memory-test"); 30 | usage = log4js.getLogger("memory-usage"); 31 | 32 | for (i=0; i < 1000000; i++) { 33 | if ( (i % 5000) === 0) { 34 | usage.info("%d %d", i, process.memoryUsage().rss); 35 | } 36 | logger.info("Doing something."); 37 | } 38 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/async/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/nodeunit"] 2 | path = deps/nodeunit 3 | url = git://github.com/caolan/nodeunit.git 4 | [submodule "deps/UglifyJS"] 5 | path = deps/UglifyJS 6 | url = https://github.com/mishoo/UglifyJS.git 7 | [submodule "deps/nodelint"] 8 | path = deps/nodelint 9 | url = https://github.com/tav/nodelint.git 10 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/async/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Caolan McMahon 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/async/Makefile: -------------------------------------------------------------------------------- 1 | PACKAGE = asyncjs 2 | NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node) 3 | 4 | BUILDDIR = dist 5 | 6 | all: build 7 | 8 | build: $(wildcard lib/*.js) 9 | mkdir -p $(BUILDDIR) 10 | uglifyjs lib/async.js > $(BUILDDIR)/async.min.js 11 | 12 | test: 13 | nodeunit test 14 | 15 | clean: 16 | rm -rf $(BUILDDIR) 17 | 18 | lint: 19 | nodelint --config nodelint.cfg lib/async.js 20 | 21 | .PHONY: test build all 22 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/async/deps/nodeunit.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Styles taken from qunit.css 3 | */ 4 | 5 | h1#nodeunit-header, h1.nodeunit-header { 6 | padding: 15px; 7 | font-size: large; 8 | background-color: #06b; 9 | color: white; 10 | font-family: 'trebuchet ms', verdana, arial; 11 | margin: 0; 12 | } 13 | 14 | h1#nodeunit-header a { 15 | color: white; 16 | } 17 | 18 | h2#nodeunit-banner { 19 | height: 2em; 20 | border-bottom: 1px solid white; 21 | background-color: #eee; 22 | margin: 0; 23 | font-family: 'trebuchet ms', verdana, arial; 24 | } 25 | h2#nodeunit-banner.pass { 26 | background-color: green; 27 | } 28 | h2#nodeunit-banner.fail { 29 | background-color: red; 30 | } 31 | 32 | h2#nodeunit-userAgent, h2.nodeunit-userAgent { 33 | padding: 10px; 34 | background-color: #eee; 35 | color: black; 36 | margin: 0; 37 | font-size: small; 38 | font-weight: normal; 39 | font-family: 'trebuchet ms', verdana, arial; 40 | font-size: 10pt; 41 | } 42 | 43 | div#nodeunit-testrunner-toolbar { 44 | background: #eee; 45 | border-top: 1px solid black; 46 | padding: 10px; 47 | font-family: 'trebuchet ms', verdana, arial; 48 | margin: 0; 49 | font-size: 10pt; 50 | } 51 | 52 | ol#nodeunit-tests { 53 | font-family: 'trebuchet ms', verdana, arial; 54 | font-size: 10pt; 55 | } 56 | ol#nodeunit-tests li strong { 57 | cursor:pointer; 58 | } 59 | ol#nodeunit-tests .pass { 60 | color: green; 61 | } 62 | ol#nodeunit-tests .fail { 63 | color: red; 64 | } 65 | 66 | p#nodeunit-testresult { 67 | margin-left: 1em; 68 | font-size: 10pt; 69 | font-family: 'trebuchet ms', verdana, arial; 70 | } 71 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/async/dist/async.min.js: -------------------------------------------------------------------------------- 1 | /*global setTimeout: false, console: false */(function(){var a={},b=this,c=b.async;typeof module!="undefined"&&module.exports?module.exports=a:b.async=a,a.noConflict=function(){return b.async=c,a};var d=function(a,b){if(a.forEach)return a.forEach(b);for(var c=0;cd?1:0};d(null,e(b.sort(c),function(a){return a.value}))})},a.auto=function(a,b){b=b||function(){};var c=g(a);if(!c.length)return b(null);var e={},h=[],i=function(a){h.unshift(a)},j=function(a){for(var b=0;b 2 | 3 | Async.js Test Suite 4 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 |

Async.js Test Suite

20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/.lock-wscript: -------------------------------------------------------------------------------- 1 | argv = ['/usr/local/bin/node-waf', 'configure'] 2 | blddir = '/home/demon/workspace/schedule/node_modules/log4js/node_modules/compress-buffer/build' 3 | commands = {'dist': 0, 'configure': True, 'distcheck': 0, 'install': 0, 'build': 0, 'clean': 0, 'distclean': 0, 'check': 0, 'uninstall': 0} 4 | cwd = '/home/demon/workspace/schedule/node_modules/log4js/node_modules/compress-buffer' 5 | environ = {'npm_config_color': 'true', 'npm_config_searchopts': '', 'LC_CTYPE': 'en_US.UTF-8', 'npm_config_group': '1000', 'npm_package_homepage': 'http://egorfine.github.com/node-compress-buffer', 'npm_config_browser': 'google-chrome', 'npm_config_global': '', 'SHELL': '/bin/bash', 'XDG_DATA_DIRS': '/usr/share/ubuntu-2d:/usr/share/gnome:/usr/local/share/:/usr/share/', 'MANDATORY_PATH': '/usr/share/gconf/ubuntu-2d.mandatory.path', 'npm_config_pre': '', 'npm_config_cache': '/home/demon/.npm', 'MFLAGS': '', 'npm_config_logfd': '2', 'npm_config_tmp': '/tmp', 'npm_package_engines_node': '*', 'npm_config_argv': '{"remain":[],"cooked":["install","--loglevel","info"],"original":["install","-d"]}', 'npm_config_init_version': '0.0.0', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-icXQ0Zvkjv,guid=95aec43d1aac5fa1eda7833800000036', 'GNOME_KEYRING_PID': '1771', 'npm_lifecycle_event': 'install', 'DESKTOP_SESSION': 'ubuntu-2d', 'GTK_MODULES': 'canberra-gtk-module:canberra-gtk-module', 'npm_config_init_author_name': '', 'npm_config_yes': '', 'npm_config_usage': '', 'npm_package_description': 'Single-step Buffer compression library for Node.js', 'npm_config_shell': '/bin/bash', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:', 'npm_config_ignore': '', 'npm_config_ca': '"-----BEGIN CERTIFICATE-----\\nMIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC\\nVVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x\\nIjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w\\nbUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y\\nMTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV\\nBAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj\\nYXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA\\naXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE\\nOgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz\\nGn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl\\ny0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC\\nl7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv\\nyNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl\\nZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op\\n-----END CERTIFICATE-----"', 'npm_config_globalconfig': '/usr/local/etc/npmrc', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'npm_config_parseable': '', 'XDG_CURRENT_DESKTOP': 'Unity', 'npm_config_userignorefile': '/home/demon/.npmignore', 'USER': 'demon', 'npm_package_author_name': 'Egor Egorov', 'npm_config_versions': '', 'XAUTHORITY': '/home/demon/.Xauthority', 'LANGUAGE': 'en_US:en', 'SESSION_MANAGER': 'local/ubuntu:@/tmp/.ICE-unix/1781,unix/ubuntu:/tmp/.ICE-unix/1781', 'SHLVL': '1', 'npm_config_init_author_url': '', 'npm_config_cache_max': 'null', 'WINDOWID': '54525958', 'GPG_AGENT_INFO': '/tmp/keyring-IJNpfz/gpg:0:1', 'npm_config_proxy': '', 'npm_config_depth': 'null', 'npm_config_logprefix': 'true', 'npm_config_umask': '022', 'GDMSESSION': 'ubuntu-2d', 'npm_config_long': '', 'npm_config_editor': 'vi', 'XDG_SEAT_PATH': '/org/freedesktop/DisplayManager/Seat0', 'npm_config_prefix': '/usr/local', 'npm_package_repository_type': 'git', 'npm_config_npat': '', 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu-2d:/etc/xdg', 'UBUNTU_MENUPROXY': 'libappmenu.so', 'npm_config_json': '', 'npm_config_searchsort': 'name', 'npm_lifecycle_script': 'make build', 'COLORTERM': 'gnome-terminal', 'npm_config_git': 'git', 'npm_config_rollback': 'true', 'npm_package_repository_url': 'git://github.com/egorfine/node-compress-buffer.git', 'HOME': '/home/demon', 'DISPLAY': ':0.0', 'LANG': 'zh_CN.UTF-8', 'npm_config_save': '', 'npm_config_registry': 'http://192.168.130.107:5984/ntsregistry/_design/app/_rewrite/', 'npm_config_unicode': 'true', 'npm_config_production': '', 'npm_config_message': '%s', 'npm_config_always_auth': '', '_': '/usr/local/bin/npm', 'npm_package_devDependencies_nodeunit': '>=0.5.4', 'npm_config_searchexclude': '', 'npm_config_loglevel': 'info', 'USERNAME': 'demon', 'npm_config_strict_ssl': 'true', 'COMP_WORDBREAKS': ' \t\n"\'><;|&(:', 'npm_package_main': './index', 'npm_config_tag': 'latest', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'LC_MESSAGES': 'en_US.UTF-8', 'LC_COLLATE': 'en_US.UTF-8', 'npm_config_globalignorefile': '/usr/local/etc/npmignore', 'MAKELEVEL': '1', 'npm_config_npaturl': 'http://npat.npmjs.org/', 'npm_package_bugs_url': 'http://github.com/egorFiNE/node-compress-buffer/issues', 'npm_config_force': '', 'LOGNAME': 'demon', 'npm_config_user': '', 'npm_config_link': '', 'npm_package_name': 'compress-buffer', 'npm_config_userconfig': '/home/demon/.npmrc', 'npm_package_scripts_install': 'make build', 'npm_config_dev': '', 'npm_config_rebuild_bundle': 'true', 'npm_config_version': '', 'npm_config_username': '', 'GNOME_KEYRING_CONTROL': '/tmp/keyring-IJNpfz', 'PATH': '/usr/local/lib/node_modules/npm/bin/node-gyp-bin:/home/demon/workspace/schedule/node_modules/log4js/node_modules/compress-buffer/node_modules/.bin:/home/demon/workspace/schedule/node_modules/log4js/node_modules/.bin:/home/demon/workspace/schedule/node_modules/.bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games', 'npm_config_coverage': '', 'SSH_AGENT_PID': '1814', 'npm_config_proprietary_attribs': 'true', 'XDG_SESSION_PATH': '/org/freedesktop/DisplayManager/Session0', 'XDG_SESSION_COOKIE': 'c7c1bfc34a5f9063715d737300000007-1332814105.336553-2068594552', 'npm_config_onload_script': '', 'DEFAULTS_PATH': '/usr/share/gconf/ubuntu-2d.default.path', 'npm_config_description': 'true', 'npm_config_bindist': '0.6-ares1.7.5-DEV-evundefined-openssl1.0.0e-v83.6.6.24-linux-ia32-3.0.0-16-generic', 'MAKEFLAGS': '', 'npm_config_viewer': 'man', 'npm_config_showlevel': '1', 'npm_config_unsafe_perm': 'true', 'SSH_AUTH_SOCK': '/tmp/keyring-IJNpfz/ssh', 'TERM': 'xterm', 'npm_package_version': '0.5.1', 'npm_config_https_proxy': '', 'npm_package_engine_0': 'node >=0.4.0', 'npm_config_node_version': '0.6.14', 'npm_config_init_author_email': '', 'OLDPWD': '/home/demon/workspace/schedule/test', 'npm_config_outfd': '1', 'npm_config_bin_publish': '', 'PWD': '/home/demon/workspace/schedule/node_modules/log4js/node_modules/compress-buffer', 'npm_config_cache_min': ''} 6 | files = [] 7 | hash = 0 8 | options = {'compile_targets': None, 'force': False, 'verbose': 0, 'nocache': False, 'progress_bar': 0, 'check_cxx_compiler': 'g++ icpc sunc++', 'destdir': '', 'keep': False, 'zones': '', 'blddir': '', 'prefix': '/usr/local/', 'debug': False, 'srcdir': '', 'jobs': 2} 9 | srcdir = '/home/demon/workspace/schedule/node_modules/log4js/node_modules/compress-buffer' 10 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/.npmignore: -------------------------------------------------------------------------------- 1 | build/ 2 | lib/compress-buffer/compress-buffer-bindings.node 3 | .lock-wscript 4 | nbproject/ 5 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/CHANGELOG: -------------------------------------------------------------------------------- 1 | 0.5.1: November 7, 2011 2 | * uncompress memory management bug fixed 3 | 4 | 0.5.0: November 5, 2011 5 | * uncompress is now cyclic: allocs as much memory as needed, not just 1GB for all cases 6 | 7 | 0.4.2: October 31, 2011 8 | * remove include of node_events.h (depricated) 9 | 10 | 0.4.1: September 21, 2011 11 | * support for string compression was eliminated. It's just not right. Want it back? See the source code. 12 | 13 | 0.4.0: September 18, 2011 14 | * fixed major bug with the compression of extremely small buffers 15 | 16 | 0.3.2: September 17, 2011 17 | * build system fixed 18 | 19 | 0.3.1: September 14, 2011 20 | * node 0.5.x support 21 | 22 | 0.2.0: March 20, 2011 23 | * single initialization of strm (a few times faster for multiple compressions) 24 | * got rid of C++ object, make methods direct 25 | * got rid of JS Class layer, call C++ functions directly 26 | * move Strings/Buffers logic to C++ 27 | * thanks to Konstantin Käfer! 28 | 29 | 0.1.0: March 20, 2011 30 | * initial release 31 | 32 | 33 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/LICENSE: -------------------------------------------------------------------------------- 1 | node-compress-buffer (C) 2011 Egor Egorov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to 5 | deal in the Software without restriction, including without limitation the 6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | sell copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/Makefile: -------------------------------------------------------------------------------- 1 | TESTS = test/*.js 2 | 3 | all: test 4 | 5 | build: clean configure compile 6 | 7 | configure: 8 | node-waf configure 9 | 10 | compile: 11 | node-waf build 12 | 13 | test: build 14 | @./node_modules/nodeunit/bin/nodeunit $(TESTS) 15 | 16 | clean: 17 | rm -Rf build 18 | 19 | 20 | .PHONY: clean test build 21 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/README.md: -------------------------------------------------------------------------------- 1 | # node-compress-buffer 2 | 3 | A single-step Buffer compression library for Node.js. 4 | 5 | ## Synopsis 6 | 7 | ```javascript 8 | compress = require('compress-buffer').compress; 9 | uncompress = require('compress-buffer').uncompress; 10 | 11 | var rawData = fs.readFileSync("/etc/passwd"); 12 | 13 | var compressed = compress(rawData); 14 | var uncompressed = uncompress(compressed); 15 | 16 | uncompressed == rawData // true! 17 | ``` 18 | 19 | ## Why? 20 | 21 | For the sake of the KISS principle. Most of the time you don't need a streaming compression, you need to compress an existing and already complete data. 22 | 23 | ## Options 24 | 25 | compress() takes two arguments: the data (must be a Buffer()) and optional compression level which must be within 1..9. It returns compressed Buffer() or undefined on error. 26 | 27 | uncompress() takes a single argument: the data (must be a Buffer()) and returns uncompressed Buffer() or undefined on error. 28 | 29 | ## Installation 30 | 31 | npm install compress-buffer 32 | 33 | or 34 | 35 | npm install . 36 | 37 | ## Upgrade notice 38 | 39 | In version 0.4.1 I removed support for strings compression. It is not possible to correctly determine the encoding of an input string and different encoding yields different results. So for the sake of consistency and reliability this was removed. 40 | 41 | Use the following instead: 42 | 43 | ```javascript 44 | var compressedBuffer = compress(new Buffer("my string")); 45 | ``` 46 | 47 | ## License 48 | 49 | See LICENSE file. Basically, it's a kind of "do-whatever-you-want-for-free" license. 50 | 51 | 52 | ## Thanks to 53 | 54 | * A lot of thanks for important suggestions goes to Konstantin Käfer who implemented a nice similar module node-zlib (https://github.com/kkaefer/node-zlib) earlier than me. 55 | * Oleg Kertanov. 56 | 57 | 58 | ## Author 59 | 60 | Egor Egorov 61 | 62 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/build/.wafpickle-7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetEase/pomelo-scheduler/06e70d28faabed4dfd5fb2d4351b878c1642195e/node_modules/log4js/node_modules/compress-buffer/build/.wafpickle-7 -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/build/Release/compress-buffer-bindings.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetEase/pomelo-scheduler/06e70d28faabed4dfd5fb2d4351b878c1642195e/node_modules/log4js/node_modules/compress-buffer/build/Release/compress-buffer-bindings.node -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/build/Release/src/compress-buffer_1.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetEase/pomelo-scheduler/06e70d28faabed4dfd5fb2d4351b878c1642195e/node_modules/log4js/node_modules/compress-buffer/build/Release/src/compress-buffer_1.o -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/build/c4che/Release.cache.py: -------------------------------------------------------------------------------- 1 | AR = '/usr/bin/ar' 2 | ARFLAGS = 'rcs' 3 | CCFLAGS = ['-g'] 4 | CCFLAGS_MACBUNDLE = ['-fPIC'] 5 | CCFLAGS_NODE = ['-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64'] 6 | CC_VERSION = ('4', '6', '1') 7 | COMPILER_CXX = 'g++' 8 | CPP = '/usr/bin/cpp' 9 | CPPFLAGS_NODE = ['-D_GNU_SOURCE'] 10 | CPPPATH_NODE = '/usr/local/include/node' 11 | CPPPATH_ST = '-I%s' 12 | CXX = ['/usr/bin/g++'] 13 | CXXDEFINES_ST = '-D%s' 14 | CXXFLAGS = ['-O3'] 15 | CXXFLAGS_DEBUG = ['-g'] 16 | CXXFLAGS_NODE = ['-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64'] 17 | CXXFLAGS_RELEASE = ['-O2'] 18 | CXXLNK_SRC_F = '' 19 | CXXLNK_TGT_F = ['-o', ''] 20 | CXX_NAME = 'gcc' 21 | CXX_SRC_F = '' 22 | CXX_TGT_F = ['-c', '-o', ''] 23 | DEFINES = [] 24 | DEST_BINFMT = 'elf' 25 | DEST_CPU = 'x86' 26 | DEST_OS = 'linux' 27 | FULLSTATIC_MARKER = '-static' 28 | LIBDIR = '/home/demon/.node_libraries' 29 | LIBPATH_NODE = '/usr/local/lib' 30 | LIBPATH_ST = '-L%s' 31 | LIB_ST = '-l%s' 32 | LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup'] 33 | LINK_CXX = ['/usr/bin/g++'] 34 | NODE_PATH = '/home/demon/.node_libraries' 35 | PREFIX = '/usr/local' 36 | PREFIX_NODE = '/usr/local' 37 | RANLIB = '/usr/bin/ranlib' 38 | RPATH_ST = '-Wl,-rpath,%s' 39 | SHLIB_MARKER = '-Wl,-Bdynamic' 40 | SONAME_ST = '-Wl,-h,%s' 41 | STATICLIBPATH_ST = '-L%s' 42 | STATICLIB_MARKER = '-Wl,-Bstatic' 43 | STATICLIB_ST = '-l%s' 44 | USELIB = [] 45 | macbundle_PATTERN = '%s.bundle' 46 | program_PATTERN = '%s' 47 | shlib_CXXFLAGS = ['-fPIC', '-DPIC'] 48 | shlib_LINKFLAGS = ['-shared'] 49 | shlib_PATTERN = 'lib%s.so' 50 | staticlib_LINKFLAGS = ['-Wl,-Bstatic'] 51 | staticlib_PATTERN = 'lib%s.a' 52 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/build/c4che/build.config.py: -------------------------------------------------------------------------------- 1 | version = 0x105016 2 | tools = [{'tool': 'ar', 'tooldir': None, 'funs': None}, {'tool': 'cxx', 'tooldir': None, 'funs': None}, {'tool': 'gxx', 'tooldir': None, 'funs': None}, {'tool': 'compiler_cxx', 'tooldir': None, 'funs': None}, {'tool': 'node_addon', 'tooldir': None, 'funs': None}] 3 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/build/config.log: -------------------------------------------------------------------------------- 1 | # project noname (0.4.1) configured on Tue Mar 27 15:33:04 2012 by 2 | # waf 1.5.16 (abi 7, python 20702f0 on linux2) 3 | # using /usr/local/bin/node-waf configure 4 | # 5 | 6 | ---------------------------------------- 7 | Checking for program g++ or c++ 8 | find program=['g++', 'c++'] paths=[] var='CXX' 9 | -> '/usr/bin/g++' 10 | 11 | ---------------------------------------- 12 | Checking for program cpp 13 | find program=['cpp'] paths=[] var='CPP' 14 | -> '/usr/bin/cpp' 15 | 16 | ---------------------------------------- 17 | Checking for program ar 18 | find program=['ar'] paths=[] var='AR' 19 | -> '/usr/bin/ar' 20 | 21 | ---------------------------------------- 22 | Checking for program ranlib 23 | find program=['ranlib'] paths=[] var='RANLIB' 24 | -> '/usr/bin/ranlib' 25 | 26 | ---------------------------------------- 27 | Checking for g++ 28 | ok 29 | 30 | ---------------------------------------- 31 | Checking for node path 32 | not found 33 | 34 | ---------------------------------------- 35 | Checking for node prefix 36 | ok /usr/local 37 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/index.js: -------------------------------------------------------------------------------- 1 | try { 2 | module.exports = require(__dirname+'/build/default/compress-buffer-bindings'); 3 | } catch(e) { 4 | module.exports = require(__dirname+'/build/Release/compress-buffer-bindings'); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compress-buffer", 3 | "description": "Single-step Buffer compression library for Node.js", 4 | "homepage": "http://egorfine.github.com/node-compress-buffer", 5 | "bugs": { 6 | "url": "http://github.com/egorFiNE/node-compress-buffer/issues" 7 | }, 8 | "version": "0.5.1", 9 | "author": { 10 | "name": "Egor Egorov" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/egorfine/node-compress-buffer.git" 15 | }, 16 | "engine": [ 17 | "node >=0.4.0" 18 | ], 19 | "main": "./index", 20 | "scripts": { 21 | "install": "make build" 22 | }, 23 | "devDependencies": { 24 | "nodeunit": ">=0.5.4" 25 | }, 26 | "_id": "compress-buffer@0.5.1", 27 | "dependencies": {}, 28 | "optionalDependencies": {}, 29 | "engines": { 30 | "node": "*" 31 | }, 32 | "_engineSupported": true, 33 | "_npmVersion": "1.1.12", 34 | "_nodeVersion": "v0.6.14", 35 | "_defaultsLoaded": true, 36 | "_from": "compress-buffer@>= 0.5.0" 37 | } 38 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/src/compress-buffer.cc: -------------------------------------------------------------------------------- 1 | /* node-compress-buffer (C) 2011 Egor Egorov */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #ifdef __APPLE__ 11 | #include 12 | #endif 13 | #include 14 | 15 | // zlib magic something 16 | #define WBITS 16+MAX_WBITS 17 | 18 | #define CHUNK 1024*100 19 | 20 | z_stream strmCompress; 21 | 22 | using namespace v8; 23 | using namespace node; 24 | 25 | Handle ThrowNodeError(const char* what = NULL) { 26 | return ThrowException(Exception::Error(String::New(what))); 27 | } 28 | 29 | Handle compress(const Arguments& args) { 30 | HandleScope scope; 31 | size_t bytesIn=0; 32 | size_t bytesCompressed=0; 33 | char *dataPointer=NULL; 34 | bool shouldFreeDataPointer=false; 35 | 36 | if (args.Length() < 1) { 37 | return Undefined(); 38 | } 39 | 40 | if (!Buffer::HasInstance(args[0])) { 41 | ThrowNodeError("First argument must be a Buffer"); 42 | return Undefined(); 43 | } 44 | 45 | Local bufferIn=args[0]->ToObject(); 46 | bytesIn=Buffer::Length(bufferIn); 47 | 48 | dataPointer=Buffer::Data(bufferIn); 49 | 50 | int compressionLevel = Z_DEFAULT_COMPRESSION; 51 | if (args.Length() > 1) { 52 | compressionLevel = args[1]->IntegerValue(); 53 | if (compressionLevel <= 0 || compressionLevel > 9) { 54 | compressionLevel = Z_DEFAULT_COMPRESSION; 55 | } 56 | } 57 | 58 | deflateParams(&strmCompress, compressionLevel, Z_DEFAULT_STRATEGY); 59 | 60 | bytesCompressed=compressBound(bytesIn); 61 | 62 | // compressBound mistakes when estimating extremely small data blocks (like few bytes), so 63 | // here is the stub. Otherwise smaller buffers (like 10 bytes) would not compress. 64 | if (bytesCompressed<1024) { 65 | bytesCompressed=1024; 66 | } 67 | 68 | char *bufferOut=(char*) malloc(bytesCompressed); 69 | 70 | strmCompress.next_in=(Bytef*) dataPointer; 71 | strmCompress.avail_in=bytesIn; 72 | strmCompress.next_out=(Bytef*) bufferOut; 73 | strmCompress.avail_out=bytesCompressed; 74 | 75 | if (deflate(&strmCompress, Z_FINISH) != Z_STREAM_END) { 76 | deflateReset(&strmCompress); 77 | if (shouldFreeDataPointer) { 78 | free(dataPointer); 79 | dataPointer = NULL; 80 | } 81 | return Undefined(); 82 | } 83 | 84 | bytesCompressed=strmCompress.total_out; 85 | deflateReset(&strmCompress); 86 | 87 | Buffer *BufferOut=Buffer::New(bufferOut, bytesCompressed); 88 | free(bufferOut); 89 | 90 | if (shouldFreeDataPointer) { 91 | free(dataPointer); 92 | dataPointer = NULL; 93 | } 94 | 95 | return scope.Close(BufferOut->handle_); 96 | } 97 | 98 | 99 | Handle uncompress(const Arguments &args) { 100 | if (args.Length() < 1) { 101 | return Undefined(); 102 | } 103 | 104 | if (!Buffer::HasInstance(args[0])) { 105 | ThrowNodeError("First argument must be a Buffer"); 106 | return Undefined(); 107 | } 108 | 109 | z_stream strmUncompress; 110 | 111 | strmUncompress.zalloc=Z_NULL; 112 | strmUncompress.zfree=Z_NULL; 113 | strmUncompress.opaque=Z_NULL; 114 | strmUncompress.avail_in = 0; 115 | strmUncompress.next_in = Z_NULL; 116 | 117 | int rci = inflateInit2(&strmUncompress, WBITS); 118 | 119 | if (rci != Z_OK) { 120 | ThrowNodeError("zlib initialization error."); 121 | return Undefined(); 122 | } 123 | 124 | Local bufferIn=args[0]->ToObject(); 125 | 126 | strmUncompress.next_in = (Bytef*) Buffer::Data(bufferIn); 127 | strmUncompress.avail_in = Buffer::Length(bufferIn); 128 | 129 | Bytef *bufferOut = NULL; 130 | uint32_t malloc_size=0; 131 | uint32_t currentPosition=0; 132 | 133 | int ret; 134 | 135 | do { 136 | Bytef *tmp = (Bytef*)malloc(CHUNK); 137 | strmUncompress.avail_out = CHUNK; 138 | strmUncompress.next_out = tmp; 139 | 140 | ret = inflate(&strmUncompress, Z_NO_FLUSH); 141 | assert(ret != Z_STREAM_ERROR); 142 | switch (ret) { 143 | case Z_NEED_DICT: 144 | ret = Z_DATA_ERROR; /* and fall through */ 145 | case Z_DATA_ERROR: 146 | case Z_MEM_ERROR: 147 | (void)inflateEnd(&strmUncompress); 148 | if (bufferOut!=NULL) { 149 | free(bufferOut); 150 | } 151 | if (tmp!=NULL) { 152 | free(tmp); 153 | } 154 | ThrowNodeError("zlib error"); 155 | return Undefined(); 156 | } 157 | 158 | uint32_t have = CHUNK - strmUncompress.avail_out; 159 | if (have>0) { 160 | bufferOut = (Bytef *) realloc(bufferOut, malloc_size+have); 161 | malloc_size=malloc_size+have; 162 | } 163 | 164 | memcpy(bufferOut+currentPosition, tmp, have); 165 | currentPosition+=have; 166 | free(tmp); 167 | } while (strmUncompress.avail_out == 0 && ret != Z_STREAM_END); 168 | 169 | inflateEnd(&strmUncompress); 170 | 171 | if (ret != Z_STREAM_END) { 172 | if (bufferOut!=NULL) { 173 | free(bufferOut); 174 | } 175 | return Undefined(); 176 | } 177 | 178 | Buffer *BufferOut=Buffer::New((char *)bufferOut, malloc_size); 179 | free(bufferOut); 180 | 181 | HandleScope scope; 182 | return scope.Close(BufferOut->handle_); 183 | } 184 | 185 | extern "C" void 186 | init (Handle target) { 187 | strmCompress.zalloc=Z_NULL; 188 | strmCompress.zfree=Z_NULL; 189 | strmCompress.opaque=Z_NULL; 190 | 191 | int rcd = deflateInit2(&strmCompress, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 192 | WBITS, 8L, Z_DEFAULT_STRATEGY); 193 | 194 | if (rcd != Z_OK) { 195 | ThrowNodeError("zlib initialization error."); 196 | return; 197 | } 198 | 199 | NODE_SET_METHOD(target, "compress", compress); 200 | NODE_SET_METHOD(target, "uncompress", uncompress); 201 | } 202 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/src/compress-buffer.cc-: -------------------------------------------------------------------------------- 1 | /* node-compress-buffer (C) 2011 Egor Egorov */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #ifdef __APPLE__ 13 | #include 14 | #endif 15 | #include 16 | 17 | // zlib magic something 18 | #define WBITS 16+MAX_WBITS 19 | 20 | #define CHUNK 1024*100 21 | 22 | z_stream strmCompress; 23 | 24 | using namespace v8; 25 | using namespace node; 26 | 27 | Handle ThrowNodeError(const char* what = NULL) { 28 | return ThrowException(Exception::Error(String::New(what))); 29 | } 30 | 31 | Handle compress(const Arguments& args) { 32 | HandleScope scope; 33 | size_t bytesIn=0; 34 | size_t bytesCompressed=0; 35 | char *dataPointer=NULL; 36 | bool shouldFreeDataPointer=false; 37 | 38 | if (args.Length() < 1) { 39 | return Undefined(); 40 | } 41 | 42 | if (!Buffer::HasInstance(args[0])) { 43 | ThrowNodeError("First argument must be a Buffer"); 44 | return Undefined(); 45 | } 46 | 47 | Local bufferIn=args[0]->ToObject(); 48 | bytesIn=Buffer::Length(bufferIn); 49 | 50 | dataPointer=Buffer::Data(bufferIn); 51 | 52 | int compressionLevel = Z_DEFAULT_COMPRESSION; 53 | if (args.Length() > 1) { 54 | compressionLevel = args[1]->IntegerValue(); 55 | if (compressionLevel <= 0 || compressionLevel > 9) { 56 | compressionLevel = Z_DEFAULT_COMPRESSION; 57 | } 58 | } 59 | 60 | deflateParams(&strmCompress, compressionLevel, Z_DEFAULT_STRATEGY); 61 | 62 | bytesCompressed=compressBound(bytesIn); 63 | 64 | // compressBound mistakes when estimating extremely small data blocks (like few bytes), so 65 | // here is the stub. Otherwise smaller buffers (like 10 bytes) would not compress. 66 | if (bytesCompressed<1024) { 67 | bytesCompressed=1024; 68 | } 69 | 70 | char *bufferOut=(char*) malloc(bytesCompressed); 71 | 72 | strmCompress.next_in=(Bytef*) dataPointer; 73 | strmCompress.avail_in=bytesIn; 74 | strmCompress.next_out=(Bytef*) bufferOut; 75 | strmCompress.avail_out=bytesCompressed; 76 | 77 | if (deflate(&strmCompress, Z_FINISH) != Z_STREAM_END) { 78 | deflateReset(&strmCompress); 79 | if (shouldFreeDataPointer) { 80 | free(dataPointer); 81 | dataPointer = NULL; 82 | } 83 | return Undefined(); 84 | } 85 | 86 | bytesCompressed=strmCompress.total_out; 87 | deflateReset(&strmCompress); 88 | 89 | Buffer *BufferOut=Buffer::New(bufferOut, bytesCompressed); 90 | free(bufferOut); 91 | 92 | if (shouldFreeDataPointer) { 93 | free(dataPointer); 94 | dataPointer = NULL; 95 | } 96 | 97 | return scope.Close(BufferOut->handle_); 98 | } 99 | 100 | 101 | Handle uncompress(const Arguments &args) { 102 | if (args.Length() < 1) { 103 | return Undefined(); 104 | } 105 | 106 | if (!Buffer::HasInstance(args[0])) { 107 | ThrowNodeError("First argument must be a Buffer"); 108 | return Undefined(); 109 | } 110 | 111 | z_stream strmUncompress; 112 | 113 | strmUncompress.zalloc=Z_NULL; 114 | strmUncompress.zfree=Z_NULL; 115 | strmUncompress.opaque=Z_NULL; 116 | strmUncompress.avail_in = 0; 117 | strmUncompress.next_in = Z_NULL; 118 | 119 | int rci = inflateInit2(&strmUncompress, WBITS); 120 | 121 | if (rci != Z_OK) { 122 | ThrowNodeError("zlib initialization error."); 123 | return Undefined(); 124 | } 125 | 126 | Local bufferIn=args[0]->ToObject(); 127 | 128 | strmUncompress.next_in = (Bytef*) Buffer::Data(bufferIn); 129 | strmUncompress.avail_in = Buffer::Length(bufferIn); 130 | 131 | size_t malloc_size=CHUNK*2; 132 | Bytef *bufferOut = (Bytef *) malloc(malloc_size); 133 | if (bufferOut==NULL) { 134 | return Undefined(); // FIXME throw 135 | } 136 | size_t current_size=0; 137 | uint32_t currentPosition=0; 138 | 139 | int ret; 140 | 141 | do { 142 | Bytef *tmp = (Bytef *)malloc(CHUNK); 143 | if (tmp==NULL) { 144 | return Undefined(); // FIXME throw 145 | } 146 | strmUncompress.avail_out = CHUNK; 147 | strmUncompress.next_out = tmp; 148 | 149 | ret = inflate(&strmUncompress, Z_NO_FLUSH); 150 | assert(ret != Z_STREAM_ERROR); 151 | switch (ret) { 152 | case Z_NEED_DICT: 153 | ret = Z_DATA_ERROR; /* and fall through */ 154 | case Z_DATA_ERROR: 155 | case Z_MEM_ERROR: 156 | (void)inflateEnd(&strmUncompress); 157 | if (tmp!=NULL) { 158 | free(tmp); 159 | } 160 | if (bufferOut!=NULL) { 161 | free(bufferOut); 162 | } 163 | return Undefined(); // FIXME THROW 164 | } 165 | 166 | uint32_t have = CHUNK - strmUncompress.avail_out; 167 | 168 | if (current_size+have>malloc_size) { 169 | size_t new_size = current_size+CHUNK*2; 170 | bufferOut = (Bytef *) realloc(bufferOut, new_size); 171 | if (bufferOut==NULL) { 172 | // FIXME throw 173 | return Undefined(); 174 | } 175 | malloc_size=new_size; 176 | } 177 | 178 | memcpy(bufferOut+currentPosition, tmp, have); 179 | currentPosition+=have; 180 | current_size+=have; 181 | free(tmp); 182 | 183 | } while (strmUncompress.avail_out == 0 && ret != Z_STREAM_END); 184 | 185 | inflateEnd(&strmUncompress); 186 | 187 | if (ret != Z_STREAM_END) { 188 | return Undefined(); 189 | } 190 | 191 | Buffer *BufferOut=Buffer::New((char*)bufferOut, current_size); 192 | free(bufferOut); 193 | 194 | HandleScope scope; 195 | return scope.Close(BufferOut->handle_); 196 | } 197 | 198 | extern "C" void 199 | init (Handle target) { 200 | strmCompress.zalloc=Z_NULL; 201 | strmCompress.zfree=Z_NULL; 202 | strmCompress.opaque=Z_NULL; 203 | 204 | int rcd = deflateInit2(&strmCompress, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 205 | WBITS, 8L, Z_DEFAULT_STRATEGY); 206 | 207 | if (rcd != Z_OK) { 208 | ThrowNodeError("zlib initialization error."); 209 | return; 210 | } 211 | 212 | NODE_SET_METHOD(target, "compress", compress); 213 | NODE_SET_METHOD(target, "uncompress", uncompress); 214 | } 215 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/t: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetEase/pomelo-scheduler/06e70d28faabed4dfd5fb2d4351b878c1642195e/node_modules/log4js/node_modules/compress-buffer/t -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/t.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define WBITS 16+MAX_WBITS 9 | 10 | #define CHUNK 4000 11 | 12 | int main() { 13 | z_stream strmUncompress; 14 | 15 | strmUncompress.zalloc=Z_NULL; 16 | strmUncompress.zfree=Z_NULL; 17 | strmUncompress.opaque=Z_NULL; 18 | strmUncompress.avail_in = 0; 19 | strmUncompress.next_in = Z_NULL; 20 | 21 | int rci = inflateInit2(&strmUncompress, WBITS); 22 | 23 | if (rci != Z_OK) { 24 | printf("zlib initialization error.\n"); 25 | exit(1); 26 | } 27 | 28 | FILE *fin = fopen("./test.gz", "r"); 29 | char *in = malloc(20000); 30 | size_t readBytes = fread(in, 1, 20000, fin); 31 | printf("Read %d bytes\n", readBytes); 32 | 33 | strmUncompress.avail_in = readBytes; 34 | strmUncompress.next_in = in; 35 | 36 | int ret; 37 | int totalHave=0; 38 | 39 | char *out = NULL; 40 | uint32_t malloc_size=0; 41 | uint32_t currentPosition=0; 42 | 43 | do { 44 | unsigned char tmp[CHUNK]; 45 | 46 | strmUncompress.avail_out = CHUNK; 47 | strmUncompress.next_out = tmp; 48 | 49 | ret = inflate(&strmUncompress, Z_NO_FLUSH); 50 | assert(ret != Z_STREAM_ERROR); 51 | switch (ret) { 52 | case Z_NEED_DICT: 53 | ret = Z_DATA_ERROR; /* and fall through */ 54 | case Z_DATA_ERROR: 55 | case Z_MEM_ERROR: 56 | (void)inflateEnd(&strmUncompress); 57 | return 1; 58 | } 59 | 60 | uint32_t have = CHUNK - strmUncompress.avail_out; 61 | totalHave+=have; 62 | 63 | if (totalHave > malloc_size) { 64 | out = realloc(out, totalHave); 65 | malloc_size=totalHave; 66 | } 67 | 68 | // printf("Have = %d, total=%d\n", have, totalHave); 69 | 70 | memcpy(out+currentPosition, tmp, have); 71 | currentPosition+=have; 72 | } while (strmUncompress.avail_out == 0 && ret != Z_STREAM_END); 73 | 74 | (void)inflateEnd(&strmUncompress); 75 | 76 | if (ret == Z_STREAM_END) { 77 | printf("ok\n"); 78 | } 79 | 80 | FILE *fout = fopen("./test.csv", "w"); 81 | fwrite(out, 1, totalHave, fout); 82 | fclose(fout); 83 | } 84 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/t.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | t.c 8 | 9 | diagnostics 10 | 11 | 12 | path 13 | 14 | 15 | kindevent 16 | location 17 | 18 | line53 19 | col5 20 | file0 21 | 22 | ranges 23 | 24 | 25 | 26 | line53 27 | col11 28 | file0 29 | 30 | 31 | line53 32 | col22 33 | file0 34 | 35 | 36 | 37 | extended_message 38 | Value stored to 'ret' is never read 39 | message 40 | Value stored to 'ret' is never read 41 | 42 | 43 | descriptionValue stored to 'ret' is never read 44 | categoryDead store 45 | typeDead assignment 46 | location 47 | 48 | line53 49 | col5 50 | file0 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/test.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetEase/pomelo-scheduler/06e70d28faabed4dfd5fb2d4351b878c1642195e/node_modules/log4js/node_modules/compress-buffer/test.gz -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/test/node-compress-buffer-test.js: -------------------------------------------------------------------------------- 1 | /* node-compress-buffer (C) 2011 Egor Egorov */ 2 | 3 | util = require('util'); 4 | fs = require('fs'); 5 | crypto=require('crypto'); 6 | compress = require('../index').compress; 7 | uncompress = require('../index').uncompress; 8 | 9 | function md5(data) { 10 | var md5=crypto.createHash('md5'); 11 | md5.update(data); 12 | return md5.digest('hex'); 13 | } 14 | 15 | var loremIpsum="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; 16 | 17 | exports['basic compress']= function(test) { 18 | test.expect(2); 19 | var uncompressed = new Buffer(loremIpsum); 20 | var compressed = compress(uncompressed); 21 | test.equal(compressed.length,282); 22 | test.equal(md5(compressed), "6e31946d851b7cab51e058653a16b666"); 23 | test.done(); 24 | } 25 | 26 | exports['basic uncompress']= function(test) { 27 | test.expect(2); 28 | var uncompressed = new Buffer(loremIpsum); 29 | var compressed = compress(uncompressed); 30 | uncompressed = uncompress(compressed); 31 | test.equal(uncompressed.length,loremIpsum.length); 32 | test.equal(md5(uncompressed), "fa5c89f3c88b81bfd5e821b0316569af"); 33 | test.done(); 34 | } 35 | 36 | exports['compress with compression levels']= function(test) { 37 | test.expect(1); 38 | var uncompressedBuffer = fs.readFileSync(__dirname+"/node-compress-buffer-test.js"); 39 | 40 | var compressed1 = compress(uncompressedBuffer, 1); 41 | var compressed9 = compress(uncompressedBuffer, 9); 42 | test.ok(compressed1.length>compressed9.length); 43 | 44 | test.done(); 45 | } 46 | 47 | exports['string exceptions']= function(test) { 48 | test.expect(2); 49 | 50 | test.throws(function() { 51 | compress(loremIpsum); 52 | }); 53 | 54 | test.throws(function() { 55 | uncompress(loremIpsum); 56 | }); 57 | 58 | test.done(); 59 | } 60 | 61 | exports['compress short']= function(test) { 62 | test.expect(2); 63 | var buffer, compressed; 64 | 65 | buffer = new Buffer("too short"); 66 | compressed = compress(buffer); 67 | test.notEqual(compressed,buffer); 68 | test.notEqual(compressed.length,buffer.length); 69 | 70 | test.done(); 71 | } 72 | 73 | exports['errors']= function(test) { 74 | test.expect(2); 75 | var compressed = compress(new Buffer("")); 76 | test.ok(compressed.length>=0); 77 | 78 | var uncompressed = uncompress(new Buffer(" sfsdcfgdfgsdgfdsgdgdsgdfgsdfgsdfgdfgfsfd ")); 79 | test.ok(!uncompressed); 80 | 81 | test.done(); 82 | } 83 | -------------------------------------------------------------------------------- /node_modules/log4js/node_modules/compress-buffer/wscript: -------------------------------------------------------------------------------- 1 | import Options 2 | from os import unlink, symlink, popen 3 | from os.path import exists 4 | 5 | srcdir = "." 6 | blddir = "build" 7 | VERSION = "0.4.1" 8 | 9 | def set_options(opt): 10 | opt.tool_options("compiler_cxx") 11 | 12 | opt.add_option('--debug', dest='debug', action='store_true', default=False) 13 | 14 | def configure(conf): 15 | conf.check_tool("compiler_cxx") 16 | conf.check_tool("node_addon") 17 | 18 | conf.env.DEFINES = [] 19 | conf.env.USELIB = [] 20 | conf.env.CXXFLAGS = [ '-O3' ] 21 | 22 | 23 | def build(bld): 24 | obj = bld.new_task_gen("cxx", "shlib", "node_addon") 25 | obj.cxxflags = ["-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall"] 26 | obj.target = "compress-buffer-bindings" 27 | obj.source = "src/compress-buffer.cc" 28 | obj.defines = bld.env.DEFINES 29 | obj.uselib = bld.env.USELIB 30 | 31 | -------------------------------------------------------------------------------- /node_modules/log4js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "log4js", 3 | "version": "0.4.2", 4 | "description": "Port of Log4js to work with node.", 5 | "keywords": [ 6 | "logging", 7 | "log", 8 | "log4j", 9 | "node" 10 | ], 11 | "main": "./lib/log4js", 12 | "author": { 13 | "name": "Gareth Jones", 14 | "email": "gareth.jones@sensis.com.au" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git://github.com/nomiddlename/log4js-node.git" 19 | }, 20 | "bugs": { 21 | "url": "http://github.com/nomiddlename/log4js-node/issues" 22 | }, 23 | "engines": [ 24 | "node >=0.4" 25 | ], 26 | "scripts": { 27 | "test": "vows test/*.js" 28 | }, 29 | "directories": { 30 | "test": "test", 31 | "lib": "lib" 32 | }, 33 | "dependencies": { 34 | "async": "0.1.15", 35 | "compress-buffer": ">= 0.5.0" 36 | }, 37 | "devDependencies": { 38 | "vows": ">=0.5.2", 39 | "sandboxed-module": ">= 0.1.1", 40 | "hook.io": "0.7.7", 41 | "underscore": "1.2.1" 42 | }, 43 | "_id": "log4js@0.4.2", 44 | "optionalDependencies": {}, 45 | "_engineSupported": true, 46 | "_npmVersion": "1.1.12", 47 | "_nodeVersion": "v0.6.14", 48 | "_defaultsLoaded": true, 49 | "_from": "log4js@>=0.4.1" 50 | } 51 | -------------------------------------------------------------------------------- /node_modules/log4js/test/bufferedStream.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , assert = require('assert') 3 | , events = require('events') 4 | , BufferedWriteStream = require('../lib/streams').BufferedWriteStream; 5 | 6 | function FakeStream() { 7 | this.writes = []; 8 | this.canWrite = false; 9 | this.callbacks = {}; 10 | } 11 | 12 | FakeStream.prototype.on = function(event, callback) { 13 | this.callbacks[event] = callback; 14 | } 15 | 16 | FakeStream.prototype.write = function(data, encoding) { 17 | assert.equal("utf8", encoding); 18 | this.writes.push(data); 19 | return this.canWrite; 20 | } 21 | 22 | FakeStream.prototype.emit = function(event, payload) { 23 | this.callbacks[event](payload); 24 | } 25 | 26 | FakeStream.prototype.block = function() { 27 | this.canWrite = false; 28 | } 29 | 30 | FakeStream.prototype.unblock = function() { 31 | this.canWrite = true; 32 | this.emit("drain"); 33 | } 34 | 35 | vows.describe('BufferedWriteStream').addBatch({ 36 | 'stream': { 37 | topic: new BufferedWriteStream(new FakeStream()), 38 | 'should take a stream as an argument and return a stream': function(stream) { 39 | assert.instanceOf(stream, events.EventEmitter); 40 | } 41 | }, 42 | 'before stream is open': { 43 | topic: function() { 44 | var fakeStream = new FakeStream(), 45 | stream = new BufferedWriteStream(fakeStream); 46 | stream.write("Some data", "utf8"); 47 | stream.write("Some more data", "utf8"); 48 | return fakeStream.writes; 49 | }, 50 | 'should buffer writes': function(writes) { 51 | assert.equal(writes.length, 0); 52 | } 53 | }, 54 | 'when stream is open': { 55 | topic: function() { 56 | var fakeStream = new FakeStream(), 57 | stream = new BufferedWriteStream(fakeStream); 58 | stream.write("Some data", "utf8"); 59 | fakeStream.canWrite = true; 60 | fakeStream.emit("open"); 61 | stream.write("Some more data", "utf8"); 62 | return fakeStream.writes; 63 | }, 64 | 'should write data to stream from before stream was open': function (writes) { 65 | assert.equal(writes[0], "Some data"); 66 | }, 67 | 'should write data to stream from after stream was open': function (writes) { 68 | assert.equal(writes[1], "Some more data"); 69 | } 70 | }, 71 | 'when stream is blocked': { 72 | topic: function() { 73 | var fakeStream = new FakeStream(), 74 | stream = new BufferedWriteStream(fakeStream); 75 | fakeStream.emit("open"); 76 | fakeStream.block(); 77 | stream.write("will not know it is blocked until first write", "utf8"); 78 | stream.write("so this one will be buffered, but not the previous one", "utf8"); 79 | return fakeStream.writes; 80 | }, 81 | 'should buffer writes': function (writes) { 82 | assert.equal(writes.length, 1); 83 | assert.equal(writes[0], "will not know it is blocked until first write"); 84 | } 85 | }, 86 | 'when stream is unblocked': { 87 | topic: function() { 88 | var fakeStream = new FakeStream(), 89 | stream = new BufferedWriteStream(fakeStream); 90 | fakeStream.emit("open"); 91 | fakeStream.block(); 92 | stream.write("will not know it is blocked until first write", "utf8"); 93 | stream.write("so this one will be buffered, but not the previous one", "utf8"); 94 | fakeStream.unblock(); 95 | return fakeStream.writes; 96 | }, 97 | 'should send buffered data': function (writes) { 98 | assert.equal(writes.length, 2); 99 | assert.equal(writes[1], "so this one will be buffered, but not the previous one"); 100 | } 101 | }, 102 | 'when stream is closed': { 103 | topic: function() { 104 | var fakeStream = new FakeStream(), 105 | stream = new BufferedWriteStream(fakeStream); 106 | fakeStream.emit("open"); 107 | fakeStream.block(); 108 | stream.write("first write to notice stream is blocked", "utf8"); 109 | stream.write("data while blocked", "utf8"); 110 | stream.end(); 111 | return fakeStream.writes; 112 | }, 113 | 'should send any buffered writes to the stream': function (writes) { 114 | assert.equal(writes.length, 2); 115 | assert.equal(writes[1], "data while blocked"); 116 | } 117 | }, 118 | 'when stream errors': { 119 | topic: function() { 120 | var fakeStream = new FakeStream(), 121 | stream = new BufferedWriteStream(fakeStream); 122 | stream.on("error", this.callback); 123 | fakeStream.emit("error", "oh noes!"); 124 | }, 125 | 'should emit error': function(err, value) { 126 | assert.equal(err, "oh noes!"); 127 | } 128 | } 129 | 130 | }).exportTo(module); -------------------------------------------------------------------------------- /node_modules/log4js/test/date_format.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , assert = require('assert') 3 | , dateFormat = require('../lib/date_format'); 4 | 5 | vows.describe('date_format').addBatch({ 6 | 'Date extensions': { 7 | topic: function() { 8 | return new Date(2010, 0, 11, 14, 31, 30, 5); 9 | }, 10 | 'should format a date as string using a pattern': function(date) { 11 | assert.equal( 12 | dateFormat.asString(dateFormat.DATETIME_FORMAT, date), 13 | "11 01 2010 14:31:30.005" 14 | ); 15 | }, 16 | 'should default to the ISO8601 format': function(date) { 17 | assert.equal( 18 | dateFormat.asString(date), 19 | '2010-01-11 14:31:30.005' 20 | ); 21 | } 22 | } 23 | }).export(module); 24 | -------------------------------------------------------------------------------- /node_modules/log4js/test/fileAppender.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , fs = require('fs') 3 | , log4js = require('../lib/log4js') 4 | , assert = require('assert'); 5 | 6 | log4js.clearAppenders(); 7 | 8 | function remove(filename) { 9 | try { 10 | fs.unlinkSync(filename); 11 | } catch (e) { 12 | //doesn't really matter if it failed 13 | } 14 | } 15 | 16 | vows.describe('log4js fileAppender').addBatch({ 17 | 18 | 'with default fileAppender settings': { 19 | topic: function() { 20 | var that = this, testFile = __dirname + '/fa-default-test.log' 21 | , logger = log4js.getLogger('default-settings'); 22 | remove(testFile); 23 | log4js.clearAppenders(); 24 | log4js.addAppender(log4js.fileAppender(testFile), 'default-settings'); 25 | 26 | logger.info("This should be in the file."); 27 | 28 | setTimeout(function() { 29 | fs.readFile(testFile, "utf8", that.callback); 30 | }, 100); 31 | }, 32 | 'should write log messages to the file': function(err, fileContents) { 33 | assert.include(fileContents, "This should be in the file.\n"); 34 | }, 35 | 'log messages should be in the basic layout format': function(err, fileContents) { 36 | assert.match(fileContents, /\[\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\.\d{3}\] \[INFO\] default-settings - /); 37 | } 38 | }, 39 | 'with a max file size and no backups': { 40 | topic: function() { 41 | var testFile = __dirname + '/fa-maxFileSize-test.log' 42 | , logger = log4js.getLogger('max-file-size') 43 | , that = this; 44 | remove(testFile); 45 | remove(testFile + '.1'); 46 | //log file of 100 bytes maximum, no backups 47 | log4js.clearAppenders(); 48 | log4js.addAppender(log4js.fileAppender(testFile, log4js.layouts.basicLayout, 100, 0), 'max-file-size'); 49 | logger.info("This is the first log message."); 50 | logger.info("This is an intermediate log message."); 51 | logger.info("This is the second log message."); 52 | //wait for the file system to catch up 53 | setTimeout(function() { 54 | fs.readFile(testFile, "utf8", that.callback); 55 | }, 100); 56 | }, 57 | 'log file should only contain the second message': function(err, fileContents) { 58 | assert.include(fileContents, "This is the second log message.\n"); 59 | assert.equal(fileContents.indexOf("This is the first log message."), -1); 60 | }, 61 | 'the number of files': { 62 | topic: function() { 63 | fs.readdir(__dirname, this.callback); 64 | }, 65 | 'starting with the test file name should be two': function(err, files) { 66 | //there will always be one backup if you've specified a max log size 67 | var logFiles = files.filter(function(file) { return file.indexOf('fa-maxFileSize-test.log') > -1; }); 68 | assert.equal(logFiles.length, 2); 69 | } 70 | } 71 | }, 72 | 'with a max file size and 2 backups': { 73 | topic: function() { 74 | var testFile = __dirname + '/fa-maxFileSize-with-backups-test.log' 75 | , logger = log4js.getLogger('max-file-size-backups'); 76 | remove(testFile); 77 | remove(testFile+'.1'); 78 | remove(testFile+'.2'); 79 | 80 | //log file of 50 bytes maximum, 2 backups 81 | log4js.clearAppenders(); 82 | log4js.addAppender(log4js.fileAppender(testFile, log4js.layouts.basicLayout, 50, 2), 'max-file-size-backups'); 83 | logger.info("This is the first log message."); 84 | logger.info("This is the second log message."); 85 | logger.info("This is the third log message."); 86 | logger.info("This is the fourth log message."); 87 | var that = this; 88 | //give the system a chance to open the stream 89 | setTimeout(function() { 90 | fs.readdir(__dirname, that.callback); 91 | }, 100); 92 | }, 93 | 'the log files': { 94 | topic: function(files) { 95 | var logFiles = files.filter(function(file) { return file.indexOf('fa-maxFileSize-with-backups-test.log') > -1; }); 96 | return logFiles; 97 | }, 98 | 'should be 3': function (files) { 99 | assert.equal(files.length, 3); 100 | }, 101 | 'should be named in sequence': function (files) { 102 | assert.deepEqual(files.sort(), ['fa-maxFileSize-with-backups-test.log', 'fa-maxFileSize-with-backups-test.log.1', 'fa-maxFileSize-with-backups-test.log.2']); 103 | }, 104 | 'and the contents of the first file': { 105 | topic: function(logFiles) { 106 | fs.readFile(logFiles[0], "utf8", this.callback); 107 | }, 108 | 'should be the last log message': function(err, contents) { 109 | assert.include(contents, 'This is the fourth log message.'); 110 | } 111 | }, 112 | 'and the contents of the second file': { 113 | topic: function(logFiles) { 114 | fs.readFile(logFiles[1], "utf8", this.callback); 115 | }, 116 | 'should be the third log message': function(err, contents) { 117 | assert.include(contents, 'This is the third log message.'); 118 | } 119 | }, 120 | 'and the contents of the third file': { 121 | topic: function(logFiles) { 122 | fs.readFile(logFiles[2], "utf8", this.callback); 123 | }, 124 | 'should be the second log message': function(err, contents) { 125 | assert.include(contents, 'This is the second log message.'); 126 | } 127 | } 128 | } 129 | } 130 | }).addBatch({ 131 | 'configure' : { 132 | 'with fileAppender': { 133 | topic: function() { 134 | var log4js = require('../lib/log4js') 135 | , logger; 136 | //this config file defines one file appender (to ./tmp-tests.log) 137 | //and sets the log level for "tests" to WARN 138 | log4js.configure('test/log4js.json'); 139 | logger = log4js.getLogger('tests'); 140 | logger.info('this should not be written to the file'); 141 | logger.warn('this should be written to the file'); 142 | 143 | fs.readFile('tmp-tests.log', 'utf8', this.callback); 144 | }, 145 | 'should load appender configuration from a json file': function(err, contents) { 146 | assert.include(contents, 'this should be written to the file\n'); 147 | assert.equal(contents.indexOf('this should not be written to the file'), -1); 148 | } 149 | } 150 | } 151 | 152 | }).export(module); 153 | -------------------------------------------------------------------------------- /node_modules/log4js/test/gelfAppender.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , assert = require('assert') 3 | , sandbox = require('sandboxed-module') 4 | , log4js = require('../lib/log4js') 5 | , setupLogging = function(options, category, compressedLength) { 6 | var fakeDgram = { 7 | sent: false, 8 | socket: { 9 | packetLength: 0, 10 | close: function() { 11 | }, 12 | send: function(pkt, offset, pktLength, port, host) { 13 | fakeDgram.sent = true; 14 | this.packet = pkt; 15 | this.offset = offset; 16 | this.packetLength = pktLength; 17 | this.port = port; 18 | this.host = host; 19 | } 20 | }, 21 | createSocket: function(type) { 22 | this.type = type; 23 | return this.socket; 24 | } 25 | } 26 | , fakeCompressBuffer = { 27 | compress: function(objectToCompress) { 28 | fakeCompressBuffer.uncompressed = objectToCompress; 29 | if (compressedLength) { 30 | return { length: compressedLength }; 31 | } else { 32 | return "I've been compressed"; 33 | } 34 | } 35 | } 36 | , appender = sandbox.require('../lib/appenders/gelf', { 37 | requires: { 38 | dgram: fakeDgram, 39 | "compress-buffer": fakeCompressBuffer 40 | } 41 | }); 42 | 43 | log4js.clearAppenders(); 44 | log4js.addAppender(appender.configure(options || {}), category || "gelf-test"); 45 | return { 46 | dgram: fakeDgram, 47 | compress: fakeCompressBuffer, 48 | logger: log4js.getLogger(category || "gelf-test") 49 | }; 50 | }; 51 | 52 | //log4js.configure({ doNotReplaceConsole: true }); 53 | 54 | vows.describe('log4js gelfAppender').addBatch({ 55 | 56 | 'with default gelfAppender settings': { 57 | topic: function() { 58 | var setup = setupLogging(); 59 | setup.logger.info("This is a test"); 60 | return setup; 61 | }, 62 | 'the dgram packet': { 63 | topic: function(setup) { 64 | return setup.dgram; 65 | }, 66 | 'should be sent via udp to the localhost gelf server': function(dgram) { 67 | assert.equal(dgram.type, "udp4"); 68 | assert.equal(dgram.socket.host, "localhost"); 69 | assert.equal(dgram.socket.port, 12201); 70 | assert.equal(dgram.socket.offset, 0); 71 | assert.ok(dgram.socket.packetLength > 0, "Received blank message"); 72 | }, 73 | 'should be compressed': function(dgram) { 74 | assert.equal(dgram.socket.packet, "I've been compressed"); 75 | } 76 | }, 77 | 'the uncompressed log message': { 78 | topic: function(setup) { 79 | var message = JSON.parse(setup.compress.uncompressed); 80 | return message; 81 | }, 82 | 'should be in the gelf format': function(message) { 83 | assert.equal(message.version, '1.0'); 84 | assert.equal(message.host, require('os').hostname()); 85 | assert.equal(message.level, 6); //INFO 86 | assert.equal(message.facility, 'nodejs-server'); 87 | assert.equal(message.full_message, message.short_message); 88 | assert.equal(message.full_message, 'This is a test'); 89 | } 90 | } 91 | }, 92 | 'with a message longer than 8k': { 93 | topic: function() { 94 | var setup = setupLogging(undefined, undefined, 10240); 95 | setup.logger.info("Blah."); 96 | return setup; 97 | }, 98 | 'the dgram packet': { 99 | topic: function(setup) { 100 | return setup.dgram; 101 | }, 102 | 'should not be sent': function(dgram) { 103 | assert.equal(dgram.sent, false); 104 | } 105 | } 106 | }, 107 | 'with non-default options': { 108 | topic: function() { 109 | var setup = setupLogging({ 110 | host: 'somewhere', 111 | port: 12345, 112 | hostname: 'cheese', 113 | facility: 'nonsense' 114 | }); 115 | setup.logger.debug("Just testing."); 116 | return setup; 117 | }, 118 | 'the dgram packet': { 119 | topic: function(setup) { 120 | return setup.dgram; 121 | }, 122 | 'should pick up the options': function(dgram) { 123 | assert.equal(dgram.socket.host, 'somewhere'); 124 | assert.equal(dgram.socket.port, 12345); 125 | } 126 | }, 127 | 'the uncompressed packet': { 128 | topic: function(setup) { 129 | var message = JSON.parse(setup.compress.uncompressed); 130 | return message; 131 | }, 132 | 'should pick up the options': function(message) { 133 | assert.equal(message.host, 'cheese'); 134 | assert.equal(message.facility, 'nonsense'); 135 | } 136 | } 137 | } 138 | }).export(module); -------------------------------------------------------------------------------- /node_modules/log4js/test/hookioAppender.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows'); 2 | var assert = require('assert'); 3 | var sandbox = require('sandboxed-module'); 4 | 5 | function fancyResultingHookioAppender(opts) { 6 | var result = { ons: {}, emissions: {}, logged: [], configs: [] }; 7 | 8 | var fakeLog4Js = { 9 | appenderMakers: {} 10 | }; 11 | fakeLog4Js.loadAppender = function (appender) { 12 | fakeLog4Js.appenderMakers[appender] = function (config) { 13 | result.actualLoggerConfig = config; 14 | return function log(logEvent) { 15 | result.logged.push(logEvent); 16 | } 17 | }; 18 | }; 19 | 20 | var fakeHookIo = { Hook: function(config) { result.configs.push(config); } }; 21 | fakeHookIo.Hook.prototype.start = function () { 22 | result.startCalled = true; 23 | }; 24 | fakeHookIo.Hook.prototype.on = function (eventName, functionToExec) { 25 | result.ons[eventName] = { functionToExec: functionToExec }; 26 | if (eventName === 'hook::ready') { 27 | functionToExec(); 28 | } 29 | }; 30 | fakeHookIo.Hook.prototype.emit = function (eventName, data) { 31 | result.emissions[eventName] = result.emissions[eventName] || []; 32 | result.emissions[eventName].push({data: data}); 33 | var on = '*::' + eventName; 34 | if (eventName !== 'hook::ready' && result.ons[on]) { 35 | result.ons[on].callingCount = result.ons[on].callingCount ? result.ons[on].callingCount += 1 : 1; 36 | result.ons[on].functionToExec(data); 37 | } 38 | }; 39 | 40 | return { theResult: result, 41 | theModule: sandbox.require('../lib/appenders/hookio', { 42 | requires: { 43 | '../log4js': fakeLog4Js, 44 | 'hook.io': fakeHookIo 45 | } 46 | }) 47 | }; 48 | } 49 | 50 | 51 | vows.describe('log4js hookioAppender').addBatch({ 52 | 'master': { 53 | topic: function() { 54 | var fancy = fancyResultingHookioAppender(); 55 | var logger = fancy.theModule.configure({ name: 'ohno', mode: 'master', 'hook-port': 5001, appender: { type: 'file' } }); 56 | logger({ level: { levelStr: 'INFO' }, data: "ALRIGHTY THEN", startTime: '2011-10-27T03:53:16.031Z' }); 57 | logger({ level: { levelStr: 'DEBUG' }, data: "OH WOW", startTime: '2011-10-27T04:53:16.031Z'}); 58 | return fancy.theResult; 59 | }, 60 | 61 | 'should write to the actual appender': function (result) { 62 | assert.isTrue(result.startCalled); 63 | assert.equal(result.configs.length, 1); 64 | assert.equal(result.configs[0]['hook-port'], 5001); 65 | assert.equal(result.logged.length, 2); 66 | assert.equal(result.emissions['ohno::log'].length, 2); 67 | assert.equal(result.ons['*::ohno::log'].callingCount, 2); 68 | }, 69 | 70 | 'data written should be formatted correctly': function (result) { 71 | assert.equal(result.logged[0].level.toString(), 'INFO'); 72 | assert.equal(result.logged[0].data, 'ALRIGHTY THEN'); 73 | assert.isTrue(typeof(result.logged[0].startTime) === 'object'); 74 | assert.equal(result.logged[1].level.toString(), 'DEBUG'); 75 | assert.equal(result.logged[1].data, 'OH WOW'); 76 | assert.isTrue(typeof(result.logged[1].startTime) === 'object'); 77 | }, 78 | 79 | 'the actual logger should get the right config': function (result) { 80 | assert.equal(result.actualLoggerConfig.type, 'file'); 81 | } 82 | }, 83 | 'worker': { 84 | 'should emit logging events to the master': { 85 | topic: function() { 86 | var fancy = fancyResultingHookioAppender(); 87 | var logger = fancy.theModule.configure({ name: 'ohno', mode: 'worker', appender: { type: 'file' } }); 88 | logger({ level: { levelStr: 'INFO' }, data: "ALRIGHTY THEN", startTime: '2011-10-27T03:53:16.031Z' }); 89 | logger({ level: { levelStr: 'DEBUG' }, data: "OH WOW", startTime: '2011-10-27T04:53:16.031Z'}); 90 | return fancy.theResult; 91 | }, 92 | 93 | 'should not write to the actual appender': function (result) { 94 | assert.isTrue(result.startCalled); 95 | assert.equal(result.logged.length, 0); 96 | assert.equal(result.emissions['ohno::log'].length, 2); 97 | assert.isUndefined(result.ons['*::ohno::log']); 98 | } 99 | } 100 | } 101 | }).exportTo(module); 102 | -------------------------------------------------------------------------------- /node_modules/log4js/test/layouts.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows'), 2 | assert = require('assert'); 3 | 4 | //used for patternLayout tests. 5 | function test(args, pattern, value) { 6 | var layout = args[0] 7 | , event = args[1]; 8 | 9 | assert.equal(layout(pattern)(event), value); 10 | } 11 | 12 | vows.describe('log4js layouts').addBatch({ 13 | 'colouredLayout': { 14 | topic: function() { 15 | return require('../lib/layouts').colouredLayout; 16 | }, 17 | 18 | 'should apply level colour codes to output': function(layout) { 19 | var output = layout({ 20 | data: ["nonsense"], 21 | startTime: new Date(2010, 11, 5, 14, 18, 30, 45), 22 | categoryName: "cheese", 23 | level: { 24 | toString: function() { return "ERROR"; } 25 | } 26 | }); 27 | assert.equal(output, '\033[31m[2010-12-05 14:18:30.045] [ERROR] cheese - \033[39mnonsense'); 28 | }, 29 | 30 | 'should support the console.log format for the message': function(layout) { 31 | var output = layout({ 32 | data: ["thing %d", 2], 33 | startTime: new Date(2010, 11, 5, 14, 18, 30, 45), 34 | categoryName: "cheese", 35 | level: { 36 | toString: function() { return "ERROR"; } 37 | } 38 | }); 39 | assert.equal(output, '\033[31m[2010-12-05 14:18:30.045] [ERROR] cheese - \033[39mthing 2'); 40 | } 41 | }, 42 | 43 | 'messagePassThroughLayout': { 44 | topic: function() { 45 | return require('../lib/layouts').messagePassThroughLayout; 46 | }, 47 | 'should take a logevent and output only the message' : function(layout) { 48 | assert.equal(layout({ 49 | data: ["nonsense"], 50 | startTime: new Date(2010, 11, 5, 14, 18, 30, 45), 51 | categoryName: "cheese", 52 | level: { 53 | colour: "green", 54 | toString: function() { return "ERROR"; } 55 | } 56 | }), "nonsense"); 57 | }, 58 | 'should support the console.log format for the message' : function(layout) { 59 | assert.equal(layout({ 60 | data: ["thing %d", 1, "cheese"] 61 | , startTime: new Date(2010, 11, 5, 14, 18, 30, 45) 62 | , categoryName: "cheese" 63 | , level : { 64 | colour: "green" 65 | , toString: function() { return "ERROR"; } 66 | } 67 | }), "thing 1 'cheese'"); 68 | }, 69 | 'should output the first item even if it is not a string': function(layout) { 70 | assert.equal(layout({ 71 | data: [ { thing: 1} ] 72 | , startTime: new Date(2010, 11, 5, 14, 18, 30, 45) 73 | , categoryName: "cheese" 74 | , level: { 75 | colour: "green" 76 | , toString: function() { return "ERROR"; } 77 | } 78 | }), "{ thing: 1 }"); 79 | } 80 | 81 | }, 82 | 83 | 'basicLayout': { 84 | topic: function() { 85 | var layout = require('../lib/layouts').basicLayout, 86 | event = { 87 | data: ['this is a test'], 88 | startTime: new Date(2010, 11, 5, 14, 18, 30, 45), 89 | categoryName: "tests", 90 | level: { 91 | toString: function() { return "DEBUG"; } 92 | } 93 | }; 94 | return [layout, event]; 95 | }, 96 | 'should take a logevent and output a formatted string': function(args) { 97 | var layout = args[0], event = args[1]; 98 | assert.equal(layout(event), "[2010-12-05 14:18:30.045] [DEBUG] tests - this is a test"); 99 | }, 100 | 'should output a stacktrace, message if the event has an error attached': function(args) { 101 | var layout = args[0], event = args[1], output, lines, 102 | error = new Error("Some made-up error"), 103 | stack = error.stack.split(/\n/); 104 | 105 | event.data = ['this is a test', error]; 106 | output = layout(event); 107 | lines = output.split(/\n/); 108 | 109 | assert.equal(lines.length, stack.length); 110 | assert.equal(lines[0], "[2010-12-05 14:18:30.045] [DEBUG] tests - this is a test Error: Some made-up error"); 111 | for (var i = 1; i < stack.length; i++) { 112 | assert.equal(lines[i+1], stack[i+1]); 113 | } 114 | }, 115 | 'should output any extra data in the log event as util.inspect strings': function(args) { 116 | var layout = args[0], event = args[1], output, lines; 117 | event.data = ['this is a test', { 118 | name: 'Cheese', 119 | message: 'Gorgonzola smells.' 120 | }]; 121 | output = layout(event); 122 | assert.equal(output, "[2010-12-05 14:18:30.045] [DEBUG] tests - this is a test { name: 'Cheese', message: 'Gorgonzola smells.' }"); 123 | } 124 | }, 125 | 126 | 'patternLayout': { 127 | topic: function() { 128 | var event = { 129 | data: ['this is a test'], 130 | startTime: new Date(2010, 11, 5, 14, 18, 30, 45), 131 | categoryName: "multiple.levels.of.tests", 132 | level: { 133 | toString: function() { return "DEBUG"; } 134 | } 135 | }, layout = require('../lib/layouts').patternLayout; 136 | return [layout, event]; 137 | }, 138 | 139 | 'should default to "time logLevel loggerName - message"': function(args) { 140 | test(args, null, "14:18:30 DEBUG multiple.levels.of.tests - this is a test\n"); 141 | }, 142 | '%r should output time only': function(args) { 143 | test(args, '%r', '14:18:30'); 144 | }, 145 | '%p should output the log level': function(args) { 146 | test(args, '%p', 'DEBUG'); 147 | }, 148 | '%c should output the log category': function(args) { 149 | test(args, '%c', 'multiple.levels.of.tests'); 150 | }, 151 | '%m should output the log data': function(args) { 152 | test(args, '%m', 'this is a test'); 153 | }, 154 | '%n should output a new line': function(args) { 155 | test(args, '%n', '\n'); 156 | }, 157 | '%c should handle category names like java-style package names': function(args) { 158 | test(args, '%c{1}', 'tests'); 159 | test(args, '%c{2}', 'of.tests'); 160 | test(args, '%c{3}', 'levels.of.tests'); 161 | test(args, '%c{4}', 'multiple.levels.of.tests'); 162 | test(args, '%c{5}', 'multiple.levels.of.tests'); 163 | test(args, '%c{99}', 'multiple.levels.of.tests'); 164 | }, 165 | '%d should output the date in ISO8601 format': function(args) { 166 | test(args, '%d', '2010-12-05 14:18:30.045'); 167 | }, 168 | '%d should allow for format specification': function(args) { 169 | test(args, '%d{ISO8601}', '2010-12-05 14:18:30.045'); 170 | test(args, '%d{ABSOLUTE}', '14:18:30.045'); 171 | test(args, '%d{DATE}', '05 12 2010 14:18:30.045'); 172 | test(args, '%d{yyyy MM dd}', '2010 12 05'); 173 | test(args, '%d{yyyy MM dd hh mm ss SSS}', '2010 12 05 14 18 30 045'); 174 | }, 175 | '%% should output %': function(args) { 176 | test(args, '%%', '%'); 177 | }, 178 | 'should output anything not preceded by % as literal': function(args) { 179 | test(args, 'blah blah blah', 'blah blah blah'); 180 | }, 181 | 'should handle complicated patterns': function(args) { 182 | test(args, 183 | '%m%n %c{2} at %d{ABSOLUTE} cheese %p%n', 184 | 'this is a test\n of.tests at 14:18:30.045 cheese DEBUG\n' 185 | ); 186 | }, 187 | 'should truncate fields if specified': function(args) { 188 | test(args, '%.4m', 'this'); 189 | test(args, '%.7m', 'this is'); 190 | test(args, '%.9m', 'this is a'); 191 | test(args, '%.14m', 'this is a test'); 192 | test(args, '%.2919102m', 'this is a test'); 193 | }, 194 | 'should pad fields if specified': function(args) { 195 | test(args, '%10p', ' DEBUG'); 196 | test(args, '%8p', ' DEBUG'); 197 | test(args, '%6p', ' DEBUG'); 198 | test(args, '%4p', 'DEBUG'); 199 | test(args, '%-4p', 'DEBUG'); 200 | test(args, '%-6p', 'DEBUG '); 201 | test(args, '%-8p', 'DEBUG '); 202 | test(args, '%-10p', 'DEBUG '); 203 | } 204 | 205 | } 206 | 207 | }).export(module); 208 | 209 | -------------------------------------------------------------------------------- /node_modules/log4js/test/levels.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , assert = require('assert') 3 | , levels = require('../lib/levels'); 4 | 5 | function assertThat(level) { 6 | function assertForEach(assertion, test, otherLevels) { 7 | otherLevels.forEach(function(other) { 8 | assertion.call(assert, test.call(level, other)); 9 | }); 10 | } 11 | 12 | return { 13 | isLessThanOrEqualTo: function(levels) { 14 | assertForEach(assert.isTrue, level.isLessThanOrEqualTo, levels); 15 | }, 16 | isNotLessThanOrEqualTo: function(levels) { 17 | assertForEach(assert.isFalse, level.isLessThanOrEqualTo, levels); 18 | }, 19 | isGreaterThanOrEqualTo: function(levels) { 20 | assertForEach(assert.isTrue, level.isGreaterThanOrEqualTo, levels); 21 | }, 22 | isNotGreaterThanOrEqualTo: function(levels) { 23 | assertForEach(assert.isFalse, level.isGreaterThanOrEqualTo, levels); 24 | } 25 | }; 26 | } 27 | 28 | vows.describe('levels').addBatch({ 29 | 'values': { 30 | topic: levels, 31 | 'should define some levels': function(levels) { 32 | assert.isNotNull(levels.ALL); 33 | assert.isNotNull(levels.TRACE); 34 | assert.isNotNull(levels.DEBUG); 35 | assert.isNotNull(levels.INFO); 36 | assert.isNotNull(levels.WARN); 37 | assert.isNotNull(levels.ERROR); 38 | assert.isNotNull(levels.FATAL); 39 | assert.isNotNull(levels.OFF); 40 | }, 41 | 'ALL': { 42 | topic: levels.ALL, 43 | 'should be less than the other levels': function(all) { 44 | assertThat(all).isLessThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO, levels.WARN, levels.ERROR, levels.FATAL, levels.OFF]); 45 | }, 46 | 'should be greater than no levels': function(all) { 47 | assertThat(all).isNotGreaterThanOrEqualTo([levels.TRACE, levels.DEBUG, levels.INFO, levels.WARN, levels.ERROR, levels.FATAL, levels.OFF]); 48 | } 49 | }, 50 | 'TRACE': { 51 | topic: levels.TRACE, 52 | 'should be less than DEBUG': function(trace) { 53 | assertThat(trace).isLessThanOrEqualTo([levels.DEBUG, levels.INFO, levels.WARN, levels.ERROR, levels.FATAL, levels.OFF]); 54 | assertThat(trace).isNotLessThanOrEqualTo([levels.ALL]); 55 | }, 56 | 'should be greater than ALL': function(trace) { 57 | assertThat(trace).isGreaterThanOrEqualTo([levels.ALL, levels.TRACE]); 58 | assertThat(trace).isNotGreaterThanOrEqualTo([levels.DEBUG, levels.INFO, levels.WARN, levels.ERROR, levels.FATAL, levels.OFF]); 59 | } 60 | }, 61 | 'DEBUG': { 62 | topic: levels.DEBUG, 63 | 'should be less than INFO': function(debug) { 64 | assertThat(debug).isLessThanOrEqualTo([levels.INFO, levels.WARN, levels.ERROR, levels.FATAL, levels.OFF]); 65 | assertThat(debug).isNotLessThanOrEqualTo([levels.ALL, levels.TRACE]); 66 | }, 67 | 'should be greater than TRACE': function(debug) { 68 | assertThat(debug).isGreaterThanOrEqualTo([levels.ALL, levels.TRACE]); 69 | assertThat(debug).isNotGreaterThanOrEqualTo([levels.INFO, levels.WARN, levels.ERROR, levels.FATAL, levels.OFF]); 70 | } 71 | }, 72 | 'INFO': { 73 | topic: levels.INFO, 74 | 'should be less than WARN': function(info) { 75 | assertThat(info).isLessThanOrEqualTo([levels.WARN, levels.ERROR, levels.FATAL, levels.OFF]); 76 | assertThat(info).isNotLessThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG]); 77 | }, 78 | 'should be greater than DEBUG': function(info) { 79 | assertThat(info).isGreaterThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG]); 80 | assertThat(info).isNotGreaterThanOrEqualTo([levels.WARN, levels.ERROR, levels.FATAL, levels.OFF]); 81 | } 82 | }, 83 | 'WARN': { 84 | topic: levels.WARN, 85 | 'should be less than ERROR': function(warn) { 86 | assertThat(warn).isLessThanOrEqualTo([levels.ERROR, levels.FATAL, levels.OFF]); 87 | assertThat(warn).isNotLessThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO]); 88 | }, 89 | 'should be greater than INFO': function(warn) { 90 | assertThat(warn).isGreaterThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO]); 91 | assertThat(warn).isNotGreaterThanOrEqualTo([levels.ERROR, levels.FATAL, levels.OFF]); 92 | } 93 | }, 94 | 'ERROR': { 95 | topic: levels.ERROR, 96 | 'should be less than FATAL': function(error) { 97 | assertThat(error).isLessThanOrEqualTo([levels.FATAL, levels.OFF]); 98 | assertThat(error).isNotLessThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO, levels.WARN]); 99 | }, 100 | 'should be greater than WARN': function(error) { 101 | assertThat(error).isGreaterThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO, levels.WARN]); 102 | assertThat(error).isNotGreaterThanOrEqualTo([levels.FATAL, levels.OFF]); 103 | } 104 | }, 105 | 'FATAL': { 106 | topic: levels.FATAL, 107 | 'should be less than OFF': function(fatal) { 108 | assertThat(fatal).isLessThanOrEqualTo([levels.OFF]); 109 | assertThat(fatal).isNotLessThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO, levels.WARN, levels.ERROR]); 110 | }, 111 | 'should be greater than ERROR': function(fatal) { 112 | assertThat(fatal).isGreaterThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO, levels.WARN, levels.ERROR]); 113 | assertThat(fatal).isNotGreaterThanOrEqualTo([levels.OFF]); 114 | } 115 | }, 116 | 'OFF': { 117 | topic: levels.OFF, 118 | 'should not be less than anything': function(off) { 119 | assertThat(off).isNotLessThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO, levels.WARN, levels.ERROR, levels.FATAL]); 120 | }, 121 | 'should be greater than everything': function(off) { 122 | assertThat(off).isGreaterThanOrEqualTo([levels.ALL, levels.TRACE, levels.DEBUG, levels.INFO, levels.WARN, levels.ERROR, levels.FATAL]); 123 | } 124 | } 125 | }, 126 | 'isGreaterThanOrEqualTo': { 127 | topic: levels.INFO, 128 | 'should handle string arguments': function(info) { 129 | assertThat(info).isGreaterThanOrEqualTo(["all", "trace", "debug"]); 130 | assertThat(info).isNotGreaterThanOrEqualTo(['warn', 'ERROR', 'Fatal', 'off']); 131 | } 132 | }, 133 | 'isLessThanOrEqualTo': { 134 | topic: levels.INFO, 135 | 'should handle string arguments': function(info) { 136 | assertThat(info).isNotLessThanOrEqualTo(["all", "trace", "debug"]); 137 | assertThat(info).isLessThanOrEqualTo(['warn', 'ERROR', 'Fatal', 'off']); 138 | } 139 | }, 140 | 'toLevel': { 141 | 'with lowercase argument': { 142 | topic: levels.toLevel("debug"), 143 | 'should take the string and return the corresponding level': function(level) { 144 | assert.equal(level, levels.DEBUG); 145 | } 146 | }, 147 | 'with uppercase argument': { 148 | topic: levels.toLevel("DEBUG"), 149 | 'should take the string and return the corresponding level': function(level) { 150 | assert.equal(level, levels.DEBUG); 151 | } 152 | }, 153 | 'with varying case': { 154 | topic: levels.toLevel("DeBuG"), 155 | 'should take the string and return the corresponding level': function(level) { 156 | assert.equal(level, levels.DEBUG); 157 | } 158 | }, 159 | 'with unrecognised argument': { 160 | topic: levels.toLevel("cheese"), 161 | 'should return undefined': function(level) { 162 | assert.isUndefined(level); 163 | } 164 | }, 165 | 'with unrecognised argument and default value': { 166 | topic: levels.toLevel("cheese", levels.DEBUG), 167 | 'should return default value': function(level) { 168 | assert.equal(level, levels.DEBUG); 169 | } 170 | } 171 | } 172 | }).export(module); 173 | -------------------------------------------------------------------------------- /node_modules/log4js/test/log4js.json: -------------------------------------------------------------------------------- 1 | { 2 | "appenders": [ 3 | { 4 | "category": "tests", 5 | "type": "file", 6 | "filename": "tmp-tests.log", 7 | "layout": { 8 | "type": "messagePassThrough" 9 | } 10 | } 11 | ], 12 | 13 | "levels": { 14 | "tests": "WARN" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /node_modules/log4js/test/logLevelFilter.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , fs = require('fs') 3 | , assert = require('assert'); 4 | 5 | function remove(filename) { 6 | try { 7 | fs.unlinkSync(filename); 8 | } catch (e) { 9 | //doesn't really matter if it failed 10 | } 11 | } 12 | 13 | vows.describe('log4js logLevelFilter').addBatch({ 14 | 'appender': { 15 | topic: function() { 16 | var log4js = require('../lib/log4js'), logEvents = [], logger; 17 | log4js.clearAppenders(); 18 | log4js.addAppender(log4js.logLevelFilter('ERROR', function(evt) { logEvents.push(evt); }), "logLevelTest"); 19 | logger = log4js.getLogger("logLevelTest"); 20 | logger.debug('this should not trigger an event'); 21 | logger.warn('neither should this'); 22 | logger.error('this should, though'); 23 | logger.fatal('so should this'); 24 | return logEvents; 25 | }, 26 | 'should only pass log events greater than or equal to its own level' : function(logEvents) { 27 | assert.equal(logEvents.length, 2); 28 | assert.equal(logEvents[0].data[0], 'this should, though'); 29 | assert.equal(logEvents[1].data[0], 'so should this'); 30 | } 31 | }, 32 | 33 | 'configure': { 34 | topic: function() { 35 | var log4js = require('../lib/log4js') 36 | , logger; 37 | 38 | remove(__dirname + '/logLevelFilter.log'); 39 | remove(__dirname + '/logLevelFilter-warnings.log'); 40 | 41 | log4js.configure('test/with-logLevelFilter.json'); 42 | logger = log4js.getLogger("tests"); 43 | logger.info('main'); 44 | logger.error('both'); 45 | logger.warn('both'); 46 | logger.debug('main'); 47 | //wait for the file system to catch up 48 | setTimeout(this.callback, 100); 49 | }, 50 | 'tmp-tests.log': { 51 | topic: function() { 52 | fs.readFile(__dirname + '/logLevelFilter.log', 'utf8', this.callback); 53 | }, 54 | 'should contain all log messages': function(contents) { 55 | var messages = contents.trim().split('\n'); 56 | assert.deepEqual(messages, ['main','both','both','main']); 57 | } 58 | }, 59 | 'tmp-tests-warnings.log': { 60 | topic: function() { 61 | fs.readFile(__dirname + '/logLevelFilter-warnings.log','utf8',this.callback); 62 | }, 63 | 'should contain only error and warning log messages': function(contents) { 64 | var messages = contents.trim().split('\n'); 65 | assert.deepEqual(messages, ['both','both']); 66 | } 67 | } 68 | } 69 | }).export(module); -------------------------------------------------------------------------------- /node_modules/log4js/test/multiprocessAppender.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows'); 2 | var assert = require('assert'); 3 | var sandbox = require('sandboxed-module'); 4 | var _ = require('underscore'); 5 | 6 | function fancyResultingMultiprocessAppender(opts) { 7 | var result = { clientOns: {}, serverOns: {}, logged: [], ended: [] }; 8 | 9 | var fakeSocket = { 10 | on: function (event, fn) { 11 | result.clientOns[event] = fn; 12 | if (event === 'connect') { 13 | fn(); 14 | } 15 | }, 16 | end: function (data, encoding) { 17 | result.ended.push({ data: data, encoding: encoding }); 18 | } 19 | } 20 | 21 | var fakeServerSocket = { 22 | on: function (event, fn) { 23 | result.serverOns[event] = fn; 24 | if (event === 'connect') { 25 | fn(); 26 | } 27 | } 28 | } 29 | 30 | var fakeServer = { 31 | listen: function (port, host) { 32 | result.listenPort = port; 33 | result.listenHost = host; 34 | } 35 | } 36 | 37 | var fakeNet = { 38 | createServer: function (fn) { 39 | fn(fakeServerSocket); 40 | return fakeServer; 41 | }, 42 | createConnection: function (port, host) { 43 | result.connectPort = port; 44 | result.connectHost = host; 45 | return fakeSocket; 46 | } 47 | } 48 | 49 | var fakeLog4Js = { 50 | appenderMakers: {} 51 | }; 52 | fakeLog4Js.loadAppender = function (appender) { 53 | fakeLog4Js.appenderMakers[appender] = function (config) { 54 | result.actualLoggerConfig = config; 55 | return function log(logEvent) { 56 | result.logged.push(logEvent); 57 | } 58 | }; 59 | }; 60 | 61 | return { theResult: result, 62 | theModule: sandbox.require('../lib/appenders/multiprocess', { 63 | requires: { 64 | '../log4js': fakeLog4Js, 65 | 'net': fakeNet 66 | } 67 | }) 68 | }; 69 | } 70 | 71 | function logMessages(result, logs, raw) { 72 | logs.forEach(function log(item) { 73 | var logItem = { startTime: "Wed, 02 Nov 2011 21:46:39 GMT", level: { levelStr: 'DEBUG' }, data: [ item ] }; 74 | result.serverOns.data(JSON.stringify(logItem)); 75 | result.serverOns.end(); 76 | result.serverOns.connect(); 77 | }); 78 | if (raw) { 79 | raw.forEach(function log(rawItem) { 80 | result.serverOns.data(rawItem); 81 | result.serverOns.end(); 82 | result.serverOns.connect(); 83 | }); 84 | } 85 | } 86 | 87 | 88 | vows.describe('log4js multiprocessAppender').addBatch({ 89 | 'master': { 90 | topic: function() { 91 | var fancy = fancyResultingMultiprocessAppender(); 92 | var logger = fancy.theModule.configure({ mode: 'master', 'loggerPort': 5001, 'loggerHost': 'abba', appender: { type: 'file' } }); 93 | logMessages(fancy.theResult, [ 'ALRIGHTY THEN', 'OH WOW' ]); 94 | return fancy.theResult; 95 | }, 96 | 97 | 'should write to the actual appender': function (result) { 98 | assert.equal(result.listenPort, 5001); 99 | assert.equal(result.listenHost, 'abba'); 100 | assert.equal(result.logged.length, 2); 101 | assert.equal(result.logged[0].data[0], 'ALRIGHTY THEN'); 102 | assert.equal(result.logged[1].data[0], 'OH WOW'); 103 | }, 104 | 105 | 'data written should be formatted correctly': function (result) { 106 | assert.equal(result.logged[0].level.toString(), 'DEBUG'); 107 | assert.equal(result.logged[0].data, 'ALRIGHTY THEN'); 108 | assert.isTrue(typeof(result.logged[0].startTime) === 'object'); 109 | assert.equal(result.logged[1].level.toString(), 'DEBUG'); 110 | assert.equal(result.logged[1].data, 'OH WOW'); 111 | assert.isTrue(typeof(result.logged[1].startTime) === 'object'); 112 | }, 113 | 114 | 'the actual logger should get the right config': function (result) { 115 | assert.equal(result.actualLoggerConfig.type, 'file'); 116 | }, 117 | 118 | 'client should not be called': function (result) { 119 | assert.equal(_.keys(result.clientOns).length, 0); 120 | } 121 | }, 122 | 'master with bad request': { 123 | topic: function() { 124 | var fancy = fancyResultingMultiprocessAppender(); 125 | var logger = fancy.theModule.configure({ mode: 'master', 'loggerPort': 5001, 'loggerHost': 'abba', appender: { type: 'file' } }); 126 | logMessages(fancy.theResult, [], [ 'ALRIGHTY THEN', 'OH WOW' ]); 127 | return fancy.theResult; 128 | }, 129 | 130 | 'should write to the actual appender': function (result) { 131 | assert.equal(result.listenPort, 5001); 132 | assert.equal(result.listenHost, 'abba'); 133 | assert.equal(result.logged.length, 2); 134 | assert.equal(result.logged[0].data[0], 'Unable to parse log: ALRIGHTY THEN'); 135 | assert.equal(result.logged[1].data[0], 'Unable to parse log: OH WOW'); 136 | }, 137 | 138 | 'data written should be formatted correctly': function (result) { 139 | assert.equal(result.logged[0].level.toString(), 'ERROR'); 140 | assert.equal(result.logged[0].data, 'Unable to parse log: ALRIGHTY THEN'); 141 | assert.isTrue(typeof(result.logged[0].startTime) === 'object'); 142 | assert.equal(result.logged[1].level.toString(), 'ERROR'); 143 | assert.equal(result.logged[1].data, 'Unable to parse log: OH WOW'); 144 | assert.isTrue(typeof(result.logged[1].startTime) === 'object'); 145 | } 146 | }, 147 | 'worker': { 148 | 'should emit logging events to the master': { 149 | topic: function() { 150 | var fancy = fancyResultingMultiprocessAppender(); 151 | var logger = fancy.theModule.configure({ loggerHost: 'baba', loggerPort: 1232, name: 'ohno', mode: 'worker', appender: { type: 'file' } }); 152 | logger({ level: { levelStr: 'INFO' }, data: "ALRIGHTY THEN", startTime: '2011-10-27T03:53:16.031Z' }); 153 | logger({ level: { levelStr: 'DEBUG' }, data: "OH WOW", startTime: '2011-10-27T04:53:16.031Z'}); 154 | return fancy.theResult; 155 | }, 156 | 157 | 'client configuration should be correct': function (result) { 158 | assert.equal(result.connectHost, 'baba'); 159 | assert.equal(result.connectPort, 1232); 160 | }, 161 | 162 | 'should not write to the actual appender': function (result) { 163 | assert.equal(result.logged.length, 0); 164 | assert.equal(result.ended.length, 2); 165 | assert.equal(result.ended[0].data, JSON.stringify({ level: { levelStr: 'INFO' }, data: "ALRIGHTY THEN", startTime: '2011-10-27T03:53:16.031Z' })); 166 | assert.equal(result.ended[0].encoding, 'utf8'); 167 | assert.equal(result.ended[1].data, JSON.stringify({ level: { levelStr: 'DEBUG' }, data: "OH WOW", startTime: '2011-10-27T04:53:16.031Z'})); 168 | assert.equal(result.ended[1].encoding, 'utf8'); 169 | assert.equal(_.keys(result.serverOns).length, 0); 170 | } 171 | } 172 | } 173 | }).exportTo(module); 174 | -------------------------------------------------------------------------------- /node_modules/log4js/test/rollingFileStream.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , assert = require('assert') 3 | , events = require('events') 4 | , fs = require('fs') 5 | , RollingFileStream = require('../lib/streams').RollingFileStream; 6 | 7 | function remove(filename) { 8 | try { 9 | fs.unlinkSync(filename); 10 | } catch (e) { 11 | //doesn't really matter if it failed 12 | } 13 | } 14 | 15 | vows.describe('RollingFileStream').addBatch({ 16 | 'arguments': { 17 | topic: function() { 18 | remove(__dirname + "/test-rolling-file-stream"); 19 | return new RollingFileStream("test-rolling-file-stream", 1024, 5); 20 | }, 21 | 'should take a filename, file size in bytes, number of backups as arguments and return a FileWriteStream': function(stream) { 22 | assert.instanceOf(stream, fs.FileWriteStream); 23 | assert.equal(stream.filename, "test-rolling-file-stream"); 24 | assert.equal(stream.size, 1024); 25 | assert.equal(stream.backups, 5); 26 | }, 27 | 'with default settings for the underlying stream': function(stream) { 28 | assert.equal(stream.mode, 420); 29 | assert.equal(stream.flags, 'a'); 30 | assert.equal(stream.encoding, 'utf8'); 31 | } 32 | }, 33 | 'with stream arguments': { 34 | topic: function() { 35 | remove(__dirname + '/test-rolling-file-stream'); 36 | return new RollingFileStream('test-rolling-file-stream', 1024, 5, { mode: 0666 }); 37 | }, 38 | 'should pass them to the underlying stream': function(stream) { 39 | assert.equal(stream.mode, 0666); 40 | } 41 | }, 42 | 'without size': { 43 | topic: function() { 44 | try { 45 | new RollingFileStream(__dirname + "/test-rolling-file-stream"); 46 | } catch (e) { 47 | return e; 48 | } 49 | }, 50 | 'should throw an error': function(err) { 51 | assert.instanceOf(err, Error); 52 | } 53 | }, 54 | 'without number of backups': { 55 | topic: function() { 56 | remove('test-rolling-file-stream'); 57 | return new RollingFileStream(__dirname + "/test-rolling-file-stream", 1024); 58 | }, 59 | 'should default to 1 backup': function(stream) { 60 | assert.equal(stream.backups, 1); 61 | } 62 | }, 63 | 'writing less than the file size': { 64 | topic: function() { 65 | remove(__dirname + "/test-rolling-file-stream-write-less"); 66 | var that = this, stream = new RollingFileStream(__dirname + "/test-rolling-file-stream-write-less", 100); 67 | stream.on("open", function() { that.callback(null, stream); }); 68 | }, 69 | '(when open)': { 70 | topic: function(stream) { 71 | stream.write("cheese", "utf8"); 72 | stream.end(); 73 | fs.readFile(__dirname + "/test-rolling-file-stream-write-less", "utf8", this.callback); 74 | }, 75 | 'should write to the file': function(contents) { 76 | assert.equal(contents, "cheese"); 77 | }, 78 | 'the number of files': { 79 | topic: function() { 80 | fs.readdir(__dirname, this.callback); 81 | }, 82 | 'should be one': function(files) { 83 | assert.equal(files.filter(function(file) { return file.indexOf('test-rolling-file-stream-write-less') > -1; }).length, 1); 84 | } 85 | } 86 | } 87 | }, 88 | 'writing more than the file size': { 89 | topic: function() { 90 | remove(__dirname + "/test-rolling-file-stream-write-more"); 91 | remove(__dirname + "/test-rolling-file-stream-write-more.1"); 92 | var that = this, stream = new RollingFileStream(__dirname + "/test-rolling-file-stream-write-more", 45); 93 | stream.on("open", function() { 94 | for (var i=0; i < 7; i++) { 95 | stream.write(i +".cheese\n", "utf8"); 96 | } 97 | //wait for the file system to catch up with us 98 | setTimeout(that.callback, 100); 99 | }); 100 | }, 101 | 'the number of files': { 102 | topic: function() { 103 | fs.readdir(__dirname, this.callback); 104 | }, 105 | 'should be two': function(files) { 106 | assert.equal(files.filter(function(file) { return file.indexOf('test-rolling-file-stream-write-more') > -1; }).length, 2); 107 | } 108 | }, 109 | 'the first file': { 110 | topic: function() { 111 | fs.readFile(__dirname + "/test-rolling-file-stream-write-more", "utf8", this.callback); 112 | }, 113 | 'should contain the last two log messages': function(contents) { 114 | assert.equal(contents, '5.cheese\n6.cheese\n'); 115 | } 116 | }, 117 | 'the second file': { 118 | topic: function() { 119 | fs.readFile(__dirname + '/test-rolling-file-stream-write-more.1', "utf8", this.callback); 120 | }, 121 | 'should contain the first five log messages': function(contents) { 122 | assert.equal(contents, '0.cheese\n1.cheese\n2.cheese\n3.cheese\n4.cheese\n'); 123 | } 124 | } 125 | } 126 | }).exportTo(module); 127 | -------------------------------------------------------------------------------- /node_modules/log4js/test/smtpAppender.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows'), 2 | assert = require('assert'), 3 | log4js = require('../lib/log4js'), 4 | sandbox = require('sandboxed-module'); 5 | 6 | function setupLogging(category, options) { 7 | var msgs = []; 8 | 9 | var fakeMailer = { 10 | send_mail: function (msg, callback) { 11 | msgs.push(msg); 12 | callback(null, true); 13 | } 14 | }; 15 | 16 | var smtpModule = sandbox.require('../lib/appenders/smtp', { 17 | requires: { 18 | 'nodemailer': fakeMailer 19 | } 20 | }); 21 | 22 | log4js.addAppender(smtpModule.configure(options), category); 23 | 24 | return { 25 | logger: log4js.getLogger(category), 26 | mailer: fakeMailer, 27 | results: msgs 28 | }; 29 | } 30 | 31 | function checkMessages (result, sender, subject) { 32 | for (var i = 0; i < result.results.length; ++i) { 33 | assert.equal(result.results[i].sender, sender ? sender : result.mailer.SMTP.user); 34 | assert.equal(result.results[i].to, 'recipient@domain.com'); 35 | assert.equal(result.results[i].subject, subject ? subject : 'Log event #' + (i+1)); 36 | assert.ok(new RegExp('.+Log event #' + (i+1) + '\n$').test(result.results[i].body)); 37 | } 38 | } 39 | 40 | log4js.clearAppenders(); 41 | vows.describe('log4js smtpAppender').addBatch({ 42 | 'minimal config': { 43 | topic: function() { 44 | var setup = setupLogging('minimal config', { 45 | recipients: 'recipient@domain.com', 46 | smtp: { 47 | port: 25, 48 | user: 'user@domain.com' 49 | } 50 | }); 51 | setup.logger.info('Log event #1'); 52 | return setup; 53 | }, 54 | 'mailer should be configured properly': function (result) { 55 | assert.ok(result.mailer.SMTP); 56 | assert.equal(result.mailer.SMTP.port, 25); 57 | assert.equal(result.mailer.SMTP.user, 'user@domain.com'); 58 | }, 59 | 'there should be one message only': function (result) { 60 | assert.equal(result.results.length, 1); 61 | }, 62 | 'message should contain proper data': function (result) { 63 | checkMessages(result); 64 | } 65 | }, 66 | 'fancy config': { 67 | topic: function() { 68 | var setup = setupLogging('fancy config', { 69 | recipients: 'recipient@domain.com', 70 | sender: 'sender@domain.com', 71 | subject: 'This is subject', 72 | smtp: { 73 | port: 25, 74 | user: 'user@domain.com' 75 | } 76 | }); 77 | setup.logger.info('Log event #1'); 78 | return setup; 79 | }, 80 | 'mailer should be configured properly': function (result) { 81 | assert.ok(result.mailer.SMTP); 82 | assert.equal(result.mailer.SMTP.port, 25); 83 | assert.equal(result.mailer.SMTP.user, 'user@domain.com'); 84 | }, 85 | 'there should be one message only': function (result) { 86 | assert.equal(result.results.length, 1); 87 | }, 88 | 'message should contain proper data': function (result) { 89 | checkMessages(result, 'sender@domain.com', 'This is subject'); 90 | } 91 | }, 92 | 'separate email for each event': { 93 | topic: function() { 94 | var self = this; 95 | var setup = setupLogging('separate email for each event', { 96 | recipients: 'recipient@domain.com', 97 | smtp: { 98 | port: 25, 99 | user: 'user@domain.com' 100 | } 101 | }); 102 | setTimeout(function () { 103 | setup.logger.info('Log event #1'); 104 | }, 0); 105 | setTimeout(function () { 106 | setup.logger.info('Log event #2'); 107 | }, 500); 108 | setTimeout(function () { 109 | setup.logger.info('Log event #3'); 110 | }, 1050); 111 | setTimeout(function () { 112 | self.callback(null, setup); 113 | }, 2100); 114 | }, 115 | 'there should be three messages': function (result) { 116 | assert.equal(result.results.length, 3); 117 | }, 118 | 'messages should contain proper data': function (result) { 119 | checkMessages(result); 120 | } 121 | }, 122 | 'multiple events in one email': { 123 | topic: function() { 124 | var self = this; 125 | var setup = setupLogging('multiple events in one email', { 126 | recipients: 'recipient@domain.com', 127 | sendInterval: 1, 128 | smtp: { 129 | port: 25, 130 | user: 'user@domain.com' 131 | } 132 | }); 133 | setTimeout(function () { 134 | setup.logger.info('Log event #1'); 135 | }, 0); 136 | setTimeout(function () { 137 | setup.logger.info('Log event #2'); 138 | }, 500); 139 | setTimeout(function () { 140 | setup.logger.info('Log event #3'); 141 | }, 1050); 142 | setTimeout(function () { 143 | self.callback(null, setup); 144 | }, 2100); 145 | }, 146 | 'there should be two messages': function (result) { 147 | assert.equal(result.results.length, 2); 148 | }, 149 | 'messages should contain proper data': function (result) { 150 | assert.equal(result.results[0].sender, result.mailer.SMTP.user); 151 | assert.equal(result.results[0].to, 'recipient@domain.com'); 152 | assert.equal(result.results[0].subject, 'Log event #1'); 153 | assert.equal(result.results[0].body.match(new RegExp('.+Log event #[1-2]$', 'gm')).length, 2); 154 | 155 | assert.equal(result.results[1].sender, result.mailer.SMTP.user); 156 | assert.equal(result.results[1].to, 'recipient@domain.com'); 157 | assert.equal(result.results[1].subject, 'Log event #3'); 158 | assert.ok(new RegExp('.+Log event #3\n$').test(result.results[1].body)); 159 | } 160 | } 161 | 162 | }).export(module); 163 | -------------------------------------------------------------------------------- /node_modules/log4js/test/test-connect-logger.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , assert = require('assert') 3 | , levels = require('../lib/levels'); 4 | 5 | function MockLogger() { 6 | 7 | var that = this; 8 | this.messages = []; 9 | 10 | this.log = function(level, message, exception) { 11 | that.messages.push({ level: level, message: message }); 12 | }; 13 | 14 | this.isLevelEnabled = function(level) { 15 | return level.isGreaterThanOrEqualTo(that.level); 16 | }; 17 | 18 | this.level = levels.TRACE; 19 | 20 | } 21 | 22 | function MockRequest(remoteAddr, method, originalUrl) { 23 | 24 | this.socket = { remoteAddress: remoteAddr }; 25 | this.originalUrl = originalUrl; 26 | this.method = method; 27 | this.httpVersionMajor = '5'; 28 | this.httpVersionMinor = '0'; 29 | this.headers = {} 30 | 31 | } 32 | 33 | function MockResponse(statusCode) { 34 | 35 | this.statusCode = statusCode; 36 | 37 | this.end = function(chunk, encoding) { 38 | 39 | } 40 | 41 | } 42 | 43 | vows.describe('log4js connect logger').addBatch({ 44 | 'getConnectLoggerModule': { 45 | topic: function() { 46 | var clm = require('../lib/connect-logger'); 47 | return clm; 48 | }, 49 | 50 | 'should return a "connect logger" factory' : function(clm) { 51 | assert.isObject(clm); 52 | }, 53 | 54 | 'take a log4js logger and return a "connect logger"' : { 55 | topic: function(clm) { 56 | var ml = new MockLogger(); 57 | var cl = clm.connectLogger(ml); 58 | return cl; 59 | }, 60 | 61 | 'should return a "connect logger"': function(cl) { 62 | assert.isFunction(cl); 63 | } 64 | }, 65 | 66 | 'log events' : { 67 | topic: function(clm) { 68 | var ml = new MockLogger(); 69 | var cl = clm.connectLogger(ml); 70 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url'); 71 | var res = new MockResponse(200); 72 | cl(req, res, function() { }); 73 | res.end('chunk', 'encoding'); 74 | return ml.messages; 75 | }, 76 | 77 | 'check message': function(messages) { 78 | assert.isArray(messages); 79 | assert.equal(messages.length, 1); 80 | assert.equal(messages[0].level, levels.INFO); 81 | assert.include(messages[0].message, 'GET'); 82 | assert.include(messages[0].message, 'http://url'); 83 | assert.include(messages[0].message, 'my.remote.addr'); 84 | assert.include(messages[0].message, '200'); 85 | } 86 | }, 87 | 88 | 'log events with level below logging level' : { 89 | topic: function(clm) { 90 | var ml = new MockLogger(); 91 | ml.level = levels.FATAL; 92 | var cl = clm.connectLogger(ml); 93 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url'); 94 | var res = new MockResponse(200); 95 | cl(req, res, function() { }); 96 | res.end('chunk', 'encoding'); 97 | return ml.messages; 98 | }, 99 | 100 | 'check message': function(messages) { 101 | assert.isArray(messages); 102 | assert.isEmpty(messages); 103 | } 104 | }, 105 | 106 | 'log events with non-default level and custom format' : { 107 | topic: function(clm) { 108 | var ml = new MockLogger(); 109 | ml.level = levels.INFO; 110 | var cl = clm.connectLogger(ml, { level: levels.INFO, format: ':method :url' } ); 111 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url'); 112 | var res = new MockResponse(200); 113 | cl(req, res, function() { }); 114 | res.end('chunk', 'encoding'); 115 | return ml.messages; 116 | }, 117 | 118 | 'check message': function(messages) { 119 | assert.isArray(messages); 120 | assert.equal(messages.length, 1); 121 | assert.equal(messages[0].level, levels.INFO); 122 | assert.equal(messages[0].message, 'GET http://url'); 123 | } 124 | } 125 | 126 | } 127 | 128 | }).export(module); 129 | -------------------------------------------------------------------------------- /node_modules/log4js/test/test-global-log-level.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows'), 2 | assert = require('assert'); 3 | 4 | vows.describe('log4js global loglevel').addBatch({ 5 | 'global loglevel' : { 6 | topic: function() { 7 | var log4js = require('../lib/log4js'); 8 | return log4js; 9 | }, 10 | 11 | 'set global loglevel on creation': function(log4js) { 12 | var log1 = log4js.getLogger('log1'); 13 | var level = 'OFF'; 14 | if (log1.level.toString() == level) { 15 | level = 'TRACE'; 16 | } 17 | assert.notEqual(log1.level.toString(), level); 18 | 19 | log4js.setGlobalLogLevel(level); 20 | assert.equal(log1.level.toString(), level); 21 | 22 | var log2 = log4js.getLogger('log2'); 23 | assert.equal(log2.level.toString(), level); 24 | }, 25 | 26 | 'global change loglevel': function(log4js) { 27 | var log1 = log4js.getLogger('log1'); 28 | var log2 = log4js.getLogger('log2'); 29 | var level = 'OFF'; 30 | if (log1.level.toString() == level) { 31 | level = 'TRACE'; 32 | } 33 | assert.notEqual(log1.level.toString(), level); 34 | 35 | log4js.setGlobalLogLevel(level); 36 | assert.equal(log1.level.toString(), level); 37 | assert.equal(log2.level.toString(), level); 38 | }, 39 | 40 | 'override loglevel': function(log4js) { 41 | var log1 = log4js.getLogger('log1'); 42 | var log2 = log4js.getLogger('log2'); 43 | var level = 'OFF'; 44 | if (log1.level.toString() == level) { 45 | level = 'TRACE'; 46 | } 47 | assert.notEqual(log1.level.toString(), level); 48 | 49 | var oldLevel = log1.level.toString(); 50 | assert.equal(log2.level.toString(), oldLevel); 51 | 52 | log2.setLevel(level); 53 | assert.equal(log1.level.toString(), oldLevel); 54 | assert.equal(log2.level.toString(), level); 55 | assert.notEqual(oldLevel, level); 56 | 57 | log2.removeLevel(); 58 | assert.equal(log1.level.toString(), oldLevel); 59 | assert.equal(log2.level.toString(), oldLevel); 60 | }, 61 | 62 | 'preload loglevel': function(log4js) { 63 | var log1 = log4js.getLogger('log1'); 64 | var level = 'OFF'; 65 | if (log1.level.toString() == level) { 66 | level = 'TRACE'; 67 | } 68 | assert.notEqual(log1.level.toString(), level); 69 | 70 | var oldLevel = log1.level.toString(); 71 | log4js.getLogger('log2').setLevel(level); 72 | 73 | assert.equal(log1.level.toString(), oldLevel); 74 | 75 | // get again same logger but as different variable 76 | var log2 = log4js.getLogger('log2'); 77 | assert.equal(log2.level.toString(), level); 78 | assert.notEqual(oldLevel, level); 79 | 80 | log2.removeLevel(); 81 | assert.equal(log1.level.toString(), oldLevel); 82 | assert.equal(log2.level.toString(), oldLevel); 83 | } 84 | } 85 | }).export(module); 86 | -------------------------------------------------------------------------------- /node_modules/log4js/test/test-log-abspath.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , assert = require('assert') 3 | , sandbox = require('sandboxed-module'); 4 | 5 | vows.describe('log4js-abspath').addBatch({ 6 | 'configuration is passed as object with options.cwd': { 7 | topic: function() { 8 | var appenderConfig 9 | , log4js = sandbox.require( 10 | '../lib/log4js' 11 | , { requires: 12 | { './appenders/file': 13 | { 14 | name: "file" 15 | , appender: function() {} 16 | , configure: function(configuration) { 17 | appenderConfig = configuration; 18 | return function() {}; 19 | } 20 | } 21 | } 22 | } 23 | ) 24 | , config = { 25 | "appenders": [ 26 | { 27 | "type" : "file", 28 | "filename" : "cheesy-wotsits.log", 29 | "maxLogSize" : 1024, 30 | "backups" : 3, 31 | "pollInterval" : 15 32 | } 33 | ] 34 | }; 35 | log4js.configure(config, { 36 | cwd: '/absolute/path/to' 37 | }); 38 | return appenderConfig; 39 | }, 40 | 'should be an absolute path': function(configuration) { 41 | assert.equal(configuration.filename, '/absolute/path/to/cheesy-wotsits.log'); 42 | } 43 | }, 44 | 45 | 'configuration passed as filename with options.cwd': { 46 | topic: function() { 47 | var appenderConfig 48 | , configFilename 49 | , log4js = sandbox.require( 50 | '../lib/log4js' 51 | , { requires: 52 | { 'fs': 53 | { 54 | statSync: function() { 55 | return { mtime: Date.now() }; 56 | }, 57 | readFileSync: function(filename) { 58 | configFilename = filename; 59 | return JSON.stringify({ 60 | appenders: [ 61 | { type: "file" 62 | , filename: "whatever.log" 63 | } 64 | ] 65 | }); 66 | }, 67 | readdirSync: function() { 68 | return ['file']; 69 | } 70 | } 71 | , './appenders/file': 72 | { 73 | name: "file" 74 | , appender: function() {} 75 | , configure: function(configuration) { 76 | appenderConfig = configuration; 77 | return function() {}; 78 | } 79 | } 80 | } 81 | } 82 | ); 83 | log4js.configure("/path/to/cheese.json", { 84 | cwd: '/absolute/path/to' 85 | }); 86 | return [ configFilename, appenderConfig ]; 87 | }, 88 | 'should read the config from a file': function(args) { 89 | assert.equal(args[0], '/path/to/cheese.json'); 90 | }, 91 | 'should be an absolute path': function(args) { 92 | assert.equal(args[1].filename, "/absolute/path/to/whatever.log"); 93 | } 94 | }, 95 | }).export(module); -------------------------------------------------------------------------------- /node_modules/log4js/test/test-nolog.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | , assert = require('assert') 3 | , levels = require('../lib/levels'); 4 | 5 | function MockLogger() { 6 | 7 | var that = this; 8 | this.messages = []; 9 | 10 | this.log = function(level, message, exception) { 11 | that.messages.push({ level: level, message: message }); 12 | }; 13 | 14 | this.isLevelEnabled = function(level) { 15 | return level.isGreaterThanOrEqualTo(that.level); 16 | }; 17 | 18 | this.level = levels.TRACE; 19 | 20 | } 21 | 22 | function MockRequest(remoteAddr, method, originalUrl) { 23 | 24 | this.socket = { remoteAddress: remoteAddr }; 25 | this.originalUrl = originalUrl; 26 | this.method = method; 27 | this.httpVersionMajor = '5'; 28 | this.httpVersionMinor = '0'; 29 | this.headers = {}; 30 | } 31 | 32 | function MockResponse(statusCode) { 33 | 34 | this.statusCode = statusCode; 35 | 36 | this.end = function(chunk, encoding) { 37 | 38 | }; 39 | } 40 | 41 | vows.describe('log4js connect logger').addBatch({ 42 | 'getConnectLoggerModule': { 43 | topic: function() { 44 | var clm = require('../lib/connect-logger'); 45 | return clm; 46 | }, 47 | 48 | 'should return a "connect logger" factory' : function(clm) { 49 | assert.isObject(clm); 50 | }, 51 | 52 | 'nolog String' : { 53 | topic: function(clm) { 54 | var ml = new MockLogger(); 55 | var cl = clm.connectLogger(ml, {nolog: "\\.gif"}); 56 | return {cl: cl, ml: ml}; 57 | }, 58 | 59 | 'check unmatch url request': { 60 | topic: function(d){ 61 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.png'); // not gif 62 | var res = new MockResponse(200); 63 | d.cl(req, res, function() { }); 64 | res.end('chunk', 'encoding'); 65 | return d.ml.messages; 66 | } 67 | , 'check message': function(messages){ 68 | assert.isArray(messages); 69 | assert.equal(messages.length, 1); 70 | assert.equal(messages[0].level, levels.INFO); 71 | assert.include(messages[0].message, 'GET'); 72 | assert.include(messages[0].message, 'http://url'); 73 | assert.include(messages[0].message, 'my.remote.addr'); 74 | assert.include(messages[0].message, '200'); 75 | messages.pop(); 76 | } 77 | }, 78 | 79 | 'check match url request': { 80 | topic: function(d) { 81 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.gif'); // gif 82 | var res = new MockResponse(200); 83 | d.cl(req, res, function() { }); 84 | res.end('chunk', 'encoding'); 85 | return d.ml.messages; 86 | } 87 | , 'check message': function(messages) { 88 | assert.isArray(messages); 89 | assert.equal(messages.length, 0); 90 | } 91 | } 92 | }, 93 | 94 | 'nolog Strings' : { 95 | topic: function(clm) { 96 | var ml = new MockLogger(); 97 | var cl = clm.connectLogger(ml, {nolog: "\\.gif|\\.jpe?g"}); 98 | return {cl: cl, ml: ml}; 99 | }, 100 | 101 | 'check unmatch url request (png)': { 102 | topic: function(d){ 103 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.png'); // not gif 104 | var res = new MockResponse(200); 105 | d.cl(req, res, function() { }); 106 | res.end('chunk', 'encoding'); 107 | return d.ml.messages; 108 | } 109 | , 'check message': function(messages){ 110 | assert.isArray(messages); 111 | assert.equal(messages.length, 1); 112 | assert.equal(messages[0].level, levels.INFO); 113 | assert.include(messages[0].message, 'GET'); 114 | assert.include(messages[0].message, 'http://url'); 115 | assert.include(messages[0].message, 'my.remote.addr'); 116 | assert.include(messages[0].message, '200'); 117 | messages.pop(); 118 | } 119 | }, 120 | 121 | 'check match url request (gif)': { 122 | topic: function(d) { 123 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.gif'); // gif 124 | var res = new MockResponse(200); 125 | d.cl(req, res, function() { }); 126 | res.end('chunk', 'encoding'); 127 | return d.ml.messages; 128 | } 129 | , 'check message': function(messages) { 130 | assert.isArray(messages); 131 | assert.equal(messages.length, 0); 132 | } 133 | }, 134 | 'check match url request (jpeg)': { 135 | topic: function(d) { 136 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.jpeg'); // gif 137 | var res = new MockResponse(200); 138 | d.cl(req, res, function() { }); 139 | res.end('chunk', 'encoding'); 140 | return d.ml.messages; 141 | } 142 | , 'check message': function(messages) { 143 | assert.isArray(messages); 144 | assert.equal(messages.length, 0); 145 | } 146 | } 147 | }, 148 | 'nolog Array' : { 149 | topic: function(clm) { 150 | var ml = new MockLogger(); 151 | var cl = clm.connectLogger(ml, {nolog: ["\\.gif", "\\.jpe?g"]}); 152 | return {cl: cl, ml: ml}; 153 | }, 154 | 155 | 'check unmatch url request (png)': { 156 | topic: function(d){ 157 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.png'); // not gif 158 | var res = new MockResponse(200); 159 | d.cl(req, res, function() { }); 160 | res.end('chunk', 'encoding'); 161 | return d.ml.messages; 162 | } 163 | , 'check message': function(messages){ 164 | assert.isArray(messages); 165 | assert.equal(messages.length, 1); 166 | assert.equal(messages[0].level, levels.INFO); 167 | assert.include(messages[0].message, 'GET'); 168 | assert.include(messages[0].message, 'http://url'); 169 | assert.include(messages[0].message, 'my.remote.addr'); 170 | assert.include(messages[0].message, '200'); 171 | messages.pop(); 172 | } 173 | }, 174 | 175 | 'check match url request (gif)': { 176 | topic: function(d) { 177 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.gif'); // gif 178 | var res = new MockResponse(200); 179 | d.cl(req, res, function() { }); 180 | res.end('chunk', 'encoding'); 181 | return d.ml.messages; 182 | } 183 | , 'check message': function(messages) { 184 | assert.isArray(messages); 185 | assert.equal(messages.length, 0); 186 | } 187 | }, 188 | 189 | 'check match url request (jpeg)': { 190 | topic: function(d) { 191 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.jpeg'); // gif 192 | var res = new MockResponse(200); 193 | d.cl(req, res, function() { }); 194 | res.end('chunk', 'encoding'); 195 | return d.ml.messages; 196 | } 197 | , 'check message': function(messages) { 198 | assert.isArray(messages); 199 | assert.equal(messages.length, 0); 200 | } 201 | }, 202 | }, 203 | 'nolog RegExp' : { 204 | topic: function(clm) { 205 | var ml = new MockLogger(); 206 | var cl = clm.connectLogger(ml, {nolog: /\.gif|\.jpe?g/}); 207 | return {cl: cl, ml: ml}; 208 | }, 209 | 210 | 'check unmatch url request (png)': { 211 | topic: function(d){ 212 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.png'); // not gif 213 | var res = new MockResponse(200); 214 | d.cl(req, res, function() { }); 215 | res.end('chunk', 'encoding'); 216 | return d.ml.messages; 217 | } 218 | , 'check message': function(messages){ 219 | assert.isArray(messages); 220 | assert.equal(messages.length, 1); 221 | assert.equal(messages[0].level, levels.INFO); 222 | assert.include(messages[0].message, 'GET'); 223 | assert.include(messages[0].message, 'http://url'); 224 | assert.include(messages[0].message, 'my.remote.addr'); 225 | assert.include(messages[0].message, '200'); 226 | messages.pop(); 227 | } 228 | }, 229 | 230 | 'check match url request (gif)': { 231 | topic: function(d) { 232 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.gif'); // gif 233 | var res = new MockResponse(200); 234 | d.cl(req, res, function() { }); 235 | res.end('chunk', 'encoding'); 236 | return d.ml.messages; 237 | } 238 | , 'check message': function(messages) { 239 | assert.isArray(messages); 240 | assert.equal(messages.length, 0); 241 | } 242 | }, 243 | 244 | 'check match url request (jpeg)': { 245 | topic: function(d) { 246 | var req = new MockRequest('my.remote.addr', 'GET', 'http://url/hoge.jpeg'); // gif 247 | var res = new MockResponse(200); 248 | d.cl(req, res, function() { }); 249 | res.end('chunk', 'encoding'); 250 | return d.ml.messages; 251 | } 252 | , 'check message': function(messages) { 253 | assert.isArray(messages); 254 | assert.equal(messages.length, 0); 255 | } 256 | }, 257 | } 258 | } 259 | 260 | }).export(module); 261 | -------------------------------------------------------------------------------- /node_modules/log4js/test/test-rolling-file-stream: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetEase/pomelo-scheduler/06e70d28faabed4dfd5fb2d4351b878c1642195e/node_modules/log4js/test/test-rolling-file-stream -------------------------------------------------------------------------------- /node_modules/log4js/test/test-rolling-file-stream-write: -------------------------------------------------------------------------------- 1 | cheese -------------------------------------------------------------------------------- /node_modules/log4js/test/test-rolling-file-stream-write-less: -------------------------------------------------------------------------------- 1 | cheese -------------------------------------------------------------------------------- /node_modules/log4js/test/test-rolling-file-stream-write-more: -------------------------------------------------------------------------------- 1 | 5.cheese 2 | 6.cheese 3 | -------------------------------------------------------------------------------- /node_modules/log4js/test/test-rolling-file-stream-write-more.1: -------------------------------------------------------------------------------- 1 | 0.cheese 2 | 1.cheese 3 | 2.cheese 4 | 3.cheese 5 | 4.cheese 6 | -------------------------------------------------------------------------------- /node_modules/log4js/test/with-log-rolling.json: -------------------------------------------------------------------------------- 1 | { 2 | "appenders": [ 3 | { 4 | "type": "file", 5 | "filename": "tmp-test.log", 6 | "maxLogSize": 1024, 7 | "backups": 3, 8 | "pollInterval": 15 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /node_modules/log4js/test/with-logLevelFilter.json: -------------------------------------------------------------------------------- 1 | { 2 | "appenders": [ 3 | { 4 | "category": "tests", 5 | "type": "logLevelFilter", 6 | "level": "WARN", 7 | "appender": { 8 | "type": "file", 9 | "filename": "test/logLevelFilter-warnings.log", 10 | "layout": { 11 | "type": "messagePassThrough" 12 | } 13 | } 14 | }, 15 | { 16 | "category": "tests", 17 | "type": "file", 18 | "filename": "test/logLevelFilter.log", 19 | "layout": { 20 | "type": "messagePassThrough" 21 | } 22 | } 23 | ], 24 | 25 | "levels": { 26 | "tests": "DEBUG" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pomelo-scheduler", 3 | "version": "0.4.1", 4 | "main": "./lib/schedule", 5 | "author": "XiaogangZhang , fantasyni ", 6 | "dependencies": { 7 | "log4js": "0.6.7" 8 | } 9 | } -------------------------------------------------------------------------------- /test/cronTriggerTest.js: -------------------------------------------------------------------------------- 1 | var cronTrigger = require('../lib/cronTrigger'); 2 | 3 | var SECOND = 0; 4 | var MIN = 1; 5 | var HOUR = 2; 6 | var DOM = 3; 7 | var MONTH = 4; 8 | var DOW = 5; 9 | 10 | function decoderTest(){ 11 | var result = []; 12 | 13 | result.push(cronTrigger.decodeTrigger('12 2 3,4,5 4 5 1')); 14 | 15 | result.push(cronTrigger.decodeTrigger('* 1-3,2-9,4 3,4,5 4-9 5 1')); 16 | 17 | result.push(cronTrigger.decodeTrigger('12 2 3 4 5 1')); 18 | console.log(result); 19 | } 20 | 21 | function nextTimeTest(count){ 22 | var timer = cronTrigger.decodeTrigger('0 0 0 1 0 2-5'); 23 | 24 | 25 | var value = Date.now(); 26 | console.log(timer); 27 | 28 | // console.log([1,2] instanceof Array); 29 | var r1, r2; 30 | var start = Date.now(); 31 | for(var i = 0; i < count; i++) 32 | r1 = cronTrigger.nextTime(value, timer); 33 | var end = Date.now(); 34 | 35 | console.log("first run time : " + (end-start)); 36 | 37 | var start = Date.now(); 38 | for(var i = 0; i < count; i++) 39 | r2 = nextExcuteTimeTest(value, timer); 40 | var end = Date.now(); 41 | 42 | console.log("second run time : " + (end-start)); 43 | 44 | console.log("first run time:" + r1); 45 | console.log("second run time:" + r2); 46 | } 47 | 48 | function nextExcuteTimeTest(time, cronTrigger){ 49 | var next = new Date(time + 1000); 50 | 51 | while (true) 52 | { 53 | if (!timeMatch(next.getMonth(), cronTrigger[MONTH])) 54 | { 55 | next.setMonth(next.getMonth()+1); 56 | next.setDate(1); 57 | next.setHours(0); 58 | next.setMinutes(0); 59 | next.setSeconds(0); 60 | continue; 61 | } 62 | if (!timeMatch(next.getDate(), cronTrigger[DOM])) 63 | { 64 | next.setDate(next.getDate() + 1); 65 | next.setHours(0); 66 | next.setMinutes(0); 67 | next.setSeconds(0); 68 | continue; 69 | } 70 | if (!timeMatch(next.getDay(), cronTrigger[DOW])) 71 | { 72 | next.setDate(next.getDate() + 1); 73 | next.setHours(0); 74 | next.setMinutes(0); 75 | next.setSeconds(0); 76 | continue; 77 | } 78 | if (!timeMatch(next.getHours(), cronTrigger[HOUR])) 79 | { 80 | next.setHours(next.getHours() + 1); 81 | next.setMinutes(0); 82 | next.setSeconds(0); 83 | continue; 84 | } 85 | if (!timeMatch(next.getMinutes(), cronTrigger[MIN])) 86 | { 87 | next.setMinutes(next.getMinutes() + 1); 88 | next.setSeconds(0); 89 | continue; 90 | } 91 | if (!timeMatch(next.getSeconds(), cronTrigger[SECOND])) 92 | { 93 | next.setSeconds(next.getSeconds()+1); 94 | continue; 95 | } 96 | 97 | break; 98 | } 99 | 100 | return next; 101 | } 102 | 103 | function getDomLimitTest(y1,y2,m1,m2){ 104 | for(var year = y1; year <= y2; year++) 105 | for(var month = m1; month <= m2; month++){ 106 | console.log(year + "." + (month +1)+ " limit : " + cronTrigger.getDomLimit(year,month)); 107 | } 108 | } 109 | 110 | function timeMatch(value, cronTime){ 111 | // console.log("match value " + value + ' cronTime ' + cronTime); 112 | if(typeof(cronTime) == 'number'){ 113 | if(cronTime == -1) 114 | return true; 115 | if(value == cronTime) 116 | return true; 117 | return false; 118 | }else if(typeof(cronTime) == 'object' && cronTime instanceof Array){ 119 | if(value < cronTime[0] || value > cronTime[cronTime.length -1]) 120 | return false; 121 | 122 | for(var i = 0; i < cronTime.length; i++) 123 | if(value == cronTime[i]) 124 | return true; 125 | 126 | return false; 127 | } 128 | 129 | return null; 130 | } 131 | 132 | function test(){ 133 | nextTimeTest(100); 134 | // getDomLimitTest(1800,2002,1,1); 135 | } 136 | 137 | test(); -------------------------------------------------------------------------------- /test/priorityQueueTest.js: -------------------------------------------------------------------------------- 1 | var PriorityQueue = require('../lib/priorityQueue'); 2 | //var Queue = require('./PriorityQueue'); 3 | // 4 | //var queue = new Queue(); 5 | 6 | function testPriorityQueue(num, count){ 7 | var queue = PriorityQueue.createPriorityQueue(); 8 | 9 | for(var k = 0; k < num; k++){ 10 | var testCase = []; 11 | var result = new Array(count); 12 | 13 | for(var i = 0; i < count; i++){ 14 | testCase[i] = Math.random()*count; 15 | } 16 | 17 | var start = (new Date()).getTime(); 18 | for(var i = 0; i < count; i++) 19 | queue.offer(testCase[i]); 20 | var end = (new Date()).getTime(); 21 | console.log(end - start); 22 | 23 | start = (new Date()).getTime(); 24 | // var value = queue.pop(); 25 | for(var i = 0; i < count; i++){ 26 | result[i] = queue.pop(); 27 | // next = result[i]; 28 | // if(value > next){ 29 | // console.log('PriorityQueue error!'); 30 | // console.log(queue); 31 | // console.log(result); 32 | // break; 33 | // } 34 | // value = next; 35 | // queue.pop(); 36 | } 37 | end = (new Date()).getTime(); 38 | 39 | console.log(end - start); 40 | 41 | // console.log(result); 42 | 43 | var start = result[0]; 44 | 45 | for(var i = 1; i < count; i++){ 46 | var next = result[i]; 47 | 48 | if(start > next){ 49 | console.log("Error!!!!!!"); 50 | console.log("start : " + start + " next : " + next + " i : " + i); 51 | // console.log(result); 52 | break; 53 | } 54 | 55 | start = next; 56 | } 57 | 58 | console.log('After the ' + k + ' iteration with test count : ' + count); 59 | } 60 | } 61 | 62 | testPriorityQueue(10, 100000); 63 | //var test = []; 64 | //start = Date.now(); 65 | //var k; 66 | //for(var i = 0; i < 100000000; i++){ 67 | // k = i + 34354/i ; 68 | //} 69 | //end = Date.now(); 70 | // 71 | //console.log(end - start); 72 | -------------------------------------------------------------------------------- /test/scheduleTest.js: -------------------------------------------------------------------------------- 1 | var schedule = require('../lib/schedule'); 2 | var cronTrigger = require('../lib/cronTrigger'); 3 | var jobMap = []; 4 | 5 | var simpleJob = function(data){ 6 | var t = data.id+data.period; 7 | console.log("run for simple job :" + data.id + " period: " + data.period + " at time " + (new Date())); 8 | } 9 | 10 | var cronJob = function(data){ 11 | console.log("run for cronJob :" + data.id + " at time " + (new Date())); 12 | } 13 | 14 | function scheduleSimpleJobTest(count){ 15 | var id = 0; 16 | for(var i = 0; i < count; i ++){ 17 | var time = Math.ceil(Math.random() * 10 * 1000); 18 | var period = Math.ceil(Math.random()*60 * 1000 + 100) 19 | var id = schedule.scheduleJob({start:Date.now()+time,period:period}, simpleJob, {id:id++, period:period}); 20 | jobMap.push(id); 21 | } 22 | } 23 | 24 | function scheduleCronJobTest(count){ 25 | var id = 0; 26 | 27 | // var trigger = cronTrigger.decodeTrigger('* * 2-20 * * *'); 28 | for(var i = 0; i < count; i++){ 29 | var second = Math.floor(Math.random()*10); 30 | var id = schedule.scheduleJob('0/2,2-10,13-20,40-45,55-56 * * * * *', cronJob, {id:id++}); 31 | jobMap.push(id); 32 | } 33 | } 34 | 35 | function cancleJob(data){ 36 | var jobMap = data.jobMap; 37 | if(jobMap.length>0){ 38 | var id = jobMap.pop(); 39 | console.log("Cancel job : " + id + " Last jobs count : " + jobMap.length); 40 | data.schedule.cancelJob(id); 41 | }else 42 | console.log("All job has been cancled"); 43 | } 44 | 45 | function scheduleCancleJobTest(){ 46 | var id = schedule.scheduleJob({start:Date.now(),period:100, count:jobMap.length}, cancleJob, {jobMap:jobMap,schedule:schedule}); 47 | } 48 | 49 | function test(){ 50 | scheduleSimpleJobTest(5); 51 | 52 | scheduleCronJobTest(5); 53 | 54 | // scheduleCancleJobTest(); 55 | } 56 | 57 | test(); 58 | //schedule.scheduleJob({period:30, count:4}, simpleJob, {name:'simpleJob'}); -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var schedule = require('pomelo-scheduler'); 2 | 3 | var cronJob = function() { 4 | console.log('doing %s', Date.now()) 5 | } 6 | 7 | try { 8 | schedule.scheduleJob("0 5 14/2 * * *", cronJob, { 9 | name: 'cronJobExample' 10 | }); 11 | } catch (e) { 12 | console.log(e.stack); 13 | } --------------------------------------------------------------------------------