logbuffer.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2010 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview A buffer for log records. The purpose of this is to improve
  16. * logging performance by re-using old objects when the buffer becomes full and
  17. * to eliminate the need for each app to implement their own log buffer. The
  18. * disadvantage to doing this is that log handlers cannot maintain references to
  19. * log records and expect that they are not overwriten at a later point.
  20. *
  21. * @author agrieve@google.com (Andrew Grieve)
  22. */
  23. goog.provide('goog.debug.LogBuffer');
  24. goog.require('goog.asserts');
  25. goog.require('goog.debug.LogRecord');
  26. /**
  27. * Creates the log buffer.
  28. * @constructor
  29. * @final
  30. */
  31. goog.debug.LogBuffer = function() {
  32. goog.asserts.assert(
  33. goog.debug.LogBuffer.isBufferingEnabled(),
  34. 'Cannot use goog.debug.LogBuffer without defining ' +
  35. 'goog.debug.LogBuffer.CAPACITY.');
  36. this.clear();
  37. };
  38. /**
  39. * A static method that always returns the same instance of LogBuffer.
  40. * @return {!goog.debug.LogBuffer} The LogBuffer singleton instance.
  41. */
  42. goog.debug.LogBuffer.getInstance = function() {
  43. if (!goog.debug.LogBuffer.instance_) {
  44. // This function is written with the return statement after the assignment
  45. // to avoid the jscompiler StripCode bug described in http://b/2608064.
  46. // After that bug is fixed this can be refactored.
  47. goog.debug.LogBuffer.instance_ = new goog.debug.LogBuffer();
  48. }
  49. return goog.debug.LogBuffer.instance_;
  50. };
  51. /**
  52. * @define {number} The number of log records to buffer. 0 means disable
  53. * buffering.
  54. */
  55. goog.define('goog.debug.LogBuffer.CAPACITY', 0);
  56. /**
  57. * The array to store the records.
  58. * @type {!Array<!goog.debug.LogRecord|undefined>}
  59. * @private
  60. */
  61. goog.debug.LogBuffer.prototype.buffer_;
  62. /**
  63. * The index of the most recently added record or -1 if there are no records.
  64. * @type {number}
  65. * @private
  66. */
  67. goog.debug.LogBuffer.prototype.curIndex_;
  68. /**
  69. * Whether the buffer is at capacity.
  70. * @type {boolean}
  71. * @private
  72. */
  73. goog.debug.LogBuffer.prototype.isFull_;
  74. /**
  75. * Adds a log record to the buffer, possibly overwriting the oldest record.
  76. * @param {goog.debug.Logger.Level} level One of the level identifiers.
  77. * @param {string} msg The string message.
  78. * @param {string} loggerName The name of the source logger.
  79. * @return {!goog.debug.LogRecord} The log record.
  80. */
  81. goog.debug.LogBuffer.prototype.addRecord = function(level, msg, loggerName) {
  82. var curIndex = (this.curIndex_ + 1) % goog.debug.LogBuffer.CAPACITY;
  83. this.curIndex_ = curIndex;
  84. if (this.isFull_) {
  85. var ret = this.buffer_[curIndex];
  86. ret.reset(level, msg, loggerName);
  87. return ret;
  88. }
  89. this.isFull_ = curIndex == goog.debug.LogBuffer.CAPACITY - 1;
  90. return this.buffer_[curIndex] =
  91. new goog.debug.LogRecord(level, msg, loggerName);
  92. };
  93. /**
  94. * @return {boolean} Whether the log buffer is enabled.
  95. */
  96. goog.debug.LogBuffer.isBufferingEnabled = function() {
  97. return goog.debug.LogBuffer.CAPACITY > 0;
  98. };
  99. /**
  100. * Removes all buffered log records.
  101. */
  102. goog.debug.LogBuffer.prototype.clear = function() {
  103. this.buffer_ = new Array(goog.debug.LogBuffer.CAPACITY);
  104. this.curIndex_ = -1;
  105. this.isFull_ = false;
  106. };
  107. /**
  108. * Calls the given function for each buffered log record, starting with the
  109. * oldest one.
  110. * @param {function(!goog.debug.LogRecord)} func The function to call.
  111. */
  112. goog.debug.LogBuffer.prototype.forEachRecord = function(func) {
  113. var buffer = this.buffer_;
  114. // Corner case: no records.
  115. if (!buffer[0]) {
  116. return;
  117. }
  118. var curIndex = this.curIndex_;
  119. var i = this.isFull_ ? curIndex : -1;
  120. do {
  121. i = (i + 1) % goog.debug.LogBuffer.CAPACITY;
  122. func(/** @type {!goog.debug.LogRecord} */ (buffer[i]));
  123. } while (i != curIndex);
  124. };