UNPKG

@aws-lambda-powertools/logger

Version:
117 lines (116 loc) 3.16 kB
import { isString } from '@aws-lambda-powertools/commons/typeutils'; /** * A data structure that holds a value and its byte size. * * @internal */ export class SizedItem { value; logLevel; byteSize; constructor(value, logLevel) { if (!isString(value)) { throw new Error('Value should be a string'); } this.value = value; this.logLevel = logLevel; this.byteSize = Buffer.byteLength(value); } } /** * A set that tracks its current byte size. * * @internal */ export class SizedSet extends Set { currentBytesSize = 0; hasEvictedLog = false; /** * Adds an item to the set and updates the current byte size. * * @param item - The item to add */ add(item) { this.currentBytesSize += item.byteSize; super.add(item); return this; } /** * Deletes an item from the set and updates the current byte size. * * @param item - The item to delete */ delete(item) { const wasDeleted = super.delete(item); if (wasDeleted) { this.currentBytesSize -= item.byteSize; } return wasDeleted; } /** * Clears all items from the set and resets the current byte size. */ clear() { super.clear(); this.currentBytesSize = 0; } /** * Removes the first item from the set and returns it. */ shift() { const firstElement = this.values().next().value; if (firstElement) { this.delete(firstElement); } return firstElement; } } /** * A ring buffer that stores logs in a circular manner. * * @internal */ export class CircularMap extends Map { #maxBytesSize; #onBufferOverflow; constructor({ maxBytesSize, onBufferOverflow, }) { super(); this.#maxBytesSize = maxBytesSize; this.#onBufferOverflow = onBufferOverflow; } /** * Adds an item to the buffer, evicting older items if necessary. * * @param key - The key to associate with the item * @param value - The item to add * @param logLevel - The log level of the item */ setItem(key, value, logLevel) { const item = new SizedItem(value, logLevel); if (item.byteSize > this.#maxBytesSize) { throw new Error('Item too big'); } const buffer = this.get(key) || new SizedSet(); if (buffer.currentBytesSize + item.byteSize >= this.#maxBytesSize) { this.#deleteFromBufferUntilSizeIsLessThanMax(buffer, item); if (this.#onBufferOverflow) { this.#onBufferOverflow(); } } buffer.add(item); super.set(key, buffer); return this; } /** * Deletes an item from the buffer. * * @param key - The key associated with the item * @param value - The item to delete */ #deleteFromBufferUntilSizeIsLessThanMax(buffer, item) { while (buffer.currentBytesSize + item.byteSize >= this.#maxBytesSize) { buffer.shift(); buffer.hasEvictedLog = true; } } }