@aws-lambda-powertools/logger
Version:
The logging package for the Powertools for AWS Lambda (TypeScript) library
117 lines (116 loc) • 3.16 kB
JavaScript
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;
}
}
}