lyrpy 2024.0.4__py3-none-any.whl → 2025.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of lyrpy might be problematic. Click here for more details.
- SRC/LIB/__init__.py +21 -0
- SRC/LIB/lyrpy/LUConst.py +358 -0
- {lyrpy → SRC/LIB/lyrpy}/LUDateTime.py +2 -4
- {lyrpy → SRC/LIB/lyrpy}/LUDecotators.py +2 -3
- {lyrpy → SRC/LIB/lyrpy}/LUDict.py +0 -1
- {lyrpy → SRC/LIB/lyrpy}/LUDoc.py +4 -3
- {lyrpy → SRC/LIB/lyrpy}/LUErrors.py +0 -1
- {lyrpy → SRC/LIB/lyrpy}/LUFile.py +115 -61
- {lyrpy → SRC/LIB/lyrpy}/LUFileUtils.py +60 -45
- {lyrpy → SRC/LIB/lyrpy}/LULog.py +267 -191
- {lyrpy → SRC/LIB/lyrpy}/LUObjects.py +4 -4
- {lyrpy → SRC/LIB/lyrpy}/LUObjectsYT.py +39 -22
- {lyrpy → SRC/LIB/lyrpy}/LUParserARG.py +2 -3
- {lyrpy → SRC/LIB/lyrpy}/LUParserINI.py +8 -3
- {lyrpy → SRC/LIB/lyrpy}/LUParserREG.py +5 -1
- {lyrpy → SRC/LIB/lyrpy}/LUQThread.py +6 -4
- {lyrpy → SRC/LIB/lyrpy}/LUQTimer.py +5 -5
- {lyrpy → SRC/LIB/lyrpy}/LUSheduler.py +24 -23
- SRC/LIB/lyrpy/LUTelegram.py +428 -0
- {lyrpy → SRC/LIB/lyrpy}/LUThread.py +7 -6
- {lyrpy → SRC/LIB/lyrpy}/LUTimer.py +5 -3
- {lyrpy → SRC/LIB/lyrpy}/LUVersion.py +4 -1
- {lyrpy → SRC/LIB/lyrpy}/LUYouTube.py +6 -7
- {lyrpy → SRC/LIB/lyrpy}/LUos.py +13 -3
- SRC/LIB/lyrpy/__init__.py +21 -0
- {lyrpy → SRC/LIB/lyrpy}/__main__.py +20 -19
- SRC/__init__.py +0 -0
- SRC/lyrpy/LUConsole.py +402 -0
- SRC/lyrpy/LUConst.py +358 -0
- SRC/lyrpy/LUDateTime.py +205 -0
- SRC/lyrpy/LUDecotators.py +417 -0
- SRC/lyrpy/LUDict.py +116 -0
- SRC/lyrpy/LUDoc.py +62 -0
- SRC/lyrpy/LUErrors.py +79 -0
- SRC/lyrpy/LUFile.py +1228 -0
- SRC/lyrpy/LUFileUtils.py +501 -0
- SRC/lyrpy/LULog.py +2324 -0
- SRC/lyrpy/LUNetwork.py +277 -0
- SRC/lyrpy/LUNumUtils.py +305 -0
- SRC/lyrpy/LUObjects.py +208 -0
- SRC/lyrpy/LUObjectsYT.py +846 -0
- SRC/lyrpy/LUParserARG.py +364 -0
- SRC/lyrpy/LUParserINI.py +376 -0
- SRC/lyrpy/LUParserREG.py +514 -0
- SRC/lyrpy/LUProc.py +110 -0
- SRC/lyrpy/LUQThread.py +141 -0
- SRC/lyrpy/LUQTimer.py +197 -0
- SRC/lyrpy/LUSheduler.py +941 -0
- SRC/lyrpy/LUStrDecode.py +223 -0
- SRC/lyrpy/LUStrUtils.py +633 -0
- SRC/lyrpy/LUSupport.py +124 -0
- SRC/lyrpy/LUTelegram.py +428 -0
- SRC/lyrpy/LUThread.py +177 -0
- SRC/lyrpy/LUTimer.py +141 -0
- SRC/lyrpy/LUVersion.py +383 -0
- SRC/lyrpy/LUYouTube.py +203 -0
- SRC/lyrpy/LUos.py +807 -0
- lyrpy/LUConst.py → SRC/lyrpy/LUsys.py +12 -10
- SRC/lyrpy/__init__.py +21 -0
- lyrpy/__init__.py → SRC/lyrpy/__main__.py +2 -3
- TESTS/__init__.py +0 -0
- TESTS/test_lyrpy.py +4 -0
- TESTS/test_main.py +10 -0
- __SRC/LIB/__init__.py +0 -0
- __SRC/LIB/lyrpy/LUConsole.py +402 -0
- __SRC/LIB/lyrpy/LUConst.py +358 -0
- __SRC/LIB/lyrpy/LUDateTime.py +205 -0
- __SRC/LIB/lyrpy/LUDecotators.py +417 -0
- __SRC/LIB/lyrpy/LUDict.py +116 -0
- __SRC/LIB/lyrpy/LUDoc.py +62 -0
- __SRC/LIB/lyrpy/LUErrors.py +79 -0
- __SRC/LIB/lyrpy/LUFile.py +1228 -0
- __SRC/LIB/lyrpy/LUFileUtils.py +501 -0
- __SRC/LIB/lyrpy/LULog.py +2324 -0
- __SRC/LIB/lyrpy/LUNetwork.py +277 -0
- __SRC/LIB/lyrpy/LUNumUtils.py +305 -0
- __SRC/LIB/lyrpy/LUObjects.py +208 -0
- __SRC/LIB/lyrpy/LUObjectsYT.py +846 -0
- __SRC/LIB/lyrpy/LUParserARG.py +364 -0
- __SRC/LIB/lyrpy/LUParserINI.py +376 -0
- __SRC/LIB/lyrpy/LUParserREG.py +514 -0
- __SRC/LIB/lyrpy/LUProc.py +110 -0
- __SRC/LIB/lyrpy/LUQThread.py +141 -0
- __SRC/LIB/lyrpy/LUQTimer.py +197 -0
- __SRC/LIB/lyrpy/LUSheduler.py +941 -0
- __SRC/LIB/lyrpy/LUStrDecode.py +223 -0
- __SRC/LIB/lyrpy/LUStrUtils.py +633 -0
- __SRC/LIB/lyrpy/LUSupport.py +124 -0
- __SRC/LIB/lyrpy/LUTelegram.py +428 -0
- __SRC/LIB/lyrpy/LUThread.py +177 -0
- __SRC/LIB/lyrpy/LUTimer.py +141 -0
- __SRC/LIB/lyrpy/LUVersion.py +383 -0
- __SRC/LIB/lyrpy/LUYouTube.py +203 -0
- __SRC/LIB/lyrpy/LUos.py +807 -0
- __SRC/LIB/lyrpy/LUsys.py +47 -0
- __SRC/LIB/lyrpy/__init__.py +21 -0
- __SRC/LIB/lyrpy/__main__.py +20 -0
- __SRC/__init__.py +0 -0
- ____src/__init__.py +0 -0
- ____src/lyrpy/LUConsole.py +402 -0
- ____src/lyrpy/LUConst.py +358 -0
- ____src/lyrpy/LUDateTime.py +205 -0
- ____src/lyrpy/LUDecotators.py +417 -0
- ____src/lyrpy/LUDict.py +116 -0
- ____src/lyrpy/LUDoc.py +62 -0
- ____src/lyrpy/LUErrors.py +79 -0
- ____src/lyrpy/LUFile.py +1228 -0
- ____src/lyrpy/LUFileUtils.py +501 -0
- ____src/lyrpy/LULog.py +2324 -0
- ____src/lyrpy/LUNetwork.py +277 -0
- ____src/lyrpy/LUNumUtils.py +305 -0
- ____src/lyrpy/LUObjects.py +208 -0
- ____src/lyrpy/LUObjectsYT.py +846 -0
- ____src/lyrpy/LUParserARG.py +364 -0
- ____src/lyrpy/LUParserINI.py +376 -0
- ____src/lyrpy/LUParserREG.py +514 -0
- ____src/lyrpy/LUProc.py +110 -0
- ____src/lyrpy/LUQThread.py +141 -0
- ____src/lyrpy/LUQTimer.py +197 -0
- ____src/lyrpy/LUSheduler.py +941 -0
- ____src/lyrpy/LUStrDecode.py +223 -0
- ____src/lyrpy/LUStrUtils.py +633 -0
- ____src/lyrpy/LUSupport.py +124 -0
- ____src/lyrpy/LUTelegram.py +428 -0
- ____src/lyrpy/LUThread.py +177 -0
- ____src/lyrpy/LUTimer.py +141 -0
- ____src/lyrpy/LUVersion.py +383 -0
- ____src/lyrpy/LUYouTube.py +203 -0
- ____src/lyrpy/LUos.py +807 -0
- ____src/lyrpy/LUsys.py +47 -0
- ____src/lyrpy/__init__.py +21 -0
- ____src/lyrpy/__main__.py +20 -0
- lyrpy-2025.0.2.dist-info/METADATA +21 -0
- lyrpy-2025.0.2.dist-info/RECORD +145 -0
- {lyrpy-2024.0.4.dist-info → lyrpy-2025.0.2.dist-info}/WHEEL +1 -1
- lyrpy-2025.0.2.dist-info/top_level.txt +2 -0
- lyrpy-2024.0.4.data/data/data/text.txt +0 -1
- lyrpy-2024.0.4.dist-info/METADATA +0 -44
- lyrpy-2024.0.4.dist-info/RECORD +0 -38
- lyrpy-2024.0.4.dist-info/top_level.txt +0 -1
- {lyrpy → SRC/LIB/lyrpy}/LUConsole.py +0 -0
- {lyrpy → SRC/LIB/lyrpy}/LUNetwork.py +0 -0
- {lyrpy → SRC/LIB/lyrpy}/LUNumUtils.py +0 -0
- {lyrpy → SRC/LIB/lyrpy}/LUProc.py +0 -0
- {lyrpy → SRC/LIB/lyrpy}/LUStrDecode.py +0 -0
- {lyrpy → SRC/LIB/lyrpy}/LUStrUtils.py +0 -0
- {lyrpy → SRC/LIB/lyrpy}/LUSupport.py +0 -0
- {lyrpy → SRC/LIB/lyrpy}/LUsys.py +0 -0
- {lyrpy-2024.0.4.dist-info → lyrpy-2025.0.2.dist-info/licenses}/LICENSE +0 -0
SRC/lyrpy/LULog.py
ADDED
|
@@ -0,0 +1,2324 @@
|
|
|
1
|
+
"""LULog.py"""
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
__annotations__ ="""
|
|
4
|
+
=======================================================
|
|
5
|
+
Copyright (c) 2023-2024
|
|
6
|
+
Author:
|
|
7
|
+
Lisitsin Y.R.
|
|
8
|
+
Project:
|
|
9
|
+
LU_PY
|
|
10
|
+
Python (LU)
|
|
11
|
+
Module:
|
|
12
|
+
LULog.py
|
|
13
|
+
|
|
14
|
+
=======================================================
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
#------------------------------------------
|
|
18
|
+
# БИБЛИОТЕКИ python
|
|
19
|
+
#------------------------------------------
|
|
20
|
+
import os
|
|
21
|
+
import sys
|
|
22
|
+
import enum
|
|
23
|
+
import datetime
|
|
24
|
+
import copy
|
|
25
|
+
import logging
|
|
26
|
+
import logging.config
|
|
27
|
+
import yaml
|
|
28
|
+
import json
|
|
29
|
+
import shutil
|
|
30
|
+
|
|
31
|
+
import inspect
|
|
32
|
+
import traceback
|
|
33
|
+
|
|
34
|
+
#------------------------------------------
|
|
35
|
+
# БИБЛИОТЕКИ сторонние
|
|
36
|
+
#------------------------------------------
|
|
37
|
+
import pythonjsonlogger
|
|
38
|
+
import pythonjsonlogger.jsonlogger
|
|
39
|
+
#------------------------------------------
|
|
40
|
+
import PySide6.QtWidgets
|
|
41
|
+
|
|
42
|
+
#------------------------------------------
|
|
43
|
+
# БИБЛИОТЕКА LU
|
|
44
|
+
#------------------------------------------
|
|
45
|
+
import lyrpy.LUConst as LUConst
|
|
46
|
+
import lyrpy.LUFile as LUFile
|
|
47
|
+
import lyrpy.LUConsole as LUConsole
|
|
48
|
+
import lyrpy.LUDateTime as LUDateTime
|
|
49
|
+
import lyrpy.LUos as LUos
|
|
50
|
+
import lyrpy.LUParserINI as LUParserINI
|
|
51
|
+
import lyrpy.LUDict as LUDict
|
|
52
|
+
import lyrpy.LUSupport as LUSupport
|
|
53
|
+
|
|
54
|
+
import rich
|
|
55
|
+
import rich.console as console
|
|
56
|
+
GConsoleRich = rich.console.Console ()
|
|
57
|
+
|
|
58
|
+
# ===========================================================================
|
|
59
|
+
# CONST
|
|
60
|
+
# ===========================================================================
|
|
61
|
+
"""CONST"""
|
|
62
|
+
ctlsNOTSET = ' '
|
|
63
|
+
ctlsDEBUG = 'D'
|
|
64
|
+
ctlsINFO = 'I'
|
|
65
|
+
ctlsWARNING = 'W'
|
|
66
|
+
ctlsERROR = 'E'
|
|
67
|
+
ctlsCRITICAL = 'C'
|
|
68
|
+
ctlsBEGIN = '>'
|
|
69
|
+
ctlsEND = '<'
|
|
70
|
+
ctlsPROCESS = 'P'
|
|
71
|
+
ctlsDEBUGTEXT = 'T'
|
|
72
|
+
ctlsTEXT = ''
|
|
73
|
+
|
|
74
|
+
TruncLog = 1
|
|
75
|
+
LogPath = ''
|
|
76
|
+
Log = 30
|
|
77
|
+
LogDir = ''
|
|
78
|
+
LogFile = ''
|
|
79
|
+
|
|
80
|
+
# ДОБАВИТЬ LEVEL
|
|
81
|
+
DEBUGTEXT = 11
|
|
82
|
+
BEGIN = 21
|
|
83
|
+
END = 22
|
|
84
|
+
PROCESS = 23
|
|
85
|
+
TEXT = 24
|
|
86
|
+
|
|
87
|
+
# строка формата сообщения
|
|
88
|
+
# Cstrfmt_04 = '%(asctime)s %(msecs)03d [%(name)s] %(levelno)02d %(levelname)-8s %(module)s %(message)s'
|
|
89
|
+
Cstrfmt_01 = '%(asctime)s [%(name)s] [%(module)-15s] %(levelno)02d %(levelname)-10s %(lineno)04d %(message)s'
|
|
90
|
+
Cstrfmt_02 = '%(asctime)s %(name)s %(levelname)-10s %(message)s'
|
|
91
|
+
# строка формата времени
|
|
92
|
+
Cdatefmt_01 = '%d/%m/%Y %H:%M:%S'
|
|
93
|
+
# style
|
|
94
|
+
Cstyle_01 = '%'
|
|
95
|
+
Cstyle_02 = '{'
|
|
96
|
+
Cstyle_03 = '$'
|
|
97
|
+
# defaults
|
|
98
|
+
Cdefaults = {"ip": '_ip_'}
|
|
99
|
+
|
|
100
|
+
def AddLevelName():
|
|
101
|
+
#beginfunction
|
|
102
|
+
logging.addLevelName(DEBUGTEXT, 'DEBUGTEXT')
|
|
103
|
+
logging.addLevelName(BEGIN, 'BEGIN')
|
|
104
|
+
logging.addLevelName(END, 'END')
|
|
105
|
+
logging.addLevelName(PROCESS, 'PROCESS')
|
|
106
|
+
logging.addLevelName(TEXT, 'TEXT')
|
|
107
|
+
#endfunction
|
|
108
|
+
|
|
109
|
+
CDefaultFileLogINI = 'logging.ini'
|
|
110
|
+
CDefaultFileLogINI_CONSOLE = 'logging_CONSOLE.INI'
|
|
111
|
+
CDefaultFileLogCONFIG = 'logging.CONFIG'
|
|
112
|
+
CDefaultFileLogYAML = 'logging.YAML'
|
|
113
|
+
|
|
114
|
+
CDefaultFileLog = 'LOGGING.log'
|
|
115
|
+
CDefaultFileLogFILEINI = 'LOGGING_FILEINI.log'
|
|
116
|
+
CDefaultFileLogFILEINI_json = 'LOGGING_FILEINI_json.log'
|
|
117
|
+
|
|
118
|
+
CDefaultFileLogFILECONFIG = 'LOGGING_CONFIG.log'
|
|
119
|
+
CDefaultFileLogFILECONFIG_json = 'LOGGING_FILECONFIG_json.log'
|
|
120
|
+
|
|
121
|
+
CDefaultFileLogFILEBASIC = 'LOGGING_BASIC.log'
|
|
122
|
+
|
|
123
|
+
# ===========================================================================
|
|
124
|
+
# type
|
|
125
|
+
# ===========================================================================
|
|
126
|
+
@enum.unique
|
|
127
|
+
class TTypeSETUPLOG (enum.Enum):
|
|
128
|
+
"""TTypeSETUPLOG"""
|
|
129
|
+
tslCONFIG = 0
|
|
130
|
+
tslYAML = 1
|
|
131
|
+
tslINI = 2
|
|
132
|
+
@classmethod
|
|
133
|
+
def Empty (cls):
|
|
134
|
+
...
|
|
135
|
+
#endclass
|
|
136
|
+
|
|
137
|
+
@enum.unique
|
|
138
|
+
class TTypeLogString(enum.Enum):
|
|
139
|
+
"""TTypeLogString"""
|
|
140
|
+
tlsNOTSET = ctlsNOTSET
|
|
141
|
+
tlsDEBUG = ctlsDEBUG
|
|
142
|
+
tlsINFO = ctlsINFO
|
|
143
|
+
tlsWARNING = ctlsWARNING
|
|
144
|
+
tlsERROR = ctlsERROR
|
|
145
|
+
tlsCRITICAL = ctlsCRITICAL
|
|
146
|
+
tlsBEGIN = ctlsBEGIN
|
|
147
|
+
tlsEND = ctlsEND
|
|
148
|
+
tlsPROCESS = ctlsPROCESS
|
|
149
|
+
tlsDEBUGTEXT = ctlsDEBUGTEXT
|
|
150
|
+
tlsTEXT = ctlsTEXT
|
|
151
|
+
@classmethod
|
|
152
|
+
def Empty(cls):
|
|
153
|
+
...
|
|
154
|
+
#endclass
|
|
155
|
+
|
|
156
|
+
@enum.unique
|
|
157
|
+
class TTypeLogCODE (enum.Enum):
|
|
158
|
+
"""TTypeLogCODE"""
|
|
159
|
+
tlcOEM = 0
|
|
160
|
+
tlcANSI = 1
|
|
161
|
+
@classmethod
|
|
162
|
+
def Empty (cls):
|
|
163
|
+
...
|
|
164
|
+
#endclass
|
|
165
|
+
|
|
166
|
+
@enum.unique
|
|
167
|
+
class TLogOutput (enum.Enum):
|
|
168
|
+
loStandard = 0
|
|
169
|
+
loTextFile = 1
|
|
170
|
+
@classmethod
|
|
171
|
+
def Empty (cls):
|
|
172
|
+
...
|
|
173
|
+
#endclass
|
|
174
|
+
|
|
175
|
+
Cbold = 'bold '
|
|
176
|
+
Cblue = 'blue'
|
|
177
|
+
Cwhite = 'white'
|
|
178
|
+
Cyellow = 'yellow'
|
|
179
|
+
Cred = 'red'
|
|
180
|
+
Cgreen = 'green'
|
|
181
|
+
Con = 'on'
|
|
182
|
+
|
|
183
|
+
Cbold_blue = Cbold+Cblue
|
|
184
|
+
Cbold_white = Cbold+Cwhite
|
|
185
|
+
Cbold_yellow = Cbold+Cyellow
|
|
186
|
+
Cbold_red = Cbold+Cred
|
|
187
|
+
Cbold_red_blue = Cbold+Cred+' on '+Cblue
|
|
188
|
+
Cbold_green = Cbold+Cred
|
|
189
|
+
|
|
190
|
+
COLORS_tls = {
|
|
191
|
+
TTypeLogString.tlsNOTSET: LUConsole.cFG8_BLUE + LUConsole.sEND,
|
|
192
|
+
TTypeLogString.tlsDEBUG: LUConsole.cFG8_BLUE + LUConsole.sEND,
|
|
193
|
+
TTypeLogString.tlsINFO: LUConsole.cFG8_WHITE + LUConsole.sEND,
|
|
194
|
+
TTypeLogString.tlsWARNING: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_YELLOW + LUConsole.sEND,
|
|
195
|
+
TTypeLogString.tlsERROR: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_RED + LUConsole.sEND,
|
|
196
|
+
TTypeLogString.tlsCRITICAL: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_BLACK + ';' + LUConsole.cBG8_RED + LUConsole.sEND,
|
|
197
|
+
TTypeLogString.tlsBEGIN: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_GREEN + LUConsole.sEND,
|
|
198
|
+
TTypeLogString.tlsEND: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_GREEN + LUConsole.sEND,
|
|
199
|
+
TTypeLogString.tlsPROCESS: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_GREEN + LUConsole.sEND,
|
|
200
|
+
TTypeLogString.tlsDEBUGTEXT: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_BLUE + LUConsole.sEND,
|
|
201
|
+
TTypeLogString.tlsTEXT: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_YELLOW + LUConsole.sEND
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
COLORS_tls_rich = {
|
|
205
|
+
TTypeLogString.tlsNOTSET: Cbold_blue,
|
|
206
|
+
TTypeLogString.tlsDEBUG: Cbold_blue,
|
|
207
|
+
TTypeLogString.tlsINFO: Cbold_white,
|
|
208
|
+
TTypeLogString.tlsWARNING: Cbold_yellow,
|
|
209
|
+
TTypeLogString.tlsERROR: Cbold_red,
|
|
210
|
+
TTypeLogString.tlsCRITICAL: Cbold_red_blue,
|
|
211
|
+
TTypeLogString.tlsBEGIN: Cbold_green,
|
|
212
|
+
TTypeLogString.tlsEND: Cbold_green,
|
|
213
|
+
TTypeLogString.tlsPROCESS: Cbold_green,
|
|
214
|
+
TTypeLogString.tlsDEBUGTEXT: Cbold_blue,
|
|
215
|
+
TTypeLogString.tlsTEXT: Cbold_yellow
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
COLORS = {
|
|
219
|
+
logging.NOTSET: LUConsole.cFG8_BLUE + LUConsole.sEND,
|
|
220
|
+
logging.DEBUG: LUConsole.cFG8_BLUE + LUConsole.sEND,
|
|
221
|
+
logging.INFO: LUConsole.cFG8_WHITE + LUConsole.sEND,
|
|
222
|
+
logging.WARNING: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_YELLOW + LUConsole.sEND,
|
|
223
|
+
logging.ERROR: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_RED + LUConsole.sEND,
|
|
224
|
+
logging.CRITICAL: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_BLACK + ';' + LUConsole.cBG8_RED + LUConsole.sEND,
|
|
225
|
+
BEGIN: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_GREEN + LUConsole.sEND,
|
|
226
|
+
END: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_GREEN + LUConsole.sEND,
|
|
227
|
+
PROCESS: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_GREEN + LUConsole.sEND,
|
|
228
|
+
DEBUGTEXT: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_BLUE + LUConsole.sEND,
|
|
229
|
+
TEXT: LUConsole.cS_BOLD + ';' + LUConsole.cFG8_YELLOW + LUConsole.sEND
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
COLORS_rich = {
|
|
233
|
+
logging.NOTSET: Cbold_blue,
|
|
234
|
+
logging.DEBUG: Cbold_blue,
|
|
235
|
+
logging.INFO: Cbold_white,
|
|
236
|
+
logging.WARNING: Cbold_yellow,
|
|
237
|
+
logging.ERROR: Cbold_red,
|
|
238
|
+
logging.CRITICAL: Cbold_red_blue,
|
|
239
|
+
BEGIN: Cbold_green,
|
|
240
|
+
END: Cbold_green,
|
|
241
|
+
PROCESS: Cbold_green,
|
|
242
|
+
DEBUGTEXT: Cbold_blue,
|
|
243
|
+
TEXT: Cbold_yellow
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
#TLogOutputs = set of TLogOutput;
|
|
247
|
+
|
|
248
|
+
class TFileMemoLog (object):
|
|
249
|
+
"""TFileMemoLog"""
|
|
250
|
+
luClassName = "TFileMemoLog"
|
|
251
|
+
|
|
252
|
+
#--------------------------------------------------
|
|
253
|
+
# constructor
|
|
254
|
+
#--------------------------------------------------
|
|
255
|
+
def __init__(self):
|
|
256
|
+
"""Constructor"""
|
|
257
|
+
#beginfunction
|
|
258
|
+
super().__init__()
|
|
259
|
+
self.__FCountLogStrings: int = 200
|
|
260
|
+
self.__FFileName: str = ''
|
|
261
|
+
self.__FStandardOut: bool = True
|
|
262
|
+
self.__FLogCODE: TTypeLogCODE = TTypeLogCODE.tlcANSI
|
|
263
|
+
self.__FLogEnabled: bool = True
|
|
264
|
+
self.__FTruncateDays: int = 3
|
|
265
|
+
self.__FLogStringOEM: str = ''
|
|
266
|
+
self.__FLogStringAnsi: str = ''
|
|
267
|
+
self.__FMemoLog = None #TMemo
|
|
268
|
+
self.__FLogStrings: list = list() #TStringList;
|
|
269
|
+
self.__FLogSave: list = list() #TStringList;
|
|
270
|
+
self.__FLogCODE = LUFile.cDefaultEncoding
|
|
271
|
+
self.__FConsoleRich = rich.console.Console()
|
|
272
|
+
|
|
273
|
+
# self.__FLogger: logging.Logger = CreateLoggerFILEINI (CDefaultFileLogINI, 'root')
|
|
274
|
+
|
|
275
|
+
self.Clear ()
|
|
276
|
+
#endfunction
|
|
277
|
+
|
|
278
|
+
#--------------------------------------------------
|
|
279
|
+
# destructor
|
|
280
|
+
#--------------------------------------------------
|
|
281
|
+
def __del__(self):
|
|
282
|
+
"""destructor"""
|
|
283
|
+
#beginfunction
|
|
284
|
+
del self.__FLogStrings
|
|
285
|
+
del self.__FLogSave
|
|
286
|
+
# LClassName = self.__class__.__name__
|
|
287
|
+
# s = '{} уничтожен'.format (LClassName)
|
|
288
|
+
# print (s)
|
|
289
|
+
#endfunction
|
|
290
|
+
|
|
291
|
+
def Clear(self):
|
|
292
|
+
"""Clear"""
|
|
293
|
+
#beginfunction
|
|
294
|
+
...
|
|
295
|
+
#endfunction
|
|
296
|
+
|
|
297
|
+
#--------------------------------------------------
|
|
298
|
+
# @property LogCODE
|
|
299
|
+
#--------------------------------------------------
|
|
300
|
+
@property
|
|
301
|
+
# getter
|
|
302
|
+
def LogCODE (self) -> int:
|
|
303
|
+
#beginfunction
|
|
304
|
+
return self.__FLogCODE
|
|
305
|
+
#endfunction
|
|
306
|
+
@LogCODE.setter
|
|
307
|
+
def LogCODE (self, Value: int):
|
|
308
|
+
#beginfunction
|
|
309
|
+
self.__FLogCODE = Value
|
|
310
|
+
#endfunction
|
|
311
|
+
|
|
312
|
+
#--------------------------------------------------
|
|
313
|
+
# @property CountLogStrings
|
|
314
|
+
#--------------------------------------------------
|
|
315
|
+
@property
|
|
316
|
+
# getter
|
|
317
|
+
def CountLogStrings (self) -> int:
|
|
318
|
+
#beginfunction
|
|
319
|
+
return self.__FCountLogStrings
|
|
320
|
+
#endfunction
|
|
321
|
+
@CountLogStrings.setter
|
|
322
|
+
def CountLogStrings (self, Value: int):
|
|
323
|
+
#beginfunction
|
|
324
|
+
self.__FCountLogStrings = Value
|
|
325
|
+
#endfunction
|
|
326
|
+
|
|
327
|
+
#--------------------------------------------------
|
|
328
|
+
# @property LogEnabled
|
|
329
|
+
#--------------------------------------------------
|
|
330
|
+
# getter
|
|
331
|
+
@property
|
|
332
|
+
def LogEnabled (self) -> bool:
|
|
333
|
+
#beginfunction
|
|
334
|
+
return self.__FLogEnabled
|
|
335
|
+
#endfunction
|
|
336
|
+
@LogEnabled.setter
|
|
337
|
+
def LogEnabled (self, Value: bool):
|
|
338
|
+
#beginfunction
|
|
339
|
+
self.__FLogEnabled = Value
|
|
340
|
+
#endfunction
|
|
341
|
+
|
|
342
|
+
#--------------------------------------------------
|
|
343
|
+
# @property Filename
|
|
344
|
+
#--------------------------------------------------
|
|
345
|
+
# getter
|
|
346
|
+
@property
|
|
347
|
+
def FileName (self) -> str:
|
|
348
|
+
#beginfunction
|
|
349
|
+
return self.__FFileName
|
|
350
|
+
#endfunction
|
|
351
|
+
@FileName.setter
|
|
352
|
+
def FileName (self, Value: str):
|
|
353
|
+
#beginfunction
|
|
354
|
+
self.__FFileName = Value
|
|
355
|
+
if len(self.__FFileName) > 0 and LUFile.FileExists (self.__FFileName):
|
|
356
|
+
# FMemoLog.Lines.LoadFromFile (self.__FFileName);
|
|
357
|
+
...
|
|
358
|
+
#endif
|
|
359
|
+
#endfunction
|
|
360
|
+
|
|
361
|
+
#--------------------------------------------------
|
|
362
|
+
# @property StandardOut
|
|
363
|
+
#--------------------------------------------------
|
|
364
|
+
# getter
|
|
365
|
+
@property
|
|
366
|
+
def StandardOut (self) -> bool:
|
|
367
|
+
#beginfunction
|
|
368
|
+
return self.__FStandardOut
|
|
369
|
+
#endfunction
|
|
370
|
+
@StandardOut.setter
|
|
371
|
+
def StandardOut (self, Value: bool):
|
|
372
|
+
#beginfunction
|
|
373
|
+
self.__FStandardOut = Value
|
|
374
|
+
#endfunction
|
|
375
|
+
|
|
376
|
+
#--------------------------------------------------
|
|
377
|
+
# @property MemoLog
|
|
378
|
+
#--------------------------------------------------
|
|
379
|
+
# getter
|
|
380
|
+
@property
|
|
381
|
+
def MemoLog (self):
|
|
382
|
+
#beginfunction
|
|
383
|
+
return self.__FMemoLog
|
|
384
|
+
#endfunction
|
|
385
|
+
@MemoLog.setter
|
|
386
|
+
def MemoLog (self, Value):
|
|
387
|
+
#beginfunction
|
|
388
|
+
self.__FMemoLog = Value
|
|
389
|
+
# if FMemoLog <> nil then
|
|
390
|
+
# begin
|
|
391
|
+
# with FMemoLog do
|
|
392
|
+
# begin
|
|
393
|
+
# Clear;
|
|
394
|
+
# Align := alClient;
|
|
395
|
+
# readonly := True;
|
|
396
|
+
# TabStop := False;
|
|
397
|
+
# WantReturns := False;
|
|
398
|
+
# WantTabs := False;
|
|
399
|
+
# WordWrap := False;
|
|
400
|
+
# ParentColor := True;
|
|
401
|
+
# ScrollBars := ssVertical;
|
|
402
|
+
# ScrollBars := ssBoth;
|
|
403
|
+
# end;
|
|
404
|
+
# if (Filename <> '') and FileExists (Filename) then
|
|
405
|
+
# begin
|
|
406
|
+
# try
|
|
407
|
+
# FMemoLog.Lines.LoadFromFile (Filename);
|
|
408
|
+
# except
|
|
409
|
+
# end;
|
|
410
|
+
# end;
|
|
411
|
+
# end;
|
|
412
|
+
...
|
|
413
|
+
#endfunction
|
|
414
|
+
|
|
415
|
+
def _SetMemoLog (self, Value): #TMemo
|
|
416
|
+
"""_SetMemoLog"""
|
|
417
|
+
#beginfunction
|
|
418
|
+
...
|
|
419
|
+
#endfunction
|
|
420
|
+
|
|
421
|
+
@staticmethod
|
|
422
|
+
def _LogDateStr (ATimeOnly: bool) -> str:
|
|
423
|
+
"""LogDateStr"""
|
|
424
|
+
#beginfunction
|
|
425
|
+
LToday: datetime.datetime = LUDateTime.Now ()
|
|
426
|
+
if ATimeOnly:
|
|
427
|
+
LResult = ' '*15 + LUDateTime.DateTimeStr (ATimeOnly, LToday, LUDateTime.cFormatDateTimeLog01, True)
|
|
428
|
+
else:
|
|
429
|
+
LResult = LUDateTime.DateTimeStr (ATimeOnly, LToday, LUDateTime.cFormatDateTimeLog01, True)
|
|
430
|
+
#endif
|
|
431
|
+
return LResult
|
|
432
|
+
#endfunction
|
|
433
|
+
|
|
434
|
+
def _GetLogSave (self, Filename: str) -> list: #TStringList
|
|
435
|
+
"""_GetLogSave"""
|
|
436
|
+
#beginfunction
|
|
437
|
+
...
|
|
438
|
+
#endfunction
|
|
439
|
+
|
|
440
|
+
def _GetLogSaveCurrent (self) -> list: #TStringList;
|
|
441
|
+
#beginfunction
|
|
442
|
+
"""_GetLogSaveCurrent"""
|
|
443
|
+
LResult = self._GetLogSave (self.__FFileName)
|
|
444
|
+
return LResult
|
|
445
|
+
#endfunction
|
|
446
|
+
|
|
447
|
+
def TruncateLog (self):
|
|
448
|
+
"""TruncateLog"""
|
|
449
|
+
#beginfunction
|
|
450
|
+
# Filename
|
|
451
|
+
ts: list = list()
|
|
452
|
+
if LUFile.FileExists (self.__FFileName):
|
|
453
|
+
# Открыть для чтения
|
|
454
|
+
LEncoding = LUFile.GetFileEncoding (self.__FFileName)
|
|
455
|
+
LFile = open (self.__FFileName, 'r', encoding = LEncoding)
|
|
456
|
+
try:
|
|
457
|
+
# работа с файлом
|
|
458
|
+
for s in LFile:
|
|
459
|
+
ts.append (s)
|
|
460
|
+
#file.next() возвращает следующую строку файла
|
|
461
|
+
#endfor
|
|
462
|
+
except:
|
|
463
|
+
s = f'TruncateLog: Неправильная кодировка журнала!'
|
|
464
|
+
LoggerTOOLS.error(s)
|
|
465
|
+
finally:
|
|
466
|
+
LFile.close ()
|
|
467
|
+
# TruncateMemo (ts)
|
|
468
|
+
# try
|
|
469
|
+
# ts.SaveToFile (Filename)
|
|
470
|
+
# except:
|
|
471
|
+
# #endtry
|
|
472
|
+
#endif
|
|
473
|
+
del ts
|
|
474
|
+
|
|
475
|
+
# Memo
|
|
476
|
+
ts: list = list()
|
|
477
|
+
if self.__FMemoLog is not None:
|
|
478
|
+
ts.clear()
|
|
479
|
+
# ts.Assign (FMemoLog.Lines)
|
|
480
|
+
# TruncateMemo (ts)
|
|
481
|
+
# FMemoLog.Clear
|
|
482
|
+
# FMemoLog.Lines.Assign (ts)
|
|
483
|
+
#endif
|
|
484
|
+
del ts
|
|
485
|
+
#endfunction
|
|
486
|
+
|
|
487
|
+
def _HandlerCONSOLE (self, T: TTypeLogString):
|
|
488
|
+
"""_HandlerCONSOLE"""
|
|
489
|
+
#beginfunction
|
|
490
|
+
|
|
491
|
+
# if self.FUseColor:
|
|
492
|
+
|
|
493
|
+
self.__FLogStrings.clear ()
|
|
494
|
+
self.__FLogStrings.append (self.__FLogStringAnsi)
|
|
495
|
+
for s in self.__FLogStrings:
|
|
496
|
+
if T == TTypeLogString.tlsTEXT:
|
|
497
|
+
_s = s
|
|
498
|
+
else:
|
|
499
|
+
_s = self._LogDateStr (False) + ' ' + str(T.value) + ' ' + s
|
|
500
|
+
if not LUSupport.IsTerminal ():
|
|
501
|
+
LCOLOR = COLORS_tls.get (T)
|
|
502
|
+
if LCOLOR is not None:
|
|
503
|
+
LFmt = LUConsole.sBEGIN_oct + LCOLOR + _s + LUConsole.sRESET
|
|
504
|
+
else:
|
|
505
|
+
LFmt = _s
|
|
506
|
+
LUConsole.WriteLN (LFmt)
|
|
507
|
+
else:
|
|
508
|
+
LCOLOR = COLORS_tls_rich.get (T)
|
|
509
|
+
LFmt = _s
|
|
510
|
+
if len(LCOLOR) > 0:
|
|
511
|
+
LFmt = '[' + LCOLOR + ']' + _s
|
|
512
|
+
else:
|
|
513
|
+
LFmt = s
|
|
514
|
+
self.__FConsoleRich.print (LFmt)
|
|
515
|
+
#endif
|
|
516
|
+
#endfor
|
|
517
|
+
#endfunction
|
|
518
|
+
|
|
519
|
+
def _HandlerFILE (self, T: TTypeLogString):
|
|
520
|
+
"""_HandlerFILE"""
|
|
521
|
+
#beginfunction
|
|
522
|
+
s = LUFile.ExpandFileName (self.__FFileName)
|
|
523
|
+
s = LUFile.ExtractFileDir (s)
|
|
524
|
+
if len (s) > 0:
|
|
525
|
+
if not LUFile.DirectoryExists (s):
|
|
526
|
+
LUFile.ForceDirectories (s)
|
|
527
|
+
#endif
|
|
528
|
+
#endif
|
|
529
|
+
|
|
530
|
+
self.__FLogStrings.clear ()
|
|
531
|
+
self.__FLogStrings.append (self.__FLogStringAnsi)
|
|
532
|
+
|
|
533
|
+
for s in self.__FLogStrings:
|
|
534
|
+
if T == TTypeLogString.tlsTEXT:
|
|
535
|
+
_s = s
|
|
536
|
+
else:
|
|
537
|
+
_s = self._LogDateStr (False) + ' ' + str(T.value) + ' ' + s
|
|
538
|
+
#endif
|
|
539
|
+
try:
|
|
540
|
+
LEncoding = self.__FLogCODE
|
|
541
|
+
|
|
542
|
+
# LEncoding = LUFile.GetFileEncoding (self.__FFileName)
|
|
543
|
+
# if LEncoding == '':
|
|
544
|
+
# LEncoding = LUFile.cDefaultEncoding
|
|
545
|
+
|
|
546
|
+
LEncoding = LUFile.cDefaultEncoding
|
|
547
|
+
with open (self.__FFileName, 'a+', encoding = LEncoding) as LFile:
|
|
548
|
+
|
|
549
|
+
# _s = str (s.encode ('utf-8'), 'cp1251')
|
|
550
|
+
# _s = str (s.encode ('cp1251'), 'cp1251')
|
|
551
|
+
|
|
552
|
+
# _s = str (_s.encode (self.__FLogCODE), self.__FLogCODE)
|
|
553
|
+
|
|
554
|
+
LFile.write (_s + '\n')
|
|
555
|
+
|
|
556
|
+
#endwith
|
|
557
|
+
except:
|
|
558
|
+
s = f'_HandlerFILE: Неправильная кодировка журнала!'
|
|
559
|
+
LoggerTOOLS.error (s)
|
|
560
|
+
#endtry
|
|
561
|
+
#endfor
|
|
562
|
+
#endfunction
|
|
563
|
+
|
|
564
|
+
def _Execute (self, T: TTypeLogString):
|
|
565
|
+
"""_Execute"""
|
|
566
|
+
#beginfunction
|
|
567
|
+
# StandardOut
|
|
568
|
+
if self.__FStandardOut: # and isConsole:
|
|
569
|
+
self._HandlerCONSOLE (T)
|
|
570
|
+
#endif
|
|
571
|
+
# Filename
|
|
572
|
+
if self.__FFileName != '':
|
|
573
|
+
self._HandlerFILE (T)
|
|
574
|
+
#endif
|
|
575
|
+
# Memo
|
|
576
|
+
if self.__FMemoLog is not None:
|
|
577
|
+
self.__FLogStrings.clear()
|
|
578
|
+
self.__FLogStrings.append(self.__FLogStringAnsi)
|
|
579
|
+
"""
|
|
580
|
+
for s in self.__FLogStrings:
|
|
581
|
+
self.__FMemoLog.add
|
|
582
|
+
#endfor
|
|
583
|
+
"""
|
|
584
|
+
#endif
|
|
585
|
+
#endfunction
|
|
586
|
+
|
|
587
|
+
#--------------------------------------------------
|
|
588
|
+
#
|
|
589
|
+
#--------------------------------------------------
|
|
590
|
+
def AddLog (self, T: TTypeLogString, Value: str):
|
|
591
|
+
"""AddLog"""
|
|
592
|
+
#beginfunction
|
|
593
|
+
self.__FLogStringOEM = Value
|
|
594
|
+
self.__FLogStringAnsi = Value
|
|
595
|
+
if self.LogEnabled:
|
|
596
|
+
self._Execute(T)
|
|
597
|
+
#endif
|
|
598
|
+
#endfunction
|
|
599
|
+
|
|
600
|
+
def AddLogFile (self, AFileName: str):
|
|
601
|
+
"""AddLogFile"""
|
|
602
|
+
#beginfunction
|
|
603
|
+
if LUFile.FileExists (AFileName):
|
|
604
|
+
LEncoding = LUFile.GetFileEncoding (AFileName)
|
|
605
|
+
if LEncoding == '':
|
|
606
|
+
LEncoding = LUFile.cDefaultEncoding
|
|
607
|
+
#endif
|
|
608
|
+
try:
|
|
609
|
+
# работа с файлом
|
|
610
|
+
with open (AFileName, 'r', encoding = LEncoding) as LFile:
|
|
611
|
+
for s in LFile:
|
|
612
|
+
self.AddLog (TTypeLogString.tlsTEXT, s.rstrip('\n'))
|
|
613
|
+
#endfor
|
|
614
|
+
#endwith
|
|
615
|
+
except:
|
|
616
|
+
self.AddLog (TTypeLogString.tlsERROR, AFileName)
|
|
617
|
+
s = f'AddLogFile: Неправильная кодировка журнала!'
|
|
618
|
+
LoggerTOOLS.error (s)
|
|
619
|
+
#endtry
|
|
620
|
+
#endif
|
|
621
|
+
#endfunction
|
|
622
|
+
#endclass
|
|
623
|
+
|
|
624
|
+
#----------------------------------------------
|
|
625
|
+
# TLogging
|
|
626
|
+
#----------------------------------------------
|
|
627
|
+
|
|
628
|
+
#-------------------------------------------------
|
|
629
|
+
# TLogRecord(logging.LogRecord):
|
|
630
|
+
#-------------------------------------------------
|
|
631
|
+
class TLogRecord(logging.LogRecord):
|
|
632
|
+
"""TLogRecord"""
|
|
633
|
+
luClassName = "TLogRecord"
|
|
634
|
+
#--------------------------------------------------
|
|
635
|
+
# constructor
|
|
636
|
+
#--------------------------------------------------
|
|
637
|
+
#class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)
|
|
638
|
+
def __init__(self, **kwargs):
|
|
639
|
+
"""Constructor"""
|
|
640
|
+
#beginfunction
|
|
641
|
+
logging.LogRecord.__init__(self, **kwargs)
|
|
642
|
+
#endfunction
|
|
643
|
+
#endclass
|
|
644
|
+
|
|
645
|
+
#-------------------------------------------------
|
|
646
|
+
# THandler(logging.Handler):
|
|
647
|
+
#-------------------------------------------------
|
|
648
|
+
class THandler(logging.Handler):
|
|
649
|
+
"""THandler"""
|
|
650
|
+
luClassName = "THandler"
|
|
651
|
+
#--------------------------------------------------
|
|
652
|
+
# constructor
|
|
653
|
+
#--------------------------------------------------
|
|
654
|
+
#class logging.Handler
|
|
655
|
+
def __init__(self, parent, **kwargs):
|
|
656
|
+
# def __init__ (self, parent):
|
|
657
|
+
"""Constructor"""
|
|
658
|
+
#beginfunction
|
|
659
|
+
logging.Handler.__init__(self, **kwargs)
|
|
660
|
+
# super ().__init__ ()
|
|
661
|
+
|
|
662
|
+
self.__Fwidget = None
|
|
663
|
+
# self.__Fwidget = PySide6.QtWidgets.QPlainTextEdit (parent)
|
|
664
|
+
# self.__Fwidget.setReadOnly (True)
|
|
665
|
+
#endfunction
|
|
666
|
+
|
|
667
|
+
#--------------------------------------------------
|
|
668
|
+
# @property widget
|
|
669
|
+
#--------------------------------------------------
|
|
670
|
+
# getter
|
|
671
|
+
@property
|
|
672
|
+
def widget (self):
|
|
673
|
+
#beginfunction
|
|
674
|
+
return self.__Fwidget
|
|
675
|
+
#endfunction
|
|
676
|
+
@widget.setter
|
|
677
|
+
def widget (self, Value):
|
|
678
|
+
#beginfunction
|
|
679
|
+
self.__Fwidget = Value
|
|
680
|
+
#endfunction
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
def emit(self, record):
|
|
684
|
+
if self.widget is None:
|
|
685
|
+
super (THandler, self).emit (record)
|
|
686
|
+
else:
|
|
687
|
+
msg = self.format (record)
|
|
688
|
+
self.widget.appendPlainText (msg)
|
|
689
|
+
#endif
|
|
690
|
+
#endclass
|
|
691
|
+
|
|
692
|
+
#-------------------------------------------------
|
|
693
|
+
# class TStreamHandler(logging.StreamHandler):
|
|
694
|
+
#-------------------------------------------------
|
|
695
|
+
class TStreamHandler(logging.StreamHandler):
|
|
696
|
+
"""TStreamHandler"""
|
|
697
|
+
luClassName = "TStreamHandler"
|
|
698
|
+
#--------------------------------------------------
|
|
699
|
+
# constructor
|
|
700
|
+
#--------------------------------------------------
|
|
701
|
+
def __init__(self, *args, **kwargs):
|
|
702
|
+
"""Constructor"""
|
|
703
|
+
#beginfunction
|
|
704
|
+
logging.StreamHandler.__init__(self, *args, **kwargs)
|
|
705
|
+
self.name = 'CONSOLE'
|
|
706
|
+
self.FAPPGUI = False
|
|
707
|
+
|
|
708
|
+
self.__FConsoleRich = rich.console.Console()
|
|
709
|
+
|
|
710
|
+
self.__FWidget:PySide6.QtWidgets.QPlainTextEdit = None
|
|
711
|
+
# self.__Fwidget = PySide6.QtWidgets.QPlainTextEdit (parent)
|
|
712
|
+
# self.__Fwidget = PySide6.QtWidgets.QPlainTextEdit ()
|
|
713
|
+
# self.__Fwidget.setReadOnly (True)
|
|
714
|
+
|
|
715
|
+
#endfunction
|
|
716
|
+
|
|
717
|
+
#--------------------------------------------------
|
|
718
|
+
# @property widget
|
|
719
|
+
#--------------------------------------------------
|
|
720
|
+
# getter
|
|
721
|
+
@property
|
|
722
|
+
def Widget (self):
|
|
723
|
+
#beginfunction
|
|
724
|
+
return self.__FWidget
|
|
725
|
+
#endfunction
|
|
726
|
+
@Widget.setter
|
|
727
|
+
def Widget (self, Value):
|
|
728
|
+
#beginfunction
|
|
729
|
+
self.__FWidget = Value
|
|
730
|
+
#endfunction
|
|
731
|
+
|
|
732
|
+
#--------------------------------------------------
|
|
733
|
+
# emit
|
|
734
|
+
#--------------------------------------------------
|
|
735
|
+
def emit(self, record):
|
|
736
|
+
"""emit"""
|
|
737
|
+
#beginfunction
|
|
738
|
+
if type(self.formatter) is TFormatter:
|
|
739
|
+
LFormatter: TFormatter = self.formatter
|
|
740
|
+
# widget
|
|
741
|
+
if not self.Widget is None:
|
|
742
|
+
b = LFormatter.FUseColor
|
|
743
|
+
LFormatter.FUseColor = False
|
|
744
|
+
msg = LFormatter.format (record)
|
|
745
|
+
self.Widget.appendPlainText (msg)
|
|
746
|
+
# self.widget.document().end()
|
|
747
|
+
self.Widget.verticalScrollBar().setValue (self.Widget.verticalScrollBar().maximum ())
|
|
748
|
+
LFormatter.FUseColor = b
|
|
749
|
+
#endif
|
|
750
|
+
|
|
751
|
+
if LFormatter.FUseColor:
|
|
752
|
+
# self.emit(record)
|
|
753
|
+
try:
|
|
754
|
+
msg = self.format(record)
|
|
755
|
+
stream = self.stream
|
|
756
|
+
# issue 35046: merged two stream.writes into one.
|
|
757
|
+
if not LUSupport.IsTerminal ():
|
|
758
|
+
stream.write(msg + self.terminator)
|
|
759
|
+
self.flush()
|
|
760
|
+
else:
|
|
761
|
+
msg = self.format (record)
|
|
762
|
+
if not self.FAPPGUI:
|
|
763
|
+
#rich.print (msg)
|
|
764
|
+
self.__FConsoleRich.print(msg)
|
|
765
|
+
#endif
|
|
766
|
+
#endif
|
|
767
|
+
except RecursionError: # See issue 36272
|
|
768
|
+
raise
|
|
769
|
+
except Exception:
|
|
770
|
+
self.handleError(record)
|
|
771
|
+
#endtry
|
|
772
|
+
#endif
|
|
773
|
+
else:
|
|
774
|
+
super(TStreamHandler, self).emit(record)
|
|
775
|
+
#endif
|
|
776
|
+
#endfunction
|
|
777
|
+
#endclass
|
|
778
|
+
|
|
779
|
+
#-------------------------------------------------
|
|
780
|
+
# TFilter(logging.Filter):
|
|
781
|
+
#-------------------------------------------------
|
|
782
|
+
class TFilter(logging.Filter):
|
|
783
|
+
"""TFilter"""
|
|
784
|
+
luClassName = "TFilter"
|
|
785
|
+
COLOR = {
|
|
786
|
+
"DEBUG": "BLUE",
|
|
787
|
+
"INFO": "WHITE",
|
|
788
|
+
"WARNING": "YELLOW",
|
|
789
|
+
"ERROR": "RED",
|
|
790
|
+
"CRITICAL": "RED",
|
|
791
|
+
"DEBUGTEXT": "RED",
|
|
792
|
+
"BEGIN": "RED",
|
|
793
|
+
"END": "RED",
|
|
794
|
+
"PROCESS": "RED",
|
|
795
|
+
"TEXT": "RED"
|
|
796
|
+
}
|
|
797
|
+
#--------------------------------------------------
|
|
798
|
+
# constructor
|
|
799
|
+
#--------------------------------------------------
|
|
800
|
+
#class logging.Filter (name='')
|
|
801
|
+
def __init__(self, **kwargs):
|
|
802
|
+
"""Constructor"""
|
|
803
|
+
#beginfunction
|
|
804
|
+
logging.Filter.__init__(self, **kwargs)
|
|
805
|
+
#endfunction
|
|
806
|
+
|
|
807
|
+
def filter(self, record):
|
|
808
|
+
#beginfunction
|
|
809
|
+
record.color = self.COLOR[record.levelname]
|
|
810
|
+
#print(record.color)
|
|
811
|
+
return True
|
|
812
|
+
#endfunction
|
|
813
|
+
#endclass
|
|
814
|
+
|
|
815
|
+
# #-------------------------------------------------
|
|
816
|
+
# # TFilter(logging.Filter):
|
|
817
|
+
# #-------------------------------------------------
|
|
818
|
+
# # Фильтр, который вводит контекстную информацию в журнал.
|
|
819
|
+
# # Вместо того, чтобы использовать фактическую контекстуальную информацию, мы
|
|
820
|
+
# # просто используем случайные данные в этой демонстрации.
|
|
821
|
+
# from random import choice
|
|
822
|
+
#
|
|
823
|
+
# class TFilter (logging.Filter):
|
|
824
|
+
# """TFilter"""
|
|
825
|
+
# luClassName = "TFilter"
|
|
826
|
+
# USERS = ['jim', 'fred', 'sheila']
|
|
827
|
+
# IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1']
|
|
828
|
+
# def filter(self, record):
|
|
829
|
+
# #beginfunction
|
|
830
|
+
# record.ip = choice(TFilter.IPS)
|
|
831
|
+
# record.user = choice(TFilter.USERS)
|
|
832
|
+
# return True
|
|
833
|
+
# #endfunction
|
|
834
|
+
# #endclass
|
|
835
|
+
#
|
|
836
|
+
# def Test ():
|
|
837
|
+
# #beginfunction
|
|
838
|
+
# levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
|
|
839
|
+
# logging.basicConfig(level=logging.DEBUG,
|
|
840
|
+
# format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
|
|
841
|
+
# a1 = logging.getLogger('a.b.c')
|
|
842
|
+
# a2 = logging.getLogger('d.e.f')
|
|
843
|
+
# f = TFilter()
|
|
844
|
+
# a1.addFilter(f)
|
|
845
|
+
# a2.addFilter(f)
|
|
846
|
+
# a1.debug('A debug message')
|
|
847
|
+
# a1.info('An info message with %s', 'some parameters')
|
|
848
|
+
# for x in range(10):
|
|
849
|
+
# lvl = choice(levels)
|
|
850
|
+
# lvlname = logging.getLevelName(lvl)
|
|
851
|
+
# a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
|
|
852
|
+
# #endfunction
|
|
853
|
+
|
|
854
|
+
#-------------------------------------------------
|
|
855
|
+
# TAdapter(logging.LoggerAdapter):
|
|
856
|
+
#-------------------------------------------------
|
|
857
|
+
class TAdapter(logging.LoggerAdapter):
|
|
858
|
+
"""TAdapter"""
|
|
859
|
+
luClassName = "TAdapter"
|
|
860
|
+
#--------------------------------------------------
|
|
861
|
+
# constructor
|
|
862
|
+
#--------------------------------------------------
|
|
863
|
+
#class logging.LoggerAdapter(logger, extra)
|
|
864
|
+
def __init__(self, **kwargs):
|
|
865
|
+
"""Constructor"""
|
|
866
|
+
#beginfunction
|
|
867
|
+
# logging.LoggerAdapter.__init__(self, logger = None, extra = None)
|
|
868
|
+
logging.LoggerAdapter.__init__(self, **kwargs)
|
|
869
|
+
#endfunction
|
|
870
|
+
|
|
871
|
+
def process(self, msg, kwargs):
|
|
872
|
+
my_context = kwargs.pop('id', self.extra['id'])
|
|
873
|
+
return '[%s] %s' % (my_context, msg), kwargs
|
|
874
|
+
#endclass
|
|
875
|
+
|
|
876
|
+
#-------------------------------------------------
|
|
877
|
+
# TFormatter(logging.Formatter):
|
|
878
|
+
#-------------------------------------------------
|
|
879
|
+
class TFormatter(logging.Formatter):
|
|
880
|
+
"""TFormatter"""
|
|
881
|
+
luClassName = "TFormatter"
|
|
882
|
+
|
|
883
|
+
#--------------------------------------------------
|
|
884
|
+
# constructor
|
|
885
|
+
#--------------------------------------------------
|
|
886
|
+
def __init__ (self, AUseColor = True, **kwargs):
|
|
887
|
+
"""Constructor"""
|
|
888
|
+
#beginfunction
|
|
889
|
+
#class logging.Formatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)
|
|
890
|
+
logging.Formatter.__init__(self, **kwargs)
|
|
891
|
+
self.FUseColor = AUseColor
|
|
892
|
+
#endfunction
|
|
893
|
+
|
|
894
|
+
def _SetColor(self, AFmt: str, ALevelNo: int) -> str:
|
|
895
|
+
"""_SetColor"""
|
|
896
|
+
#beginfunction
|
|
897
|
+
if self.FUseColor:
|
|
898
|
+
if not LUSupport.IsTerminal ():
|
|
899
|
+
LCOLOR = COLORS.get (ALevelNo)
|
|
900
|
+
LFmt = LUConsole.sBEGIN_oct + LCOLOR + AFmt + LUConsole.sRESET
|
|
901
|
+
return LFmt
|
|
902
|
+
else:
|
|
903
|
+
LCOLOR = COLORS_rich.get (ALevelNo)
|
|
904
|
+
_s = AFmt
|
|
905
|
+
LFmt = _s
|
|
906
|
+
LFmt = '[' + LCOLOR + ']' + _s
|
|
907
|
+
if len(LCOLOR) > 0:
|
|
908
|
+
LFmt = '[' + LCOLOR + ']' + _s
|
|
909
|
+
else:
|
|
910
|
+
LFmt = _s
|
|
911
|
+
return LFmt
|
|
912
|
+
#endif
|
|
913
|
+
else:
|
|
914
|
+
return AFmt
|
|
915
|
+
#endif
|
|
916
|
+
#endfunction
|
|
917
|
+
|
|
918
|
+
def format(self, record):
|
|
919
|
+
"""format"""
|
|
920
|
+
#beginfunction
|
|
921
|
+
# отдельный атрибут
|
|
922
|
+
# LLevelname = record.levelname
|
|
923
|
+
# record.levelname = '_'+LLevelname+'_'
|
|
924
|
+
|
|
925
|
+
Ldatefmt = self.datefmt
|
|
926
|
+
if self.FUseColor:
|
|
927
|
+
if record.levelno == TEXT:
|
|
928
|
+
# установить новый fmt
|
|
929
|
+
Lfmt = self._SetColor ('%(message)s', record.levelno)
|
|
930
|
+
else:
|
|
931
|
+
Lfmt = self._SetColor (self._fmt, record.levelno)
|
|
932
|
+
#endif
|
|
933
|
+
else:
|
|
934
|
+
if record.levelno == TEXT:
|
|
935
|
+
# установить новый fmt
|
|
936
|
+
Lfmt = '%(message)s'
|
|
937
|
+
else:
|
|
938
|
+
Lfmt = self._fmt
|
|
939
|
+
#endif
|
|
940
|
+
#endif
|
|
941
|
+
# установить новый fmt
|
|
942
|
+
Lformatter = logging.Formatter (Lfmt, Ldatefmt)
|
|
943
|
+
s = Lformatter.format (record)
|
|
944
|
+
return s
|
|
945
|
+
#endfunction
|
|
946
|
+
#endclass
|
|
947
|
+
|
|
948
|
+
#-------------------------------------------------
|
|
949
|
+
# TFormatterJSON(jsonlogger.JsonFormatter):
|
|
950
|
+
#-------------------------------------------------
|
|
951
|
+
class TFormatterJSON(pythonjsonlogger.jsonlogger.JsonFormatter):
|
|
952
|
+
"""TFormatterJSON"""
|
|
953
|
+
luClassName = "TFormatterJSON"
|
|
954
|
+
|
|
955
|
+
#--------------------------------------------------
|
|
956
|
+
# constructor
|
|
957
|
+
#--------------------------------------------------
|
|
958
|
+
#class jsonlogger.JsonFormatter(*args, **kwargs)
|
|
959
|
+
def __init__(self, *args, **kwargs):
|
|
960
|
+
"""Constructor"""
|
|
961
|
+
#beginfunction
|
|
962
|
+
super(TFormatterJSON, self).__init__(*args, **kwargs)
|
|
963
|
+
self.json_ensure_ascii = False
|
|
964
|
+
...
|
|
965
|
+
#endfunction
|
|
966
|
+
|
|
967
|
+
def format(self, record):
|
|
968
|
+
"""format"""
|
|
969
|
+
#beginfunction
|
|
970
|
+
return super().format(record)
|
|
971
|
+
#endfunction
|
|
972
|
+
#endclass
|
|
973
|
+
|
|
974
|
+
def AddHandlerCONSOLE (ALogger: logging.Logger, ALevel: int, Astrfmt: str, Adatefmt: str,
|
|
975
|
+
Astyle: str, Adefaults):
|
|
976
|
+
"""AddFileHandler"""
|
|
977
|
+
|
|
978
|
+
#beginfunction
|
|
979
|
+
LHandler = TStreamHandler ()
|
|
980
|
+
LHandler.setLevel (ALevel)
|
|
981
|
+
LHandler.set_name ('CONSOLE')
|
|
982
|
+
LHandler.setStream (sys.stdout)
|
|
983
|
+
LFormater = TFormatter (fmt=Astrfmt, datefmt=Adatefmt,
|
|
984
|
+
style=Astyle, validate=True, defaults=Adefaults)
|
|
985
|
+
LHandler.setFormatter (LFormater)
|
|
986
|
+
ALogger.addHandler (LHandler)
|
|
987
|
+
#endfunction
|
|
988
|
+
|
|
989
|
+
def AddHandlerFILE (ALogger: logging.Logger, AFileName: str, ALevel: int, Astrfmt: str, Adatefmt: str,
|
|
990
|
+
Astyle: str, Adefaults):
|
|
991
|
+
"""AddFileHandler"""
|
|
992
|
+
#beginfunction
|
|
993
|
+
LHandler = logging.FileHandler (AFileName, mode='a+',
|
|
994
|
+
encoding=LUFile.cDefaultEncoding, delay=False, errors=None)
|
|
995
|
+
LHandler.setLevel (ALevel)
|
|
996
|
+
LHandler.set_name ('FILE')
|
|
997
|
+
LFormater = TFormatter (fmt=Astrfmt, datefmt=Adatefmt,
|
|
998
|
+
style=Astyle, validate=True, defaults=Adefaults)
|
|
999
|
+
LHandler.setFormatter (LFormater)
|
|
1000
|
+
ALogger.addHandler (LHandler)
|
|
1001
|
+
#endfunction
|
|
1002
|
+
|
|
1003
|
+
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
1004
|
+
# class TLogging (logging.Logger):
|
|
1005
|
+
# class ColoredLogger(logging.Logger):
|
|
1006
|
+
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
1007
|
+
|
|
1008
|
+
# ??????????????????????????????????????????????
|
|
1009
|
+
# class TLogger (logging.getLoggerClass()):
|
|
1010
|
+
# ??????????????????????????????????????????????
|
|
1011
|
+
|
|
1012
|
+
class TLogger (logging.Logger):
|
|
1013
|
+
"""TLogging"""
|
|
1014
|
+
luClassName = "TLogger"
|
|
1015
|
+
|
|
1016
|
+
#--------------------------------------------------
|
|
1017
|
+
# constructor
|
|
1018
|
+
#--------------------------------------------------
|
|
1019
|
+
def __init__(self, ALogerName: str):
|
|
1020
|
+
"""Constructor"""
|
|
1021
|
+
#beginfunction
|
|
1022
|
+
super().__init__(ALogerName)
|
|
1023
|
+
self.__FFileName: str = ''
|
|
1024
|
+
# Formater
|
|
1025
|
+
self.__Fstrfmt = Cstrfmt_01
|
|
1026
|
+
self.__Fdatefmt = Cdatefmt_01
|
|
1027
|
+
self.__Fstyle = Cstyle_01
|
|
1028
|
+
self.__Fdefaults = Cdefaults
|
|
1029
|
+
# LEVEL
|
|
1030
|
+
self.LEVEL = logging.DEBUG
|
|
1031
|
+
# propagate
|
|
1032
|
+
self.propagate = True
|
|
1033
|
+
self.propagate = False
|
|
1034
|
+
AddHandlerCONSOLE (self, self.LEVEL, self.__Fstrfmt, self.__Fdatefmt, self.__Fstyle, self.__Fdefaults)
|
|
1035
|
+
self.Clear ()
|
|
1036
|
+
#endfunction
|
|
1037
|
+
|
|
1038
|
+
#--------------------------------------------------
|
|
1039
|
+
# destructor
|
|
1040
|
+
#--------------------------------------------------
|
|
1041
|
+
def __del__(self):
|
|
1042
|
+
"""destructor"""
|
|
1043
|
+
#beginfunction
|
|
1044
|
+
LClassName = self.__class__.__name__
|
|
1045
|
+
s = '{} уничтожен'.format(LClassName)
|
|
1046
|
+
#print (s)
|
|
1047
|
+
#endfunction
|
|
1048
|
+
|
|
1049
|
+
def Clear(self):
|
|
1050
|
+
"""Clear"""
|
|
1051
|
+
#beginfunction
|
|
1052
|
+
...
|
|
1053
|
+
#endfunction
|
|
1054
|
+
|
|
1055
|
+
#--------------------------------------------------
|
|
1056
|
+
# @property FileName
|
|
1057
|
+
#--------------------------------------------------
|
|
1058
|
+
# getter
|
|
1059
|
+
@property
|
|
1060
|
+
def FileName (self) -> str:
|
|
1061
|
+
#beginfunction
|
|
1062
|
+
return self.__FFileName
|
|
1063
|
+
#endfunction
|
|
1064
|
+
@FileName.setter
|
|
1065
|
+
def FileName (self, Value: str):
|
|
1066
|
+
#beginfunction
|
|
1067
|
+
self.__FFileName = Value
|
|
1068
|
+
if len(self.__FFileName) > 0 and LUFile.FileExists (self.__FFileName):
|
|
1069
|
+
...
|
|
1070
|
+
#endif
|
|
1071
|
+
#endfunction
|
|
1072
|
+
|
|
1073
|
+
#--------------------------------------------------
|
|
1074
|
+
# @property LEVEL
|
|
1075
|
+
#--------------------------------------------------
|
|
1076
|
+
# getter
|
|
1077
|
+
@property
|
|
1078
|
+
def LEVEL (self):
|
|
1079
|
+
#beginfunction
|
|
1080
|
+
return self.level
|
|
1081
|
+
#endfunction
|
|
1082
|
+
@LEVEL.setter
|
|
1083
|
+
def LEVEL (self, Value):
|
|
1084
|
+
#beginfunction
|
|
1085
|
+
self.setLevel (Value)
|
|
1086
|
+
#endfunction
|
|
1087
|
+
|
|
1088
|
+
def AddHandlerCONSOLE(self, ALevel: int):
|
|
1089
|
+
#beginfunction
|
|
1090
|
+
# AddHandlerCONSOLE (self, ALevel, self.__Fstrfmt, self.__Fdatefmt, self.__Fstyle, self.__Fdefaults)
|
|
1091
|
+
# LHandler = logging.StreamHandler ()
|
|
1092
|
+
# LHandler.setLevel (ALevel)
|
|
1093
|
+
# LHandler.set_name ('CONSOLE')
|
|
1094
|
+
# LHandler.setStream (sys.stdout)
|
|
1095
|
+
# LFormater = TFormatter (fmt=self.__Fstrfmt, datefmt=self.__Fdatefmt,
|
|
1096
|
+
# style=self.__Fstyle, validate=True, defaults=self.__Fdefaults)
|
|
1097
|
+
# LHandler.setFormatter (LFormater)
|
|
1098
|
+
# self.addHandler (LHandler)
|
|
1099
|
+
...
|
|
1100
|
+
#endfunction
|
|
1101
|
+
|
|
1102
|
+
def AddHandlerFILE(self, AFileName: str, ALevel: int):
|
|
1103
|
+
#beginfunction
|
|
1104
|
+
LHandler = logging.FileHandler (AFileName, mode='a+',
|
|
1105
|
+
encoding=LUFile.cDefaultEncoding, delay=False, errors=None)
|
|
1106
|
+
LHandler.setLevel (ALevel)
|
|
1107
|
+
LHandler.set_name ('FILE')
|
|
1108
|
+
LFormater = TFormatter (AUseColor = False,
|
|
1109
|
+
fmt=self.__Fstrfmt, datefmt=self.__Fdatefmt,
|
|
1110
|
+
style=self.__Fstyle, validate=True, defaults=self.__Fdefaults)
|
|
1111
|
+
LHandler.setFormatter (LFormater)
|
|
1112
|
+
self.addHandler (LHandler)
|
|
1113
|
+
#endfunction
|
|
1114
|
+
|
|
1115
|
+
def AddHandlerFILE_JSON(self, AFileName: str, ALevel):
|
|
1116
|
+
#beginfunction
|
|
1117
|
+
LHandler = logging.FileHandler (AFileName, mode='a+',
|
|
1118
|
+
encoding=LUFile.cDefaultEncoding, delay=False, errors=None)
|
|
1119
|
+
LHandler.setLevel (ALevel)
|
|
1120
|
+
LHandler.set_name ('FILE_JSON')
|
|
1121
|
+
LFormater = TFormatterJSON (AUseColor = False,
|
|
1122
|
+
fmt=self.__Fstrfmt, datefmt=self.__Fdatefmt,
|
|
1123
|
+
style=self.__Fstyle, validate=True, defaults=self.__Fdefaults)
|
|
1124
|
+
LFormater.json_ensure_ascii = False
|
|
1125
|
+
LHandler.setFormatter (LFormater)
|
|
1126
|
+
self.addHandler (LHandler)
|
|
1127
|
+
#endfunction
|
|
1128
|
+
#endclass
|
|
1129
|
+
|
|
1130
|
+
"""
|
|
1131
|
+
# logger
|
|
1132
|
+
logger = logging.getLogger(__name__)
|
|
1133
|
+
|
|
1134
|
+
# LEVEL
|
|
1135
|
+
NOTSET
|
|
1136
|
+
DEBUG - уровень отладочной информации, зачастую помогает при разработке приложения на машине программиста.
|
|
1137
|
+
INFO - уровень вспомогательной информации о ходе работы приложения/скрипта.
|
|
1138
|
+
WARNING - уровень предупреждения. Например, мы можем предупреждать о том, что та или иная функция будет удалена в будущих версиях вашего приложения.
|
|
1139
|
+
ERROR - с таким уровнем разработчики пишут логи с ошибками, например, о том, что внешний сервис недоступен.
|
|
1140
|
+
CRITICAL - уровень сообщений после которых работа приложения продолжаться не может.
|
|
1141
|
+
|
|
1142
|
+
# УСТАНОВИТЬ LEVEL
|
|
1143
|
+
logger.setLevel(logging.DEBUG)
|
|
1144
|
+
logger.setLevel(logging.INFO)
|
|
1145
|
+
|
|
1146
|
+
# ЗАПИСЬ в logger
|
|
1147
|
+
logger.debug('debug')
|
|
1148
|
+
logger.info('info')
|
|
1149
|
+
logger.warning('warning')
|
|
1150
|
+
logger.error('error')
|
|
1151
|
+
logger.exception('error')
|
|
1152
|
+
logger.critical('critical')
|
|
1153
|
+
|
|
1154
|
+
# handler
|
|
1155
|
+
Задача класса Handler и его потомков обрабатывать запись сообщений/логов. Т.е. Handler отвечает за то куда будут записаны сообщения. В базовом наборе logging предоставляет ряд готовых классов-обработчиков:
|
|
1156
|
+
SteamHandler - запись в поток, например, stdout или stderr.
|
|
1157
|
+
handler = StreamHandler(stream=sys.stdout)
|
|
1158
|
+
FileHandler - запись в файл, класс имеет множество производных классов с различной функциональностью
|
|
1159
|
+
ротация файлов логов по размеру, времени и т.д.)
|
|
1160
|
+
handler = StreamHandler(stream=)
|
|
1161
|
+
BaseRotatingHandler
|
|
1162
|
+
handler = BaseRotatingHandler(filename, mode, encoding=None, delay=False, errors=None
|
|
1163
|
+
RotatingFileHandler
|
|
1164
|
+
handler = RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None,
|
|
1165
|
+
delay=False, errors=None
|
|
1166
|
+
TimedRotatingFileHandler
|
|
1167
|
+
handler = TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None,
|
|
1168
|
+
delay=False, utc=False, atTime=None, errors=None)
|
|
1169
|
+
|
|
1170
|
+
SocketHandler - запись сообщений в сокет по TCP
|
|
1171
|
+
handler = SocketHandler(host, port)
|
|
1172
|
+
DatagramHandler - запись сообщений в сокет по UDP
|
|
1173
|
+
handler = DatagramHandler(host, port)
|
|
1174
|
+
SysLogHandler - запись в syslog
|
|
1175
|
+
handler = SysLogHandler(address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM)
|
|
1176
|
+
HTTPHandler - запись по HTTP
|
|
1177
|
+
handler = HTTPHandler(host, url, method='GET', secure=False, credentials=None, context=None)
|
|
1178
|
+
NullHandler = NullHandler
|
|
1179
|
+
handler = StreamHandler(stream=)
|
|
1180
|
+
WatchedFileHandler
|
|
1181
|
+
handler = WatchedFileHandler(filename, mode='a', encoding=None, delay=False, errors=None)
|
|
1182
|
+
NTEventLogHandler
|
|
1183
|
+
handler = NTEventLogHandler(appname, dllname=None, logtype='Application')
|
|
1184
|
+
SMTPHandler
|
|
1185
|
+
handler = SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None, timeout=1.0)
|
|
1186
|
+
MemoryHandler
|
|
1187
|
+
handler = BufferingHandler(capacity)¶
|
|
1188
|
+
QueueHandler
|
|
1189
|
+
handler = QueueHandler(queue)
|
|
1190
|
+
QueueListener
|
|
1191
|
+
handler = QueueListener(queue, *handlers, respect_handler_level=False)¶
|
|
1192
|
+
|
|
1193
|
+
# ДОБАВИТЬ handler
|
|
1194
|
+
logger.addHandler(handler)
|
|
1195
|
+
|
|
1196
|
+
# Formatter
|
|
1197
|
+
#class logging.Formatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)
|
|
1198
|
+
formster = logging.Formatter (fmt=self.strfmt_03, datefmt=self.datefmt_02, style = '%', validate = True,
|
|
1199
|
+
defaults = {"ip": None} )
|
|
1200
|
+
handler.setFormatter(Formatter(fmt='[%(asctime)s: %(levelname)s] %(message)s'))
|
|
1201
|
+
|
|
1202
|
+
Параметр defaults может быть словарем со значениями по умолчанию для использования в настраиваемых полях.
|
|
1203
|
+
Например: logging.Formatter('%(ip)s %(message)s', defaults={"ip": None})
|
|
1204
|
+
|
|
1205
|
+
# Filter
|
|
1206
|
+
def filter_python(record: LogRecord) -> bool:
|
|
1207
|
+
return record.getMessage().find('python') != -1
|
|
1208
|
+
logger.addFilter(filter_python)
|
|
1209
|
+
|
|
1210
|
+
# LoggerAdapter
|
|
1211
|
+
class CustomLoggerAdapter(LoggerAdapter):
|
|
1212
|
+
def process(self, msg, kwargs):
|
|
1213
|
+
return f'{msg} from {self.extra["username"]}', kwargs
|
|
1214
|
+
|
|
1215
|
+
logger2 = logging.getLogger('adapter')
|
|
1216
|
+
logger2.setLevel(logging.DEBUG)
|
|
1217
|
+
|
|
1218
|
+
handler = StreamHandler(stream=sys.stdout)
|
|
1219
|
+
handler.setFormatter(Formatter(fmt='[%(asctime)s: %(levelname)s] %(message)s'))
|
|
1220
|
+
|
|
1221
|
+
adapter = CustomLoggerAdapter(logger2, {'username': 'adilkhash'})
|
|
1222
|
+
|
|
1223
|
+
logger2.addHandler(handler)
|
|
1224
|
+
adapter.error('failed to save')
|
|
1225
|
+
|
|
1226
|
+
# extra и не только
|
|
1227
|
+
logger.debug('debug info', extra={"response": response.text})
|
|
1228
|
+
Formatter(fmt='[%(asctime)s: %(levelname)s] %(message)s, response: %(response)s')
|
|
1229
|
+
|
|
1230
|
+
# Конфигурация logging
|
|
1231
|
+
Официальная документация рекомендует конфигурировать logging через python-словарь.
|
|
1232
|
+
Для этого необходимо вызвать функцию logging.config.dictConfig и передать ей специальный словарь.
|
|
1233
|
+
Схема словаря описана здесь. Я лишь вкратце пробегусь по основным ключам:
|
|
1234
|
+
version -
|
|
1235
|
+
ключ указывает версию конфига, рекомендуется наличие этого ключа со значением 1, нужно для обратной совместимости в случае, если в будущем появятся новые версии конфигов.
|
|
1236
|
+
disable_existing_loggers -
|
|
1237
|
+
запрещает или разрешает настройки для существующих логеров (на момент запуска), по умолчанию равен True
|
|
1238
|
+
formatters -
|
|
1239
|
+
настройки форматов логов
|
|
1240
|
+
handlers -
|
|
1241
|
+
настройки для обработчиков логов
|
|
1242
|
+
loggers -
|
|
1243
|
+
настройки существующих логеров
|
|
1244
|
+
|
|
1245
|
+
LOGGING_CONFIG = {
|
|
1246
|
+
'version': 1,
|
|
1247
|
+
'disable_existing_loggers': False,
|
|
1248
|
+
|
|
1249
|
+
'formatters': {
|
|
1250
|
+
'default_formatter': {
|
|
1251
|
+
'format': '[%(levelname)s:%(asctime)s] %(message)s'
|
|
1252
|
+
},
|
|
1253
|
+
},
|
|
1254
|
+
|
|
1255
|
+
'handlers': {
|
|
1256
|
+
'stream_handler': {
|
|
1257
|
+
'class': 'logging.StreamHandler',
|
|
1258
|
+
'formatter': 'default_formatter',
|
|
1259
|
+
},
|
|
1260
|
+
},
|
|
1261
|
+
|
|
1262
|
+
'loggers': {
|
|
1263
|
+
'my_logger': {
|
|
1264
|
+
'handlers': ['stream_handler'],
|
|
1265
|
+
'level': 'DEBUG',
|
|
1266
|
+
'propagate': True
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
logging.config.dictConfig(LOGGING_CONFIG)
|
|
1272
|
+
logger = logging.getLogger('my_logger')
|
|
1273
|
+
logger.debug('debug log')
|
|
1274
|
+
|
|
1275
|
+
# Наследование в logging
|
|
1276
|
+
Ещё одним удобным механизмом в logging является "наследование" настроек корневого логера
|
|
1277
|
+
его потомками. Наследование задаётся через символ . в названии логера.
|
|
1278
|
+
То есть логер с названием my_package.logger1 унаследует все настройки, заданные для my_package.
|
|
1279
|
+
Давайте обновим пример выше, добавив в LOGGING_CONFIG настройку для my_package
|
|
1280
|
+
|
|
1281
|
+
LOGGING_CONFIG['loggers'].update (
|
|
1282
|
+
{
|
|
1283
|
+
'my_package': {
|
|
1284
|
+
'handlers': ['stream_handler'],
|
|
1285
|
+
'level': 'DEBUG',
|
|
1286
|
+
'propagate': False
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
)
|
|
1290
|
+
|
|
1291
|
+
Available format attributes:
|
|
1292
|
+
args You shouldn’t need to format this yourself.
|
|
1293
|
+
The tuple of arguments merged into msg to produce message, or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary).
|
|
1294
|
+
exc_info You shouldn’t need to format this yourself.
|
|
1295
|
+
Exception tuple (à la sys.exc_info) or, if no exception has occurred, None.
|
|
1296
|
+
msg You shouldn’t need to format this yourself.
|
|
1297
|
+
The format string passed in the original logging call. Merged with args to produce message, or an arbitrary object (see Using arbitrary objects as messages).
|
|
1298
|
+
stack_info You shouldn’t need to format this yourself.
|
|
1299
|
+
Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record.
|
|
1300
|
+
|
|
1301
|
+
%(msg)s Message passed to logging call (same as %(message)s)
|
|
1302
|
+
%(hostname)s System hostname
|
|
1303
|
+
%(username)s System username
|
|
1304
|
+
%(programname)s System programname
|
|
1305
|
+
|
|
1306
|
+
%(asctime)s Time as human-readable string, when logging call was issued
|
|
1307
|
+
%(created)f Time as float when logging call was issued
|
|
1308
|
+
%(filename)s File name
|
|
1309
|
+
%(funcName)s Name of function containing the logging call
|
|
1310
|
+
%(levelname)s Text logging level
|
|
1311
|
+
%(levelno)s Integer logging level
|
|
1312
|
+
%(lineno)d Line number where the logging call was issued
|
|
1313
|
+
%(message)s Message passed to logging call (same as %(msg)s)
|
|
1314
|
+
%(module)s File name without extension where the logging call was issued
|
|
1315
|
+
%(msecs)d Millisecond part of the time when logging call was issued
|
|
1316
|
+
%(name)s Logger name
|
|
1317
|
+
%(pathname)s Full pathname to file containing the logging call
|
|
1318
|
+
%(process)d Process ID
|
|
1319
|
+
%(processName)s Process name
|
|
1320
|
+
%(relativeCreated)d - Time as integer in milliseconds when logging call was issued, relative to the time when logging module was loaded
|
|
1321
|
+
%(thread)d Thread ID
|
|
1322
|
+
%(threadName)s Thread name
|
|
1323
|
+
|
|
1324
|
+
%(asctime)s Human-readable time when the LogRecord was created. By default this is of the form ‘2003-07-08 16:49:45,896’ (the numbers after the comma are millisecond portion of the time).
|
|
1325
|
+
%(created)f Time when the LogRecord was created (as returned by time.time()).
|
|
1326
|
+
%(filename)s Filename portion of pathname.
|
|
1327
|
+
%(funcName)s Name of function containing the logging call.
|
|
1328
|
+
%(levelname)s Text logging level for the message ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').
|
|
1329
|
+
%(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL).
|
|
1330
|
+
%(lineno)d Source line number where the logging call was issued (if available).
|
|
1331
|
+
%(message)s The logged message, computed as msg % args. This is set when Formatter.format() is invoked.
|
|
1332
|
+
%(module)s Module (name portion of filename).
|
|
1333
|
+
%(msecs)d Millisecond portion of the time when the LogRecord was created.
|
|
1334
|
+
%(name)s Name of the logger used to log the call.
|
|
1335
|
+
%(pathname)s Full pathname of the source file where the logging call was issued (if available).
|
|
1336
|
+
%(process)d Process ID (if available).
|
|
1337
|
+
%(processName)s Process name (if available).
|
|
1338
|
+
%(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded.
|
|
1339
|
+
%(thread)d Thread ID (if available).
|
|
1340
|
+
%(threadName)s Thread name (if available).
|
|
1341
|
+
|
|
1342
|
+
Emoji
|
|
1343
|
+
You can use colors for text as others mentioned in their answers to have colorful text with a background or foreground color.
|
|
1344
|
+
But you can use emojis instead! for example, you can use ⚠️ for warning messages and 🛑 for error messages.
|
|
1345
|
+
Or simply use these notebooks as a color:
|
|
1346
|
+
|
|
1347
|
+
print("📕: error message")
|
|
1348
|
+
print("📙: warning message")
|
|
1349
|
+
print("📗: ok status message")
|
|
1350
|
+
print("📘: action message")
|
|
1351
|
+
print("📓: canceled status message")
|
|
1352
|
+
print("📔: Or anything you like and want to recognize immediately by color")
|
|
1353
|
+
|
|
1354
|
+
🎁 Bonus:
|
|
1355
|
+
This method also helps you to quickly scan and find logs directly in the source code.
|
|
1356
|
+
|
|
1357
|
+
How to open emoji picker?
|
|
1358
|
+
mac os: control + command + space
|
|
1359
|
+
windows: win + .
|
|
1360
|
+
linux: control + . or control + ;
|
|
1361
|
+
|
|
1362
|
+
# Отправляем логи в Telegram
|
|
1363
|
+
|
|
1364
|
+
"""
|
|
1365
|
+
#endclass
|
|
1366
|
+
|
|
1367
|
+
#-------------------------------------------------
|
|
1368
|
+
# Функциональное исполнение
|
|
1369
|
+
#-------------------------------------------------
|
|
1370
|
+
|
|
1371
|
+
def GetLogDirLogon () -> str:
|
|
1372
|
+
"""GetLogDirLogon"""
|
|
1373
|
+
#beginfunction
|
|
1374
|
+
"""
|
|
1375
|
+
if @LDomain <> ''
|
|
1376
|
+
LogDir = LogDir + '\\'+@LDomain
|
|
1377
|
+
endif
|
|
1378
|
+
s = AddCharR ('_', $USERID, 15)
|
|
1379
|
+
LogFile = s + "_" + UCase (@WKSTA)+'.log'
|
|
1380
|
+
"""
|
|
1381
|
+
return ''
|
|
1382
|
+
#endfunction
|
|
1383
|
+
|
|
1384
|
+
def GetLogFileName () -> str:
|
|
1385
|
+
"""GetLogFileName"""
|
|
1386
|
+
#beginfunction
|
|
1387
|
+
LResult = LUDateTime.Now ().strftime ('%Y%m%d') + '.log'
|
|
1388
|
+
return LResult
|
|
1389
|
+
#endfunction
|
|
1390
|
+
|
|
1391
|
+
def GetLogFileNameSufix (ASufix: str) -> str:
|
|
1392
|
+
"""GetLogFileNameSufix"""
|
|
1393
|
+
#beginfunction
|
|
1394
|
+
LResult = LUDateTime.Now ().strftime ('%Y%m%d') + ASufix + '.log'
|
|
1395
|
+
return LResult
|
|
1396
|
+
#endfunction
|
|
1397
|
+
|
|
1398
|
+
#-------------------------------------------------
|
|
1399
|
+
# LogFileName(ALog: str, ALogDir: str, ALogFile: str) -> str:
|
|
1400
|
+
#-------------------------------------------------
|
|
1401
|
+
def LogFileName(ALog: int, ALogDir: str, ALogFile: str) -> str:
|
|
1402
|
+
"""LogFileName"""
|
|
1403
|
+
#beginfunction
|
|
1404
|
+
LToday: datetime = LUDateTime.Now ()
|
|
1405
|
+
match ALog:
|
|
1406
|
+
case 1|3|10|30:
|
|
1407
|
+
LLogDir = ALogDir
|
|
1408
|
+
if len (ALogDir) == 0:
|
|
1409
|
+
# LLogDir = os.environ['TEMP']
|
|
1410
|
+
LLogDir = LUFile.GetTempDir()
|
|
1411
|
+
#endif
|
|
1412
|
+
LLogFile = ALogFile
|
|
1413
|
+
if ALogFile == '':
|
|
1414
|
+
s = LUDateTime.DateTimeStr (False, LToday, LUDateTime.cFormatDateYYMMDD_01, False)
|
|
1415
|
+
LLogFile = s+'.log'
|
|
1416
|
+
#endif
|
|
1417
|
+
LLogFileName = os.path.join(LLogDir, LLogFile)
|
|
1418
|
+
if ALog == 10 or ALog == 30:
|
|
1419
|
+
if LUFile.FileExists(LLogFileName):
|
|
1420
|
+
try:
|
|
1421
|
+
LUFile.FileDelete(LLogFileName)
|
|
1422
|
+
except:
|
|
1423
|
+
# except LUErrors.LUFileError_FileERROR as ERROR:
|
|
1424
|
+
s = f'Ошибка при удалении файла {LLogFileName}'
|
|
1425
|
+
LoggerTOOLS.error (s)
|
|
1426
|
+
else:
|
|
1427
|
+
...
|
|
1428
|
+
#endif
|
|
1429
|
+
#endif
|
|
1430
|
+
case _:
|
|
1431
|
+
LLogFileName = ""
|
|
1432
|
+
#endmatch
|
|
1433
|
+
return LLogFileName
|
|
1434
|
+
#endfunction
|
|
1435
|
+
|
|
1436
|
+
#--------------------------------------------------------------------------------
|
|
1437
|
+
# LogAdd (ALog: int, ALogFile: str, AOpt: str, AMessage: str,
|
|
1438
|
+
# AStyles = '', AFG8 = '', ABG8 = '', AFG256 = '', ABG256 = '', AESC = ''):
|
|
1439
|
+
#--------------------------------------------------------------------------------
|
|
1440
|
+
def LogAdd (ALog: int, ALogFile: str, AOpt: TTypeLogString, AMessage: str):
|
|
1441
|
+
"""LogAdd"""
|
|
1442
|
+
|
|
1443
|
+
def _WriteConsole(_s, T):
|
|
1444
|
+
#beginfunction
|
|
1445
|
+
if not LUSupport.IsTerminal ():
|
|
1446
|
+
LCOLOR = COLORS_tls.get (T)
|
|
1447
|
+
if LCOLOR is not None:
|
|
1448
|
+
LFmt = LUConsole.sBEGIN_oct + LCOLOR + _s + LUConsole.sRESET
|
|
1449
|
+
else:
|
|
1450
|
+
LFmt = _s
|
|
1451
|
+
LUConsole.WriteLN (LFmt)
|
|
1452
|
+
else:
|
|
1453
|
+
LCOLOR = COLORS_tls_rich.get (T)
|
|
1454
|
+
LFmt_default = _s
|
|
1455
|
+
LFmt = '[' + LCOLOR + ']' + _s
|
|
1456
|
+
GConsoleRich.print (LFmt)
|
|
1457
|
+
#endif
|
|
1458
|
+
#endfunction
|
|
1459
|
+
|
|
1460
|
+
def _WriteFile(_s):
|
|
1461
|
+
#beginfunction
|
|
1462
|
+
|
|
1463
|
+
LEncoding = LUFile.GetFileEncoding (ALogFile)
|
|
1464
|
+
if LEncoding == '':
|
|
1465
|
+
LEncoding = LUFile.cDefaultEncoding
|
|
1466
|
+
|
|
1467
|
+
LEncoding = LUFile.cDefaultEncoding
|
|
1468
|
+
# sWIN = s.encode (encoding = 'UTF-8').decode(encoding = 'ANSI')
|
|
1469
|
+
# sWIN = s.encode (encoding = 'WINDOWS-1251').decode(encoding = 'UTF-8')
|
|
1470
|
+
# Это работает !!!!!!!!!!!!!!!!!
|
|
1471
|
+
try:
|
|
1472
|
+
with open (ALogFile, 'a+', encoding = LEncoding) as LFile:
|
|
1473
|
+
LFile.write (_s+'\n')
|
|
1474
|
+
except:
|
|
1475
|
+
_s = f'_WriteFile: Неправильная кодировка журнала!'
|
|
1476
|
+
LoggerTOOLS.error (_s)
|
|
1477
|
+
#endtry
|
|
1478
|
+
#endfunction
|
|
1479
|
+
|
|
1480
|
+
#beginfunction
|
|
1481
|
+
LToday = LUDateTime.Now ()
|
|
1482
|
+
if AOpt == TTypeLogString.tlsTEXT:
|
|
1483
|
+
s = AMessage
|
|
1484
|
+
else:
|
|
1485
|
+
s = LUDateTime.DateTimeStr(False, LToday, LUDateTime.cFormatDateTimeLog01, True)+' '+\
|
|
1486
|
+
AOpt.value+' '+AMessage
|
|
1487
|
+
match ALog:
|
|
1488
|
+
case 1|10:
|
|
1489
|
+
_WriteConsole (s, AOpt)
|
|
1490
|
+
_WriteFile (s)
|
|
1491
|
+
case 2:
|
|
1492
|
+
_WriteConsole (s, AOpt)
|
|
1493
|
+
case 3|30:
|
|
1494
|
+
_WriteConsole (s, AOpt)
|
|
1495
|
+
_WriteFile (s)
|
|
1496
|
+
#endmatch
|
|
1497
|
+
#endfunction
|
|
1498
|
+
|
|
1499
|
+
#--------------------------------------------------------------------------------
|
|
1500
|
+
# LogAddFile (ALog: int, ALogFile: str, AOpt: str, AFileName: str,
|
|
1501
|
+
# AStyles='', AFG8='', ABG8='', AFG256='', ABG256='', AESC=''):
|
|
1502
|
+
#--------------------------------------------------------------------------------
|
|
1503
|
+
def LogAddFile (ALog: int, ALogFile: str, AOpt: TTypeLogString, AFileName: str):
|
|
1504
|
+
"""LogAddFile"""
|
|
1505
|
+
#beginfunction
|
|
1506
|
+
if LUFile.FileExists (AFileName):
|
|
1507
|
+
try:
|
|
1508
|
+
LEncoding = LUFile.GetFileEncoding (AFileName)
|
|
1509
|
+
if LEncoding == '':
|
|
1510
|
+
LEncoding = LUFile.cDefaultEncoding
|
|
1511
|
+
with open (AFileName, 'r', encoding = LEncoding) as LFile:
|
|
1512
|
+
for s in LFile:
|
|
1513
|
+
Ls = s.split ('\n')[0]
|
|
1514
|
+
LogAdd (ALog, ALogFile, AOpt, Ls)
|
|
1515
|
+
#endfor
|
|
1516
|
+
#endwith
|
|
1517
|
+
except:
|
|
1518
|
+
s = f'LogAddFile: Неправильная кодировка журнала!'+AFileName
|
|
1519
|
+
LoggerTOOLS.error (s)
|
|
1520
|
+
#endtry
|
|
1521
|
+
#endif
|
|
1522
|
+
#endfunction
|
|
1523
|
+
|
|
1524
|
+
#-------------------------------------------------
|
|
1525
|
+
# GLOBAL
|
|
1526
|
+
#-------------------------------------------------
|
|
1527
|
+
def SetFormatterForLogger (ALogger: logging.Logger):
|
|
1528
|
+
"""SetFormatterForLogger"""
|
|
1529
|
+
#beginfunction
|
|
1530
|
+
for item in ALogger.handlers:
|
|
1531
|
+
if type (item.formatter) is pythonjsonlogger.jsonlogger.JsonFormatter:
|
|
1532
|
+
item.formatter.json_ensure_ascii = False
|
|
1533
|
+
#endif
|
|
1534
|
+
if type (item) is logging.StreamHandler or type (item) is TStreamHandler:
|
|
1535
|
+
# if LUSupport.ISTerminal ():
|
|
1536
|
+
# TStreamHandler(item).setLevel(logging.CRITICAL)
|
|
1537
|
+
# # print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
|
1538
|
+
# ...
|
|
1539
|
+
# #endif
|
|
1540
|
+
Lfmt = item.formatter._fmt
|
|
1541
|
+
Ldatefmt = item.formatter.datefmt
|
|
1542
|
+
LFormaterConsole = TFormatter (fmt = Lfmt, datefmt = Ldatefmt)
|
|
1543
|
+
item.setFormatter (LFormaterConsole)
|
|
1544
|
+
#endif
|
|
1545
|
+
#enfor
|
|
1546
|
+
#endfunction
|
|
1547
|
+
|
|
1548
|
+
def PrintHandlers (ALogger: logging.Logger):
|
|
1549
|
+
"""Printhandlers"""
|
|
1550
|
+
#beginfunction
|
|
1551
|
+
for item in ALogger.root.handlers:
|
|
1552
|
+
s = f'{item.name}={item}'
|
|
1553
|
+
# LoggerTOOLS.info(s)
|
|
1554
|
+
if type(item) is logging.StreamHandler:
|
|
1555
|
+
LoggerTOOLS.info ('logging.StreamHandler='+s)
|
|
1556
|
+
# Lfmt = item.formatter._fmt
|
|
1557
|
+
# Ldatefmt = item.formatter.datefmt
|
|
1558
|
+
# LFormaterConsole = TFormatter (AUseColor=True, fmt=Lfmt, datefmt=Ldatefmt)
|
|
1559
|
+
...
|
|
1560
|
+
#endif
|
|
1561
|
+
if type (item) is TStreamHandler:
|
|
1562
|
+
LoggerTOOLS.info ('TStreamHandler='+s)
|
|
1563
|
+
# Lfmt = item.formatter._fmt
|
|
1564
|
+
# Ldatefmt = item.formatter.datefmt
|
|
1565
|
+
# LFormaterConsole = TFormatter (AUseColor=True, fmt=Lfmt, datefmt=Ldatefmt)
|
|
1566
|
+
...
|
|
1567
|
+
#endif
|
|
1568
|
+
#enfor
|
|
1569
|
+
#endfunction
|
|
1570
|
+
|
|
1571
|
+
def GetHandler (ALogger: logging.Logger, ANameHandler: str):
|
|
1572
|
+
"""Printhandlers"""
|
|
1573
|
+
#beginfunction
|
|
1574
|
+
for item in ALogger.root.handlers:
|
|
1575
|
+
# s = f'{item.name}={item}'
|
|
1576
|
+
# LoggerTOOLS.info(s)
|
|
1577
|
+
if item.name == ANameHandler:
|
|
1578
|
+
return item
|
|
1579
|
+
#endif
|
|
1580
|
+
#enfor
|
|
1581
|
+
#endfunction
|
|
1582
|
+
|
|
1583
|
+
def WinToUnix (Astr: str) -> str:
|
|
1584
|
+
"""WinToUnix"""
|
|
1585
|
+
#beginfunction
|
|
1586
|
+
LOSInfo = LUos.TOSInfo ()
|
|
1587
|
+
print ('HostName = ' + LOSInfo.node)
|
|
1588
|
+
print ('OS = ' + LOSInfo.system)
|
|
1589
|
+
# print ('OS = ' + LOSInfo.uname.system)
|
|
1590
|
+
match LOSInfo.system.upper ():
|
|
1591
|
+
case 'LINUX':
|
|
1592
|
+
Lstr = os.path.abspath (Astr).replace ("\\", "/")
|
|
1593
|
+
case 'WINDOWS':
|
|
1594
|
+
Lstr = Astr
|
|
1595
|
+
case _:
|
|
1596
|
+
# print ('INFO: Only LINUX or WINDOWS')
|
|
1597
|
+
Lstr = Astr
|
|
1598
|
+
#endmatch
|
|
1599
|
+
return Lstr
|
|
1600
|
+
#endfunction
|
|
1601
|
+
|
|
1602
|
+
#-------------------------------------------------
|
|
1603
|
+
# LOGGING_CONFIG
|
|
1604
|
+
#-------------------------------------------------
|
|
1605
|
+
LOGGING_CONFIG = \
|
|
1606
|
+
{
|
|
1607
|
+
'version': 1,
|
|
1608
|
+
'disable_existing_loggers': 1,
|
|
1609
|
+
'loggers': {
|
|
1610
|
+
'root': {
|
|
1611
|
+
'handlers': [
|
|
1612
|
+
'CONSOLE',
|
|
1613
|
+
'FILE_01'
|
|
1614
|
+
],
|
|
1615
|
+
'level': 'DEBUG',
|
|
1616
|
+
'propagate': 1
|
|
1617
|
+
},
|
|
1618
|
+
'log01': {
|
|
1619
|
+
'handlers': [
|
|
1620
|
+
'FILE_01'
|
|
1621
|
+
],
|
|
1622
|
+
'level': 'DEBUG',
|
|
1623
|
+
'propagate': 0,
|
|
1624
|
+
'qualname': 'log01'
|
|
1625
|
+
},
|
|
1626
|
+
'log02': {
|
|
1627
|
+
'handlers': [
|
|
1628
|
+
'FILE_02'
|
|
1629
|
+
],
|
|
1630
|
+
'level': 'DEBUG',
|
|
1631
|
+
'propagate': 0,
|
|
1632
|
+
'qualname': 'log02'
|
|
1633
|
+
}
|
|
1634
|
+
},
|
|
1635
|
+
'handlers': {
|
|
1636
|
+
'CONSOLE': {
|
|
1637
|
+
# 'class': 'logging.StreamHandler',
|
|
1638
|
+
'class': 'LULog.TStreamHandler',
|
|
1639
|
+
'level': 'DEBUG',
|
|
1640
|
+
'formatter': 'FORMAT_01',
|
|
1641
|
+
'stream': 'ext://sys.stdout'
|
|
1642
|
+
},
|
|
1643
|
+
'FILE_01': {
|
|
1644
|
+
'class': 'logging.handlers.RotatingFileHandler',
|
|
1645
|
+
'level': 'DEBUG',
|
|
1646
|
+
'formatter': 'FORMAT_01',
|
|
1647
|
+
'maxBytes': 10000000,
|
|
1648
|
+
'backupCount': 5,
|
|
1649
|
+
'filename': 'LOGGING_CONFIG.log'
|
|
1650
|
+
},
|
|
1651
|
+
'FILE_02': {
|
|
1652
|
+
# 'class': 'logging.handlers.TimedRotatingFileHandler',
|
|
1653
|
+
'class': 'logging.handlers.RotatingFileHandler',
|
|
1654
|
+
'level': 'INFO',
|
|
1655
|
+
'formatter': 'FORMAT_json',
|
|
1656
|
+
# 'interval': 'M',
|
|
1657
|
+
'maxBytes': 1024,
|
|
1658
|
+
'backupCount': 5,
|
|
1659
|
+
'filename': 'LOGGING_CONFIG_json.log'
|
|
1660
|
+
}
|
|
1661
|
+
},
|
|
1662
|
+
'formatters': {
|
|
1663
|
+
'FORMAT_01': {
|
|
1664
|
+
'format': Cstrfmt_01,
|
|
1665
|
+
'datefmt': Cdatefmt_01
|
|
1666
|
+
},
|
|
1667
|
+
'FORMAT_json': {
|
|
1668
|
+
'class': 'pythonjsonlogger.jsonlogger.JsonFormatter',
|
|
1669
|
+
'format': Cstrfmt_01,
|
|
1670
|
+
'datefmt': Cdatefmt_01
|
|
1671
|
+
}
|
|
1672
|
+
},
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
#-------------------------------------------------
|
|
1676
|
+
# CreateLoggerCONFIG
|
|
1677
|
+
#-------------------------------------------------
|
|
1678
|
+
def CreateLoggerCONFIG (AFileNameCONFIG: str, ALogerName: str,
|
|
1679
|
+
ADirectoryLOG: str, AFileNameLOG: str, AFileNameLOGjson: str) -> logging.Logger:
|
|
1680
|
+
"""CreateLoggerCONFIG"""
|
|
1681
|
+
#beginfunction
|
|
1682
|
+
global CONFIG
|
|
1683
|
+
CONFIG = {}
|
|
1684
|
+
global LoggerTOOLS
|
|
1685
|
+
|
|
1686
|
+
#print ('CONFIG:ADirectoryLOG:',ADirectoryLOG)
|
|
1687
|
+
|
|
1688
|
+
LPath = LUFile.ExtractFileDir(__file__)
|
|
1689
|
+
LFileNameCONFIG = os.path.join (LPath, AFileNameCONFIG)
|
|
1690
|
+
if LUFile.FileExists(LFileNameCONFIG):
|
|
1691
|
+
# читаем конфигурацию из файла
|
|
1692
|
+
try:
|
|
1693
|
+
with open (LFileNameCONFIG, 'r') as FileCONFIG:
|
|
1694
|
+
CONFIG = json.load(FileCONFIG)
|
|
1695
|
+
#endwith
|
|
1696
|
+
except FileNotFoundError as ERROR:
|
|
1697
|
+
print ('ERROR: Невозможно открыть файл', ERROR)
|
|
1698
|
+
#endtry
|
|
1699
|
+
else:
|
|
1700
|
+
CONFIG = copy.deepcopy (LOGGING_CONFIG)
|
|
1701
|
+
#endif
|
|
1702
|
+
#-------------------------------------------------------------------
|
|
1703
|
+
# CONFIG = copy.deepcopy (LOGGING_CONFIG)
|
|
1704
|
+
#-------------------------------------------------------------------
|
|
1705
|
+
|
|
1706
|
+
if AFileNameLOG == '':
|
|
1707
|
+
LOptionValue_01 = CONFIG['handlers']['FILE_01']['filename']
|
|
1708
|
+
# print ('LOptionValue_01:',LOptionValue_01)
|
|
1709
|
+
LFileNameLOG = LUFile.ExtractFileName (LOptionValue_01)
|
|
1710
|
+
else:
|
|
1711
|
+
LFileNameLOG = LUFile.ExtractFileName (AFileNameLOG)
|
|
1712
|
+
#endif
|
|
1713
|
+
# print('LFileNameLOG:',LFileNameLOG)
|
|
1714
|
+
|
|
1715
|
+
if AFileNameLOGjson == '':
|
|
1716
|
+
LOptionValue_02 = CONFIG['handlers']['FILE_02']['filename']
|
|
1717
|
+
# print ('LOptionValue_02:',LOptionValue_02)
|
|
1718
|
+
LFileNameLOGjson = LUFile.ExtractFileName (LOptionValue_02)
|
|
1719
|
+
else:
|
|
1720
|
+
LFileNameLOGjson = LUFile.ExtractFileName (AFileNameLOGjson)
|
|
1721
|
+
#endif
|
|
1722
|
+
# print('LFileNameLOGjson:',LFileNameLOGjson)
|
|
1723
|
+
|
|
1724
|
+
if ADirectoryLOG == '':
|
|
1725
|
+
# log будет создан в текущем каталоге (по умолчанию)
|
|
1726
|
+
LDirectoryLOG = LUos.GetCurrentDir ()
|
|
1727
|
+
else:
|
|
1728
|
+
# log будет создан в ADirectoryLOG
|
|
1729
|
+
LDirectoryLOG = LUFile.ExpandFileName (ADirectoryLOG)
|
|
1730
|
+
#endif
|
|
1731
|
+
# print('LDirectoryLOG:',LDirectoryLOG)
|
|
1732
|
+
if not LUFile.DirectoryExists (LDirectoryLOG):
|
|
1733
|
+
LUFile.ForceDirectories(LDirectoryLOG)
|
|
1734
|
+
#endif
|
|
1735
|
+
|
|
1736
|
+
# установить имена log файлов в CONFIG
|
|
1737
|
+
LOptionValue_01 = os.path.join (LDirectoryLOG, LFileNameLOG)
|
|
1738
|
+
# print('LOptionValue_01:', LOptionValue_01)
|
|
1739
|
+
CONFIG ['handlers'] ['FILE_01'] ['filename'] = LOptionValue_01
|
|
1740
|
+
|
|
1741
|
+
LOptionValue_02 = os.path.join (LDirectoryLOG, LFileNameLOGjson)
|
|
1742
|
+
# print('LOptionValue_02:', LOptionValue_02)
|
|
1743
|
+
CONFIG ['handlers'] ['FILE_02'] ['filename'] = LOptionValue_02
|
|
1744
|
+
|
|
1745
|
+
if len(CONFIG) > 0:
|
|
1746
|
+
#-------------------------------------------------------------------
|
|
1747
|
+
# LFileNameCONFIG = os.path.join (LUos.GetCurrentDir (), CDefaultFileLogCONFIG)
|
|
1748
|
+
LFileNameCONFIG = os.path.join (LUFile.GetTempDir(), CDefaultFileLogCONFIG)
|
|
1749
|
+
|
|
1750
|
+
LUDict.SaveDictSTR (CONFIG, LFileNameCONFIG)
|
|
1751
|
+
#-------------------------------------------------------------------
|
|
1752
|
+
# читаем конфигурацию из словаря
|
|
1753
|
+
logging.config.dictConfig (CONFIG)
|
|
1754
|
+
# создаем регистратор
|
|
1755
|
+
LResult = logging.getLogger (ALogerName)
|
|
1756
|
+
# установить форматер
|
|
1757
|
+
SetFormatterForLogger (LResult)
|
|
1758
|
+
return LResult
|
|
1759
|
+
else:
|
|
1760
|
+
return None
|
|
1761
|
+
#endfunction
|
|
1762
|
+
|
|
1763
|
+
#-------------------------------------------------
|
|
1764
|
+
# CreateLoggerYAML
|
|
1765
|
+
#-------------------------------------------------
|
|
1766
|
+
def CreateLoggerYAML (AFileNameYAML: str, ALogerName: str, ADirectoryLOG: str, AFileNameLOG: str, AFileNameLOGjson: str) -> logging.Logger:
|
|
1767
|
+
"""CreateLoggerFILEYAML"""
|
|
1768
|
+
#beginfunction
|
|
1769
|
+
global CONFIG_YAML
|
|
1770
|
+
CONFIG_YAML = {}
|
|
1771
|
+
|
|
1772
|
+
LPath = LUFile.ExtractFileDir(__file__)
|
|
1773
|
+
LFileNameYAML = os.path.join (LPath, AFileNameYAML)
|
|
1774
|
+
if LUFile.FileExists (LFileNameYAML):
|
|
1775
|
+
# читаем конфигурацию из файла
|
|
1776
|
+
try:
|
|
1777
|
+
with (open (LFileNameYAML, 'r') as FileCONFIG_YAML):
|
|
1778
|
+
CONFIG_YAML = yaml.load(FileCONFIG_YAML, Loader=yaml.FullLoader)
|
|
1779
|
+
#endwith
|
|
1780
|
+
except FileNotFoundError as ERROR:
|
|
1781
|
+
print ('ERROR: Невозможно открыть файл', ERROR)
|
|
1782
|
+
#endtry
|
|
1783
|
+
else:
|
|
1784
|
+
CONFIG_YAML = copy.deepcopy (LOGGING_CONFIG)
|
|
1785
|
+
#endif
|
|
1786
|
+
#-------------------------------------------------------------------
|
|
1787
|
+
# CONFIG_YAML = copy.deepcopy (LOGGING_CONFIG)
|
|
1788
|
+
#-------------------------------------------------------------------
|
|
1789
|
+
|
|
1790
|
+
if AFileNameLOG == '':
|
|
1791
|
+
LOptionValue_01 = CONFIG_YAML ['handlers'] ['FILE_01'] ['filename']
|
|
1792
|
+
# print ('LOptionValue_01:', LOptionValue_01)
|
|
1793
|
+
LFileNameLOG = LUFile.ExtractFileName (LOptionValue_01)
|
|
1794
|
+
else:
|
|
1795
|
+
LFileNameLOG = LUFile.ExtractFileName (AFileNameLOG)
|
|
1796
|
+
#endif
|
|
1797
|
+
# print ('LFileNameLOG:', LFileNameLOG)
|
|
1798
|
+
|
|
1799
|
+
if AFileNameLOGjson == '':
|
|
1800
|
+
LOptionValue_02 = CONFIG_YAML ['handlers'] ['FILE_02'] ['filename']
|
|
1801
|
+
# print ('LOptionValue_02:', LOptionValue_02)
|
|
1802
|
+
LFileNameLOGjson = LUFile.ExtractFileName (LOptionValue_02)
|
|
1803
|
+
else:
|
|
1804
|
+
LFileNameLOGjson = LUFile.ExtractFileName (AFileNameLOGjson)
|
|
1805
|
+
#endif
|
|
1806
|
+
# print ('LFileNameLOGjson:', LFileNameLOGjson)
|
|
1807
|
+
|
|
1808
|
+
if ADirectoryLOG == '':
|
|
1809
|
+
# log будет создан в текущем каталоге (по умолчанию)
|
|
1810
|
+
LDirectoryLOG = LUos.GetCurrentDir ()
|
|
1811
|
+
else:
|
|
1812
|
+
# log будет создан в ADirectoryLOG
|
|
1813
|
+
LDirectoryLOG = LUFile.ExpandFileName (ADirectoryLOG)
|
|
1814
|
+
#endif
|
|
1815
|
+
# print('LDirectoryLOG:',LDirectoryLOG)
|
|
1816
|
+
if not LUFile.DirectoryExists (LDirectoryLOG):
|
|
1817
|
+
LUFile.ForceDirectories(LDirectoryLOG)
|
|
1818
|
+
#endif
|
|
1819
|
+
|
|
1820
|
+
# установить имена log файлов в CONFIG
|
|
1821
|
+
LOptionValue_01 = os.path.join (LDirectoryLOG, LFileNameLOG)
|
|
1822
|
+
# print('LOptionValue_01:', LOptionValue_01)
|
|
1823
|
+
CONFIG_YAML ['handlers'] ['FILE_01'] ['filename'] = LOptionValue_01
|
|
1824
|
+
LOptionValue_02 = os.path.join (LDirectoryLOG, LFileNameLOGjson)
|
|
1825
|
+
# print('LOptionValue_02:', LOptionValue_02)
|
|
1826
|
+
CONFIG_YAML ['handlers'] ['FILE_02'] ['filename'] = LOptionValue_02
|
|
1827
|
+
|
|
1828
|
+
if len (CONFIG_YAML) > 0:
|
|
1829
|
+
#-------------------------------------------------------------------
|
|
1830
|
+
LFileNameYAML = os.path.join (LUos.GetCurrentDir (), CDefaultFileLogYAML)
|
|
1831
|
+
LUDict.SaveDictSTR (CONFIG_YAML, LFileNameYAML)
|
|
1832
|
+
#-------------------------------------------------------------------
|
|
1833
|
+
# читаем конфигурацию из словаря
|
|
1834
|
+
logging.config.dictConfig (CONFIG_YAML)
|
|
1835
|
+
# создаем регистратор
|
|
1836
|
+
LResult = logging.getLogger (ALogerName)
|
|
1837
|
+
# установить форматер
|
|
1838
|
+
SetFormatterForLogger (LResult)
|
|
1839
|
+
return LResult
|
|
1840
|
+
else:
|
|
1841
|
+
return None
|
|
1842
|
+
#endif
|
|
1843
|
+
|
|
1844
|
+
#endfunction
|
|
1845
|
+
|
|
1846
|
+
#-------------------------------------------------
|
|
1847
|
+
# CreateLoggerFILEINI
|
|
1848
|
+
#-------------------------------------------------
|
|
1849
|
+
def CreateLoggerFILEINI (AFileNameINI: str, ALogerName: str,
|
|
1850
|
+
ADirectoryLOG: str, AFileNameLOG: str, AFileNameLOGjson: str) -> logging.Logger:
|
|
1851
|
+
"""CreateLoggerFILEINI"""
|
|
1852
|
+
#beginfunction
|
|
1853
|
+
LDirectoryLOG = ADirectoryLOG
|
|
1854
|
+
|
|
1855
|
+
# читаем конфигурацию из файла INI
|
|
1856
|
+
LFileNameINI = LUFile.ExpandFileName (AFileNameINI)
|
|
1857
|
+
|
|
1858
|
+
if LUFile.FileExists (LFileNameINI):
|
|
1859
|
+
# существует файл, который можно редактировать
|
|
1860
|
+
SetEditINI = True
|
|
1861
|
+
LPathINI = LUFile.ExtractFileDir (LFileNameINI)
|
|
1862
|
+
LFileNameINI = os.path.join (LPathINI, LUFile.ExtractFileName (AFileNameINI))
|
|
1863
|
+
else:
|
|
1864
|
+
SetEditINI = False
|
|
1865
|
+
if not ALogerName == 'console':
|
|
1866
|
+
LPathINI = LUos.GetCurrentDir ()
|
|
1867
|
+
LFileNameINI = os.path.join (LPathINI, LUFile.ExtractFileName (AFileNameINI))
|
|
1868
|
+
if LUFile.FileExists (LFileNameINI):
|
|
1869
|
+
# существует файл в текущем каталоге, который можно редактировать
|
|
1870
|
+
SetEditINI = True
|
|
1871
|
+
else:
|
|
1872
|
+
# берем имя файла из проекта, если оно есть
|
|
1873
|
+
SetEditINI = True
|
|
1874
|
+
LPathINI = LUFile.ExtractFileDir (__file__)
|
|
1875
|
+
LFileNameINIorig = os.path.join (LPathINI, CDefaultFileLogINI)
|
|
1876
|
+
# Копирование файла
|
|
1877
|
+
shutil.copy (LFileNameINIorig, LFileNameINI)
|
|
1878
|
+
#endif
|
|
1879
|
+
else:
|
|
1880
|
+
LPathINI = LUFile.ExtractFileDir (__file__)
|
|
1881
|
+
LFileNameINI = os.path.join (LPathINI, LUFile.ExtractFileName (AFileNameINI))
|
|
1882
|
+
#endif
|
|
1883
|
+
#endif
|
|
1884
|
+
|
|
1885
|
+
# print ('LFileNameINI:', LFileNameINI)
|
|
1886
|
+
|
|
1887
|
+
if not SetEditINI:
|
|
1888
|
+
# print ('ALogerName:',ALogerName)
|
|
1889
|
+
pass
|
|
1890
|
+
else:
|
|
1891
|
+
# print ('AFileNameLOG:', AFileNameLOG)
|
|
1892
|
+
LINIFile = LUParserINI.TINIFile ()
|
|
1893
|
+
LINIFile.FileNameINI = LFileNameINI
|
|
1894
|
+
LOptionName = 'args'
|
|
1895
|
+
if AFileNameLOG == '':
|
|
1896
|
+
LSectionName_01 = 'handler_FILE_01'
|
|
1897
|
+
LOptionValue_01 = LINIFile.GetOption(LSectionName_01, LOptionName, '')
|
|
1898
|
+
# print ('LOptionValue_01:',LOptionValue_01)
|
|
1899
|
+
LFileNameLOG = LOptionValue_01.split("'")[1]
|
|
1900
|
+
# print('LFileNameLOG:',LFileNameLOG)
|
|
1901
|
+
LFileNameLOG = LUFile.ExtractFileName (LFileNameLOG)
|
|
1902
|
+
else:
|
|
1903
|
+
LFileNameLOG = LUFile.ExtractFileName (AFileNameLOG)
|
|
1904
|
+
#endif
|
|
1905
|
+
# print('LFileNameLOG:',LFileNameLOG)
|
|
1906
|
+
|
|
1907
|
+
if AFileNameLOGjson == '':
|
|
1908
|
+
LSectionName_02 = 'handler_FILE_02'
|
|
1909
|
+
LOptionValue_02 = LINIFile.GetOption(LSectionName_02, LOptionName, '')
|
|
1910
|
+
# print ('LOptionValue_02:',LOptionValue_02)
|
|
1911
|
+
LFileNameLOGjson = LOptionValue_02.split("'")[1]
|
|
1912
|
+
# print('LFileNameLOGjson:',LFileNameLOGjson)
|
|
1913
|
+
LFileNameLOGjson = LUFile.ExtractFileName (LFileNameLOGjson)
|
|
1914
|
+
else:
|
|
1915
|
+
LFileNameLOGjson = LUFile.ExtractFileName (AFileNameLOGjson)
|
|
1916
|
+
#endif
|
|
1917
|
+
print('AFileNameLOGjson:',AFileNameLOGjson)
|
|
1918
|
+
print('LFileNameLOGjson:',LFileNameLOGjson)
|
|
1919
|
+
|
|
1920
|
+
# установить имена log файлов в ini
|
|
1921
|
+
LOptionValue_01 = "('" + os.path.join (LDirectoryLOG, LFileNameLOG) + "',)"
|
|
1922
|
+
if LUos.GOSInfo.system == 'Windows':
|
|
1923
|
+
LOptionValue_01 = LOptionValue_01.replace ('\\', "\\\\")
|
|
1924
|
+
#endif
|
|
1925
|
+
if LUos.GOSInfo.system == 'Linux':
|
|
1926
|
+
raise 'ERROR: Linux не поддерживается'
|
|
1927
|
+
#endif
|
|
1928
|
+
# print('LOptionValue_01:',LOptionValue_01)
|
|
1929
|
+
LINIFile.SetOption ('handler_FILE_01', LOptionName, LOptionValue_01)
|
|
1930
|
+
LOptionValue_02 = "('" + os.path.join (LDirectoryLOG, LFileNameLOGjson) + "',)"
|
|
1931
|
+
if LUos.GOSInfo.system == 'Windows':
|
|
1932
|
+
LOptionValue_02 = LOptionValue_02.replace ("\\", "\\\\")
|
|
1933
|
+
#endif
|
|
1934
|
+
if LUos.GOSInfo.system == 'Linux':
|
|
1935
|
+
raise 'ERROR: Linux не поддерживается'
|
|
1936
|
+
#endif
|
|
1937
|
+
# print('LOptionValue_02:',LOptionValue_02)
|
|
1938
|
+
|
|
1939
|
+
LINIFile.SetOption ('handler_FILE_02', LOptionName, LOptionValue_02)
|
|
1940
|
+
LINIFile.UpdateFileINI ()
|
|
1941
|
+
#endif
|
|
1942
|
+
|
|
1943
|
+
# print ('INI:ADirectoryLOG:',ADirectoryLOG)
|
|
1944
|
+
if ADirectoryLOG == '':
|
|
1945
|
+
# log будет создан в текущем каталоге (по умолчанию)
|
|
1946
|
+
LDirectoryLOG = LUos.GetCurrentDir ()
|
|
1947
|
+
else:
|
|
1948
|
+
# log будет создан в ADirectoryLOG
|
|
1949
|
+
LDirectoryLOG = LUFile.ExpandFileName (ADirectoryLOG)
|
|
1950
|
+
#endif
|
|
1951
|
+
# print('...LDirectoryLOG:',LDirectoryLOG)
|
|
1952
|
+
|
|
1953
|
+
if not LUFile.DirectoryExists (LDirectoryLOG):
|
|
1954
|
+
LUFile.ForceDirectories(LDirectoryLOG)
|
|
1955
|
+
#endif
|
|
1956
|
+
|
|
1957
|
+
# os.chdir (LDirectoryLOG)
|
|
1958
|
+
|
|
1959
|
+
# print(LFileNameINI)
|
|
1960
|
+
|
|
1961
|
+
logging.config.fileConfig (LFileNameINI, disable_existing_loggers=True,
|
|
1962
|
+
encoding=LUFile.cDefaultEncoding)
|
|
1963
|
+
# logging.config.fileConfig (LFileNameINI, disable_existing_loggers=True, encoding='cp1251')
|
|
1964
|
+
|
|
1965
|
+
# создаем регистратор
|
|
1966
|
+
LResult = logging.getLogger (ALogerName)
|
|
1967
|
+
# print(f'{LResult.name=}')
|
|
1968
|
+
# print(f'{LResult.handlers=}')
|
|
1969
|
+
# установить форматер
|
|
1970
|
+
SetFormatterForLogger (LResult)
|
|
1971
|
+
|
|
1972
|
+
return LResult
|
|
1973
|
+
#endfunction
|
|
1974
|
+
|
|
1975
|
+
#-------------------------------------------------
|
|
1976
|
+
# CreateLoggerBASIC
|
|
1977
|
+
#-------------------------------------------------
|
|
1978
|
+
def CreateLoggerBASIC (ALevel, AFileNameLOG: str, ALogerName: str) -> logging.Logger:
|
|
1979
|
+
"""CreateTLoggingCONFIG"""
|
|
1980
|
+
#beginfunction
|
|
1981
|
+
# читаем конфигурацию из
|
|
1982
|
+
if len(AFileNameLOG) > 0:
|
|
1983
|
+
logging.basicConfig (level = ALevel, filename = AFileNameLOG, style='%',
|
|
1984
|
+
datefmt = Cdatefmt_01, format = Cstrfmt_01)
|
|
1985
|
+
else:
|
|
1986
|
+
logging.basicConfig (level = ALevel, stream=sys.stdout, style='%',
|
|
1987
|
+
datefmt = Cdatefmt_01, format = Cstrfmt_01)
|
|
1988
|
+
# создаем регистратор
|
|
1989
|
+
LResult = logging.getLogger (ALogerName)
|
|
1990
|
+
# установить форматер
|
|
1991
|
+
SetFormatterForLogger (LResult)
|
|
1992
|
+
return LResult
|
|
1993
|
+
#endfunction
|
|
1994
|
+
|
|
1995
|
+
#-------------------------------------------------
|
|
1996
|
+
# LoggerTLogger
|
|
1997
|
+
#-------------------------------------------------
|
|
1998
|
+
def CreateTLogger (ALogerName: str) -> TLogger:
|
|
1999
|
+
"""CreateTLogging"""
|
|
2000
|
+
#beginfunction
|
|
2001
|
+
logging.setLoggerClass (TLogger)
|
|
2002
|
+
# создаем регистратор
|
|
2003
|
+
LResult = TLogger(ALogerName)
|
|
2004
|
+
SetFormatterForLogger (LResult)
|
|
2005
|
+
return LResult
|
|
2006
|
+
#endfunction
|
|
2007
|
+
|
|
2008
|
+
#-------------------------------------------------
|
|
2009
|
+
# FileMemoLog
|
|
2010
|
+
#-------------------------------------------------
|
|
2011
|
+
def CreateTFileMemoLog () -> TFileMemoLog:
|
|
2012
|
+
"""CreateTFileMemoLog"""
|
|
2013
|
+
#beginfunction
|
|
2014
|
+
LFileMemoLog = TFileMemoLog ()
|
|
2015
|
+
return LFileMemoLog
|
|
2016
|
+
#endfunction
|
|
2017
|
+
|
|
2018
|
+
#-------------------------------------------------
|
|
2019
|
+
# Инициализация системы logging
|
|
2020
|
+
#-------------------------------------------------
|
|
2021
|
+
STATLogging = True
|
|
2022
|
+
|
|
2023
|
+
GLoggerFILEINI = logging.Logger
|
|
2024
|
+
GLoggerCONFIG = logging.Logger
|
|
2025
|
+
LoggerTOOLS = logging.Logger
|
|
2026
|
+
LoggerAPPS = logging.Logger
|
|
2027
|
+
LoggerTLogger = TLogger
|
|
2028
|
+
FileMemoLog = TFileMemoLog
|
|
2029
|
+
|
|
2030
|
+
def STARTLogging (T: TTypeSETUPLOG, ALogerName, ADirectoryLOG: str, AFileNameLOG: str, AFileNameLOGjson: str) -> None:
|
|
2031
|
+
"""STARTLogging"""
|
|
2032
|
+
#beginfunction
|
|
2033
|
+
global GLoggerFILEINI
|
|
2034
|
+
global GLoggerCONFIG
|
|
2035
|
+
global LoggerTOOLS
|
|
2036
|
+
global LoggerAPPS
|
|
2037
|
+
global LoggerTLogger
|
|
2038
|
+
global FileMemoLog
|
|
2039
|
+
global STATLogging
|
|
2040
|
+
|
|
2041
|
+
STATLogging = False
|
|
2042
|
+
|
|
2043
|
+
# print (sys._getframe (0).f_code.co_name, '...')
|
|
2044
|
+
# print (inspect.currentframe().f_code.co_name, '...')
|
|
2045
|
+
# print (inspect.stack () [0] [3], '...')
|
|
2046
|
+
# print (traceback.extract_stack () [-1].name, '...')
|
|
2047
|
+
|
|
2048
|
+
LLogerNames = ['root','log01','log01', 'console']
|
|
2049
|
+
|
|
2050
|
+
AddLevelName ()
|
|
2051
|
+
|
|
2052
|
+
LT = T
|
|
2053
|
+
if LUos.GOSInfo.system == 'Windows':
|
|
2054
|
+
LT = T
|
|
2055
|
+
#endif
|
|
2056
|
+
if LUos.GOSInfo.system == 'Linux':
|
|
2057
|
+
LT = TTypeSETUPLOG.tslCONFIG
|
|
2058
|
+
#endif
|
|
2059
|
+
|
|
2060
|
+
if ALogerName in LLogerNames:
|
|
2061
|
+
match LT:
|
|
2062
|
+
case TTypeSETUPLOG.tslCONFIG:
|
|
2063
|
+
GLoggerCONFIG = CreateLoggerCONFIG (CDefaultFileLogCONFIG, ALogerName,
|
|
2064
|
+
ADirectoryLOG, AFileNameLOG,
|
|
2065
|
+
AFileNameLOGjson)
|
|
2066
|
+
case TTypeSETUPLOG.tslYAML:
|
|
2067
|
+
GLoggerYAML = CreateLoggerYAML (CDefaultFileLogYAML, ALogerName,
|
|
2068
|
+
ADirectoryLOG, AFileNameLOG,
|
|
2069
|
+
AFileNameLOGjson)
|
|
2070
|
+
case TTypeSETUPLOG.tslINI:
|
|
2071
|
+
if ALogerName == 'console' or LUConst.GAPPName is None:
|
|
2072
|
+
# 'logging_CONSOLE.INI'
|
|
2073
|
+
LFileLogINI = CDefaultFileLogINI
|
|
2074
|
+
LFileLogINI = CDefaultFileLogINI_CONSOLE
|
|
2075
|
+
else:
|
|
2076
|
+
LFileLogINI = LUConst.GAPPName+'.ini'
|
|
2077
|
+
#endif
|
|
2078
|
+
GLoggerFILEINI = CreateLoggerFILEINI (LFileLogINI, ALogerName,
|
|
2079
|
+
ADirectoryLOG, AFileNameLOG,
|
|
2080
|
+
AFileNameLOGjson)
|
|
2081
|
+
case _:
|
|
2082
|
+
pass
|
|
2083
|
+
#endmatch
|
|
2084
|
+
else:
|
|
2085
|
+
exit()
|
|
2086
|
+
#endif
|
|
2087
|
+
|
|
2088
|
+
#-------------------------------------------------
|
|
2089
|
+
# GLoggerBASIC = CreateLoggerBASIC (logging.DEBUG, 'LOG\\' + CDefaultFileLogFILEBASIC, 'root')
|
|
2090
|
+
# GLoggerBASIC = CreateLoggerBASIC (logging.DEBUG, '', 'root')
|
|
2091
|
+
#-------------------------------------------------
|
|
2092
|
+
|
|
2093
|
+
#-------------------------------------------------
|
|
2094
|
+
# LoggerTOOLS
|
|
2095
|
+
#-------------------------------------------------
|
|
2096
|
+
CLoggerTOOLS = 'TOOLS__'
|
|
2097
|
+
LoggerTOOLS = logging.getLogger (CLoggerTOOLS)
|
|
2098
|
+
# LoggerTOOLS.disabled = False
|
|
2099
|
+
# LoggerTOOLS.info ('info')
|
|
2100
|
+
# print('LoggerTOOLS' in vars () or 'LoggerTOOLS' in globals ())
|
|
2101
|
+
# print('LoggerTOOLS' in vars ())
|
|
2102
|
+
# print('LoggerTOOLS' in globals ())
|
|
2103
|
+
# if not ('LoggerTOOLS' in vars () or 'LoggerTOOLS' in globals ()):
|
|
2104
|
+
# CLoggerTOOLS = 'TOOLS__'
|
|
2105
|
+
# LoggerTOOLS = logging.getLogger (CLoggerTOOLS)
|
|
2106
|
+
# #endif
|
|
2107
|
+
|
|
2108
|
+
#-------------------------------------------------
|
|
2109
|
+
# LoggerAPPS
|
|
2110
|
+
#-------------------------------------------------
|
|
2111
|
+
CLoggerAPPS = 'APPS__'
|
|
2112
|
+
LoggerAPPS = logging.getLogger(CLoggerAPPS)
|
|
2113
|
+
|
|
2114
|
+
#-------------------------------------------------
|
|
2115
|
+
# LoggerTLogger
|
|
2116
|
+
#-------------------------------------------------
|
|
2117
|
+
CTLogger = 'TLOGGER'
|
|
2118
|
+
LoggerTLogger = CreateTLogger (CTLogger)
|
|
2119
|
+
|
|
2120
|
+
#-------------------------------------------------
|
|
2121
|
+
# FileMemoLog
|
|
2122
|
+
#-------------------------------------------------
|
|
2123
|
+
FileMemoLog = CreateTFileMemoLog ()
|
|
2124
|
+
|
|
2125
|
+
#-------------------------------------------------
|
|
2126
|
+
# Отключить журнал 'chardet.charsetprober'
|
|
2127
|
+
#-------------------------------------------------
|
|
2128
|
+
logger = logging.getLogger('chardet.charsetprober')
|
|
2129
|
+
logger.setLevel(logging.INFO)
|
|
2130
|
+
logger = logging.getLogger('chardet.universaldetector')
|
|
2131
|
+
logger.setLevel(logging.INFO)
|
|
2132
|
+
|
|
2133
|
+
#-------------------------------------------------
|
|
2134
|
+
# Отключить журнал 'pytube.extract'
|
|
2135
|
+
#-------------------------------------------------
|
|
2136
|
+
logger = logging.getLogger('pytube.extract')
|
|
2137
|
+
logger.setLevel(logging.INFO)
|
|
2138
|
+
|
|
2139
|
+
#-------------------------------------------------
|
|
2140
|
+
# Отключить журнал 'pytube.streams'
|
|
2141
|
+
#-------------------------------------------------
|
|
2142
|
+
logger = logging.getLogger('pytube.streams')
|
|
2143
|
+
logger.setLevel(logging.INFO)
|
|
2144
|
+
|
|
2145
|
+
#-------------------------------------------------
|
|
2146
|
+
# Отключить журнал 'pytube.cipher'
|
|
2147
|
+
#-------------------------------------------------
|
|
2148
|
+
logger = logging.getLogger('pytube.cipher')
|
|
2149
|
+
logger.setLevel(logging.INFO)
|
|
2150
|
+
|
|
2151
|
+
#-------------------------------------------------
|
|
2152
|
+
# Отключить журнал 'pytube.helpers'
|
|
2153
|
+
#-------------------------------------------------
|
|
2154
|
+
logger = logging.getLogger('pytube.helpers')
|
|
2155
|
+
logger.setLevel(logging.INFO)
|
|
2156
|
+
|
|
2157
|
+
STATLogging = True
|
|
2158
|
+
#endfunction
|
|
2159
|
+
|
|
2160
|
+
#-------------------------------------------------
|
|
2161
|
+
# Выключить систему logging
|
|
2162
|
+
#-------------------------------------------------
|
|
2163
|
+
def STOPLogging () -> None:
|
|
2164
|
+
"""STOPLogging"""
|
|
2165
|
+
#beginfunction
|
|
2166
|
+
global STATLogging
|
|
2167
|
+
# global LoggerTOOLS
|
|
2168
|
+
STATLogging = False
|
|
2169
|
+
# LoggerTOOLS.disabled = True# Выключить систему logging для логгирования
|
|
2170
|
+
#endfunction
|
|
2171
|
+
|
|
2172
|
+
#-------------------------------------------------
|
|
2173
|
+
# LoggerAdd
|
|
2174
|
+
#-------------------------------------------------
|
|
2175
|
+
def LoggerAdd (ALogger, ALevel, Astr):
|
|
2176
|
+
#beginfunction
|
|
2177
|
+
if STATLogging:
|
|
2178
|
+
try:
|
|
2179
|
+
ALogger.log(ALevel, Astr)
|
|
2180
|
+
except:
|
|
2181
|
+
print("ERROR:")
|
|
2182
|
+
...
|
|
2183
|
+
#endtry
|
|
2184
|
+
else:
|
|
2185
|
+
print("INFO: система не включена для записи логов")
|
|
2186
|
+
#endif
|
|
2187
|
+
#endfunction
|
|
2188
|
+
|
|
2189
|
+
# #-------------------------------------------------
|
|
2190
|
+
# # LoggerTOOLS_AddLevel
|
|
2191
|
+
# #-------------------------------------------------
|
|
2192
|
+
# def LoggerTOOLS_AddLevel (ALevel, Astr):
|
|
2193
|
+
# #beginfunction
|
|
2194
|
+
# if STATLogging:
|
|
2195
|
+
# try:
|
|
2196
|
+
# LoggerTOOLS.log(ALevel, Astr)
|
|
2197
|
+
# except:
|
|
2198
|
+
# ...
|
|
2199
|
+
# #endtry
|
|
2200
|
+
# else:
|
|
2201
|
+
# print("INFO: система не включена для записи логов")
|
|
2202
|
+
# #endif
|
|
2203
|
+
# #endfunction
|
|
2204
|
+
#
|
|
2205
|
+
# #-------------------------------------------------
|
|
2206
|
+
# # LoggerTOOLS_AddDebug
|
|
2207
|
+
# #-------------------------------------------------
|
|
2208
|
+
# def LoggerTOOLS_AddDebug (Astr):
|
|
2209
|
+
# #beginfunction
|
|
2210
|
+
# if STATLogging:
|
|
2211
|
+
# try:
|
|
2212
|
+
# LoggerTOOLS.debug(Astr)
|
|
2213
|
+
# except:
|
|
2214
|
+
# ...
|
|
2215
|
+
# #endtry
|
|
2216
|
+
# else:
|
|
2217
|
+
# print("INFO: система не включена для записи логов")
|
|
2218
|
+
# #endif
|
|
2219
|
+
# #endfunction
|
|
2220
|
+
#
|
|
2221
|
+
# #-------------------------------------------------
|
|
2222
|
+
# # LoggerTOOLS_AddError
|
|
2223
|
+
# #-------------------------------------------------
|
|
2224
|
+
# def LoggerTOOLS_AddError (Astr):
|
|
2225
|
+
# #beginfunction
|
|
2226
|
+
# if STATLogging:
|
|
2227
|
+
# try:
|
|
2228
|
+
# LoggerTOOLS.error(Astr)
|
|
2229
|
+
# except:
|
|
2230
|
+
# ...
|
|
2231
|
+
# #endtry
|
|
2232
|
+
# else:
|
|
2233
|
+
# print("INFO: система не включена для записи логов")
|
|
2234
|
+
# #endif
|
|
2235
|
+
# #endfunction
|
|
2236
|
+
#
|
|
2237
|
+
# #-------------------------------------------------
|
|
2238
|
+
# # LoggerAPPS_AddLevel
|
|
2239
|
+
# #-------------------------------------------------
|
|
2240
|
+
# #LULog.LoggerAPPS.log
|
|
2241
|
+
# def LoggerAPPS_AddLevel (ALevel, Astr):
|
|
2242
|
+
# #beginfunction
|
|
2243
|
+
# if STATLogging:
|
|
2244
|
+
# try:
|
|
2245
|
+
# LoggerAPPS.log(ALevel, Astr)
|
|
2246
|
+
# except:
|
|
2247
|
+
# ...
|
|
2248
|
+
# #endtry
|
|
2249
|
+
# else:
|
|
2250
|
+
# print("INFO: система не включена для записи логов")
|
|
2251
|
+
# #endif
|
|
2252
|
+
# #endfunction
|
|
2253
|
+
#
|
|
2254
|
+
# #-------------------------------------------------
|
|
2255
|
+
# # LoggerAPPS_AddInfo
|
|
2256
|
+
# #-------------------------------------------------
|
|
2257
|
+
# #LULog.LoggerAPPS.info
|
|
2258
|
+
# def LoggerAPPS_AddInfo (Astr):
|
|
2259
|
+
# #beginfunction
|
|
2260
|
+
# if STATLogging:
|
|
2261
|
+
# try:
|
|
2262
|
+
# LoggerAPPS.info(Astr)
|
|
2263
|
+
# except:
|
|
2264
|
+
# ...
|
|
2265
|
+
# #endtry
|
|
2266
|
+
# else:
|
|
2267
|
+
# print("INFO: система не включена для записи логов")
|
|
2268
|
+
# #endif
|
|
2269
|
+
# #endfunction
|
|
2270
|
+
#
|
|
2271
|
+
# #-------------------------------------------------
|
|
2272
|
+
# # LoggerAPPS_AddError
|
|
2273
|
+
# #-------------------------------------------------
|
|
2274
|
+
# #LULog.LoggerAPPS.error
|
|
2275
|
+
# def LoggerAPPS_AddError (Astr):
|
|
2276
|
+
# #beginfunction
|
|
2277
|
+
# if STATLogging:
|
|
2278
|
+
# try:
|
|
2279
|
+
# LoggerAPPS.error(Astr)
|
|
2280
|
+
# except:
|
|
2281
|
+
# ...
|
|
2282
|
+
# #endtry
|
|
2283
|
+
# else:
|
|
2284
|
+
# print("INFO: система не включена для записи логов")
|
|
2285
|
+
# #endif
|
|
2286
|
+
# #endfunction
|
|
2287
|
+
#
|
|
2288
|
+
# #-------------------------------------------------
|
|
2289
|
+
# # LoggerAPPS_AddDebug
|
|
2290
|
+
# #-------------------------------------------------
|
|
2291
|
+
# #LULog.LoggerAPPS.debug
|
|
2292
|
+
# def LoggerAPPS_AddDebug (Astr):
|
|
2293
|
+
# #beginfunction
|
|
2294
|
+
# if STATLogging:
|
|
2295
|
+
# try:
|
|
2296
|
+
# LoggerAPPS.debug(Astr)
|
|
2297
|
+
# except:
|
|
2298
|
+
# ...
|
|
2299
|
+
# #endtry
|
|
2300
|
+
# else:
|
|
2301
|
+
# print("INFO: система не включена для записи логов")
|
|
2302
|
+
# #endif
|
|
2303
|
+
# #endfunction
|
|
2304
|
+
|
|
2305
|
+
#-------------------------------------------------
|
|
2306
|
+
# main
|
|
2307
|
+
#-------------------------------------------------
|
|
2308
|
+
def main ():
|
|
2309
|
+
#beginfunction
|
|
2310
|
+
print('main LULog.py...')
|
|
2311
|
+
#endfunction
|
|
2312
|
+
|
|
2313
|
+
#------------------------------------------
|
|
2314
|
+
#
|
|
2315
|
+
#------------------------------------------
|
|
2316
|
+
#beginmodule
|
|
2317
|
+
|
|
2318
|
+
if __name__ == "__main__":
|
|
2319
|
+
main()
|
|
2320
|
+
else:
|
|
2321
|
+
STOPLogging ()
|
|
2322
|
+
#endif
|
|
2323
|
+
|
|
2324
|
+
#endmodule
|