You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/core/logger.md
+28-30
Original file line number
Diff line number
Diff line change
@@ -475,9 +475,9 @@ You can use any of the following built-in JMESPath expressions as part of [injec
475
475
476
476
### Reusing Logger across your code
477
477
478
-
Similar to [Tracer](./tracer.md#reusing-tracer-across-your-code){target="_blank"}, a new instance that uses the same `service` name - env var or explicit parameter - will reuse a previous Logger instance. Just like `logging.getLogger("logger_name")` would in the standard library if called with the same logger name.
478
+
Similar to [Tracer](./tracer.md#reusing-tracer-across-your-code){target="_blank"}, a new instance that uses the same `service` name will reuse a previous Logger instance.
479
479
480
-
Notice in the CloudWatch Logs output how `payment_id`appeared as expected when logging in `collect.py`.
480
+
Notice in the CloudWatch Logs output how `payment_id`appears as expected when logging in `collect.py`.
481
481
482
482
=== "logger_reuse.py"
483
483
@@ -497,17 +497,6 @@ Notice in the CloudWatch Logs output how `payment_id` appeared as expected when
Coming from standard library, you might be used to use `logging.getLogger(__name__)`. This will create a new instance of a Logger with a different name.
502
-
503
-
In Powertools, you can have the same effect by using `child=True` parameter: `Logger(child=True)`. This creates a new Logger instance named after `service.<module>`. All state changes will be propagated bi-directionally between Child and Parent.
504
-
505
-
For that reason, there could be side effects depending on the order the Child Logger is instantiated, because Child Loggers don't have a handler.
506
-
507
-
For example, if you instantiated a Child Logger and immediately used `logger.append_keys/remove_keys/set_correlation_id` to update logging state, this might fail if the Parent Logger wasn't instantiated.
508
-
509
-
In this scenario, you can either ensure any calls manipulating state are only called when a Parent Logger is instantiated (example above), or refrain from using `child=True` parameter altogether.
510
-
511
500
### Sampling debug logs
512
501
513
502
Use sampling when you want to dynamically change your log level to **DEBUG** based on a **percentage of your concurrent/cold start invocations**.
@@ -582,31 +571,40 @@ You can use import and use them as any other Logger formatter via `logger_format
582
571
583
572
### Migrating from other Loggers
584
573
585
-
If you're migrating from other Loggers, there are few key points to be aware of: [Service parameter](#the-service-parameter), [Inheriting Loggers](#inheriting-loggers), [Overriding Log records](#overriding-log-records), and [Logging exceptions](#logging-exceptions).
574
+
If you're migrating from other Loggers, there are few key points to be aware of: [Service parameter](#the-service-parameter), [Child Loggers](#child-loggers), [Overriding Log records](#overriding-log-records), and [Logging exceptions](#logging-exceptions).
586
575
587
576
#### The service parameter
588
577
589
578
Service is what defines the Logger name, including what the Lambda function is responsible for, or part of (e.g payment service).
590
579
591
580
For Logger, the `service` is the logging key customers can use to search log operations for one or more functions - For example, **search for all errors, or messages like X, where service is payment**.
592
581
593
-
#### Inheriting Loggers
582
+
#### Child Loggers
594
583
595
-
??? tip "Tip: Prefer [Logger Reuse feature](#reusing-logger-across-your-code) over inheritance unless strictly necessary, [see caveats.](#reusing-logger-across-your-code)"
584
+
<center>
585
+
```mermaid
586
+
stateDiagram-v2
587
+
direction LR
588
+
Parent: Logger()
589
+
Child: Logger(child=True)
590
+
591
+
Parent --> Child: bi-directional updates
596
592
597
-
> Python Logging hierarchy happens via the dot notation: `service`, `service.child`, `service.child_2`
593
+
Note right of Child
594
+
Both have the same service
595
+
end note
598
596
599
-
For inheritance, Logger uses a `child=True` parameter along with `service` being the same value across Loggers.
597
+
```
598
+
</center>
600
599
601
-
For child Loggers, we introspect the name of your module where `Logger(child=True, service="name")` is called, and we name your Logger as **{service}.{filename}**.
600
+
For inheritance, Logger uses `child` parameter to ensure we don't compete with its parents config. We name child Loggers following Python's convention: _`{service}`.`{filename}`_.
602
601
603
-
???+ danger
604
-
A common issue when migrating from other Loggers is that `service` might be defined in the parent Logger (no child param), and not defined in the child Logger:
602
+
Changes are bidirectional between parents and loggers. That is, appending a key in a child or parent will ensure both have them. This means, having the same `service` name is important when instantiating them.
In this case, Logger will register a Logger named `payment`, and a Logger named `service_undefined`. The latter isn't inheriting from the parent, and will have no handler, resulting in no message being logged to standard output.
619
-
620
-
???+ tip
621
-
This can be fixed by either ensuring both has the `service` value as `payment`, or simply use the environment variable `POWERTOOLS_SERVICE_NAME` to ensure service value will be the same across all Loggers when not explicitly set.
616
+
There are two important side effects when using child loggers:
622
617
623
-
Do this instead:
618
+
1.**Service name mismatch**. Logging messages will be dropped as child loggers don't have logging handlers.
619
+
* Solution: use `POWERTOOLS_SERVICE_NAME` env var. Alternatively, use the same service explicit value.
620
+
2.**Changing state before a parent instantiate**. Using `logger.append_keys` or `logger.remove_keys` without a parent Logger will lead to `OrphanedChildLoggerError` exception.
621
+
* Solution: always initialize parent Loggers first. Alternatively, move calls to `append_keys`/`remove_keys` from the child at a later stage.
0 commit comments