Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 4 additions & 4 deletions
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

Lines changed: 21 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 61 additions & 5 deletions
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

Lines changed: 20 additions & 1 deletion
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)

AltStyle によって変換されたページ (->オリジナル) /