From 13e37800ecb5fe3c8374801f72a09e942d6ee8a9 Mon Sep 17 00:00:00 2001 From: Sergei Cherniaev Date: Tue, 28 Feb 2023 17:58:30 +0400 Subject: [PATCH 1/5] feat(logger): add silent log level to suppress the emission of all logs --- docs/core/logger.md | 2 +- packages/logger/src/Logger.ts | 1 + packages/logger/src/types/Log.ts | 3 +- packages/logger/tests/unit/Logger.test.ts | 165 +++++++++++++-------- packages/logger/tests/unit/helpers.test.ts | 24 ++- 5 files changed, 116 insertions(+), 79 deletions(-) diff --git a/docs/core/logger.md b/docs/core/logger.md index fb25804135..8d6078cb5c 100644 --- a/docs/core/logger.md +++ b/docs/core/logger.md @@ -49,7 +49,7 @@ These settings will be used across all logs emitted: | Setting | Description | Environment variable | Default Value | Allowed Values | Example Value | Constructor parameter | |-------------------------|------------------------------------------------------------------------------------------------------------------|---------------------------------|---------------------|--------------------------------|--------------------|-----------------------| | **Service name** | Sets the name of service of which the Lambda function is part of, that will be present across all log statements | `POWERTOOLS_SERVICE_NAME` | `service_undefined` | Any string | `serverlessAirline`| `serviceName` | -| **Logging level** | Sets how verbose Logger should be | `LOG_LEVEL` | `info` |`DEBUG`, `INFO`, `WARN`, `ERROR`| `ERROR` | `logLevel` | +| **Logging level** | Sets how verbose Logger should be | `LOG_LEVEL` | `info` |`DEBUG`, `INFO`, `WARN`, `ERROR`, `SILENT` | `ERROR` | `logLevel` | | **Log incoming event** | Whether to log or not the incoming event when using the decorator or middleware. | `POWERTOOLS_LOGGER_LOG_EVENT` | `false` | `true`, `false` | `false` | `logEvent` | | **Debug log sampling** | Probability that a Lambda invocation will print all the log items regardless of the log level setting. | `POWERTOOLS_LOGGER_SAMPLE_RATE` | `0` | `0.0` to `1` | `0.5` | `sampleRateValue` | diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index 663ce2bd37..dea7cc0d48 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -135,6 +135,7 @@ class Logger extends Utility implements ClassThatLogs { INFO: 12, WARN: 16, ERROR: 20, + SILENT: 24, }; private logsSampled: boolean = false; diff --git a/packages/logger/src/types/Log.ts b/packages/logger/src/types/Log.ts index 020b9cf200..15042910e5 100644 --- a/packages/logger/src/types/Log.ts +++ b/packages/logger/src/types/Log.ts @@ -2,8 +2,9 @@ type LogLevelDebug = 'DEBUG'; type LogLevelInfo = 'INFO'; type LogLevelWarn = 'WARN'; type LogLevelError = 'ERROR'; +type LogLevelSilent = 'SILENT'; -type LogLevel = LogLevelDebug | Lowercase | LogLevelInfo | Lowercase | LogLevelWarn | Lowercase | LogLevelError | Lowercase; +type LogLevel = LogLevelDebug | Lowercase | LogLevelInfo | Lowercase | LogLevelWarn | Lowercase | LogLevelError | Lowercase | LogLevelSilent | Lowercase; type LogLevelThresholds = { [key in Uppercase]: number; diff --git a/packages/logger/tests/unit/Logger.test.ts b/packages/logger/tests/unit/Logger.test.ts index eedb348c81..886d4db160 100644 --- a/packages/logger/tests/unit/Logger.test.ts +++ b/packages/logger/tests/unit/Logger.test.ts @@ -10,7 +10,7 @@ import { import { createLogger, Logger } from '../../src'; import { EnvironmentVariablesService } from '../../src/config'; import { PowertoolLogFormatter } from '../../src/formatter'; -import { ClassThatLogs, LogJsonIndent, ConstructorOptions } from '../../src/types'; +import { ClassThatLogs, LogJsonIndent, ConstructorOptions, LogLevelThresholds } from '../../src/types'; import { Context } from 'aws-lambda'; import { Console } from 'console'; @@ -22,6 +22,13 @@ describe('Class: Logger', () => { const ENVIRONMENT_VARIABLES = process.env; const context = dummyContext.helloworldContext; const event = dummyEvent.Custom.CustomEvent; + const logLevelThresholds: LogLevelThresholds = { + DEBUG: 8, + INFO: 12, + WARN: 16, + ERROR: 20, + SILENT: 24, + }; beforeEach(() => { dateSpy.mockClear(); @@ -60,9 +67,7 @@ describe('Class: Logger', () => { const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); // Act - if (logger[methodOfLogger]) { - logger[methodOfLogger]('foo'); - } + logger[methodOfLogger]('foo'); // Assess expect(consoleSpy).toBeCalledTimes(debugPrints ? 1 : 0); @@ -87,9 +92,7 @@ describe('Class: Logger', () => { const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); // Act - if (logger[methodOfLogger]) { - logger[methodOfLogger]('foo'); - } + logger[methodOfLogger]('foo'); // Assess expect(consoleSpy).toBeCalledTimes(infoPrints ? 1 : 0); @@ -114,9 +117,7 @@ describe('Class: Logger', () => { const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); // Act - if (logger[methodOfLogger]) { - logger[methodOfLogger]('foo'); - } + logger[methodOfLogger]('foo'); // Assess expect(consoleSpy).toBeCalledTimes(warnPrints ? 1 : 0); @@ -141,9 +142,7 @@ describe('Class: Logger', () => { const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); // Act - if (logger[methodOfLogger]) { - logger[methodOfLogger]('foo'); - } + logger[methodOfLogger]('foo'); // Assess expect(consoleSpy).toBeCalledTimes(errorPrints ? 1 : 0); @@ -159,6 +158,41 @@ describe('Class: Logger', () => { }); + test('when the Logger\'s log level is SILENT, it DOES NOT print to stdout', () => { + + // Prepare + const logger: Logger = createLogger({ + logLevel: 'SILENT', + }); + const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); + + // Act + logger[methodOfLogger]('foo'); + + // Assess + expect(consoleSpy).toBeCalledTimes(0); + }); + + test('when the Logger\'s log level is set through LOG_LEVEL env variable, it should print to stdout', () => { + + // Prepare + process.env.LOG_LEVEL = methodOfLogger.toUpperCase(); + const logger = new Logger(); + const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); + + // Act + logger[methodOfLogger]('foo'); + + // Assess + expect(consoleSpy).toBeCalledTimes(1); + expect(consoleSpy).toHaveBeenNthCalledWith(1, JSON.stringify({ + level: methodOfLogger.toUpperCase(), + message: 'foo', + service: 'hello-world', + timestamp: '2016-06-20T12:08:10.000Z', + xray_trace_id: '1-5759e988-bd862e3fe1be46a994272793', + })); + }); }); describe('Feature: sample rate', () => { @@ -169,7 +203,7 @@ describe('Class: Logger', () => { // Prepare const logger: Logger = createLogger({ - logLevel: 'ERROR', + logLevel: 'SILENT', sampleRateValue: 0, }); const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); @@ -180,14 +214,14 @@ describe('Class: Logger', () => { } // Assess - expect(consoleSpy).toBeCalledTimes(method === 'error' ? 1 : 0); + expect(consoleSpy).toBeCalledTimes(0); }); test('when the Logger\'s log level is higher and the current Lambda invocation IS sampled for logging, it DOES print to stdout', () => { // Prepare const logger: Logger = createLogger({ - logLevel: 'ERROR', + logLevel: 'SILENT', sampleRateValue: 1, }); const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); @@ -630,10 +664,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: {}, @@ -1396,10 +1427,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: {}, @@ -1422,10 +1450,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: true, persistentLogAttributes: {}, @@ -1448,10 +1473,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: true, persistentLogAttributes: {}, @@ -1512,10 +1534,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: {}, @@ -1538,10 +1557,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: { @@ -1566,10 +1582,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: true, persistentLogAttributes: {}, @@ -1592,10 +1605,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'ERROR', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: {}, @@ -1641,10 +1651,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: {}, @@ -1667,10 +1674,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: { @@ -1700,10 +1704,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: { @@ -1746,10 +1747,7 @@ describe('Class: Logger', () => { logFormatter: expect.any(PowertoolLogFormatter), logLevel: 'DEBUG', logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: {}, @@ -1981,4 +1979,43 @@ describe('Class: Logger', () => { }); + // // methods.each + // describe.each([ + // [ 'debug', 'DOES', true, 'DOES NOT', false, 'DOES NOT', false, 'DOES NOT', false ], + // [ 'info', 'DOES', true, 'DOES', true, 'DOES NOT', false, 'DOES NOT', false ], + // [ 'warn', 'DOES', true, 'DOES', true, 'DOES', true, 'DOES NOT', false ], + // [ 'error', 'DOES', true, 'DOES', true, 'DOES', true, 'DOES', true ], + // ])( + // 'Method: %p', + // ( + // method: string, + // ) => { + + // const methodOfLogger = method as keyof ClassThatLogs; + + // describe(`Method: ${method}`, () => { + // test(`it SILENT MODE in ${method}`, () => { + // // Prepare + // const logger: Logger = createLogger({ + // logLevel: 'SILENT', + // }); + + // const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); + + // // Act + // logger[methodOfLogger]('foo'); + + // // Assess + // expect(consoleSpy).toBeCalledTimes(0); + // // expect(consoleSpy).toHaveBeenNthCalledWith(1, JSON.stringify({ + // // level: "INFO", + // // message: 'foo', + // // service: 'hello-world', + // // timestamp: '2016-06-20T12:08:10.000Z', + // // xray_trace_id: '1-5759e988-bd862e3fe1be46a994272793', + // // })); + +// }); +// }); +// }); }); diff --git a/packages/logger/tests/unit/helpers.test.ts b/packages/logger/tests/unit/helpers.test.ts index 31842614fb..7da1226802 100644 --- a/packages/logger/tests/unit/helpers.test.ts +++ b/packages/logger/tests/unit/helpers.test.ts @@ -6,12 +6,19 @@ import { Console } from 'console'; import { ConfigServiceInterface, EnvironmentVariablesService } from '../../src/config'; import { LogFormatter, PowertoolLogFormatter } from '../../src/formatter'; -import { ConstructorOptions } from '../../src/types'; +import { ConstructorOptions, LogLevelThresholds } from '../../src/types'; import { createLogger, Logger } from './../../src'; describe('Helper: createLogger function', () => { const ENVIRONMENT_VARIABLES = process.env; + const logLevelThresholds: LogLevelThresholds = { + DEBUG: 8, + INFO: 12, + WARN: 16, + ERROR: 20, + SILENT: 24, + }; beforeEach(() => { jest.resetModules(); @@ -83,10 +90,7 @@ describe('Helper: createLogger function', () => { logLevel: 'WARN', console: expect.any(Console), logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: true, persistentLogAttributes: { @@ -125,10 +129,7 @@ describe('Helper: createLogger function', () => { logLevel: 'INFO', console: expect.any(Console), logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: {}, @@ -279,10 +280,7 @@ describe('Helper: createLogger function', () => { logLevel: 'INFO', console: expect.any(Console), logLevelThresholds: { - DEBUG: 8, - ERROR: 20, - INFO: 12, - WARN: 16, + ...logLevelThresholds }, logsSampled: false, persistentLogAttributes: {}, From c45b21aa6e9efceb53503cfe14a76e42bf75d8f6 Mon Sep 17 00:00:00 2001 From: Sergei Cherniaev Date: Tue, 28 Feb 2023 18:22:20 +0400 Subject: [PATCH 2/5] test: cleanup --- packages/logger/tests/unit/Logger.test.ts | 40 ----------------------- 1 file changed, 40 deletions(-) diff --git a/packages/logger/tests/unit/Logger.test.ts b/packages/logger/tests/unit/Logger.test.ts index 886d4db160..65b07c9fce 100644 --- a/packages/logger/tests/unit/Logger.test.ts +++ b/packages/logger/tests/unit/Logger.test.ts @@ -1978,44 +1978,4 @@ describe('Class: Logger', () => { }); }); - - // // methods.each - // describe.each([ - // [ 'debug', 'DOES', true, 'DOES NOT', false, 'DOES NOT', false, 'DOES NOT', false ], - // [ 'info', 'DOES', true, 'DOES', true, 'DOES NOT', false, 'DOES NOT', false ], - // [ 'warn', 'DOES', true, 'DOES', true, 'DOES', true, 'DOES NOT', false ], - // [ 'error', 'DOES', true, 'DOES', true, 'DOES', true, 'DOES', true ], - // ])( - // 'Method: %p', - // ( - // method: string, - // ) => { - - // const methodOfLogger = method as keyof ClassThatLogs; - - // describe(`Method: ${method}`, () => { - // test(`it SILENT MODE in ${method}`, () => { - // // Prepare - // const logger: Logger = createLogger({ - // logLevel: 'SILENT', - // }); - - // const consoleSpy = jest.spyOn(logger['console'], methodOfLogger).mockImplementation(); - - // // Act - // logger[methodOfLogger]('foo'); - - // // Assess - // expect(consoleSpy).toBeCalledTimes(0); - // // expect(consoleSpy).toHaveBeenNthCalledWith(1, JSON.stringify({ - // // level: "INFO", - // // message: 'foo', - // // service: 'hello-world', - // // timestamp: '2016-06-20T12:08:10.000Z', - // // xray_trace_id: '1-5759e988-bd862e3fe1be46a994272793', - // // })); - -// }); -// }); -// }); }); From 697d7853ae5144d5d6cec0f3c8426e1133bb804c Mon Sep 17 00:00:00 2001 From: Sergei Cherniaev Date: Wed, 1 Mar 2023 09:51:26 +0400 Subject: [PATCH 3/5] docs(logger): update text and formatting, add comments --- docs/core/logger.md | 6 +++--- packages/logger/src/Logger.ts | 1 + packages/logger/tests/unit/Logger.test.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/core/logger.md b/docs/core/logger.md index 8d6078cb5c..5c4d0a610e 100644 --- a/docs/core/logger.md +++ b/docs/core/logger.md @@ -49,9 +49,9 @@ These settings will be used across all logs emitted: | Setting | Description | Environment variable | Default Value | Allowed Values | Example Value | Constructor parameter | |-------------------------|------------------------------------------------------------------------------------------------------------------|---------------------------------|---------------------|--------------------------------|--------------------|-----------------------| | **Service name** | Sets the name of service of which the Lambda function is part of, that will be present across all log statements | `POWERTOOLS_SERVICE_NAME` | `service_undefined` | Any string | `serverlessAirline`| `serviceName` | -| **Logging level** | Sets how verbose Logger should be | `LOG_LEVEL` | `info` |`DEBUG`, `INFO`, `WARN`, `ERROR`, `SILENT` | `ERROR` | `logLevel` | -| **Log incoming event** | Whether to log or not the incoming event when using the decorator or middleware. | `POWERTOOLS_LOGGER_LOG_EVENT` | `false` | `true`, `false` | `false` | `logEvent` | -| **Debug log sampling** | Probability that a Lambda invocation will print all the log items regardless of the log level setting. | `POWERTOOLS_LOGGER_SAMPLE_RATE` | `0` | `0.0` to `1` | `0.5` | `sampleRateValue` | +| **Logging level** | Sets how verbose Logger should be, from the most verbose to the least verbose (no logs) | `LOG_LEVEL` | `info` |`DEBUG`, `INFO`, `WARN`, `ERROR`, `SILENT` | `ERROR` | `logLevel` | +| **Log incoming event** | Whether to log or not the incoming event when using the decorator or middleware | `POWERTOOLS_LOGGER_LOG_EVENT` | `false` | `true`, `false` | `false` | `logEvent` | +| **Debug log sampling** | Probability that a Lambda invocation will print all the log items regardless of the log level setting | `POWERTOOLS_LOGGER_SAMPLE_RATE` | `0` | `0.0` to `1` | `0.5` | `sampleRateValue` | #### Example using AWS Serverless Application Model (SAM) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index dea7cc0d48..13f80db3ed 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -130,6 +130,7 @@ class Logger extends Utility implements ClassThatLogs { private logLevel?: Uppercase; + // Log levels are in ascending order from the most verbose to the least verbose (no logs) private readonly logLevelThresholds: LogLevelThresholds = { DEBUG: 8, INFO: 12, diff --git a/packages/logger/tests/unit/Logger.test.ts b/packages/logger/tests/unit/Logger.test.ts index 65b07c9fce..026e2ccb20 100644 --- a/packages/logger/tests/unit/Logger.test.ts +++ b/packages/logger/tests/unit/Logger.test.ts @@ -173,7 +173,7 @@ describe('Class: Logger', () => { expect(consoleSpy).toBeCalledTimes(0); }); - test('when the Logger\'s log level is set through LOG_LEVEL env variable, it should print to stdout', () => { + test('when the Logger\'s log level is set through LOG_LEVEL env variable, it DOES print to stdout', () => { // Prepare process.env.LOG_LEVEL = methodOfLogger.toUpperCase(); From b9ce817a482db67f3ea0db1cabe0941cd5cf7beb Mon Sep 17 00:00:00 2001 From: Sergei Cherniaev Date: Wed, 1 Mar 2023 13:39:21 +0400 Subject: [PATCH 4/5] docs(logger): update table formatting --- docs/core/logger.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/core/logger.md b/docs/core/logger.md index 5c4d0a610e..f44265c572 100644 --- a/docs/core/logger.md +++ b/docs/core/logger.md @@ -46,12 +46,12 @@ The library requires two settings. You can set them as environment variables, or These settings will be used across all logs emitted: -| Setting | Description | Environment variable | Default Value | Allowed Values | Example Value | Constructor parameter | -|-------------------------|------------------------------------------------------------------------------------------------------------------|---------------------------------|---------------------|--------------------------------|--------------------|-----------------------| -| **Service name** | Sets the name of service of which the Lambda function is part of, that will be present across all log statements | `POWERTOOLS_SERVICE_NAME` | `service_undefined` | Any string | `serverlessAirline`| `serviceName` | -| **Logging level** | Sets how verbose Logger should be, from the most verbose to the least verbose (no logs) | `LOG_LEVEL` | `info` |`DEBUG`, `INFO`, `WARN`, `ERROR`, `SILENT` | `ERROR` | `logLevel` | -| **Log incoming event** | Whether to log or not the incoming event when using the decorator or middleware | `POWERTOOLS_LOGGER_LOG_EVENT` | `false` | `true`, `false` | `false` | `logEvent` | -| **Debug log sampling** | Probability that a Lambda invocation will print all the log items regardless of the log level setting | `POWERTOOLS_LOGGER_SAMPLE_RATE` | `0` | `0.0` to `1` | `0.5` | `sampleRateValue` | +| Setting | Description | Environment variable | Default Value | Allowed Values | Example Value | Constructor parameter | +|-------------------------|------------------------------------------------------------------------------------------------------------------|---------------------------------|---------------------|-------------------------------------------|--------------------|-----------------------| +| **Service name** | Sets the name of service of which the Lambda function is part of, that will be present across all log statements | `POWERTOOLS_SERVICE_NAME` | `service_undefined` | Any string | `serverlessAirline`| `serviceName` | +| **Logging level** | Sets how verbose Logger should be, from the most verbose to the least verbose (no logs) | `LOG_LEVEL` | `info` |`DEBUG`, `INFO`, `WARN`, `ERROR`, `SILENT` | `ERROR` | `logLevel` | +| **Log incoming event** | Whether to log or not the incoming event when using the decorator or middleware | `POWERTOOLS_LOGGER_LOG_EVENT` | `false` | `true`, `false` | `false` | `logEvent` | +| **Debug log sampling** | Probability that a Lambda invocation will print all the log items regardless of the log level setting | `POWERTOOLS_LOGGER_SAMPLE_RATE` | `0` | `0.0` to `1` | `0.5` | `sampleRateValue` | #### Example using AWS Serverless Application Model (SAM) From 2aaa3d8b2ca47b8ed7593c55353aef1e2a400b10 Mon Sep 17 00:00:00 2001 From: Sergei Cherniaev Date: Fri, 3 Mar 2023 10:15:06 +0400 Subject: [PATCH 5/5] docs(logger): add section about silencing logs --- docs/core/logger.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/core/logger.md b/docs/core/logger.md index f44265c572..a36660baa3 100644 --- a/docs/core/logger.md +++ b/docs/core/logger.md @@ -81,7 +81,7 @@ Your Logger will include the following keys to your structured logging (default | Key | Example | Note | |-----------------------------|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **level**: `string` | `INFO` | Logging level set for the Lambda function"s invocation | +| **level**: `string` | `INFO` | Logging level set for the Lambda function's invocation | | **message**: `string` | `Query performed to DynamoDB` | A descriptive, human-readable representation of this log item | | **sampling_rate**: `float` | `0.1` | When enabled, it prints all the logs of a percentage of invocations, e.g. 10% | | **service**: `string` | `serverlessAirline` | A unique name identifier of the service this Lambda function belongs to, by default `service_undefined` | @@ -555,6 +555,17 @@ For example, by setting the "sample rate" to `0.5`, roughly 50% of your lambda i } ``` +### Silencing logs + +The `SILENT` log level provides a simple and efficient way to suppress all log messages without the need to modify your code. When you set this log level, all log messages, regardless of their severity, will be silenced. + +This feature is useful when you want to have your code instrumented to produce logs, but due to some requirement or business decision, you prefer to not emit them. + +By setting the log level to `SILENT`, which can be done either through the `logLevel` constructor option or by using the `LOG_LEVEL` environment variable, you can easily suppress all logs as needed. + +!!! note + Use the `SILENT` log level with care, as it can make it more challenging to monitor and debug your application. Therefore, we advise using this log level judiciously. + ### Custom Log formatter (Bring Your Own Formatter) You can customize the structure (keys and values) of your log items by passing a custom log formatter, an object that implements the `LogFormatter` abstract class.