1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
|
%global _empty_manifest_terminate_build 0
Name: python-nb-log
Version: 8.6
Release: 1
Summary: very sharp color display,monkey patch bulitin print and high-performance multiprocess safe roating file handler,other handlers includeing dintalk ,email,kafka,elastic and so on
License: BSD License
URL: https://github.com/ydf0509/nb_log
Source0: https://mirrors.aliyun.com/pypi/web/packages/a6/02/541ab1253721944f293d814eeda4df2498848463c2b955d1190257ee5655/nb_log-8.6.tar.gz
BuildArch: noarch
%description
# 1.nb_log 简介
[nb_log readthedocs文档链接](https://nb-log-doc.readthedocs.io/zh_CN/latest)
[nb_log 源码链接](https://github.com/ydf0509/nb_log)
[](https://postimg.cc/HJ2shsBC)
文中文档较长,但其中大部分不是 讲解nb_log 的用法,是复习内置logging的概念。
是由于python人员不懂logging包的日志命名空间和python日志树形命名空间结构,不懂handlers和logger的关系是什么。
所以需要很长的篇幅。
很多pythoner到现在都不知道python的 logging.getLogger() 第一个入参的意义和作用,造成nb_log也不知道怎么使用多命名空间。
## 1.0 nb_log 安装
pip install nb_log
## 1.1 nb_log 简单使用例子
```python
print('导入nb_log之前的print是普通的')
from nb_log import get_logger
logger = get_logger('lalala',) # get_logger 只有一个name是必传递的,其他的参数不是必传。
# logger = get_logger('lalala',log_filename='lalala.log',formatter_template=5,log_file_handler_type=2) # get_logger有很多其他入参可以自由定制logger。
logger.debug(f'debug是绿色,说明是调试的,代码ok ')
logger.info('info是天蓝色,日志正常 ')
logger.warning('黄色yello,有警告了 ')
logger.error('粉红色说明代码有错误 ')
logger.critical('血红色,说明发生了严重错误 ')
print('导入nb_log之后的print是强化版的可点击跳转的')
```
### 1.1.b nb_log 的最核心函数 get_logger入参说明
```doctest
:param name: 日志命名空间,意义非常非常非常重要,有些人到现在还不知道 logging.getLogger() 第一个入参的作用,太low了。不同的name的logger可以表现出不同的行为。
例如让 aa命名空间的日志打印控制台并且写入到文件,并且只记录info级别以上,让 bb 命名空间的日志仅仅打印控制台,并且打印debug以上级别,
这种就可以通过不同的日志命名空间做到。
:param log_level_int: 日志输出级别,设置为 1 2 3 4 5,分别对应原生logging.DEBUG(10),logging.INFO(20),
logging.WARNING(30),logging.ERROR(40),logging.CRITICAL(50)级别,现在可以直接用10 20 30 40 50了,兼容了。
:param is_add_stream_handler: 是否打印日志到控制台,默认会打印控制台。
:param do_not_use_color_handler :是否禁止使用color彩色日志
:param log_path: 设置存放日志的文件夹路径,如果不设置,则取nb_log_config.LOG_PATH,如果配置中也没指定则自动在代码所在磁盘的根目录创建/pythonlogs文件夹,
非windwos下要注意账号权限问题(如果python没权限在根目录建/pythonlogs,则需要手动先创建好)
:param log_filename: 日志的名字,仅当log_path和log_filename都不为None时候才会写入到日志文件。用户不指定 log_filename 默认当作用户不希望把日志写入到文件中。
:param log_file_size :日志大小,单位M,默认100M
:param log_file_handler_type :这个值可以设置为 1 2 3 4 5 五种值,1为使用多进程安全按日志文件大小切割的文件日志,
2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个日志
3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题)
4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
:param mongo_url : mongodb的连接,为None时候不添加mongohandler
:param is_add_elastic_handler: 是否记录到es中。
:param is_add_kafka_handler: 日志是否发布到kafka。
:param ding_talk_token:钉钉机器人token
:param ding_talk_time_interval : 时间间隔,少于这个时间不发送钉钉消息
:param mail_handler_config : 邮件配置
:param is_add_mail_handler :是否发邮件
:param formatter_template :日志模板,如果为数字,则为nb_log_config.py字典formatter_dict的键对应的模板,
1为formatter_dict的详细模板,2为简要模板,5为最好模板。
如果值为logging.Formatter对象,则直接使用用户传入的模板,不从formatter_dict中选择模板。
```
log_filename 用于设置是否写入日志文件和写入什么文件中。有的人不看入参文档,就问nb_log为什么不写入日志文件中。
logger和handler是观察者模式,日志记录到哪些地方,是由添加了什么handlers决定的。
### 1.1.c nb_log配置文件的生成和导入。
项目中任意脚本使用nb_log,第一次运行代码时候,会自动在 sys.path[1] 目录下创建 nb_log_config.py文件并写入默认值。
之后nb_log 会自动 import nb_log_config, 如果import到这个模块了,控制台会提示读取了什么文件作为配置文件。
如果是 cmd或者linux运行不是pycharm,需要 设置 PYTHONPATH为项目根目录,这样就能自动在当前项目根目录下生成或者找到 nb_log_config.py了。
用户可以print(sys.path) print(sys.path[1]) 来查看 sys.path[1]的值是什么就知道了。
连PYTHONPATH作用是什么都不知道的python小白,一定要看下面文章 。
[pythonpath作用介绍的文章](https://github.com/ydf0509/pythonpathdemo)
### 1.1.d nb_log配置文件的一些参数说明。
```doctest
DEFAULUT_USE_COLOR_HANDLER = True # 是否默认使用有彩的日志。
DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = True # 在控制台是否显示彩色块状的日志。为False则不使用大块的背景颜色。
AUTO_PATCH_PRINT = True # 是否自动打print的猴子补丁,如果打了猴子补丁,print自动变色和可点击跳转。
SHOW_PYCHARM_COLOR_SETINGS = True # 有的人很反感启动代码时候提示教你怎么优化pycahrm控制台颜色,可以把这里设置为False
DEFAULT_ADD_MULTIPROCESSING_SAFE_ROATING_FILE_HANDLER = False # 是否默认同时将日志记录到记log文件记事本中,就是用户不指定 log_filename的值,会自动写入日志命名空间.log文件中。
LOG_FILE_SIZE = 100 # 单位是M,每个文件的切片大小,超过多少后就自动切割
LOG_FILE_BACKUP_COUNT = 14 # 对同一个日志文件,默认最多备份几个文件,超过就删除了。
LOG_PATH = '/pythonlogs' # 默认的日志文件夹,如果不写明磁盘名,则是项目代码所在磁盘的根目录下的/pythonlogs
# LOG_PATH = Path(__file__).absolute().parent / Path("pythonlogs") #这么配置就会自动在你项目的根目录下创建pythonlogs文件夹了并写入。
if os.name == 'posix': # linux非root用户和mac用户无法操作 /pythonlogs 文件夹,没有权限,默认修改为 home/[username] 下面了。例如你的linux用户名是 xiaomin,那么默认会创建并在 /home/xiaomin/pythonlogs文件夹下写入日志文件。
home_path = os.environ.get("HOME", '/') # 这个是获取linux系统的当前用户的主目录,不需要亲自设置
LOG_PATH = Path(home_path) / Path('pythonlogs') # linux mac 权限很严格,非root权限不能在/pythonlogs写入,修改一下默认值。
LOG_FILE_HANDLER_TYPE = 1 # 1 2 3 4 5
"""
LOG_FILE_HANDLER_TYPE 这个值可以设置为 1 2 3 4 5 四种值,
1为使用多进程安全按日志文件大小切割的文件日志,这是本人实现的批量写入日志,减少操作文件锁次数,测试10进程快速写入文件,win上性能比第5种提高了100倍,linux提升5倍
2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个新的日志文件。日志文件名字后缀自动加上日期。
3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题)
4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
"""
```
以上只是部分配置的例子,其他配置在你项目根目录下的 nb_log_config.py中都有默认值,自己按需修改设置。
其他例如日志模板定义,默认日志模板选择什么,都可以在 nb_log_config.py文件中设置。
### 1.1.1e 日志配置文件和get_logger传参的关系。
nb_log_config.py中是设置全局设置,get_logger是针对单个logger对象生成的设置。
例如 nb_log_config.py 中写 FORMATTER_KIND = 4,get_logger 传参 formatter_template=6,那么最终还是使用第6个日志模板。
如果get_logger函数没有传参指定就使用 nb_log_config.py中的配置。
就是说 get_logger 是优先级高的,nb_log_config.py 是优先级低的配置方式。
## 1.2 nb_log功能介绍
### 1.2.1 nb_log 支持日志根据级别自动变彩色
如图:日志彩色符合交通灯颜色认知。绿色是debug等级的日志,天蓝色是info等级日志,
黄色是warnning等级的警告日志,粉红色是error等级的错误日志,血红色是criticl等级的严重错误日志
### 1.2.1b 设置是否需要彩色
nb_log支持自动彩色,也支持关闭背景色块只要颜色,也支持彻底不要颜色所有日志显示为正常黑白颜色。
可以在你项目根目录下自动生成的nb_log_config.py配置文件中修改相关配置,来控制是否需要颜色,或者要颜色但不要大块的背景色块。
```angular2html
如果反对日志有各种彩色,可以设置 DEFAULUT_USE_COLOR_HANDLER = False
如果反对日志有块状背景彩色,可以设置 DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = False
如果想屏蔽nb_log包对怎么设置pycahrm的颜色的提示,可以设置 WARNING_PYCHARM_COLOR_SETINGS = False
如果想改变日志模板,可以设置 FORMATTER_KIND 参数,只带了7种模板,可以自定义添加喜欢的模板
LOG_PATH 配置文件日志的保存路径的文件夹。
```
### 1.2.1c 关于彩色显示效果的最终显示的说明
有的人听说了python显示颜色的博客,例如这种
[python print显示颜色](https://www.cnblogs.com/ping-y/p/5897018.html)
```
python在控制台可以同时显示7种颜色,但是同时显示不出来65536种颜色,pycahrm控制台/win cmd/linux的控制台终端不是浏览器网页,不能显示丰富的65536色模式,
只能暴露7种ansi颜色钩子,显示控制台输出的终端软件一般提供了颜色的自定义设置,例如 pycahrm finashell xhsell
这些软件都可以对ansi颜色自定义65536色模式的颜色代码,
例如nb_log启动时候就打印提示了教用户怎么设置颜色。
例如一件拍摄街道的彩色相片有60多种颜色,在cmd pycahrm终端是不可能同时显示出那么多种颜色的。
例如你想要控制台显示杨幂穿的淡红色衣服的颜色,控制台能做得到吗?当然是能做到得,但不是在python种 用所谓得 \033[ 来设置颜色,
因为软件终端只能识别7种ansi颜色钩子,红色在65536色模式下最起码也有几万种颜色代码,有白浅红色 水红色 大红色 粉红色 红的发紫的红色 红得发黑的红色,
所以你想精确得让控制台显示多种不同的红色,你自己用大脑想想呗,仅仅在python print中 \033就想得到理想的所需的红色,简直是做梦吧。
我说的是要精确控制颜色,不能光靠python的\033[,而是要在python的终端输出软件中设置颜色。例如pycharm xhsell finashell软件中都支持自定义颜色。
所以有些小白用户觉得颜色不好看,让我在配置文件中放开自定义颜色,这是不可行的,颜色最终的显示效果由控制台终端决定,不是所谓的\033能决定的,
例如我就想问 \033后面加什么字母能精确得到桃红色 金黄色 亮绿色这些 ,这么简单的想不到吗?如果控制台自动支持65536种颜色同时显示,那么nb_log可以暴露出来怎么配置颜色。
例如 \033[32 是绿色,但是软件终端中重定义ansi 颜色,可以让你代码的\033[32 显示出1万种不同的绿色,当然也可以让\033[32 绿色但是显示成黄色 紫色啥的,
因为最终渲染颜色效果是由终端决定,不是代码中\033后面数字来决定的。用户需要在软件终端中重新定义颜色,拿pycahrm为例,设置各种想要的颜色30秒钟,配置颜色要不了很久。
```
### 1.2.1d pycharm中精确设置控制台颜色的方式
```
要说明的是,即使是同一个颜色代码在pycahrm不同主题都是颜色显示区别很大的,默认的可能很丑或者由于颜色不好导致文字看不清晰
为了达到我这种色彩效果需要重新设置主题颜色,在控制台输出的第一行就教大家怎么设置颜色了。
也可以按下面设置,需要花30秒设置。
1)使用pycharm时候,建议重新自定义设置pycharm的console里面的主题颜色。
设置方式为 打开pycharm的 file -> settings -> Editor -> Color Scheme -> Console Colors 选择monokai,
并重新修改自定义7个颜色,设置Blue为 0454F3 ,Cyan为 04DCF8 ,Green 为 13FC02 ,Magenta为 ff1cd5 ,red为 F80606 ,yellow为 EAFA04 ,gray 为 FFFFFF ,white 为 FFFFFF 。
如果设置为显示背景色快,由于不同版本的pycahrm或主题,可以根据控制台实际显示设置 White 为 1F1F1F, Black 为 FFFFFF,因为背景色是深色,前景色的文字设置为白色比黑色好。
2)使用xshell或finashell工具连接linux也可以自定义主题颜色,默认使用shell连接工具的颜色也可以。
```
### 1.2.2 nb_log 不仅支持日志变彩色,还支持项目中所有python文件的任意print自动变彩色
```
导入nb_log时候会给内置的 ptint 打猴子补丁,所以用户所有地方的print行为自动发生了变化,重定向到nb_log定义的print了
```
### 1.2.2b print自动化效果转换的好处说明
```
自动转换print效果,再也不怕有人在项目中随意print,导致很难找到是从哪里冒出来的print。
只要import nb_log,项目所有地方的print自动现型并在控制台可点击几精确跳转到print的地方。
在项目里面的几百个文件中疯狂print真的让人很生气,一个run.py运行起来几百个py文件,
每个文件print 七八次,到底自己想看想关心的print是在控制台的哪一行呢,找到老眼昏花都找不到。
比如打印x变量的值,有人是为了省代码直接 print(x),而没有多打几个字母使用print("x的值是:",x),
这样打印出来的x变量,根本无法通过全局查找找到打印x变量是在什么py文件的哪一行。
有人说把之前的print全部用#注释不就好了,那这要全局找找print,一个一个的修改,一个10万行项目,
就算平均100行有一个print关键字,那起码也得有1000个print关键字吧,一个个的修改那要改到猴年马月呢。
只有使用nb_log,才能让一切print妖魔鬼怪自动现形。
另外,在正式项目或工具类甚至做得包里面,疯狂print真的很low,可以参考大神的三方包,从来都没直接print的不存在的,
他们都是用的日志。
日志比print灵活多了,对命名空间的控制、级别过滤控制、模板自定义、能记录到的地方扩展性很强远强过print的只有控制台。
```
### 1.2.2c nb_log 五彩日志的效果截图
[](https://postimg.cc/HJ2shsBC)
## 1.3 nb_log 支持pycharm控制台点击日志精确跳转到打印日志的文件和行号
[](https://postimg.cc/w3WRBF5d)
## 1.4 nb_log是原生logging类型,兼容性 扩展性非常好。
nb_log 是基于python自带的原生logging模块封装的, nb_log.get_logger()生成的日志类型是 原生logging.Logger类型,
所以nb_log包对常用三方包日志兼容性替换芯做到了100%。是否是原生日志非常重要,logbook和loguru都不是python自带的原生日志,
所以和三方包结合或者替换性不好。
```
比如logru和logbook这种三方库,完全重新写的日志,
它里面主要被用户使用的logger变量类型不是python内置Logger类型,
造成logger说拥有的属性和方法有的不存在或者不一致,这样的日志和python内置的经典日志兼容性差,
只能兼容(一键替换logger类型)一些简单的debug info warning errror等方法,。
```
## 1.5 nb_log 能够简单讲日志记录到十几种地方的任意几种的组合。
内置了一键入参,每个参数是独立开关,可以把日志同时记录到10几个常用的地方的任意几种组合,
包括 控制台 文件 钉钉 邮件 mongo kafka es 等等 。
有的人以为日志只能记录到控制台和文件,其实是错的,日志可以记录到很多种地方,日志记录到哪里,是由logger添加了什么handler决定的。
## 1.6 日志命名空间独立,采用了多实例logger,按日志命名空间区分。
```python
"""
命名空间独立意味着每个logger单独的日志界别过滤,单独的控制要记录到哪些地方。
"""
from nb_log import get_logger, LogManager
logger_aa = LogManager('aa').get_logger_and_add_handlers(10, log_filename='aa.log')
logger_bb = get_logger("bb", log_level_int=30, is_add_stream_handler=False, ding_talk_token='your_dingding_token')
logger_cc = get_logger('cc', log_level_int=10, log_filename='cc.log')
logger_aa.debug('哈哈哈')
# 将会同时记录到控制台和文件aa.log中,只要debug及debug以上级别都会记录。
logger_bb.warning('嘿嘿嘿')
# 将只会发送到钉钉群消息,并且logger_bb的info debug级别日志不会被记录,非常方便测试调试然后稳定了调高界别到生产。
logger_cc.debug('嘻嘻')
# logger_cc的日志会写在cc.log中,和logger_aa的日志是不同的文件。
```
## 1.7 对内置looging包打了猴子补丁,使日志永远不会使用同种handler重复记录 ,例如,原生的
```
from logging import getLogger,StreamHandler
logger = getLogger('hi')
getLogger('hi').addHandler(StreamHandler())
getLogger('hi').addHandler(StreamHandler())
getLogger('hi').addHandler(StreamHandler())
logger.warning('啦啦啦')
明明只warning了一次,但实际会造成 啦啦啦 在控制台打印3次。
使用nb_log,对同一命名空间的日志,可以无惧反复添加同类型handler,不会重复记录。
关于重复记录的例子,更惨的例子在文档后面的例子,直接把机器cpu性能耗尽,磁盘弄爆炸。
```
## 1.8 nb_log使用对比原生logging和 loguru 更简单
### 1.8.1 logging 代码方式创建logger对象
```python
import logging
logger = logging.getLogger('my.logger.namespace')
fh = logging.FileHandler('test.log') # 可以向文件发送日志
ch = logging.StreamHandler() # 可以向屏幕发送日志
fm = logging.Formatter('%(asctime)s %(message)s') # 打印格式
fh.setFormatter(fm)
ch.setFormatter(fm)
logger.addHandler(fh)
logger.addHandler(ch)
logger.setLevel(logging.DEBUG) # 设置级别
logger.debug('debug 喜喜')
```
有些人简直是怕了原生logging了,为了创建一个好用的logger对象,代码步骤复杂的吓人,很多人完全没看懂这段代码意义,
因为他是一步步创建观察者handler,给handler设置好看的formattor,给给被观察者添加多个观察者对象。
大部分人不看设计模式,不仅不懂观察者模式,而且没听说观察者模式,所以这种创建logger方式完全蒙蔽的节奏。
其实这样一步步的写代码是为了给用户最大的自由来怎么创建一个所需的logger对象。如果高度封装创建logger过程那是简单了,
但是自定义自由度就下降了。
logging是原生日志,每个三方包肯定使用logging了,为了兼容性和看懂三方包,那肯定是要学习logging的,对logging望而却步,
想投机取巧只使用loguru是行不通的,三方包不会使用loguru,三方包里面各种命名空间的日志,等待用户添加handlers来记录日志,
loguru缺点太大了。
nb_log把logging创建logger封装了,但同时get_logger暴露了很多个入参,来让用户自由自定义logger添加什么handler和设置什么formattor。
所以nb_log有原生logging的普遍兼容性,又使用简单
### 1.8.2 python中 创建logger的第二种方式,logging.config.dictConfig()
```python
import logging
import logging.config
LOGGING_CONFIG = {
"version": 1,
"formatters": {
"default": {
'format':'%(asctime)s %(filename)s %(lineno)s %(levelname)s %(message)s',
},
"plain": {
"format": "%(message)s",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "default",
},
"console_plain": {
"class": "logging.StreamHandler",
"level":logging.INFO,
"formatter": "plain"
},
"file":{
"class": "logging.FileHandler",
"level":20,
"filename": "./log.txt",
"formatter": "default",
}
},
"loggers": {
"console_logger": {
"handlers": ["console"],
"level": "INFO",
"propagate": False,
},
"console_plain_file_logger": {
"handlers": ["console_plain","file"],
"level": "DEBUG",
"propagate": False,
},
"file_logger":{
"handlers": ["file"],
"level": "INFO",
"propagate": False,
}
},
"disable_existing_loggers": True,
}
# 运行测试
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("console_logger")
logger.debug('debug message')
logger.info('info message')
logger.warn('warning message')
logger.error('error message')
logger.critical('critical message')
```
这种方式和上面1.8.1的方式差不多, 但不需要写大量python代码来创建logger对象。
虽然不需要写大量python代码来构建logger对象,但是需要写 LOGGING_CONFIG 字典,
这种字典如果写错了导致配置不生效或者报错,还是很麻烦的。很多人对这个配置完全蒙蔽,不知道什么意思。
先创建formattor,创建文件和控制台handler(当然也可以自定义发送钉钉的handler),handler设置日志过滤级别,handler设置formattor,
不同的handler可以设置不同的formattor,例如同样是 logger.debug("hello world"),可以使文件和控制台记录的这条日志的前缀和字段不一样。
对不同命名空间的logger添加不同的handlers,
例如你只想打印控制台 就 logger = logging.getLogger("console_logger"),然后用这个logger.info(xxx)就可以打印控制台了。
例如你只想打写入文件 就 logger = logging.getLogger("file_logger"),然后用这个logger.info(xxx)就可以打印控制台了。
例如你打写入文件并且打印控制台 就 logger = logging.getLogger("console_plain_file_logger"),然后用这个logger.info(xxx)就可以打印控制台并且同时写入文件了。
对1.8.1和1.8.2不理解造成恐惧,是使大家使用loguru的主要原因。
### 1.8.3 loguru的简单使用
```python
from loguru import logger
logger.add("./log_files/loguru-test1.log", rotation="100000 KB")
logger.info("hello")
```
```
代码是loguru打印控制台和写入文件,和nb_log一样代码少。
甚至如果用户不需要写入文件只需要导入logger就好了,
from loguru import logger
logger.info("hello")
看起来很简单,nb_log还需要 get_logger一下,有的人觉得loguru少写一行代码,直接import就能使用了,所以loguru简单牛逼。
nb_log早就知道有人会这么想了,nb_log也支持导入即可使用。
from nb_log import defaul_logger
defaul_logger.info("hello")
但这样有个弊端,用户想使用什么日志模板,用户希望日志记录到 控制台 文件 钉钉 es中的哪几个地方没法定义。
用户如果想屏蔽a函数里面的日志,但想放开b函数里面的日志,这种不传参/不设置日志命名空间的日志就无能为力做到了。
所以nb_log推荐用户调用get_logger函数来自定义日志,而不是直接import defaul_logger然后所有地方都使用这个 defaul_logger来记录日志。
```
综上所述 nb_log既使用简单,又兼容性高。
## 1.9 内置logging包的日志命名空间是什么
```python
import logging
logger1 = logging.getLogger('aaa')
logger2 = logging.getLogger('aaa')
logger3 = logging.getLogger('bbb')
print('logger1 id: ',id(logger1),'logger2 id: ',id(logger2),'logger3 id: ',id(logger3))
```
运行上面可以发现 logger1和logger2对象是同一个id,logger3对象是另外一个id。
通过不同的日志命名空间,可以设置不同级别的日志显示,设置不同类型的日志记录到不同的文件,是否打印控制台,是否发送邮件 钉钉消息。
有的人到现在还是不知道日志命名空间的作用,对一个大项目的所有的日志只会处理成一种表现行为,悲了个剧。
## 1.10 nb_log比logurur有10胜
[nb_log比logurur有10个优点方面](https://nb-log-doc.readthedocs.io/zh_CN/latest/articles/c6.html)
## 1.20 完整readthedocs文档地址
[nb_log readthedocs文档链接](https://nb-log-doc.readthedocs.io/zh_CN/latest)
[nb_log 源码链接](https://github.com/ydf0509/nb_log)

<div> </div>
%package -n python3-nb-log
Summary: very sharp color display,monkey patch bulitin print and high-performance multiprocess safe roating file handler,other handlers includeing dintalk ,email,kafka,elastic and so on
Provides: python-nb-log
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-pip
%description -n python3-nb-log
# 1.nb_log 简介
[nb_log readthedocs文档链接](https://nb-log-doc.readthedocs.io/zh_CN/latest)
[nb_log 源码链接](https://github.com/ydf0509/nb_log)
[](https://postimg.cc/HJ2shsBC)
文中文档较长,但其中大部分不是 讲解nb_log 的用法,是复习内置logging的概念。
是由于python人员不懂logging包的日志命名空间和python日志树形命名空间结构,不懂handlers和logger的关系是什么。
所以需要很长的篇幅。
很多pythoner到现在都不知道python的 logging.getLogger() 第一个入参的意义和作用,造成nb_log也不知道怎么使用多命名空间。
## 1.0 nb_log 安装
pip install nb_log
## 1.1 nb_log 简单使用例子
```python
print('导入nb_log之前的print是普通的')
from nb_log import get_logger
logger = get_logger('lalala',) # get_logger 只有一个name是必传递的,其他的参数不是必传。
# logger = get_logger('lalala',log_filename='lalala.log',formatter_template=5,log_file_handler_type=2) # get_logger有很多其他入参可以自由定制logger。
logger.debug(f'debug是绿色,说明是调试的,代码ok ')
logger.info('info是天蓝色,日志正常 ')
logger.warning('黄色yello,有警告了 ')
logger.error('粉红色说明代码有错误 ')
logger.critical('血红色,说明发生了严重错误 ')
print('导入nb_log之后的print是强化版的可点击跳转的')
```
### 1.1.b nb_log 的最核心函数 get_logger入参说明
```doctest
:param name: 日志命名空间,意义非常非常非常重要,有些人到现在还不知道 logging.getLogger() 第一个入参的作用,太low了。不同的name的logger可以表现出不同的行为。
例如让 aa命名空间的日志打印控制台并且写入到文件,并且只记录info级别以上,让 bb 命名空间的日志仅仅打印控制台,并且打印debug以上级别,
这种就可以通过不同的日志命名空间做到。
:param log_level_int: 日志输出级别,设置为 1 2 3 4 5,分别对应原生logging.DEBUG(10),logging.INFO(20),
logging.WARNING(30),logging.ERROR(40),logging.CRITICAL(50)级别,现在可以直接用10 20 30 40 50了,兼容了。
:param is_add_stream_handler: 是否打印日志到控制台,默认会打印控制台。
:param do_not_use_color_handler :是否禁止使用color彩色日志
:param log_path: 设置存放日志的文件夹路径,如果不设置,则取nb_log_config.LOG_PATH,如果配置中也没指定则自动在代码所在磁盘的根目录创建/pythonlogs文件夹,
非windwos下要注意账号权限问题(如果python没权限在根目录建/pythonlogs,则需要手动先创建好)
:param log_filename: 日志的名字,仅当log_path和log_filename都不为None时候才会写入到日志文件。用户不指定 log_filename 默认当作用户不希望把日志写入到文件中。
:param log_file_size :日志大小,单位M,默认100M
:param log_file_handler_type :这个值可以设置为 1 2 3 4 5 五种值,1为使用多进程安全按日志文件大小切割的文件日志,
2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个日志
3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题)
4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
:param mongo_url : mongodb的连接,为None时候不添加mongohandler
:param is_add_elastic_handler: 是否记录到es中。
:param is_add_kafka_handler: 日志是否发布到kafka。
:param ding_talk_token:钉钉机器人token
:param ding_talk_time_interval : 时间间隔,少于这个时间不发送钉钉消息
:param mail_handler_config : 邮件配置
:param is_add_mail_handler :是否发邮件
:param formatter_template :日志模板,如果为数字,则为nb_log_config.py字典formatter_dict的键对应的模板,
1为formatter_dict的详细模板,2为简要模板,5为最好模板。
如果值为logging.Formatter对象,则直接使用用户传入的模板,不从formatter_dict中选择模板。
```
log_filename 用于设置是否写入日志文件和写入什么文件中。有的人不看入参文档,就问nb_log为什么不写入日志文件中。
logger和handler是观察者模式,日志记录到哪些地方,是由添加了什么handlers决定的。
### 1.1.c nb_log配置文件的生成和导入。
项目中任意脚本使用nb_log,第一次运行代码时候,会自动在 sys.path[1] 目录下创建 nb_log_config.py文件并写入默认值。
之后nb_log 会自动 import nb_log_config, 如果import到这个模块了,控制台会提示读取了什么文件作为配置文件。
如果是 cmd或者linux运行不是pycharm,需要 设置 PYTHONPATH为项目根目录,这样就能自动在当前项目根目录下生成或者找到 nb_log_config.py了。
用户可以print(sys.path) print(sys.path[1]) 来查看 sys.path[1]的值是什么就知道了。
连PYTHONPATH作用是什么都不知道的python小白,一定要看下面文章 。
[pythonpath作用介绍的文章](https://github.com/ydf0509/pythonpathdemo)
### 1.1.d nb_log配置文件的一些参数说明。
```doctest
DEFAULUT_USE_COLOR_HANDLER = True # 是否默认使用有彩的日志。
DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = True # 在控制台是否显示彩色块状的日志。为False则不使用大块的背景颜色。
AUTO_PATCH_PRINT = True # 是否自动打print的猴子补丁,如果打了猴子补丁,print自动变色和可点击跳转。
SHOW_PYCHARM_COLOR_SETINGS = True # 有的人很反感启动代码时候提示教你怎么优化pycahrm控制台颜色,可以把这里设置为False
DEFAULT_ADD_MULTIPROCESSING_SAFE_ROATING_FILE_HANDLER = False # 是否默认同时将日志记录到记log文件记事本中,就是用户不指定 log_filename的值,会自动写入日志命名空间.log文件中。
LOG_FILE_SIZE = 100 # 单位是M,每个文件的切片大小,超过多少后就自动切割
LOG_FILE_BACKUP_COUNT = 14 # 对同一个日志文件,默认最多备份几个文件,超过就删除了。
LOG_PATH = '/pythonlogs' # 默认的日志文件夹,如果不写明磁盘名,则是项目代码所在磁盘的根目录下的/pythonlogs
# LOG_PATH = Path(__file__).absolute().parent / Path("pythonlogs") #这么配置就会自动在你项目的根目录下创建pythonlogs文件夹了并写入。
if os.name == 'posix': # linux非root用户和mac用户无法操作 /pythonlogs 文件夹,没有权限,默认修改为 home/[username] 下面了。例如你的linux用户名是 xiaomin,那么默认会创建并在 /home/xiaomin/pythonlogs文件夹下写入日志文件。
home_path = os.environ.get("HOME", '/') # 这个是获取linux系统的当前用户的主目录,不需要亲自设置
LOG_PATH = Path(home_path) / Path('pythonlogs') # linux mac 权限很严格,非root权限不能在/pythonlogs写入,修改一下默认值。
LOG_FILE_HANDLER_TYPE = 1 # 1 2 3 4 5
"""
LOG_FILE_HANDLER_TYPE 这个值可以设置为 1 2 3 4 5 四种值,
1为使用多进程安全按日志文件大小切割的文件日志,这是本人实现的批量写入日志,减少操作文件锁次数,测试10进程快速写入文件,win上性能比第5种提高了100倍,linux提升5倍
2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个新的日志文件。日志文件名字后缀自动加上日期。
3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题)
4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
"""
```
以上只是部分配置的例子,其他配置在你项目根目录下的 nb_log_config.py中都有默认值,自己按需修改设置。
其他例如日志模板定义,默认日志模板选择什么,都可以在 nb_log_config.py文件中设置。
### 1.1.1e 日志配置文件和get_logger传参的关系。
nb_log_config.py中是设置全局设置,get_logger是针对单个logger对象生成的设置。
例如 nb_log_config.py 中写 FORMATTER_KIND = 4,get_logger 传参 formatter_template=6,那么最终还是使用第6个日志模板。
如果get_logger函数没有传参指定就使用 nb_log_config.py中的配置。
就是说 get_logger 是优先级高的,nb_log_config.py 是优先级低的配置方式。
## 1.2 nb_log功能介绍
### 1.2.1 nb_log 支持日志根据级别自动变彩色
如图:日志彩色符合交通灯颜色认知。绿色是debug等级的日志,天蓝色是info等级日志,
黄色是warnning等级的警告日志,粉红色是error等级的错误日志,血红色是criticl等级的严重错误日志
### 1.2.1b 设置是否需要彩色
nb_log支持自动彩色,也支持关闭背景色块只要颜色,也支持彻底不要颜色所有日志显示为正常黑白颜色。
可以在你项目根目录下自动生成的nb_log_config.py配置文件中修改相关配置,来控制是否需要颜色,或者要颜色但不要大块的背景色块。
```angular2html
如果反对日志有各种彩色,可以设置 DEFAULUT_USE_COLOR_HANDLER = False
如果反对日志有块状背景彩色,可以设置 DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = False
如果想屏蔽nb_log包对怎么设置pycahrm的颜色的提示,可以设置 WARNING_PYCHARM_COLOR_SETINGS = False
如果想改变日志模板,可以设置 FORMATTER_KIND 参数,只带了7种模板,可以自定义添加喜欢的模板
LOG_PATH 配置文件日志的保存路径的文件夹。
```
### 1.2.1c 关于彩色显示效果的最终显示的说明
有的人听说了python显示颜色的博客,例如这种
[python print显示颜色](https://www.cnblogs.com/ping-y/p/5897018.html)
```
python在控制台可以同时显示7种颜色,但是同时显示不出来65536种颜色,pycahrm控制台/win cmd/linux的控制台终端不是浏览器网页,不能显示丰富的65536色模式,
只能暴露7种ansi颜色钩子,显示控制台输出的终端软件一般提供了颜色的自定义设置,例如 pycahrm finashell xhsell
这些软件都可以对ansi颜色自定义65536色模式的颜色代码,
例如nb_log启动时候就打印提示了教用户怎么设置颜色。
例如一件拍摄街道的彩色相片有60多种颜色,在cmd pycahrm终端是不可能同时显示出那么多种颜色的。
例如你想要控制台显示杨幂穿的淡红色衣服的颜色,控制台能做得到吗?当然是能做到得,但不是在python种 用所谓得 \033[ 来设置颜色,
因为软件终端只能识别7种ansi颜色钩子,红色在65536色模式下最起码也有几万种颜色代码,有白浅红色 水红色 大红色 粉红色 红的发紫的红色 红得发黑的红色,
所以你想精确得让控制台显示多种不同的红色,你自己用大脑想想呗,仅仅在python print中 \033就想得到理想的所需的红色,简直是做梦吧。
我说的是要精确控制颜色,不能光靠python的\033[,而是要在python的终端输出软件中设置颜色。例如pycharm xhsell finashell软件中都支持自定义颜色。
所以有些小白用户觉得颜色不好看,让我在配置文件中放开自定义颜色,这是不可行的,颜色最终的显示效果由控制台终端决定,不是所谓的\033能决定的,
例如我就想问 \033后面加什么字母能精确得到桃红色 金黄色 亮绿色这些 ,这么简单的想不到吗?如果控制台自动支持65536种颜色同时显示,那么nb_log可以暴露出来怎么配置颜色。
例如 \033[32 是绿色,但是软件终端中重定义ansi 颜色,可以让你代码的\033[32 显示出1万种不同的绿色,当然也可以让\033[32 绿色但是显示成黄色 紫色啥的,
因为最终渲染颜色效果是由终端决定,不是代码中\033后面数字来决定的。用户需要在软件终端中重新定义颜色,拿pycahrm为例,设置各种想要的颜色30秒钟,配置颜色要不了很久。
```
### 1.2.1d pycharm中精确设置控制台颜色的方式
```
要说明的是,即使是同一个颜色代码在pycahrm不同主题都是颜色显示区别很大的,默认的可能很丑或者由于颜色不好导致文字看不清晰
为了达到我这种色彩效果需要重新设置主题颜色,在控制台输出的第一行就教大家怎么设置颜色了。
也可以按下面设置,需要花30秒设置。
1)使用pycharm时候,建议重新自定义设置pycharm的console里面的主题颜色。
设置方式为 打开pycharm的 file -> settings -> Editor -> Color Scheme -> Console Colors 选择monokai,
并重新修改自定义7个颜色,设置Blue为 0454F3 ,Cyan为 04DCF8 ,Green 为 13FC02 ,Magenta为 ff1cd5 ,red为 F80606 ,yellow为 EAFA04 ,gray 为 FFFFFF ,white 为 FFFFFF 。
如果设置为显示背景色快,由于不同版本的pycahrm或主题,可以根据控制台实际显示设置 White 为 1F1F1F, Black 为 FFFFFF,因为背景色是深色,前景色的文字设置为白色比黑色好。
2)使用xshell或finashell工具连接linux也可以自定义主题颜色,默认使用shell连接工具的颜色也可以。
```
### 1.2.2 nb_log 不仅支持日志变彩色,还支持项目中所有python文件的任意print自动变彩色
```
导入nb_log时候会给内置的 ptint 打猴子补丁,所以用户所有地方的print行为自动发生了变化,重定向到nb_log定义的print了
```
### 1.2.2b print自动化效果转换的好处说明
```
自动转换print效果,再也不怕有人在项目中随意print,导致很难找到是从哪里冒出来的print。
只要import nb_log,项目所有地方的print自动现型并在控制台可点击几精确跳转到print的地方。
在项目里面的几百个文件中疯狂print真的让人很生气,一个run.py运行起来几百个py文件,
每个文件print 七八次,到底自己想看想关心的print是在控制台的哪一行呢,找到老眼昏花都找不到。
比如打印x变量的值,有人是为了省代码直接 print(x),而没有多打几个字母使用print("x的值是:",x),
这样打印出来的x变量,根本无法通过全局查找找到打印x变量是在什么py文件的哪一行。
有人说把之前的print全部用#注释不就好了,那这要全局找找print,一个一个的修改,一个10万行项目,
就算平均100行有一个print关键字,那起码也得有1000个print关键字吧,一个个的修改那要改到猴年马月呢。
只有使用nb_log,才能让一切print妖魔鬼怪自动现形。
另外,在正式项目或工具类甚至做得包里面,疯狂print真的很low,可以参考大神的三方包,从来都没直接print的不存在的,
他们都是用的日志。
日志比print灵活多了,对命名空间的控制、级别过滤控制、模板自定义、能记录到的地方扩展性很强远强过print的只有控制台。
```
### 1.2.2c nb_log 五彩日志的效果截图
[](https://postimg.cc/HJ2shsBC)
## 1.3 nb_log 支持pycharm控制台点击日志精确跳转到打印日志的文件和行号
[](https://postimg.cc/w3WRBF5d)
## 1.4 nb_log是原生logging类型,兼容性 扩展性非常好。
nb_log 是基于python自带的原生logging模块封装的, nb_log.get_logger()生成的日志类型是 原生logging.Logger类型,
所以nb_log包对常用三方包日志兼容性替换芯做到了100%。是否是原生日志非常重要,logbook和loguru都不是python自带的原生日志,
所以和三方包结合或者替换性不好。
```
比如logru和logbook这种三方库,完全重新写的日志,
它里面主要被用户使用的logger变量类型不是python内置Logger类型,
造成logger说拥有的属性和方法有的不存在或者不一致,这样的日志和python内置的经典日志兼容性差,
只能兼容(一键替换logger类型)一些简单的debug info warning errror等方法,。
```
## 1.5 nb_log 能够简单讲日志记录到十几种地方的任意几种的组合。
内置了一键入参,每个参数是独立开关,可以把日志同时记录到10几个常用的地方的任意几种组合,
包括 控制台 文件 钉钉 邮件 mongo kafka es 等等 。
有的人以为日志只能记录到控制台和文件,其实是错的,日志可以记录到很多种地方,日志记录到哪里,是由logger添加了什么handler决定的。
## 1.6 日志命名空间独立,采用了多实例logger,按日志命名空间区分。
```python
"""
命名空间独立意味着每个logger单独的日志界别过滤,单独的控制要记录到哪些地方。
"""
from nb_log import get_logger, LogManager
logger_aa = LogManager('aa').get_logger_and_add_handlers(10, log_filename='aa.log')
logger_bb = get_logger("bb", log_level_int=30, is_add_stream_handler=False, ding_talk_token='your_dingding_token')
logger_cc = get_logger('cc', log_level_int=10, log_filename='cc.log')
logger_aa.debug('哈哈哈')
# 将会同时记录到控制台和文件aa.log中,只要debug及debug以上级别都会记录。
logger_bb.warning('嘿嘿嘿')
# 将只会发送到钉钉群消息,并且logger_bb的info debug级别日志不会被记录,非常方便测试调试然后稳定了调高界别到生产。
logger_cc.debug('嘻嘻')
# logger_cc的日志会写在cc.log中,和logger_aa的日志是不同的文件。
```
## 1.7 对内置looging包打了猴子补丁,使日志永远不会使用同种handler重复记录 ,例如,原生的
```
from logging import getLogger,StreamHandler
logger = getLogger('hi')
getLogger('hi').addHandler(StreamHandler())
getLogger('hi').addHandler(StreamHandler())
getLogger('hi').addHandler(StreamHandler())
logger.warning('啦啦啦')
明明只warning了一次,但实际会造成 啦啦啦 在控制台打印3次。
使用nb_log,对同一命名空间的日志,可以无惧反复添加同类型handler,不会重复记录。
关于重复记录的例子,更惨的例子在文档后面的例子,直接把机器cpu性能耗尽,磁盘弄爆炸。
```
## 1.8 nb_log使用对比原生logging和 loguru 更简单
### 1.8.1 logging 代码方式创建logger对象
```python
import logging
logger = logging.getLogger('my.logger.namespace')
fh = logging.FileHandler('test.log') # 可以向文件发送日志
ch = logging.StreamHandler() # 可以向屏幕发送日志
fm = logging.Formatter('%(asctime)s %(message)s') # 打印格式
fh.setFormatter(fm)
ch.setFormatter(fm)
logger.addHandler(fh)
logger.addHandler(ch)
logger.setLevel(logging.DEBUG) # 设置级别
logger.debug('debug 喜喜')
```
有些人简直是怕了原生logging了,为了创建一个好用的logger对象,代码步骤复杂的吓人,很多人完全没看懂这段代码意义,
因为他是一步步创建观察者handler,给handler设置好看的formattor,给给被观察者添加多个观察者对象。
大部分人不看设计模式,不仅不懂观察者模式,而且没听说观察者模式,所以这种创建logger方式完全蒙蔽的节奏。
其实这样一步步的写代码是为了给用户最大的自由来怎么创建一个所需的logger对象。如果高度封装创建logger过程那是简单了,
但是自定义自由度就下降了。
logging是原生日志,每个三方包肯定使用logging了,为了兼容性和看懂三方包,那肯定是要学习logging的,对logging望而却步,
想投机取巧只使用loguru是行不通的,三方包不会使用loguru,三方包里面各种命名空间的日志,等待用户添加handlers来记录日志,
loguru缺点太大了。
nb_log把logging创建logger封装了,但同时get_logger暴露了很多个入参,来让用户自由自定义logger添加什么handler和设置什么formattor。
所以nb_log有原生logging的普遍兼容性,又使用简单
### 1.8.2 python中 创建logger的第二种方式,logging.config.dictConfig()
```python
import logging
import logging.config
LOGGING_CONFIG = {
"version": 1,
"formatters": {
"default": {
'format':'%(asctime)s %(filename)s %(lineno)s %(levelname)s %(message)s',
},
"plain": {
"format": "%(message)s",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "default",
},
"console_plain": {
"class": "logging.StreamHandler",
"level":logging.INFO,
"formatter": "plain"
},
"file":{
"class": "logging.FileHandler",
"level":20,
"filename": "./log.txt",
"formatter": "default",
}
},
"loggers": {
"console_logger": {
"handlers": ["console"],
"level": "INFO",
"propagate": False,
},
"console_plain_file_logger": {
"handlers": ["console_plain","file"],
"level": "DEBUG",
"propagate": False,
},
"file_logger":{
"handlers": ["file"],
"level": "INFO",
"propagate": False,
}
},
"disable_existing_loggers": True,
}
# 运行测试
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("console_logger")
logger.debug('debug message')
logger.info('info message')
logger.warn('warning message')
logger.error('error message')
logger.critical('critical message')
```
这种方式和上面1.8.1的方式差不多, 但不需要写大量python代码来创建logger对象。
虽然不需要写大量python代码来构建logger对象,但是需要写 LOGGING_CONFIG 字典,
这种字典如果写错了导致配置不生效或者报错,还是很麻烦的。很多人对这个配置完全蒙蔽,不知道什么意思。
先创建formattor,创建文件和控制台handler(当然也可以自定义发送钉钉的handler),handler设置日志过滤级别,handler设置formattor,
不同的handler可以设置不同的formattor,例如同样是 logger.debug("hello world"),可以使文件和控制台记录的这条日志的前缀和字段不一样。
对不同命名空间的logger添加不同的handlers,
例如你只想打印控制台 就 logger = logging.getLogger("console_logger"),然后用这个logger.info(xxx)就可以打印控制台了。
例如你只想打写入文件 就 logger = logging.getLogger("file_logger"),然后用这个logger.info(xxx)就可以打印控制台了。
例如你打写入文件并且打印控制台 就 logger = logging.getLogger("console_plain_file_logger"),然后用这个logger.info(xxx)就可以打印控制台并且同时写入文件了。
对1.8.1和1.8.2不理解造成恐惧,是使大家使用loguru的主要原因。
### 1.8.3 loguru的简单使用
```python
from loguru import logger
logger.add("./log_files/loguru-test1.log", rotation="100000 KB")
logger.info("hello")
```
```
代码是loguru打印控制台和写入文件,和nb_log一样代码少。
甚至如果用户不需要写入文件只需要导入logger就好了,
from loguru import logger
logger.info("hello")
看起来很简单,nb_log还需要 get_logger一下,有的人觉得loguru少写一行代码,直接import就能使用了,所以loguru简单牛逼。
nb_log早就知道有人会这么想了,nb_log也支持导入即可使用。
from nb_log import defaul_logger
defaul_logger.info("hello")
但这样有个弊端,用户想使用什么日志模板,用户希望日志记录到 控制台 文件 钉钉 es中的哪几个地方没法定义。
用户如果想屏蔽a函数里面的日志,但想放开b函数里面的日志,这种不传参/不设置日志命名空间的日志就无能为力做到了。
所以nb_log推荐用户调用get_logger函数来自定义日志,而不是直接import defaul_logger然后所有地方都使用这个 defaul_logger来记录日志。
```
综上所述 nb_log既使用简单,又兼容性高。
## 1.9 内置logging包的日志命名空间是什么
```python
import logging
logger1 = logging.getLogger('aaa')
logger2 = logging.getLogger('aaa')
logger3 = logging.getLogger('bbb')
print('logger1 id: ',id(logger1),'logger2 id: ',id(logger2),'logger3 id: ',id(logger3))
```
运行上面可以发现 logger1和logger2对象是同一个id,logger3对象是另外一个id。
通过不同的日志命名空间,可以设置不同级别的日志显示,设置不同类型的日志记录到不同的文件,是否打印控制台,是否发送邮件 钉钉消息。
有的人到现在还是不知道日志命名空间的作用,对一个大项目的所有的日志只会处理成一种表现行为,悲了个剧。
## 1.10 nb_log比logurur有10胜
[nb_log比logurur有10个优点方面](https://nb-log-doc.readthedocs.io/zh_CN/latest/articles/c6.html)
## 1.20 完整readthedocs文档地址
[nb_log readthedocs文档链接](https://nb-log-doc.readthedocs.io/zh_CN/latest)
[nb_log 源码链接](https://github.com/ydf0509/nb_log)

<div> </div>
%package help
Summary: Development documents and examples for nb-log
Provides: python3-nb-log-doc
%description help
# 1.nb_log 简介
[nb_log readthedocs文档链接](https://nb-log-doc.readthedocs.io/zh_CN/latest)
[nb_log 源码链接](https://github.com/ydf0509/nb_log)
[](https://postimg.cc/HJ2shsBC)
文中文档较长,但其中大部分不是 讲解nb_log 的用法,是复习内置logging的概念。
是由于python人员不懂logging包的日志命名空间和python日志树形命名空间结构,不懂handlers和logger的关系是什么。
所以需要很长的篇幅。
很多pythoner到现在都不知道python的 logging.getLogger() 第一个入参的意义和作用,造成nb_log也不知道怎么使用多命名空间。
## 1.0 nb_log 安装
pip install nb_log
## 1.1 nb_log 简单使用例子
```python
print('导入nb_log之前的print是普通的')
from nb_log import get_logger
logger = get_logger('lalala',) # get_logger 只有一个name是必传递的,其他的参数不是必传。
# logger = get_logger('lalala',log_filename='lalala.log',formatter_template=5,log_file_handler_type=2) # get_logger有很多其他入参可以自由定制logger。
logger.debug(f'debug是绿色,说明是调试的,代码ok ')
logger.info('info是天蓝色,日志正常 ')
logger.warning('黄色yello,有警告了 ')
logger.error('粉红色说明代码有错误 ')
logger.critical('血红色,说明发生了严重错误 ')
print('导入nb_log之后的print是强化版的可点击跳转的')
```
### 1.1.b nb_log 的最核心函数 get_logger入参说明
```doctest
:param name: 日志命名空间,意义非常非常非常重要,有些人到现在还不知道 logging.getLogger() 第一个入参的作用,太low了。不同的name的logger可以表现出不同的行为。
例如让 aa命名空间的日志打印控制台并且写入到文件,并且只记录info级别以上,让 bb 命名空间的日志仅仅打印控制台,并且打印debug以上级别,
这种就可以通过不同的日志命名空间做到。
:param log_level_int: 日志输出级别,设置为 1 2 3 4 5,分别对应原生logging.DEBUG(10),logging.INFO(20),
logging.WARNING(30),logging.ERROR(40),logging.CRITICAL(50)级别,现在可以直接用10 20 30 40 50了,兼容了。
:param is_add_stream_handler: 是否打印日志到控制台,默认会打印控制台。
:param do_not_use_color_handler :是否禁止使用color彩色日志
:param log_path: 设置存放日志的文件夹路径,如果不设置,则取nb_log_config.LOG_PATH,如果配置中也没指定则自动在代码所在磁盘的根目录创建/pythonlogs文件夹,
非windwos下要注意账号权限问题(如果python没权限在根目录建/pythonlogs,则需要手动先创建好)
:param log_filename: 日志的名字,仅当log_path和log_filename都不为None时候才会写入到日志文件。用户不指定 log_filename 默认当作用户不希望把日志写入到文件中。
:param log_file_size :日志大小,单位M,默认100M
:param log_file_handler_type :这个值可以设置为 1 2 3 4 5 五种值,1为使用多进程安全按日志文件大小切割的文件日志,
2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个日志
3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题)
4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
:param mongo_url : mongodb的连接,为None时候不添加mongohandler
:param is_add_elastic_handler: 是否记录到es中。
:param is_add_kafka_handler: 日志是否发布到kafka。
:param ding_talk_token:钉钉机器人token
:param ding_talk_time_interval : 时间间隔,少于这个时间不发送钉钉消息
:param mail_handler_config : 邮件配置
:param is_add_mail_handler :是否发邮件
:param formatter_template :日志模板,如果为数字,则为nb_log_config.py字典formatter_dict的键对应的模板,
1为formatter_dict的详细模板,2为简要模板,5为最好模板。
如果值为logging.Formatter对象,则直接使用用户传入的模板,不从formatter_dict中选择模板。
```
log_filename 用于设置是否写入日志文件和写入什么文件中。有的人不看入参文档,就问nb_log为什么不写入日志文件中。
logger和handler是观察者模式,日志记录到哪些地方,是由添加了什么handlers决定的。
### 1.1.c nb_log配置文件的生成和导入。
项目中任意脚本使用nb_log,第一次运行代码时候,会自动在 sys.path[1] 目录下创建 nb_log_config.py文件并写入默认值。
之后nb_log 会自动 import nb_log_config, 如果import到这个模块了,控制台会提示读取了什么文件作为配置文件。
如果是 cmd或者linux运行不是pycharm,需要 设置 PYTHONPATH为项目根目录,这样就能自动在当前项目根目录下生成或者找到 nb_log_config.py了。
用户可以print(sys.path) print(sys.path[1]) 来查看 sys.path[1]的值是什么就知道了。
连PYTHONPATH作用是什么都不知道的python小白,一定要看下面文章 。
[pythonpath作用介绍的文章](https://github.com/ydf0509/pythonpathdemo)
### 1.1.d nb_log配置文件的一些参数说明。
```doctest
DEFAULUT_USE_COLOR_HANDLER = True # 是否默认使用有彩的日志。
DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = True # 在控制台是否显示彩色块状的日志。为False则不使用大块的背景颜色。
AUTO_PATCH_PRINT = True # 是否自动打print的猴子补丁,如果打了猴子补丁,print自动变色和可点击跳转。
SHOW_PYCHARM_COLOR_SETINGS = True # 有的人很反感启动代码时候提示教你怎么优化pycahrm控制台颜色,可以把这里设置为False
DEFAULT_ADD_MULTIPROCESSING_SAFE_ROATING_FILE_HANDLER = False # 是否默认同时将日志记录到记log文件记事本中,就是用户不指定 log_filename的值,会自动写入日志命名空间.log文件中。
LOG_FILE_SIZE = 100 # 单位是M,每个文件的切片大小,超过多少后就自动切割
LOG_FILE_BACKUP_COUNT = 14 # 对同一个日志文件,默认最多备份几个文件,超过就删除了。
LOG_PATH = '/pythonlogs' # 默认的日志文件夹,如果不写明磁盘名,则是项目代码所在磁盘的根目录下的/pythonlogs
# LOG_PATH = Path(__file__).absolute().parent / Path("pythonlogs") #这么配置就会自动在你项目的根目录下创建pythonlogs文件夹了并写入。
if os.name == 'posix': # linux非root用户和mac用户无法操作 /pythonlogs 文件夹,没有权限,默认修改为 home/[username] 下面了。例如你的linux用户名是 xiaomin,那么默认会创建并在 /home/xiaomin/pythonlogs文件夹下写入日志文件。
home_path = os.environ.get("HOME", '/') # 这个是获取linux系统的当前用户的主目录,不需要亲自设置
LOG_PATH = Path(home_path) / Path('pythonlogs') # linux mac 权限很严格,非root权限不能在/pythonlogs写入,修改一下默认值。
LOG_FILE_HANDLER_TYPE = 1 # 1 2 3 4 5
"""
LOG_FILE_HANDLER_TYPE 这个值可以设置为 1 2 3 4 5 四种值,
1为使用多进程安全按日志文件大小切割的文件日志,这是本人实现的批量写入日志,减少操作文件锁次数,测试10进程快速写入文件,win上性能比第5种提高了100倍,linux提升5倍
2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个新的日志文件。日志文件名字后缀自动加上日期。
3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题)
4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
"""
```
以上只是部分配置的例子,其他配置在你项目根目录下的 nb_log_config.py中都有默认值,自己按需修改设置。
其他例如日志模板定义,默认日志模板选择什么,都可以在 nb_log_config.py文件中设置。
### 1.1.1e 日志配置文件和get_logger传参的关系。
nb_log_config.py中是设置全局设置,get_logger是针对单个logger对象生成的设置。
例如 nb_log_config.py 中写 FORMATTER_KIND = 4,get_logger 传参 formatter_template=6,那么最终还是使用第6个日志模板。
如果get_logger函数没有传参指定就使用 nb_log_config.py中的配置。
就是说 get_logger 是优先级高的,nb_log_config.py 是优先级低的配置方式。
## 1.2 nb_log功能介绍
### 1.2.1 nb_log 支持日志根据级别自动变彩色
如图:日志彩色符合交通灯颜色认知。绿色是debug等级的日志,天蓝色是info等级日志,
黄色是warnning等级的警告日志,粉红色是error等级的错误日志,血红色是criticl等级的严重错误日志
### 1.2.1b 设置是否需要彩色
nb_log支持自动彩色,也支持关闭背景色块只要颜色,也支持彻底不要颜色所有日志显示为正常黑白颜色。
可以在你项目根目录下自动生成的nb_log_config.py配置文件中修改相关配置,来控制是否需要颜色,或者要颜色但不要大块的背景色块。
```angular2html
如果反对日志有各种彩色,可以设置 DEFAULUT_USE_COLOR_HANDLER = False
如果反对日志有块状背景彩色,可以设置 DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = False
如果想屏蔽nb_log包对怎么设置pycahrm的颜色的提示,可以设置 WARNING_PYCHARM_COLOR_SETINGS = False
如果想改变日志模板,可以设置 FORMATTER_KIND 参数,只带了7种模板,可以自定义添加喜欢的模板
LOG_PATH 配置文件日志的保存路径的文件夹。
```
### 1.2.1c 关于彩色显示效果的最终显示的说明
有的人听说了python显示颜色的博客,例如这种
[python print显示颜色](https://www.cnblogs.com/ping-y/p/5897018.html)
```
python在控制台可以同时显示7种颜色,但是同时显示不出来65536种颜色,pycahrm控制台/win cmd/linux的控制台终端不是浏览器网页,不能显示丰富的65536色模式,
只能暴露7种ansi颜色钩子,显示控制台输出的终端软件一般提供了颜色的自定义设置,例如 pycahrm finashell xhsell
这些软件都可以对ansi颜色自定义65536色模式的颜色代码,
例如nb_log启动时候就打印提示了教用户怎么设置颜色。
例如一件拍摄街道的彩色相片有60多种颜色,在cmd pycahrm终端是不可能同时显示出那么多种颜色的。
例如你想要控制台显示杨幂穿的淡红色衣服的颜色,控制台能做得到吗?当然是能做到得,但不是在python种 用所谓得 \033[ 来设置颜色,
因为软件终端只能识别7种ansi颜色钩子,红色在65536色模式下最起码也有几万种颜色代码,有白浅红色 水红色 大红色 粉红色 红的发紫的红色 红得发黑的红色,
所以你想精确得让控制台显示多种不同的红色,你自己用大脑想想呗,仅仅在python print中 \033就想得到理想的所需的红色,简直是做梦吧。
我说的是要精确控制颜色,不能光靠python的\033[,而是要在python的终端输出软件中设置颜色。例如pycharm xhsell finashell软件中都支持自定义颜色。
所以有些小白用户觉得颜色不好看,让我在配置文件中放开自定义颜色,这是不可行的,颜色最终的显示效果由控制台终端决定,不是所谓的\033能决定的,
例如我就想问 \033后面加什么字母能精确得到桃红色 金黄色 亮绿色这些 ,这么简单的想不到吗?如果控制台自动支持65536种颜色同时显示,那么nb_log可以暴露出来怎么配置颜色。
例如 \033[32 是绿色,但是软件终端中重定义ansi 颜色,可以让你代码的\033[32 显示出1万种不同的绿色,当然也可以让\033[32 绿色但是显示成黄色 紫色啥的,
因为最终渲染颜色效果是由终端决定,不是代码中\033后面数字来决定的。用户需要在软件终端中重新定义颜色,拿pycahrm为例,设置各种想要的颜色30秒钟,配置颜色要不了很久。
```
### 1.2.1d pycharm中精确设置控制台颜色的方式
```
要说明的是,即使是同一个颜色代码在pycahrm不同主题都是颜色显示区别很大的,默认的可能很丑或者由于颜色不好导致文字看不清晰
为了达到我这种色彩效果需要重新设置主题颜色,在控制台输出的第一行就教大家怎么设置颜色了。
也可以按下面设置,需要花30秒设置。
1)使用pycharm时候,建议重新自定义设置pycharm的console里面的主题颜色。
设置方式为 打开pycharm的 file -> settings -> Editor -> Color Scheme -> Console Colors 选择monokai,
并重新修改自定义7个颜色,设置Blue为 0454F3 ,Cyan为 04DCF8 ,Green 为 13FC02 ,Magenta为 ff1cd5 ,red为 F80606 ,yellow为 EAFA04 ,gray 为 FFFFFF ,white 为 FFFFFF 。
如果设置为显示背景色快,由于不同版本的pycahrm或主题,可以根据控制台实际显示设置 White 为 1F1F1F, Black 为 FFFFFF,因为背景色是深色,前景色的文字设置为白色比黑色好。
2)使用xshell或finashell工具连接linux也可以自定义主题颜色,默认使用shell连接工具的颜色也可以。
```
### 1.2.2 nb_log 不仅支持日志变彩色,还支持项目中所有python文件的任意print自动变彩色
```
导入nb_log时候会给内置的 ptint 打猴子补丁,所以用户所有地方的print行为自动发生了变化,重定向到nb_log定义的print了
```
### 1.2.2b print自动化效果转换的好处说明
```
自动转换print效果,再也不怕有人在项目中随意print,导致很难找到是从哪里冒出来的print。
只要import nb_log,项目所有地方的print自动现型并在控制台可点击几精确跳转到print的地方。
在项目里面的几百个文件中疯狂print真的让人很生气,一个run.py运行起来几百个py文件,
每个文件print 七八次,到底自己想看想关心的print是在控制台的哪一行呢,找到老眼昏花都找不到。
比如打印x变量的值,有人是为了省代码直接 print(x),而没有多打几个字母使用print("x的值是:",x),
这样打印出来的x变量,根本无法通过全局查找找到打印x变量是在什么py文件的哪一行。
有人说把之前的print全部用#注释不就好了,那这要全局找找print,一个一个的修改,一个10万行项目,
就算平均100行有一个print关键字,那起码也得有1000个print关键字吧,一个个的修改那要改到猴年马月呢。
只有使用nb_log,才能让一切print妖魔鬼怪自动现形。
另外,在正式项目或工具类甚至做得包里面,疯狂print真的很low,可以参考大神的三方包,从来都没直接print的不存在的,
他们都是用的日志。
日志比print灵活多了,对命名空间的控制、级别过滤控制、模板自定义、能记录到的地方扩展性很强远强过print的只有控制台。
```
### 1.2.2c nb_log 五彩日志的效果截图
[](https://postimg.cc/HJ2shsBC)
## 1.3 nb_log 支持pycharm控制台点击日志精确跳转到打印日志的文件和行号
[](https://postimg.cc/w3WRBF5d)
## 1.4 nb_log是原生logging类型,兼容性 扩展性非常好。
nb_log 是基于python自带的原生logging模块封装的, nb_log.get_logger()生成的日志类型是 原生logging.Logger类型,
所以nb_log包对常用三方包日志兼容性替换芯做到了100%。是否是原生日志非常重要,logbook和loguru都不是python自带的原生日志,
所以和三方包结合或者替换性不好。
```
比如logru和logbook这种三方库,完全重新写的日志,
它里面主要被用户使用的logger变量类型不是python内置Logger类型,
造成logger说拥有的属性和方法有的不存在或者不一致,这样的日志和python内置的经典日志兼容性差,
只能兼容(一键替换logger类型)一些简单的debug info warning errror等方法,。
```
## 1.5 nb_log 能够简单讲日志记录到十几种地方的任意几种的组合。
内置了一键入参,每个参数是独立开关,可以把日志同时记录到10几个常用的地方的任意几种组合,
包括 控制台 文件 钉钉 邮件 mongo kafka es 等等 。
有的人以为日志只能记录到控制台和文件,其实是错的,日志可以记录到很多种地方,日志记录到哪里,是由logger添加了什么handler决定的。
## 1.6 日志命名空间独立,采用了多实例logger,按日志命名空间区分。
```python
"""
命名空间独立意味着每个logger单独的日志界别过滤,单独的控制要记录到哪些地方。
"""
from nb_log import get_logger, LogManager
logger_aa = LogManager('aa').get_logger_and_add_handlers(10, log_filename='aa.log')
logger_bb = get_logger("bb", log_level_int=30, is_add_stream_handler=False, ding_talk_token='your_dingding_token')
logger_cc = get_logger('cc', log_level_int=10, log_filename='cc.log')
logger_aa.debug('哈哈哈')
# 将会同时记录到控制台和文件aa.log中,只要debug及debug以上级别都会记录。
logger_bb.warning('嘿嘿嘿')
# 将只会发送到钉钉群消息,并且logger_bb的info debug级别日志不会被记录,非常方便测试调试然后稳定了调高界别到生产。
logger_cc.debug('嘻嘻')
# logger_cc的日志会写在cc.log中,和logger_aa的日志是不同的文件。
```
## 1.7 对内置looging包打了猴子补丁,使日志永远不会使用同种handler重复记录 ,例如,原生的
```
from logging import getLogger,StreamHandler
logger = getLogger('hi')
getLogger('hi').addHandler(StreamHandler())
getLogger('hi').addHandler(StreamHandler())
getLogger('hi').addHandler(StreamHandler())
logger.warning('啦啦啦')
明明只warning了一次,但实际会造成 啦啦啦 在控制台打印3次。
使用nb_log,对同一命名空间的日志,可以无惧反复添加同类型handler,不会重复记录。
关于重复记录的例子,更惨的例子在文档后面的例子,直接把机器cpu性能耗尽,磁盘弄爆炸。
```
## 1.8 nb_log使用对比原生logging和 loguru 更简单
### 1.8.1 logging 代码方式创建logger对象
```python
import logging
logger = logging.getLogger('my.logger.namespace')
fh = logging.FileHandler('test.log') # 可以向文件发送日志
ch = logging.StreamHandler() # 可以向屏幕发送日志
fm = logging.Formatter('%(asctime)s %(message)s') # 打印格式
fh.setFormatter(fm)
ch.setFormatter(fm)
logger.addHandler(fh)
logger.addHandler(ch)
logger.setLevel(logging.DEBUG) # 设置级别
logger.debug('debug 喜喜')
```
有些人简直是怕了原生logging了,为了创建一个好用的logger对象,代码步骤复杂的吓人,很多人完全没看懂这段代码意义,
因为他是一步步创建观察者handler,给handler设置好看的formattor,给给被观察者添加多个观察者对象。
大部分人不看设计模式,不仅不懂观察者模式,而且没听说观察者模式,所以这种创建logger方式完全蒙蔽的节奏。
其实这样一步步的写代码是为了给用户最大的自由来怎么创建一个所需的logger对象。如果高度封装创建logger过程那是简单了,
但是自定义自由度就下降了。
logging是原生日志,每个三方包肯定使用logging了,为了兼容性和看懂三方包,那肯定是要学习logging的,对logging望而却步,
想投机取巧只使用loguru是行不通的,三方包不会使用loguru,三方包里面各种命名空间的日志,等待用户添加handlers来记录日志,
loguru缺点太大了。
nb_log把logging创建logger封装了,但同时get_logger暴露了很多个入参,来让用户自由自定义logger添加什么handler和设置什么formattor。
所以nb_log有原生logging的普遍兼容性,又使用简单
### 1.8.2 python中 创建logger的第二种方式,logging.config.dictConfig()
```python
import logging
import logging.config
LOGGING_CONFIG = {
"version": 1,
"formatters": {
"default": {
'format':'%(asctime)s %(filename)s %(lineno)s %(levelname)s %(message)s',
},
"plain": {
"format": "%(message)s",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "default",
},
"console_plain": {
"class": "logging.StreamHandler",
"level":logging.INFO,
"formatter": "plain"
},
"file":{
"class": "logging.FileHandler",
"level":20,
"filename": "./log.txt",
"formatter": "default",
}
},
"loggers": {
"console_logger": {
"handlers": ["console"],
"level": "INFO",
"propagate": False,
},
"console_plain_file_logger": {
"handlers": ["console_plain","file"],
"level": "DEBUG",
"propagate": False,
},
"file_logger":{
"handlers": ["file"],
"level": "INFO",
"propagate": False,
}
},
"disable_existing_loggers": True,
}
# 运行测试
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("console_logger")
logger.debug('debug message')
logger.info('info message')
logger.warn('warning message')
logger.error('error message')
logger.critical('critical message')
```
这种方式和上面1.8.1的方式差不多, 但不需要写大量python代码来创建logger对象。
虽然不需要写大量python代码来构建logger对象,但是需要写 LOGGING_CONFIG 字典,
这种字典如果写错了导致配置不生效或者报错,还是很麻烦的。很多人对这个配置完全蒙蔽,不知道什么意思。
先创建formattor,创建文件和控制台handler(当然也可以自定义发送钉钉的handler),handler设置日志过滤级别,handler设置formattor,
不同的handler可以设置不同的formattor,例如同样是 logger.debug("hello world"),可以使文件和控制台记录的这条日志的前缀和字段不一样。
对不同命名空间的logger添加不同的handlers,
例如你只想打印控制台 就 logger = logging.getLogger("console_logger"),然后用这个logger.info(xxx)就可以打印控制台了。
例如你只想打写入文件 就 logger = logging.getLogger("file_logger"),然后用这个logger.info(xxx)就可以打印控制台了。
例如你打写入文件并且打印控制台 就 logger = logging.getLogger("console_plain_file_logger"),然后用这个logger.info(xxx)就可以打印控制台并且同时写入文件了。
对1.8.1和1.8.2不理解造成恐惧,是使大家使用loguru的主要原因。
### 1.8.3 loguru的简单使用
```python
from loguru import logger
logger.add("./log_files/loguru-test1.log", rotation="100000 KB")
logger.info("hello")
```
```
代码是loguru打印控制台和写入文件,和nb_log一样代码少。
甚至如果用户不需要写入文件只需要导入logger就好了,
from loguru import logger
logger.info("hello")
看起来很简单,nb_log还需要 get_logger一下,有的人觉得loguru少写一行代码,直接import就能使用了,所以loguru简单牛逼。
nb_log早就知道有人会这么想了,nb_log也支持导入即可使用。
from nb_log import defaul_logger
defaul_logger.info("hello")
但这样有个弊端,用户想使用什么日志模板,用户希望日志记录到 控制台 文件 钉钉 es中的哪几个地方没法定义。
用户如果想屏蔽a函数里面的日志,但想放开b函数里面的日志,这种不传参/不设置日志命名空间的日志就无能为力做到了。
所以nb_log推荐用户调用get_logger函数来自定义日志,而不是直接import defaul_logger然后所有地方都使用这个 defaul_logger来记录日志。
```
综上所述 nb_log既使用简单,又兼容性高。
## 1.9 内置logging包的日志命名空间是什么
```python
import logging
logger1 = logging.getLogger('aaa')
logger2 = logging.getLogger('aaa')
logger3 = logging.getLogger('bbb')
print('logger1 id: ',id(logger1),'logger2 id: ',id(logger2),'logger3 id: ',id(logger3))
```
运行上面可以发现 logger1和logger2对象是同一个id,logger3对象是另外一个id。
通过不同的日志命名空间,可以设置不同级别的日志显示,设置不同类型的日志记录到不同的文件,是否打印控制台,是否发送邮件 钉钉消息。
有的人到现在还是不知道日志命名空间的作用,对一个大项目的所有的日志只会处理成一种表现行为,悲了个剧。
## 1.10 nb_log比logurur有10胜
[nb_log比logurur有10个优点方面](https://nb-log-doc.readthedocs.io/zh_CN/latest/articles/c6.html)
## 1.20 完整readthedocs文档地址
[nb_log readthedocs文档链接](https://nb-log-doc.readthedocs.io/zh_CN/latest)
[nb_log 源码链接](https://github.com/ydf0509/nb_log)

<div> </div>
%prep
%autosetup -n nb_log-8.6
%build
%py3_build
%install
%py3_install
install -d -m755 %{buildroot}/%{_pkgdocdir}
if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
pushd %{buildroot}
if [ -d usr/lib ]; then
find usr/lib -type f -printf "\"/%h/%f\"\n" >> filelist.lst
fi
if [ -d usr/lib64 ]; then
find usr/lib64 -type f -printf "\"/%h/%f\"\n" >> filelist.lst
fi
if [ -d usr/bin ]; then
find usr/bin -type f -printf "\"/%h/%f\"\n" >> filelist.lst
fi
if [ -d usr/sbin ]; then
find usr/sbin -type f -printf "\"/%h/%f\"\n" >> filelist.lst
fi
touch doclist.lst
if [ -d usr/share/man ]; then
find usr/share/man -type f -printf "\"/%h/%f.gz\"\n" >> doclist.lst
fi
popd
mv %{buildroot}/filelist.lst .
mv %{buildroot}/doclist.lst .
%files -n python3-nb-log -f filelist.lst
%dir %{python3_sitelib}/*
%files help -f doclist.lst
%{_docdir}/*
%changelog
* Fri Jun 09 2023 Python_Bot <Python_Bot@openeuler.org> - 8.6-1
- Package Spec generated
|