1/// <reference path="Definitions/jsnlog_interfaces.d.ts"/> 2var __extends = this.__extends || function (d, b) { 3 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 function __() { this.constructor = d; } 5 __.prototype = b.prototype; 6 d.prototype = new __(); 7}; 8function JL(loggerName) { 9 // If name is empty, return the root logger 10 if (!loggerName) { 11 return JL.__; 12 } 13 14 // Implements Array.reduce. JSNLog supports IE8+ and reduce is not supported in that browser. 15 // Same interface as the standard reduce, except that 16 if (!Array.prototype.reduce) { 17 Array.prototype.reduce = function (callback, initialValue) { 18 var previousValue = initialValue; 19 for (var i = 0; i < this.length; i++) { 20 previousValue = callback(previousValue, this[i], i, this); 21 } 22 23 return previousValue; 24 }; 25 } 26 27 var accumulatedLoggerName = ''; 28 var logger = ('.' + loggerName).split('.').reduce(function (prev, curr, idx, arr) { 29 // if loggername is a.b.c, than currentLogger will be set to the loggers 30 // root (prev: JL, curr: '') 31 // a (prev: JL.__, curr: 'a') 32 // a.b (prev: JL.__.__a, curr: 'b') 33 // a.b.c (prev: JL.__.__a.__a.b, curr: 'c') 34 // Note that when a new logger name is encountered (such as 'a.b.c'), 35 // a new logger object is created and added as a property to the parent ('a.b'). 36 // The root logger is added as a property of the JL object itself. 37 // It is essential that the name of the property containing the child logger 38 // contains the full 'path' name of the child logger ('a.b.c') instead of 39 // just the bit after the last period ('c'). 40 // This is because the parent inherits properties from its ancestors. 41 // So if the root has a child logger 'c' (stored in a property 'c' of the root logger), 42 // then logger 'a.b' has that same property 'c' through inheritance. 43 // The names of the logger properties start with __, so the root logger 44 // (which has name ''), has a nice property name '__'. 45 // accumulatedLoggerName evaluates false ('' is falsy) in first iteration when prev is the root logger. 46 // accumulatedLoggerName will be the logger name corresponding with the logger in currentLogger. 47 // Keep in mind that the currentLogger may not be defined yet, so can't get the name from 48 // the currentLogger object itself. 49 if (accumulatedLoggerName) { 50 accumulatedLoggerName += '.' + curr; 51 } else { 52 accumulatedLoggerName = curr; 53 } 54 55 var currentLogger = prev['__' + accumulatedLoggerName]; 56 57 // If the currentLogger (or the actual logger being sought) does not yet exist, 58 // create it now. 59 if (currentLogger === undefined) { 60 // Set the prototype of the Logger constructor function to the parent of the logger 61 // to be created. This way, __proto of the new logger object will point at the parent. 62 // When logger.level is evaluated and is not present, the JavaScript runtime will 63 // walk down the prototype chain to find the first ancestor with a level property. 64 // 65 // Note that prev at this point refers to the parent logger. 66 JL.Logger.prototype = prev; 67 68 currentLogger = new JL.Logger(accumulatedLoggerName); 69 prev['__' + accumulatedLoggerName] = currentLogger; 70 } 71 72 return currentLogger; 73 }, JL.__); 74 75 return logger; 76} 77 78var JL; 79(function (JL) { 80 JL.enabled; 81 JL.maxMessages; 82 JL.defaultAjaxUrl; 83 JL.clientIP; 84 JL.defaultBeforeSend; 85 86 // Initialise requestId to empty string. If you don't do this and the user 87 // does not set it via setOptions, then the JSNLog-RequestId header will 88 // have value "undefined", which doesn't look good in a log. 89 // 90 // Note that you always want to send a requestId as part of log requests, 91 // otherwise the server side component doesn't know this is a log request 92 // and may create a new request id for the log request, causing confusion 93 // in the log. 94 JL.requestId = ''; 95 96 /** 97 Copies the value of a property from one object to the other. 98 This is used to copy property values as part of setOption for loggers and appenders. 99 100 Because loggers inherit property values from their parents, it is important never to 101 create a property on a logger if the intent is to inherit from the parent. 102 103 Copying rules: 104 1) if the from property is undefined (for example, not mentioned in a JSON object), the 105 to property is not affected at all. 106 2) if the from property is null, the to property is deleted (so the logger will inherit from 107 its parent). 108 3) Otherwise, the from property is copied to the to property. 109 */ 110 function copyProperty(propertyName, from, to) { 111 if (from[propertyName] === undefined) { 112 return; 113 } 114 if (from[propertyName] === null) { 115 delete to[propertyName]; 116 return; 117 } 118 to[propertyName] = from[propertyName]; 119 } 120 121 /** 122 Returns true if a log should go ahead. 123 Does not check level. 124 125 @param filters 126 Filters that determine whether a log can go ahead. 127 */ 128 function allow(filters) { 129 // If enabled is not null or undefined, then if it is false, then return false 130 // Note that undefined==null (!) 131 if (!(JL.enabled == null)) { 132 if (!JL.enabled) { 133 return false;
vendor: 10,242 bytes, lines 134-414
134 } 135 } 136 137 // If maxMessages is not null or undefined, then if it is 0, then return false. 138 // Note that maxMessages contains number of messages that are still allowed to send. 139 // It is decremented each time messages are sent. It can be negative when batch size > 1. 140 // Note that undefined==null (!) 141 if (!(JL.maxMessages == null)) { 142 if (JL.maxMessages < 1) { 143 return false; 144 } 145 } 146 147 try { 148 if (filters.userAgentRegex) { 149 if (!new RegExp(filters.userAgentRegex).test(navigator.userAgent)) { 150 return false; 151 } 152 } 153 } catch (e) { 154 } 155 156 try { 157 if (filters.ipRegex && JL.clientIP) { 158 if (!new RegExp(filters.ipRegex).test(JL.clientIP)) { 159 return false; 160 } 161 } 162 } catch (e) { 163 } 164 165 return true; 166 } 167 168 /** 169 Returns true if a log should go ahead, based on the message. 170 171 @param filters 172 Filters that determine whether a log can go ahead. 173 174 @param message 175 Message to be logged. 176 */ 177 function allowMessage(filters, message) { 178 try { 179 if (filters.disallow) { 180 if (new RegExp(filters.disallow).test(message)) { 181 return false; 182 } 183 } 184 } catch (e) { 185 } 186 187 return true; 188 } 189 190 // If logObject is a function, the function is evaluated (without parameters) 191 // and the result returned. 192 // Otherwise, logObject itself is returned. 193 function stringifyLogObjectFunction(logObject) { 194 if (typeof logObject == "function") { 195 if (logObject instanceof RegExp) { 196 return logObject.toString(); 197 } else { 198 return logObject(); 199 } 200 } 201 202 return logObject; 203 } 204 205 var StringifiedLogObject = (function () { 206 // * msg - 207 // if the logObject is a scalar (after possible function evaluation), this is set to 208 // string representing the scalar. Otherwise it is left undefined. 209 // * meta - 210 // if the logObject is an object (after possible function evaluation), this is set to 211 // that object. Otherwise it is left undefined. 212 // * finalString - 213 // This is set to the string representation of logObject (after possible function evaluation), 214 // regardless of whether it is an scalar or an object. An object is stringified to a JSON string. 215 // Note that you can't call this field "final", because as some point this was a reserved 216 // JavaScript keyword and using final trips up some minifiers. 217 function StringifiedLogObject(msg, meta, finalString) { 218 this.msg = msg; 219 this.meta = meta; 220 this.finalString = finalString; 221 } 222 return StringifiedLogObject; 223 })(); 224 225 // Takes a logObject, which can be 226 // * a scalar 227 // * an object 228 // * a parameterless function, which returns the scalar or object to log. 229 // Returns a stringifiedLogObject 230 function stringifyLogObject(logObject) { 231 // Note that this works if logObject is null. 232 // typeof null is object. 233 // JSON.stringify(null) returns "null". 234 var actualLogObject = stringifyLogObjectFunction(logObject); 235 var finalString; 236 237 switch (typeof actualLogObject) { 238 case "string": 239 return new StringifiedLogObject(actualLogObject, null, actualLogObject); 240 case "number": 241 finalString = actualLogObject.toString(); 242 return new StringifiedLogObject(finalString, null, finalString); 243 case "boolean": 244 finalString = actualLogObject.toString(); 245 return new StringifiedLogObject(finalString, null, finalString); 246 case "undefined": 247 return new StringifiedLogObject("undefined", null, "undefined"); 248 case "object": 249 if ((actualLogObject instanceof RegExp) || (actualLogObject instanceof String) || (actualLogObject instanceof Number) || (actualLogObject instanceof Boolean)) { 250 finalString = actualLogObject.toString(); 251 return new StringifiedLogObject(finalString, null, finalString); 252 } else { 253 return new StringifiedLogObject(null, actualLogObject, JSON.stringify(actualLogObject)); 254 } 255 default: 256 return new StringifiedLogObject("unknown", null, "unknown"); 257 } 258 } 259 260 function setOptions(options) { 261 copyProperty("enabled", options, this); 262 copyProperty("maxMessages", options, this); 263 copyProperty("defaultAjaxUrl", options, this); 264 copyProperty("clientIP", options, this); 265 copyProperty("requestId", options, this); 266 copyProperty("defaultBeforeSend", options, this); 267 return this; 268 } 269 JL.setOptions = setOptions; 270 271 function getAllLevel() { 272 return -2147483648; 273 } 274 JL.getAllLevel = getAllLevel; 275 function getTraceLevel() { 276 return 1000; 277 } 278 JL.getTraceLevel = getTraceLevel; 279 function getDebugLevel() { 280 return 2000; 281 } 282 JL.getDebugLevel = getDebugLevel; 283 function getInfoLevel() { 284 return 3000; 285 } 286 JL.getInfoLevel = getInfoLevel; 287 function getWarnLevel() { 288 return 4000; 289 } 290 JL.getWarnLevel = getWarnLevel; 291 function getErrorLevel() { 292 return 5000; 293 } 294 JL.getErrorLevel = getErrorLevel; 295 function getFatalLevel() { 296 return 6000; 297 } 298 JL.getFatalLevel = getFatalLevel; 299 function getOffLevel() { 300 return 2147483647; 301 } 302 JL.getOffLevel = getOffLevel; 303 304 function levelToString(level) { 305 if (level <= 1000) { 306 return "trace"; 307 } 308 if (level <= 2000) { 309 return "debug"; 310 } 311 if (level <= 3000) { 312 return "info"; 313 } 314 if (level <= 4000) { 315 return "warn"; 316 } 317 if (level <= 5000) { 318 return "error"; 319 } 320 return "fatal"; 321 } 322 323 // --------------------- 324 var Exception = (function () { 325 // data replaces message. It takes not just strings, but also objects and functions, just like the log function. 326 // internally, the string representation is stored in the message property (inherited from Error) 327 // 328 // inner: inner exception. Can be null or undefined. 329 function Exception(data, inner) { 330 this.inner = inner; 331 this.name = "JL.Exception"; 332 this.message = stringifyLogObject(data).finalString; 333 } 334 return Exception; 335 })(); 336 JL.Exception = Exception; 337 338 // Derive Exception from Error (a Host object), so browsers 339 // are more likely to produce a stack trace for it in their console. 340 // 341 // Note that instanceof against an object created with this constructor 342 // will return true in these cases: 343 // <object> instanceof JL.Exception); 344 // <object> instanceof Error); 345 Exception.prototype = new Error(); 346 347 // --------------------- 348 var LogItem = (function () { 349 // l: level 350 // m: message 351 // n: logger name 352 // t (timeStamp) is number of milliseconds since 1 January 1970 00:00:00 UTC 353 // 354 // Keeping the property names really short, because they will be sent in the 355 // JSON payload to the server. 356 function LogItem(l, m, n, t) { 357 this.l = l; 358 this.m = m; 359 this.n = n; 360 this.t = t; 361 } 362 return LogItem; 363 })(); 364 JL.LogItem = LogItem; 365 366 // --------------------- 367 var Appender = (function () { 368 // sendLogItems takes an array of log items. It will be called when 369 // the appender has items to process (such as, send to the server). 370 // Note that after sendLogItems returns, the appender may truncate 371 // the LogItem array, so the function has to copy the content of the array 372 // in some fashion (eg. serialize) before returning. 373 function Appender(appenderName, sendLogItems) { 374 this.appenderName = appenderName; 375 this.sendLogItems = sendLogItems; 376 this.level = JL.getTraceLevel(); 377 // set to super high level, so if user increases level, level is unlikely to get 378 // above sendWithBufferLevel 379 this.sendWithBufferLevel = 2147483647; 380 this.storeInBufferLevel = -2147483648; 381 this.bufferSize = 0; 382 this.batchSize = 1; 383 // Holds all log items with levels higher than storeInBufferLevel 384 // but lower than level. These items may never be sent. 385 this.buffer = []; 386 // Holds all items that we do want to send, until we have a full 387 // batch (as determined by batchSize). 388 this.batchBuffer = []; 389 } 390 Appender.prototype.setOptions = function (options) { 391 copyProperty("level", options, this); 392 copyProperty("ipRegex", options, this); 393 copyProperty("userAgentRegex", options, this); 394 copyProperty("disallow", options, this); 395 copyProperty("sendWithBufferLevel", options, this); 396 copyProperty("storeInBufferLevel", options, this); 397 copyProperty("bufferSize", options, this); 398 copyProperty("batchSize", options, this); 399 400 if (this.bufferSize < this.buffer.length) { 401 this.buffer.length = this.bufferSize; 402 } 403 404 return this; 405 }; 406 407 /** 408 Called by a logger to log a log item. 409 If in response to this call one or more log items need to be processed 410 (eg., sent to the server), this method calls this.sendLogItems 411 with an array with all items to be processed. 412 413 Note that the name and parameters of this function must match those of the log function of 414 a Winston transport object, so that users can use these transports as appenders.
415 That is why there are many parameters that are not actually used by this function. 416 417 level - string with the level ("trace", "debug", etc.) Only used by Winston transports. 418 msg - human readable message. Undefined if the log item is an object. Only used by Winston transports. 419 meta - log object. Always defined, because at least it contains the logger name. Only used by Winston transports. 420 callback - function that is called when the log item has been logged. Only used by Winston transports. 421 levelNbr - level as a number. Not used by Winston transports. 422 message - log item. If the user logged an object, this is the JSON string. Not used by Winston transports. 423 loggerName: name of the logger. Not used by Winston transports. 424 */ 425 Appender.prototype.log = function (level, msg, meta, callback, levelNbr, message, loggerName) { 426 var logItem; 427 428 if (!allow(this)) { 429 return; 430 } 431 if (!allowMessage(this, message)) { 432 return; 433 } 434 435 if (levelNbr < this.storeInBufferLevel) { 436 // Ignore the log item completely 437 return; 438 } 439 440 logItem = new LogItem(levelNbr, message, loggerName, (new Date).getTime()); 441 442 if (levelNbr < this.level) { 443 // Store in the hold buffer. Do not send. 444 if (this.bufferSize > 0) { 445 this.buffer.push(logItem); 446 447 // If we exceeded max buffer size, remove oldest item 448 if (this.buffer.length > this.bufferSize) { 449 this.buffer.shift(); 450 } 451 } 452 453 return; 454 } 455 456 if (levelNbr < this.sendWithBufferLevel) { 457 // Want to send the item, but not the contents of the buffer 458 this.batchBuffer.push(logItem); 459 } else { 460 // Want to send both the item and the contents of the buffer. 461 // Send contents of buffer first, because logically they happened first. 462 if (this.buffer.length) { 463 this.batchBuffer = this.batchBuffer.concat(this.buffer); 464 this.buffer.length = 0; 465 } 466 this.batchBuffer.push(logItem); 467 } 468 469 if (this.batchBuffer.length >= this.batchSize) { 470 this.sendBatch(); 471 return; 472 } 473 }; 474 475 // Processes the batch buffer 476 Appender.prototype.sendBatch = function () { 477 if (this.batchBuffer.length == 0) { 478 return; 479 } 480 481 if (!(JL.maxMessages == null)) { 482 if (JL.maxMessages < 1) { 483 return; 484 } 485 } 486 487 // If maxMessages is not null or undefined, then decrease it by the batch size. 488 // This can result in a negative maxMessages. 489 // Note that undefined==null (!) 490 if (!(JL.maxMessages == null)) { 491 JL.maxMessages -= this.batchBuffer.length; 492 } 493 494 this.sendLogItems(this.batchBuffer); 495 this.batchBuffer.length = 0; 496 }; 497 return Appender; 498 })(); 499 JL.Appender = Appender; 500 501 // --------------------- 502 var AjaxAppender = (function (_super) { 503 __extends(AjaxAppender, _super); 504 function AjaxAppender(appenderName) { 505 _super.call(this, appenderName, AjaxAppender.prototype.sendLogItemsAjax); 506 } 507 AjaxAppender.prototype.setOptions = function (options) { 508 copyProperty("url", options, this); 509 copyProperty("beforeSend", options, this); 510 _super.prototype.setOptions.call(this, options); 511 return this; 512 }; 513 514 AjaxAppender.prototype.sendLogItemsAjax = function (logItems) { 515 try { 516 // Only determine the url right before you send a log request. 517 // Do not set the url when constructing the appender. 518 // 519 // This is because the server side component sets defaultAjaxUrl 520 // in a call to setOptions, AFTER the JL object and the default appender 521 // have been created. 522 var ajaxUrl = "/jsnlog.logger.php"; 523 524 // This evaluates to true if defaultAjaxUrl is null or undefined 525 if (!(JL.defaultAjaxUrl == null)) { 526 ajaxUrl = JL.defaultAjaxUrl; 527 } 528 529 if (this.url) { 530 ajaxUrl = this.url; 531 } 532 533 // Send the json to the server. 534 // Note that there is no event handling here. If the send is not 535 // successful, nothing can be done about it. 536 var xhr = this.getXhr(ajaxUrl); 537 538 var json = { 539 r: JL.requestId, 540 lg: logItems 541 }; 542 543 // call beforeSend callback 544 // first try the callback on the appender 545 // then the global defaultBeforeSend callback 546 if (typeof this.beforeSend === 'function') {
547 this.beforeSend.call(this, xhr, json); 548 } else if (typeof JL.defaultBeforeSend === 'function') { 549 JL.defaultBeforeSend.call(this, xhr, json); 550 } 551 552 var finalmsg = JSON.stringify(json); 553 xhr.send(finalmsg); 554 } catch (e) { 555 } 556 }; 557 558 // Creates the Xhr object to use to send the log request. 559 // Sets out to create an Xhr object that can be used for CORS. 560 // However, if there seems to be no CORS support on the browser, 561 // returns a non-CORS capable Xhr. 562 AjaxAppender.prototype.getXhr = function (ajaxUrl) { 563 var xhr = new XMLHttpRequest(); 564 565 // Check whether this xhr is CORS capable by checking whether it has 566 // withCredentials. 567 // "withCredentials" only exists on XMLHTTPRequest2 objects. 568 if (!("withCredentials" in xhr)) { 569 // Just found that no XMLHttpRequest2 available. 570 // Check if XDomainRequest is available. 571 // This only exists in IE, and is IE's way of making CORS requests. 572 if (typeof XDomainRequest != "undefined") { 573 // Note that here we're not setting request headers on the XDomainRequest 574 // object. This is because this object doesn't let you do that: 575 // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx 576 // This means that for IE8 and IE9, CORS logging requests do not carry request ids. 577 var xdr = new XDomainRequest(); 578 xdr.open('POST', ajaxUrl); 579 return xdr; 580 } 581 } 582 583 // At this point, we're going with XMLHttpRequest, whether it is CORS capable or not. 584 // If it is not CORS capable, at least will handle the non-CORS requests. 585 xhr.open('POST', ajaxUrl); 586 xhr.setRequestHeader('Content-Type', 'application/json'); 587 xhr.setRequestHeader('JSNLog-RequestId', JL.requestId); 588 589 return xhr; 590 }; 591 return AjaxAppender; 592 })(Appender); 593 JL.AjaxAppender = AjaxAppender; 594 595 // --------------------- 596 var ConsoleAppender = (function (_super) { 597 __extends(ConsoleAppender, _super); 598 function ConsoleAppender(appenderName) {
599 _super.call(this, appenderName, ConsoleAppender.prototype.sendLogItemsConsole); 600 } 601 ConsoleAppender.prototype.clog = function (logEntry) { 602 console.log(logEntry); 603 }; 604 605 ConsoleAppender.prototype.cerror = function (logEntry) { 606 if (console.error) { 607 console.error(logEntry); 608 } else { 609 this.clog(logEntry); 610 } 611 }; 612 613 ConsoleAppender.prototype.cwarn = function (logEntry) { 614 if (console.warn) { 615 console.warn(logEntry); 616 } else { 617 this.clog(logEntry); 618 } 619 }; 620 621 ConsoleAppender.prototype.cinfo = function (logEntry) { 622 if (console.info) { 623 console.info(logEntry); 624 } else { 625 this.clog(logEntry); 626 } 627 }; 628 629 // IE11 has a console.debug function. But its console doesn't have 630 // the option to show/hide debug messages (the same way Chrome and FF do), 631 // even though it does have such buttons for Error, Warn, Info. 632 // 633 // For now, this means that debug messages can not be hidden on IE. 634 // Live with this, seeing that it works fine on FF and Chrome, which 635 // will be much more popular with developers.
vendor: 6,214 bytes, lines 636-798
636 ConsoleAppender.prototype.cdebug = function (logEntry) { 637 if (console.debug) { 638 console.debug(logEntry); 639 } else { 640 this.cinfo(logEntry); 641 } 642 }; 643 644 ConsoleAppender.prototype.sendLogItemsConsole = function (logItems) { 645 try { 646 if (!console) { 647 return; 648 } 649 650 var i; 651 for (i = 0; i < logItems.length; ++i) { 652 var li = logItems[i]; 653 var msg = li.n + ": " + li.m; 654 655 // Only log the timestamp if we're on the server 656 // (window is undefined). On the browser, the user 657 // sees the log entry probably immediately, so in that case 658 // the timestamp is clutter. 659 if (typeof window === 'undefined') { 660 msg = new Date(li.t) + " | " + msg; 661 } 662 663 if (li.l <= JL.getDebugLevel()) { 664 this.cdebug(msg); 665 } else if (li.l <= JL.getInfoLevel()) { 666 this.cinfo(msg); 667 } else if (li.l <= JL.getWarnLevel()) { 668 this.cwarn(msg); 669 } else { 670 this.cerror(msg); 671 } 672 } 673 } catch (e) { 674 } 675 }; 676 return ConsoleAppender; 677 })(Appender); 678 JL.ConsoleAppender = ConsoleAppender; 679 680 // -------------------- 681 var Logger = (function () { 682 function Logger(loggerName) { 683 this.loggerName = loggerName; 684 // Create seenRexes, otherwise this logger will use the seenRexes 685 // of its parent via the prototype chain. 686 this.seenRegexes = []; 687 } 688 Logger.prototype.setOptions = function (options) { 689 copyProperty("level", options, this); 690 copyProperty("userAgentRegex", options, this); 691 copyProperty("disallow", options, this); 692 copyProperty("ipRegex", options, this); 693 copyProperty("appenders", options, this); 694 copyProperty("onceOnly", options, this); 695 696 // Reset seenRegexes, in case onceOnly has been changed. 697 this.seenRegexes = []; 698 699 return this; 700 }; 701 702 // Turns an exception into an object that can be sent to the server. 703 Logger.prototype.buildExceptionObject = function (e) { 704 var excObject = {}; 705 706 if (e.stack) { 707 excObject.stack = e.stack; 708 } else { 709 excObject.e = e; 710 } 711 if (e.message) { 712 excObject.message = e.message; 713 } 714 if (e.name) { 715 excObject.name = e.name; 716 } 717 if (e.data) { 718 excObject.data = e.data; 719 } 720 if (e.inner) { 721 excObject.inner = this.buildExceptionObject(e.inner); 722 } 723 724 return excObject; 725 }; 726 727 // Logs a log item. 728 // Parameter e contains an exception (or null or undefined). 729 // 730 // Reason that processing exceptions is done at this low level is that 731 // 1) no need to spend the cpu cycles if the logger is switched off 732 // 2) fatalException takes both a logObject and an exception, and the logObject 733 // may be a function that should only be executed if the logger is switched on. 734 // 735 // If an exception is passed in, the contents of logObject is attached to the exception 736 // object in a new property logData. 737 // The resulting exception object is than worked into a message to the server. 738 // 739 // If there is no exception, logObject itself is worked into the message to the server. 740 Logger.prototype.log = function (level, logObject, e) { 741 var i = 0; 742 var compositeMessage; 743 var excObject; 744 745 // If we can't find any appenders, do nothing 746 if (!this.appenders) { 747 return this; 748 } 749 750 if (((level >= this.level)) && allow(this)) { 751 if (e) { 752 excObject = this.buildExceptionObject(e); 753 excObject.logData = stringifyLogObjectFunction(logObject); 754 } else { 755 excObject = logObject; 756 } 757 758 compositeMessage = stringifyLogObject(excObject); 759 760 if (allowMessage(this, compositeMessage.finalString)) { 761 // See whether message is a duplicate 762 if (this.onceOnly) { 763 i = this.onceOnly.length - 1; 764 while (i >= 0) { 765 if (new RegExp(this.onceOnly[i]).test(compositeMessage.finalString)) { 766 if (this.seenRegexes[i]) { 767 return this; 768 } 769 770 this.seenRegexes[i] = true; 771 } 772 773 i--; 774 } 775 } 776 777 // Pass message to all appenders 778 // Note that these appenders could be Winston transports 779 // https://github.com/flatiron/winston 780 // 781 // These transports do not take the logger name as a parameter. 782 // So add it to the meta information, so even Winston transports will 783 // store this info. 784 compositeMessage.meta = compositeMessage.meta || {}; 785 compositeMessage.meta.loggerName = this.loggerName; 786 787 i = this.appenders.length - 1; 788 while (i >= 0) { 789 this.appenders[i].log(levelToString(level), compositeMessage.msg, compositeMessage.meta, function () { 790 }, level, compositeMessage.finalString, this.loggerName); 791 i--; 792 } 793 } 794 } 795 796 return this; 797 }; 798
799 Logger.prototype.trace = function (logObject) { 800 return this.log(getTraceLevel(), logObject); 801 }; 802 Logger.prototype.debug = function (logObject) { 803 return this.log(getDebugLevel(), logObject); 804 }; 805 Logger.prototype.info = function (logObject) { 806 return this.log(getInfoLevel(), logObject); 807 }; 808 Logger.prototype.warn = function (logObject) { 809 return this.log(getWarnLevel(), logObject); 810 }; 811 Logger.prototype.error = function (logObject) { 812 return this.log(getErrorLevel(), logObject); 813 }; 814 Logger.prototype.fatal = function (logObject) { 815 return this.log(getFatalLevel(), logObject); 816 }; 817 Logger.prototype.fatalException = function (logObject, e) { 818 return this.log(getFatalLevel(), logObject, e); 819 }; 820 return Logger; 821 })(); 822 JL.Logger = Logger; 823 824 function createAjaxAppender(appenderName) { 825 return new AjaxAppender(appenderName); 826 } 827 JL.createAjaxAppender = createAjaxAppender; 828 829 function createConsoleAppender(appenderName) { 830 return new ConsoleAppender(appenderName); 831 } 832 JL.createConsoleAppender = createConsoleAppender; 833 834 // ----------------------- 835 // In the browser, the default appender is the AjaxAppender. 836 // Under nodejs (where there is no "window"), use the ConsoleAp
836pender instead. 837 var defaultAppender = new AjaxAppender(""); 838 if (typeof window === 'undefined') { 839 defaultAppender = new ConsoleAppender(""); 840 } 841 842 // Create root logger 843 // 844 // Note that this is the parent of all other loggers. 845 // Logger "x" will be stored at 846 // JL.__.x 847 // Logger "x.y" at 848 // JL.__.x.y 849 JL.__ = new JL.Logger(""); 850 JL.__.setOptions({ 851 level: JL.getDebugLevel(), 852 appenders: [defaultAppender] 853 }); 854})(JL || (JL = {})); 855 856if (typeof exports !== 'undefined') { 857 exports.JL = JL; 858} 859 860// Support AMD module format 861var define; 862if (typeof define == 'function' && define.amd) { 863 define('jsnlog', [], function () { 864 return JL; 865 }); 866} 867 868// If the __jsnlog_configure global function has been 869// created, call it now. This allows you to create a global function 870// setting logger options etc. inline in the page before jsnlog.js 871// has been loaded. 872if (typeof __jsnlog_configure == 'function') { 873 __jsnlog_configure(JL); 874} 875//# sourceMappingURL=jsnlog.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.