Skip to content

Commit 18ef9d7

Browse files
authored
Create README.md
1 parent 5a40766 commit 18ef9d7

File tree

1 file changed

+240
-0
lines changed

1 file changed

+240
-0
lines changed

example-project/README.md

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
# Logtail Python example project
2+
3+
To help you get started with using Logtail in your Python projects, we have prepared a simple python program that showcases the usage of Logtail logger in Python code.
4+
5+
## Download the example project
6+
7+
You can download the example project from GitHub directly or you can clone it to a select directory.
8+
9+
Then install the `logtail-python` client library as shown before:
10+
11+
```bash
12+
pip install logtail-python
13+
```
14+
15+
## Run the example project
16+
17+
To run the example application, simply run the following command:
18+
19+
```bash
20+
python main.py <source-token>
21+
```
22+
23+
Don't forget to replace `<source-token>` with your actual source toke which you can find in the source settings.
24+
25+
If you have trouble running the command above, check your Python installation and try running it with the `python3` command instead.
26+
27+
You should see the following output:
28+
29+
```
30+
Output:
31+
All done! You can check your logs now.
32+
```
33+
34+
This will create a total of 6 logs. Each corresponds to its respective method.
35+
36+
# Logging
37+
38+
In this section, we will take a look at actual logging as shown in the example project.
39+
40+
## Setup
41+
42+
First, we need to import the Logtail client library to our code. This can be done using the import keyword. We also need to import the default logging library as well.
43+
44+
```python
45+
# Import Logtail client library and default logging library
46+
from logtail import LogtailHandler
47+
import logging
48+
```
49+
50+
Then we need to create a `handler`, which will be responsible for handling our log messages, and a `logger` that will create those messages and provide them to the `handler`.
51+
52+
```python
53+
# Create handler
54+
handler = LogtailHandler(source_token=sys.argv[1])
55+
56+
# Create logger
57+
logger = logging.getLogger(__name__)
58+
logger.handlers = []
59+
logger.setLevel(logging.DEBUG) # Set minimal log level
60+
logger.addHandler(handler) # asign handler to logger
61+
```
62+
63+
### Setting log level
64+
65+
In logging, you can set the log level. This level determines the severity of the log and of the event that triggered that log. The available log levels are (from least to most severe) `debug, info, warning, error, exception, critical`. When and how to use them is explained in the **Logging example** section.
66+
67+
The `setLevel()` method is used to set the minimal log level threshold. This means that any log that is less severe than the threshold will be ignored. For example, if you set the threshold to `logging.INFO` any `logging.DEBUG` logs will be ignored and won’t be handled.
68+
69+
```python
70+
...
71+
logger.setLevel(logging.INFO) # Set minimal log level
72+
...
73+
```
74+
75+
```python
76+
logger.debug('I am using Python!') # This call will be ignored
77+
logger.info('I am using Logtail!') # This call will be handled
78+
```
79+
80+
Code above will generate only one log because the debug level message has lowered severity than the set threshold.
81+
82+
## Logging example
83+
84+
The `logger` instance we created in the setup section is used to send log messages to Logtail. It provides 6 logging methods for the 6 default log levels. The log levels and their method are:
85+
86+
- **DEBUG** - Send debug messages using the `debug()` method
87+
- **INFO** - Send informative messages about the application progress using the `info()` method
88+
- **WARNING** - Report non-critical issues using the `warning()` method
89+
- **ERROR** - Send messages about serious problems using the `error()` method
90+
- **EXCEPTION** - Send exception level log about errors in runtime using the `exception()` method. **Error** level log will be sent. Exception info is added to the logging message.
91+
- **CRITICAL** - Send messages about serious problems using the `critical()` method.
92+
93+
To send a log message of select log level, use the corresponding method. In this example, we will send the **ERROR** level log and **EXCEPTION** level log.
94+
95+
```python
96+
# Send error level log about errors in runtime using the error() method
97+
logger.error('Oops! An error occurred!')
98+
99+
# Send exception level log about errors in runtime using the exception() method
100+
# Error level log will be sent. Exception info is added to the logging message.
101+
# This method should only be called from an exception handler.
102+
try:
103+
nonexisting_function() # Calling nonexisting function
104+
except Exception as Argument:
105+
logger.exception("Error occurred while calling non-existing function") # Additional info will be added
106+
```
107+
108+
The code above will generate the following JSON logs:
109+
110+
```json
111+
{
112+
"dt":"2022-02-03 12:08:55.642 UTC",
113+
"context":{
114+
"runtime":{
115+
"file_string":"main.py",
116+
"function_string":"<module>",
117+
"line_integer":"39",
118+
"logger_name_string":"__main__",
119+
"thread_id_integer":"140660399380288",
120+
"thread_name_string":"MainThread"
121+
},
122+
"system":{
123+
"pid_integer":"2701",
124+
"process_name_string":"MainProcess"
125+
}
126+
},
127+
"filename_string":"main.py",
128+
"level_string":"error",
129+
"message_string":"Oops! An error occured!",
130+
"severity_integer":"4"
131+
}
132+
133+
{
134+
"dt":"2022-02-03 12:08:55.643 UTC",
135+
"context":{
136+
"runtime":{
137+
"file_string":"main.py",
138+
"function_string":"<module>",
139+
"line_integer":"50",
140+
"logger_name_string":"__main__",
141+
"thread_id_integer":"140660399380288",
142+
"thread_name_string":"MainThread"
143+
},
144+
"system":{
145+
"pid_integer":"2701",
146+
"process_name_string":"MainProcess"
147+
}
148+
},
149+
"filename_string":"main.py",
150+
"level_string":"error",
151+
"message_string":"Error occurred while calling non-existing function\nTraceback (most recent call last):\n File \"main.py\", line 48, in <module>\n nonexisting_function() # Calling nonexisting function\nNameError: name 'nonexisting_function' is not defined",
152+
"severity_integer":"4"
153+
}
154+
```
155+
156+
As you can see, both logs are almost identical. The key difference is that the `exception()` method generated an `error` level log and appended the log message with the exception message.
157+
158+
## Logging additional data
159+
160+
All of these methods expect a string message and they allow adding additional dictionary passed as an `extra`:
161+
162+
```python
163+
# Send warning level log about worrying events using the warning() method
164+
# You can also add custom structured information to the log by passing it as a second argument
165+
logger.warning('Log structured data', extra={
166+
'item': {
167+
'url': "https://fictional-store.com/item-123",
168+
'price': 100.00
169+
}
170+
})
171+
```
172+
173+
This will generate the following JSON log:
174+
175+
```json
176+
{
177+
"dt":"2022-02-03 12:08:55.642 UTC",
178+
"context":{
179+
"runtime":{
180+
"file_string":"main.py",
181+
"function_string":"<module>",
182+
"line_integer":"31",
183+
"logger_name_string":"__main__",
184+
"thread_id_integer":"140660399380288",
185+
"thread_name_string":"MainThread"
186+
},
187+
"system":{
188+
"pid_integer":"2701",
189+
"process_name_string":"MainProcess"
190+
}
191+
},
192+
"filename_string":"main.py",
193+
"item":{
194+
"price_float":100,
195+
"url_string":"https://fictional-store.com/item-123"
196+
},
197+
"level_string":"warn",
198+
"message_string":"Log structured data",
199+
"severity_integer":"3"
200+
}
201+
```
202+
203+
## Context
204+
205+
By default, we add information about the current runtime environment and about the current process into a `context` field of the logged item.
206+
207+
If you want to add some custom information to all logged items (e.g., the ID of the current user), you can do so by adding a custom context:
208+
209+
```python
210+
with logtail.context(user={ 'id': 123 }):
211+
# ...
212+
logger.info('new subscription')
213+
```
214+
215+
This snippet will produce the following JSON log:
216+
217+
```json
218+
{
219+
"dt": "2021-03-29T11:24:21.788451Z",
220+
"level": "info",
221+
"message": "new subscription",
222+
"context": {
223+
"runtime": {
224+
"function": "function_name",
225+
"file": "script_file.py",
226+
"line": 3,
227+
"thread_id": "123456789",
228+
"thread_name": "async_thread",
229+
"logger_name": "logger"
230+
},
231+
"system": {
232+
"pid": 123456,
233+
"process_name": "python"
234+
},
235+
"user": {
236+
"id": 123
237+
}
238+
}
239+
}
240+
```

0 commit comments

Comments
 (0)