Skip to content

Commit f20d74a

Browse files
committed
logger.exception
1 parent a5fc60d commit f20d74a

File tree

6 files changed

+109
-13
lines changed

6 files changed

+109
-13
lines changed

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
*.pyc
1+
*.py[ocd]
22
.ipynb_checkpoints/
3-
.DS_Store
3+
.DS_Store

code/logging_demo.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22

33
import logging
44
import sys
5-
5+
66
LEVELS = {'debug': logging.DEBUG,
77
'info': logging.INFO,
88
'warning': logging.WARNING,
99
'error': logging.ERROR,
1010
'critical': logging.CRITICAL}
11-
11+
1212
if len(sys.argv) > 1:
1313
level_name = sys.argv[1]
1414
level = LEVELS.get(level_name, logging.NOTSET)
1515
logging.basicConfig(level=level)
16-
16+
1717
logging.debug('This is a debug message')
1818
logging.info('This is an info message')
1919
logging.warning('This is a warning message')
2020
logging.error('This is an error message')
21-
logging.critical('This is a critical error message')
21+
logging.critical('This is a critical error message')

code/logging_exception.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# coding=utf-8
2+
3+
import sys
4+
import logging
5+
6+
logger = logging.getLogger(__name__)
7+
formatter = logging.Formatter('%(name)-12s %(asctime)s %(levelname)-8s %(lineno)-4d %(message)s', '%Y %b %d %a %H:%M:%S',)
8+
9+
stream_handler = logging.StreamHandler(sys.stderr)
10+
stream_handler.setFormatter(formatter)
11+
12+
logger.addHandler(stream_handler)
13+
logger.setLevel(logging.DEBUG)
14+
15+
if __name__ == '__main__':
16+
logger.info("main start...")
17+
try:
18+
1 / 0
19+
except Exception as e:
20+
logger.exception("error %s", e)
21+
logger.info("main end.")

code/logging_format.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import logging
55

66
logger = logging.getLogger("Test Logging")
7-
formatter = logging.Formatter('%(name)-12s %(asctime)s %(levelname)-8s %(lineno)-4d %(message)s', '%a, %d %b %Y %H:%M:%S',)
7+
formatter = logging.Formatter('%(name)-12s %(asctime)s %(levelname)-8s %(lineno)-4d %(message)s', '%Y%b%d %a %H:%M:%S')
88
file_handler = logging.FileHandler("test.log")
99
file_handler.setFormatter(formatter)
1010
# file_handler.setLevel(logging.DEBUG)

content/logging.md

+61-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
标准的输出日志库,比每次用 print 输出不知道高到哪里去了。
44

55
```python
6-
6+
#coding=utf-8
77

88
import logging
99
import sys
@@ -24,18 +24,19 @@ logging.info('This is an info message')
2424
logging.warning('This is a warning message')
2525
logging.error('This is an error message')
2626
logging.critical('This is a critical error message')
27+
2728
```
2829

2930
logging 共分五个 log 等级,默认输出的 Level 为 warning 等级,可以设定为其他等级就可以将代码中的每一个等级大于等于 Level 的问题都输出。
3031

3132
```python
32-
33+
#coding=utf-8
3334

3435
import sys
3536
import logging
36-
37+
3738
logger = logging.getLogger("Test Logging")
38-
formatter = logging.Formatter('%(name)-12s %(asctime)s %(levelname)-8s %(lineno)-4d %(message)s', '%Y%b%d %a %H:%M:%S',)
39+
formatter = logging.Formatter('%(name)-12s %(asctime)s %(levelname)-8s %(lineno)-4d %(message)s', '%Y%b%d %a %H:%M:%S')
3940
file_handler = logging.FileHandler("test.log")
4041
file_handler.setFormatter(formatter)
4142
file_handler.setLevel(logging.DEBUG)
@@ -46,7 +47,7 @@ stream_handler.setLevel(logging.WARNING)
4647

4748
logger.addHandler(file_handler)
4849
logger.addHandler(stream_handler)
49-
# logger.setLevel(logging.INFO)
50+
logger.setLevel(logging.DEBUG)
5051

5152
logger.debug('This is a debug message')
5253
logger.info('This is an info message')
@@ -105,6 +106,7 @@ logger.setLevel(logging.DEBUG)
105106
也可以这样配置日志
106107

107108
```
109+
# coding=utf-8
108110
import logging
109111
110112
def main():
@@ -131,3 +133,57 @@ def main():
131133
if __name__ == '__main__':
132134
main()
133135
```
136+
137+
关于 logger 输出异常堆栈,无论使用 `logger.info` 或者 `logger.error` 输出格式都是一样的,只是日志等级不一样,但是有时在输出异常的时候,我们不只是需要知道异常名称,还需要知道异常的上下文,堆栈信息等,特别是在多线程中,子线程的异常不会被主线程捕获输出,只能通过日志打印出来。
138+
139+
所以可以使用 `logger.exception` 代替 `logger.error` ,日志等级也是 `error`, 但是会打印出异常的堆栈信息。
140+
141+
142+
示例代码
143+
144+
```
145+
# coding=utf-8
146+
147+
import sys
148+
import logging
149+
150+
logger = logging.getLogger(__name__)
151+
formatter = logging.Formatter('%(name)-12s %(asctime)s %(levelname)-8s %(lineno)-4d %(message)s', '%Y %b %d %a %H:%M:%S',)
152+
153+
stream_handler = logging.StreamHandler(sys.stderr)
154+
stream_handler.setFormatter(formatter)
155+
156+
logger.addHandler(stream_handler)
157+
logger.setLevel(logging.DEBUG)
158+
159+
if __name__ == '__main__':
160+
logger.info("main start...")
161+
try:
162+
1 / 0
163+
except Exception as e:
164+
logger.exception("error %s", e)
165+
logger.info("main end.")
166+
167+
```
168+
169+
对比一下输出的日志即可看出。
170+
171+
使用 `logger.error` 的效果
172+
173+
```
174+
__main__ 2019 May 25 Sat 22:23:36 INFO 16 main start...
175+
__main__ 2019 May 25 Sat 22:23:36 ERROR 20 error integer division or modulo by zero
176+
__main__ 2019 May 25 Sat 22:23:36 INFO 21 main end.
177+
```
178+
179+
使用 `logger.exception` 的效果
180+
181+
```
182+
__main__ 2019 May 25 Sat 22:23:52 INFO 16 main start...
183+
__main__ 2019 May 25 Sat 22:23:52 ERROR 20 error integer division or modulo by zero
184+
Traceback (most recent call last):
185+
File "code/logging_exception.py", line 18, in <module>
186+
1 / 0
187+
ZeroDivisionError: integer division or modulo by zero
188+
__main__ 2019 May 25 Sat 22:23:52 INFO 21 main end.
189+
```

content/py_compile.md

+20-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
将 py 文件编译为 pyc 文件,在前两年还说是别人都无法反编译出源文件,但是现在连[在线反编译网站](https://tool.lu/pyc/)都有了。
44

5-
源代码保护还是需要再想想别的法子.
5+
源代码保护还是需要再想想别的法子. 比如使用 cython 编译成 so 链接库。
66

77
py_compile 是 python 自带的官方库,在单个 python 文件中边解释边运行,在 python 类库里引用运行的时候就会自动编译出 pyc 文件。
88

@@ -25,6 +25,16 @@ py_compile.compile("test.py")
2525
$ python -m py_compile test.py
2626
```
2727

28+
还可以使用 py_compile 编译为 `pyo` 文件,是优化后的二进制文件
29+
30+
```
31+
$ python -O -m py_compile test.py
32+
```
33+
34+
不过好像没差吖。。。
35+
36+
确实没什么差别,可以看到[现有的编译器并没有太大的优化](https://docs.pythontab.com/python/python2.7/modules.html#python)
37+
2838
### 高级用法
2939

3040
编译整个文件夹,使用 `compileall`
@@ -56,3 +66,12 @@ Compiling home/__init__.py ...
5666
Compiling home/index.py ...
5767
1
5868
```
69+
70+
也可以使用命令行
71+
72+
```
73+
$ python -m compileall home
74+
Listing home ...
75+
Compiling home/__init__.py ...
76+
Compiling home/index.py ...
77+
```

0 commit comments

Comments
 (0)