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
"""Convenience property to access the first logger formatter"""
699
-
handler=self.registered_handler
700
-
ifhandlerisNone:
701
-
raiseOrphanedChildLoggerError(
702
-
"Orphan child loggers cannot append nor remove keys until a parent is initialized first. "
703
-
"To solve this issue, you can A) make sure a parent logger is initialized first, or B) move append/remove keys operations to a later stage."# noqa: E501
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.
501
+
502
+
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.
503
+
504
+
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.
505
+
506
+
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.
507
+
508
+
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.
499
509
500
510
### Sampling debug logs
501
511
@@ -571,56 +581,48 @@ You can use import and use them as any other Logger formatter via `logger_format
571
581
572
582
### Migrating from other Loggers
573
583
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).
584
+
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).
575
585
576
586
#### The service parameter
577
587
578
588
Service is what defines the Logger name, including what the Lambda function is responsible for, or part of (e.g payment service).
579
589
580
590
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**.
581
591
582
-
#### Child Loggers
592
+
#### Inheriting Loggers
583
593
584
-
<center>
585
-
```mermaid
586
-
stateDiagram-v2
587
-
direction LR
588
-
Parent: Logger()
589
-
Child: Logger(child=True)
590
-
Parent --> Child: bi-directional updates
591
-
Note right of Child
592
-
Both have the same service
593
-
end note
594
-
```
595
-
</center>
594
+
??? tip "Tip: Prefer [Logger Reuse feature](#reusing-logger-across-your-code) over inheritance unless strictly necessary, [see caveats.](#reusing-logger-across-your-code)"
596
595
597
-
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}`_.
596
+
> Python Logging hierarchy happens via the dot notation: `service`, `service.child`, `service.child_2`
597
+
For inheritance, Logger uses a `child=True` parameter along with `service` being the same value across Loggers.
598
598
599
-
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.
599
+
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
600
601
-
=== "logging_inheritance_good.py"
601
+
???+ danger
602
+
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:
There are two important side effects when using child loggers:
615
+
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.
614
616
615
-
1.**Service name mismatch**. Logging messages will be dropped as child loggers don't have logging handlers.
616
-
* Solution: use `POWERTOOLS_SERVICE_NAME` env var. Alternatively, use the same service explicit value.
617
-
2.**Changing state before a parent instantiate**. Using `logger.append_keys` or `logger.remove_keys` without a parent Logger will lead to `OrphanedChildLoggerError` exception.
618
-
* Solution: always initialize parent Loggers first. Alternatively, move calls to `append_keys`/`remove_keys` from the child at a later stage.
617
+
???+ tip
618
+
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.
@@ -811,10 +813,11 @@ for the given name and level to the logging module. By default, this logs all bo
811
813
812
814
You can copy the Logger setup to all or sub-sets of registered external loggers. Use the `copy_config_to_registered_logger` method to do this.
813
815
814
-
???+ tip
815
-
To help differentiate between loggers, we include the standard logger `name` attribute for all loggers we copied configuration to.
816
+
!!! tip "We include the logger `name` attribute for all loggers we copied configuration to help you differentiate them."
817
+
818
+
By default all registered loggers will be modified. You can change this behavior by providing `include` and `exclude` attributes.
816
819
817
-
By default all registered loggers will be modified. You can change this behavior by providing `include` and `exclude` attributes. You can also provide optional `log_level` attribute external loggers will be configured with.
820
+
You can also provide optional `log_level` attribute external top-level loggers will be configured with, by default it'll use the source logger log level. You can opt-out by using `ignore_log_level=True` parameter.
818
821
819
822
```python hl_lines="10" title="Cloning Logger config to all other registered standard loggers"
0 commit comments