4
4
5
5
- [ Overview] ( #overview )
6
6
- [ ` app_logger ` ] ( #app_logger )
7
- - [ ` app_logger.kv ` ] ( #app_loggerkv )
7
+ - [ Output formats] ( #output-formats )
8
+ - [ Context management] ( #context-management )
9
+ - [ Debug mode] ( #debug-mode )
10
+ - [ Advanced usage] ( #advanced-usage )
8
11
- [ Logging settings] ( #logging-settings )
9
12
10
13
## Overview
@@ -13,49 +16,124 @@ In Python, configuring logging can be surprisingly complex. For most use cases,
13
16
14
17
By default, both the ` plain ` and ` app ` loggers are set to the ` INFO ` level. You can quickly change this by using the ` PLAIN_LOG_LEVEL ` and ` APP_LOG_LEVEL ` environment variables.
15
18
19
+ The ` app_logger ` supports multiple output formats and provides a friendly kwargs-based API for structured logging.
20
+
16
21
## ` app_logger `
17
22
18
- The ` app_logger ` is a pre-configured logger you can use inside your app code .
23
+ The ` app_logger ` is an enhanced logger that supports kwargs-style logging and multiple output formats .
19
24
20
25
``` python
21
26
from plain.logs import app_logger
22
27
23
28
24
29
def example_function ():
25
- app_logger.info(" Hey!" )
30
+ # Basic logging
31
+ app_logger.info(" User logged in" )
32
+
33
+ # With structured context data (explicit **context parameter)
34
+ app_logger.info(" User action" , user_id = 123 , action = " login" , success = True )
35
+
36
+ # All log levels support context parameters
37
+ app_logger.debug(" Debug info" , step = " validation" , count = 5 )
38
+ app_logger.warning(" Rate limit warning" , user_id = 456 , limit_exceeded = True )
39
+ app_logger.error(" Database error" , error_code = 500 , table = " users" )
40
+
41
+ # Standard logging parameters with context
42
+ try :
43
+ risky_operation()
44
+ except Exception :
45
+ app_logger.error(
46
+ " Operation failed" ,
47
+ exc_info = True , # Include exception traceback
48
+ stack_info = True , # Include stack trace
49
+ user_id = 789 ,
50
+ operation = " risky_operation"
51
+ )
26
52
```
27
53
28
- ## ` app_logger.kv `
54
+ ## Output formats
55
+
56
+ The ` app_logger ` supports three output formats controlled by the ` APP_LOG_FORMAT ` environment variable:
29
57
30
- The key-value logging format is popular for outputting more structured logs that are still human-readable.
58
+ ### Key-Value format (default)
59
+
60
+ ``` bash
61
+ export APP_LOG_FORMAT=keyvalue # or leave unset for default
62
+ ```
63
+
64
+ ```
65
+ [INFO] User action user_id=123 action=login success=True
66
+ [ERROR] Database error error_code=500 table=users
67
+ ```
68
+
69
+ ### JSON format
70
+
71
+ ``` bash
72
+ export APP_LOG_FORMAT=json
73
+ ```
74
+
75
+ ``` json
76
+ {"timestamp" : " 2024-01-01 12:00:00,123" , "level" : " INFO" , "message" : " User action" , "user_id" : 123 , "action" : " login" , "success" : true }
77
+ {"timestamp" : " 2024-01-01 12:00:01,456" , "level" : " ERROR" , "message" : " Database error" , "error_code" : 500 , "table" : " users" }
78
+ ```
79
+
80
+ ### Standard format
81
+
82
+ ``` bash
83
+ export APP_LOG_FORMAT=standard
84
+ ```
85
+
86
+ ```
87
+ [INFO] User action
88
+ [ERROR] Database error
89
+ ```
90
+
91
+ Note: In standard format, the context kwargs are ignored and not displayed.
92
+
93
+ ## Context management
94
+
95
+ The ` app_logger ` provides powerful context management for adding data to multiple log statements.
96
+
97
+ ### Persistent context
98
+
99
+ Use the ` context ` dict to add data that persists across log calls:
31
100
32
101
``` python
33
- from plain.logs import app_logger
102
+ # Set persistent context
103
+ app_logger.context[" user_id" ] = 123
104
+ app_logger.context[" request_id" ] = " abc456"
34
105
106
+ app_logger.info(" Started processing" ) # Includes user_id and request_id
107
+ app_logger.info(" Validation complete" ) # Includes user_id and request_id
108
+ app_logger.info(" Processing finished" ) # Includes user_id and request_id
35
109
36
- def example_function ():
37
- app_logger.kv( " Example log line with " , example_key = " example_value " )
110
+ # Clear context
111
+ app_logger.context.clear( )
38
112
```
39
113
40
- ## Logging settings
114
+ ### Temporary context
41
115
42
- You can further configure your logging with ` settings.LOGGING ` .
116
+ Use ` include_context() ` for temporary context that only applies within a block:
43
117
44
118
``` python
45
- # app/settings.py
46
- LOGGING = {
47
- " version" : 1 ,
48
- " disable_existing_loggers" : False ,
49
- " handlers" : {
50
- " console" : {
51
- " class" : " logging.StreamHandler" ,
52
- },
53
- },
54
- " loggers" : {
55
- " mylogger" : {
56
- " handlers" : [" console" ],
57
- " level" : " DEBUG" ,
58
- },
59
- },
60
- }
119
+ app_logger.context[" user_id" ] = 123 # Persistent
120
+
121
+ with app_logger.include_context(operation = " payment" , transaction_id = " txn789" ):
122
+ app_logger.info(" Payment started" ) # Has user_id, operation, transaction_id
123
+ app_logger.info(" Payment validated" ) # Has user_id, operation, transaction_id
124
+
125
+ app_logger.info(" Payment complete" ) # Only has user_id
126
+ ```
127
+
128
+ ## Debug mode
129
+
130
+ The ` force_debug() ` context manager allows temporarily enabling DEBUG level logging:
131
+
132
+ ``` python
133
+ # Debug messages might not show at INFO level
134
+ app_logger.debug(" This might not appear" )
135
+
136
+ # Temporarily enable debug logging
137
+ with app_logger.force_debug():
138
+ app_logger.debug(" This will definitely appear" , extra_data = " debug_info" )
61
139
```
0 commit comments