@@ -1125,46 +1125,53 @@ class NTEventLogHandler(logging.Handler):
11251125 """
11261126 A handler class which sends events to the NT Event Log. Adds a
11271127 registry entry for the specified application name. If no dllname is
1128- provided, win32service.pyd (which contains some basic message
1128+ provided and pywin32 installed , win32service.pyd (which contains some basic message
11291129 placeholders) is used. Note that use of these placeholders will make
11301130 your event logs big, as the entire message source is held in the log.
11311131 If you want slimmer logs, you have to pass in the name of your own DLL
11321132 which contains the message definitions you want to use in the event log.
11331133 """
11341134 def __init__ (self , appname , dllname = None , logtype = "Application" ):
11351135 logging .Handler .__init__ (self )
1136- try :
1137- import win32evtlogutil , win32evtlog
1138- self .appname = appname
1139- self ._welu = win32evtlogutil
1140- if not dllname :
1141- dllname = os .path .split (self ._welu .__file__ )
1136+ import _winapi
1137+ self ._winapi = _winapi
1138+ self .appname = appname
1139+ if not dllname :
1140+ # backward compatibility
1141+ try :
1142+ import win32evtlogutil
1143+ dllname = os .path .split (win32evtlogutil .__file__ )
11421144 dllname = os .path .split (dllname [0 ])
11431145 dllname = os .path .join (dllname [0 ], r'win32service.pyd' )
1144- self .dllname = dllname
1145- self .logtype = logtype
1146- # Administrative privileges are required to add a source to the registry.
1147- # This may not be available for a user that just wants to add to an
1148- # existing source - handle this specific case.
1149- try :
1150- self ._welu .AddSourceToRegistry (appname , dllname , logtype )
1151- except Exception as e :
1152- # This will probably be a pywintypes.error. Only raise if it's not
1153- # an "access denied" error, else let it pass
1154- if getattr (e , 'winerror' , None ) != 5 : # not access denied
1155- raise
1156- self .deftype = win32evtlog .EVENTLOG_ERROR_TYPE
1157- self .typemap = {
1158- logging .DEBUG : win32evtlog .EVENTLOG_INFORMATION_TYPE ,
1159- logging .INFO : win32evtlog .EVENTLOG_INFORMATION_TYPE ,
1160- logging .WARNING : win32evtlog .EVENTLOG_WARNING_TYPE ,
1161- logging .ERROR : win32evtlog .EVENTLOG_ERROR_TYPE ,
1162- logging .CRITICAL : win32evtlog .EVENTLOG_ERROR_TYPE ,
1163- }
1164- except ImportError :
1165- print ("The Python Win32 extensions for NT (service, event " \
1166- "logging) appear not to be available." )
1167- self ._welu = None
1146+ except ImportError :
1147+ pass
1148+ self .dllname = dllname
1149+ self .logtype = logtype
1150+ # Administrative privileges are required to add a source to the registry.
1151+ # This may not be available for a user that just wants to add to an
1152+ # existing source - handle this specific case.
1153+ try :
1154+ self ._add_source_to_registry (appname , dllname , logtype )
1155+ except PermissionError :
1156+ pass
1157+ self .deftype = _winapi .EVENTLOG_ERROR_TYPE
1158+ self .typemap = {
1159+ logging .DEBUG : _winapi .EVENTLOG_INFORMATION_TYPE ,
1160+ logging .INFO : _winapi .EVENTLOG_INFORMATION_TYPE ,
1161+ logging .WARNING : _winapi .EVENTLOG_WARNING_TYPE ,
1162+ logging .ERROR : _winapi .EVENTLOG_ERROR_TYPE ,
1163+ logging .CRITICAL : _winapi .EVENTLOG_ERROR_TYPE ,
1164+ }
1165+
1166+ def _add_source_to_registry (self , appname , dllname , logtype ):
1167+ import winreg
1168+
1169+ key_path = f"SYSTEM\\ CurrentControlSet\\ Services\\ EventLog\\ { logtype } \\ { appname } "
1170+
1171+ with winreg .CreateKey (winreg .HKEY_LOCAL_MACHINE , key_path ) as key :
1172+ if dllname :
1173+ winreg .SetValueEx (key , "EventMessageFile" , 0 , winreg .REG_EXPAND_SZ , dllname )
1174+ winreg .SetValueEx (key , "TypesSupported" , 0 , winreg .REG_DWORD , 7 ) # All types are supported
11681175
11691176 def getMessageID (self , record ):
11701177 """
@@ -1205,13 +1212,20 @@ def emit(self, record):
12051212 Determine the message ID, event category and event type. Then
12061213 log the message in the NT event log.
12071214 """
1208- if self ._welu :
1215+ if self ._winapi :
12091216 try :
12101217 id = self .getMessageID (record )
12111218 cat = self .getEventCategory (record )
12121219 type = self .getEventType (record )
12131220 msg = self .format (record )
1214- self ._welu .ReportEvent (self .appname , id , cat , type , [msg ])
1221+
1222+ # Get a handle to the event log
1223+ handle = self ._winapi .RegisterEventSource (None , self .appname )
1224+ if handle != self ._winapi .INVALID_HANDLE_VALUE :
1225+ try :
1226+ self ._winapi .ReportEvent (handle , type , cat , id , [msg ])
1227+ finally :
1228+ self ._winapi .DeregisterEventSource (handle )
12151229 except Exception :
12161230 self .handleError (record )
12171231
0 commit comments