@@ -1129,46 +1129,54 @@ class NTEventLogHandler(logging.Handler):
11291129 """
11301130 A handler class which sends events to the NT Event Log. Adds a
11311131 registry entry for the specified application name. If no dllname is
1132- provided, win32service.pyd (which contains some basic message
1132+ provided and pywin32 installed , win32service.pyd (which contains some basic message
11331133 placeholders) is used. Note that use of these placeholders will make
11341134 your event logs big, as the entire message source is held in the log.
11351135 If you want slimmer logs, you have to pass in the name of your own DLL
11361136 which contains the message definitions you want to use in the event log.
11371137 """
11381138 def __init__ (self , appname , dllname = None , logtype = "Application" ):
11391139 logging .Handler .__init__ (self )
1140- try :
1141- import win32evtlogutil , win32evtlog
1142- self .appname = appname
1143- self ._welu = win32evtlogutil
1144- if not dllname :
1145- dllname = os .path .split (self ._welu .__file__ )
1140+ import _winapi
1141+ self ._winapi = _winapi
1142+ self .appname = appname
1143+ if not dllname :
1144+ # backward compatibility
1145+ try :
1146+ import win32evtlogutil
1147+ dllname = os .path .split (win32evtlogutil .__file__ )
11461148 dllname = os .path .split (dllname [0 ])
11471149 dllname = os .path .join (dllname [0 ], r'win32service.pyd' )
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 ._welu .AddSourceToRegistry (appname , dllname , logtype )
1155- except Exception as e :
1156- # This will probably be a pywintypes.error. Only raise if it's not
1157- # an "access denied" error, else let it pass
1158- if getattr (e , 'winerror' , None ) != 5 : # not access denied
1159- raise
1160- self .deftype = win32evtlog .EVENTLOG_ERROR_TYPE
1161- self .typemap = {
1162- logging .DEBUG : win32evtlog .EVENTLOG_INFORMATION_TYPE ,
1163- logging .INFO : win32evtlog .EVENTLOG_INFORMATION_TYPE ,
1164- logging .WARNING : win32evtlog .EVENTLOG_WARNING_TYPE ,
1165- logging .ERROR : win32evtlog .EVENTLOG_ERROR_TYPE ,
1166- logging .CRITICAL : win32evtlog .EVENTLOG_ERROR_TYPE ,
1167- }
1168- except ImportError :
1169- print ("The Python Win32 extensions for NT (service, event " \
1170- "logging) appear not to be available." )
1171- self ._welu = None
1150+ except ImportError :
1151+ pass
1152+ self .dllname = dllname
1153+ self .logtype = logtype
1154+ # Administrative privileges are required to add a source to the registry.
1155+ # This may not be available for a user that just wants to add to an
1156+ # existing source - handle this specific case.
1157+ try :
1158+ self ._add_source_to_registry (appname , dllname , logtype )
1159+ except PermissionError :
1160+ pass
1161+ self .deftype = _winapi .EVENTLOG_ERROR_TYPE
1162+ self .typemap = {
1163+ logging .DEBUG : _winapi .EVENTLOG_INFORMATION_TYPE ,
1164+ logging .INFO : _winapi .EVENTLOG_INFORMATION_TYPE ,
1165+ logging .WARNING : _winapi .EVENTLOG_WARNING_TYPE ,
1166+ logging .ERROR : _winapi .EVENTLOG_ERROR_TYPE ,
1167+ logging .CRITICAL : _winapi .EVENTLOG_ERROR_TYPE ,
1168+ }
1169+
1170+ @staticmethod
1171+ def _add_source_to_registry (appname , dllname , logtype ):
1172+ import winreg
1173+
1174+ key_path = f"SYSTEM\\ CurrentControlSet\\ Services\\ EventLog\\ { logtype } \\ { appname } "
1175+
1176+ with winreg .CreateKey (winreg .HKEY_LOCAL_MACHINE , key_path ) as key :
1177+ if dllname :
1178+ winreg .SetValueEx (key , "EventMessageFile" , 0 , winreg .REG_EXPAND_SZ , dllname )
1179+ winreg .SetValueEx (key , "TypesSupported" , 0 , winreg .REG_DWORD , 7 ) # All types are supported
11721180
11731181 def getMessageID (self , record ):
11741182 """
@@ -1209,15 +1217,20 @@ def emit(self, record):
12091217 Determine the message ID, event category and event type. Then
12101218 log the message in the NT event log.
12111219 """
1212- if self ._welu :
1220+ try :
1221+ id = self .getMessageID (record )
1222+ cat = self .getEventCategory (record )
1223+ type = self .getEventType (record )
1224+ msg = self .format (record )
1225+
1226+ # Get a handle to the event log
1227+ handle = self ._winapi .RegisterEventSource (None , self .appname )
12131228 try :
1214- id = self .getMessageID (record )
1215- cat = self .getEventCategory (record )
1216- type = self .getEventType (record )
1217- msg = self .format (record )
1218- self ._welu .ReportEvent (self .appname , id , cat , type , [msg ])
1219- except Exception :
1220- self .handleError (record )
1229+ self ._winapi .ReportEvent (handle , type , cat , id , msg )
1230+ finally :
1231+ self ._winapi .DeregisterEventSource (handle )
1232+ except Exception :
1233+ self .handleError (record )
12211234
12221235 def close (self ):
12231236 """
0 commit comments