powertools-lambda-typescript
powertools-lambda-typescript copied to clipboard
Feature request: Provide ability to refernce and modify Log Level Numerical Thresholds
Use case
Currently our logging standard has both the numerical and string representations of the Log Level. The usage of both allow us to have increased efficiency when retrieving or searching logs from storage.
Indexing the numerical value is more efficient that its string counterpart.
{
level: 'INFO',
level_index: 12,
}
Currently it is difficult to directly access the prescribed log levels when extending the Logger class or utilizing a custom log format.
Some of the workarounds include:
- Extending
UnformattedAttributes
to include the LogLevel Numerical Value (Works but adds another custom interface I then need to manage) - Manually mapping LogLevel (str) to its corresponding numerical value (Works but extra code is required)
- With TS, this also means that we also have to force uppercase matching (Less LOC than a switch) since
LogLevel
used inUnformattedAttributes
allows for upper and lowercase values.' - Since one cannot directly access the perscribed LogLevel thresholds, one must copy it manually and later update it should it change.
- With TS, this also means that we also have to force uppercase matching (Less LOC than a switch) since
class CustomLogFormatter extends LogFormatter {
private getLogLevelNumberFromName(level: LogLevel): number {
let found = 0;
for (const [key, value] of Object.entries({
DEBUG: 8,
INFO: 12,
WARN: 16,
ERROR: 20,
CRITICAL: 24,
SILENT: 28,
})) {
if (key.toUpperCase() === level) {
found = value;
break;
}
}
return found;
}
override formatAttributes(
attributes: UnformattedAttributes,
additionalLogAttributes: LogAttributes
): LogItem {
const baseAttributes = {
timestamp: this.formatTimestamp(new Date()),
level: attributes.logLevel.toUpperCase(),
level_index: this.getLogLevelNumberFromName(attributes.logLevel),
//........
If I am missing something evident please let me know. I would be happy to open an PR for this.
Solution/User Experience
Ideal Solutions:
-
logLevelThresholds
changed fromprivate
toprotected
OR utilize a "getter" - Add an additional property to
UnformattedAttributes
orPowertoolsLogData
that represents the numerical LogLevel.
This way the numerical log level is easily passed to any Custom log Formatter instead of having to map it using LogAttributes
or some other workaround.
Adding this in the other libraries would be beneficial as well!
//Open to feedback on the prop name
type PowertoolsLogData = LogAttributes & {
environment?: Environment;
serviceName: string;
sampleRateValue: number;
lambdaContext?: LambdaFunctionContext;
xRayTraceId?: string;
awsRegion: string;
logLevelIndex?: number; //OPTION #1
};
type UnformattedAttributes = PowertoolsLogData & {
error?: Error;
logLevel: LogLevel;
logLevelIndex: number; //OPTION #2
timestamp: Date;
message: string;
};
Alternative solutions
Creating a helper function in a Custom Log Formatter to map the string LogLevel to its numerical counterpart.
class CustomLogFormatter extends LogFormatter {
private getLogLevelNumberFromName(level: LogLevel): number {
let found;
for (const [key, value] of Object.entries({
DEBUG: 8,
INFO: 12,
WARN: 16,
ERROR: 20,
CRITICAL: 24,
SILENT: 28,
})) {
if (key.toUpperCase() === level) {
found = value;
break;
}
}
return found ?? 0;
}
override formatAttributes(
attributes: UnformattedAttributes,
additionalLogAttributes: LogAttributes
): LogItem {
const baseAttributes = {
timestamp: this.formatTimestamp(new Date()),
level: attributes.logLevel.toUpperCase(),
level_index: this.getLogLevelNumberFromName(attributes.logLevel),
//........
Acknowledgment
- [X] This feature request meets Powertools for AWS Lambda (TypeScript) Tenets
- [X] Should this be considered in other Powertools for AWS Lambda languages? i.e. Python, Java, and .NET
Future readers
Please react with 👍 and your use case to help us understand customer demand.