Edit File by line
/home/barbar84/www/wp-conte.../plugins/sujqvwi/AnonR/anonr.TX.../usr/lib64/python3..../logging
File: handlers.py
makeLogRecord function.
[500] Fix | Delete
"""
[501] Fix | Delete
[502] Fix | Delete
def __init__(self, host, port):
[503] Fix | Delete
"""
[504] Fix | Delete
Initializes the handler with a specific host address and port.
[505] Fix | Delete
[506] Fix | Delete
When the attribute *closeOnError* is set to True - if a socket error
[507] Fix | Delete
occurs, the socket is silently closed and then reopened on the next
[508] Fix | Delete
logging call.
[509] Fix | Delete
"""
[510] Fix | Delete
logging.Handler.__init__(self)
[511] Fix | Delete
self.host = host
[512] Fix | Delete
self.port = port
[513] Fix | Delete
if port is None:
[514] Fix | Delete
self.address = host
[515] Fix | Delete
else:
[516] Fix | Delete
self.address = (host, port)
[517] Fix | Delete
self.sock = None
[518] Fix | Delete
self.closeOnError = False
[519] Fix | Delete
self.retryTime = None
[520] Fix | Delete
#
[521] Fix | Delete
# Exponential backoff parameters.
[522] Fix | Delete
#
[523] Fix | Delete
self.retryStart = 1.0
[524] Fix | Delete
self.retryMax = 30.0
[525] Fix | Delete
self.retryFactor = 2.0
[526] Fix | Delete
[527] Fix | Delete
def makeSocket(self, timeout=1):
[528] Fix | Delete
"""
[529] Fix | Delete
A factory method which allows subclasses to define the precise
[530] Fix | Delete
type of socket they want.
[531] Fix | Delete
"""
[532] Fix | Delete
if self.port is not None:
[533] Fix | Delete
result = socket.create_connection(self.address, timeout=timeout)
[534] Fix | Delete
else:
[535] Fix | Delete
result = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
[536] Fix | Delete
result.settimeout(timeout)
[537] Fix | Delete
try:
[538] Fix | Delete
result.connect(self.address)
[539] Fix | Delete
except OSError:
[540] Fix | Delete
result.close() # Issue 19182
[541] Fix | Delete
raise
[542] Fix | Delete
return result
[543] Fix | Delete
[544] Fix | Delete
def createSocket(self):
[545] Fix | Delete
"""
[546] Fix | Delete
Try to create a socket, using an exponential backoff with
[547] Fix | Delete
a max retry time. Thanks to Robert Olson for the original patch
[548] Fix | Delete
(SF #815911) which has been slightly refactored.
[549] Fix | Delete
"""
[550] Fix | Delete
now = time.time()
[551] Fix | Delete
# Either retryTime is None, in which case this
[552] Fix | Delete
# is the first time back after a disconnect, or
[553] Fix | Delete
# we've waited long enough.
[554] Fix | Delete
if self.retryTime is None:
[555] Fix | Delete
attempt = True
[556] Fix | Delete
else:
[557] Fix | Delete
attempt = (now >= self.retryTime)
[558] Fix | Delete
if attempt:
[559] Fix | Delete
try:
[560] Fix | Delete
self.sock = self.makeSocket()
[561] Fix | Delete
self.retryTime = None # next time, no delay before trying
[562] Fix | Delete
except OSError:
[563] Fix | Delete
#Creation failed, so set the retry time and return.
[564] Fix | Delete
if self.retryTime is None:
[565] Fix | Delete
self.retryPeriod = self.retryStart
[566] Fix | Delete
else:
[567] Fix | Delete
self.retryPeriod = self.retryPeriod * self.retryFactor
[568] Fix | Delete
if self.retryPeriod > self.retryMax:
[569] Fix | Delete
self.retryPeriod = self.retryMax
[570] Fix | Delete
self.retryTime = now + self.retryPeriod
[571] Fix | Delete
[572] Fix | Delete
def send(self, s):
[573] Fix | Delete
"""
[574] Fix | Delete
Send a pickled string to the socket.
[575] Fix | Delete
[576] Fix | Delete
This function allows for partial sends which can happen when the
[577] Fix | Delete
network is busy.
[578] Fix | Delete
"""
[579] Fix | Delete
if self.sock is None:
[580] Fix | Delete
self.createSocket()
[581] Fix | Delete
#self.sock can be None either because we haven't reached the retry
[582] Fix | Delete
#time yet, or because we have reached the retry time and retried,
[583] Fix | Delete
#but are still unable to connect.
[584] Fix | Delete
if self.sock:
[585] Fix | Delete
try:
[586] Fix | Delete
self.sock.sendall(s)
[587] Fix | Delete
except OSError: #pragma: no cover
[588] Fix | Delete
self.sock.close()
[589] Fix | Delete
self.sock = None # so we can call createSocket next time
[590] Fix | Delete
[591] Fix | Delete
def makePickle(self, record):
[592] Fix | Delete
"""
[593] Fix | Delete
Pickles the record in binary format with a length prefix, and
[594] Fix | Delete
returns it ready for transmission across the socket.
[595] Fix | Delete
"""
[596] Fix | Delete
ei = record.exc_info
[597] Fix | Delete
if ei:
[598] Fix | Delete
# just to get traceback text into record.exc_text ...
[599] Fix | Delete
dummy = self.format(record)
[600] Fix | Delete
# See issue #14436: If msg or args are objects, they may not be
[601] Fix | Delete
# available on the receiving end. So we convert the msg % args
[602] Fix | Delete
# to a string, save it as msg and zap the args.
[603] Fix | Delete
d = dict(record.__dict__)
[604] Fix | Delete
d['msg'] = record.getMessage()
[605] Fix | Delete
d['args'] = None
[606] Fix | Delete
d['exc_info'] = None
[607] Fix | Delete
# Issue #25685: delete 'message' if present: redundant with 'msg'
[608] Fix | Delete
d.pop('message', None)
[609] Fix | Delete
s = pickle.dumps(d, 1)
[610] Fix | Delete
slen = struct.pack(">L", len(s))
[611] Fix | Delete
return slen + s
[612] Fix | Delete
[613] Fix | Delete
def handleError(self, record):
[614] Fix | Delete
"""
[615] Fix | Delete
Handle an error during logging.
[616] Fix | Delete
[617] Fix | Delete
An error has occurred during logging. Most likely cause -
[618] Fix | Delete
connection lost. Close the socket so that we can retry on the
[619] Fix | Delete
next event.
[620] Fix | Delete
"""
[621] Fix | Delete
if self.closeOnError and self.sock:
[622] Fix | Delete
self.sock.close()
[623] Fix | Delete
self.sock = None #try to reconnect next time
[624] Fix | Delete
else:
[625] Fix | Delete
logging.Handler.handleError(self, record)
[626] Fix | Delete
[627] Fix | Delete
def emit(self, record):
[628] Fix | Delete
"""
[629] Fix | Delete
Emit a record.
[630] Fix | Delete
[631] Fix | Delete
Pickles the record and writes it to the socket in binary format.
[632] Fix | Delete
If there is an error with the socket, silently drop the packet.
[633] Fix | Delete
If there was a problem with the socket, re-establishes the
[634] Fix | Delete
socket.
[635] Fix | Delete
"""
[636] Fix | Delete
try:
[637] Fix | Delete
s = self.makePickle(record)
[638] Fix | Delete
self.send(s)
[639] Fix | Delete
except Exception:
[640] Fix | Delete
self.handleError(record)
[641] Fix | Delete
[642] Fix | Delete
def close(self):
[643] Fix | Delete
"""
[644] Fix | Delete
Closes the socket.
[645] Fix | Delete
"""
[646] Fix | Delete
self.acquire()
[647] Fix | Delete
try:
[648] Fix | Delete
sock = self.sock
[649] Fix | Delete
if sock:
[650] Fix | Delete
self.sock = None
[651] Fix | Delete
sock.close()
[652] Fix | Delete
logging.Handler.close(self)
[653] Fix | Delete
finally:
[654] Fix | Delete
self.release()
[655] Fix | Delete
[656] Fix | Delete
class DatagramHandler(SocketHandler):
[657] Fix | Delete
"""
[658] Fix | Delete
A handler class which writes logging records, in pickle format, to
[659] Fix | Delete
a datagram socket. The pickle which is sent is that of the LogRecord's
[660] Fix | Delete
attribute dictionary (__dict__), so that the receiver does not need to
[661] Fix | Delete
have the logging module installed in order to process the logging event.
[662] Fix | Delete
[663] Fix | Delete
To unpickle the record at the receiving end into a LogRecord, use the
[664] Fix | Delete
makeLogRecord function.
[665] Fix | Delete
[666] Fix | Delete
"""
[667] Fix | Delete
def __init__(self, host, port):
[668] Fix | Delete
"""
[669] Fix | Delete
Initializes the handler with a specific host address and port.
[670] Fix | Delete
"""
[671] Fix | Delete
SocketHandler.__init__(self, host, port)
[672] Fix | Delete
self.closeOnError = False
[673] Fix | Delete
[674] Fix | Delete
def makeSocket(self):
[675] Fix | Delete
"""
[676] Fix | Delete
The factory method of SocketHandler is here overridden to create
[677] Fix | Delete
a UDP socket (SOCK_DGRAM).
[678] Fix | Delete
"""
[679] Fix | Delete
if self.port is None:
[680] Fix | Delete
family = socket.AF_UNIX
[681] Fix | Delete
else:
[682] Fix | Delete
family = socket.AF_INET
[683] Fix | Delete
s = socket.socket(family, socket.SOCK_DGRAM)
[684] Fix | Delete
return s
[685] Fix | Delete
[686] Fix | Delete
def send(self, s):
[687] Fix | Delete
"""
[688] Fix | Delete
Send a pickled string to a socket.
[689] Fix | Delete
[690] Fix | Delete
This function no longer allows for partial sends which can happen
[691] Fix | Delete
when the network is busy - UDP does not guarantee delivery and
[692] Fix | Delete
can deliver packets out of sequence.
[693] Fix | Delete
"""
[694] Fix | Delete
if self.sock is None:
[695] Fix | Delete
self.createSocket()
[696] Fix | Delete
self.sock.sendto(s, self.address)
[697] Fix | Delete
[698] Fix | Delete
class SysLogHandler(logging.Handler):
[699] Fix | Delete
"""
[700] Fix | Delete
A handler class which sends formatted logging records to a syslog
[701] Fix | Delete
server. Based on Sam Rushing's syslog module:
[702] Fix | Delete
http://www.nightmare.com/squirl/python-ext/misc/syslog.py
[703] Fix | Delete
Contributed by Nicolas Untz (after which minor refactoring changes
[704] Fix | Delete
have been made).
[705] Fix | Delete
"""
[706] Fix | Delete
[707] Fix | Delete
# from <linux/sys/syslog.h>:
[708] Fix | Delete
# ======================================================================
[709] Fix | Delete
# priorities/facilities are encoded into a single 32-bit quantity, where
[710] Fix | Delete
# the bottom 3 bits are the priority (0-7) and the top 28 bits are the
[711] Fix | Delete
# facility (0-big number). Both the priorities and the facilities map
[712] Fix | Delete
# roughly one-to-one to strings in the syslogd(8) source code. This
[713] Fix | Delete
# mapping is included in this file.
[714] Fix | Delete
#
[715] Fix | Delete
# priorities (these are ordered)
[716] Fix | Delete
[717] Fix | Delete
LOG_EMERG = 0 # system is unusable
[718] Fix | Delete
LOG_ALERT = 1 # action must be taken immediately
[719] Fix | Delete
LOG_CRIT = 2 # critical conditions
[720] Fix | Delete
LOG_ERR = 3 # error conditions
[721] Fix | Delete
LOG_WARNING = 4 # warning conditions
[722] Fix | Delete
LOG_NOTICE = 5 # normal but significant condition
[723] Fix | Delete
LOG_INFO = 6 # informational
[724] Fix | Delete
LOG_DEBUG = 7 # debug-level messages
[725] Fix | Delete
[726] Fix | Delete
# facility codes
[727] Fix | Delete
LOG_KERN = 0 # kernel messages
[728] Fix | Delete
LOG_USER = 1 # random user-level messages
[729] Fix | Delete
LOG_MAIL = 2 # mail system
[730] Fix | Delete
LOG_DAEMON = 3 # system daemons
[731] Fix | Delete
LOG_AUTH = 4 # security/authorization messages
[732] Fix | Delete
LOG_SYSLOG = 5 # messages generated internally by syslogd
[733] Fix | Delete
LOG_LPR = 6 # line printer subsystem
[734] Fix | Delete
LOG_NEWS = 7 # network news subsystem
[735] Fix | Delete
LOG_UUCP = 8 # UUCP subsystem
[736] Fix | Delete
LOG_CRON = 9 # clock daemon
[737] Fix | Delete
LOG_AUTHPRIV = 10 # security/authorization messages (private)
[738] Fix | Delete
LOG_FTP = 11 # FTP daemon
[739] Fix | Delete
[740] Fix | Delete
# other codes through 15 reserved for system use
[741] Fix | Delete
LOG_LOCAL0 = 16 # reserved for local use
[742] Fix | Delete
LOG_LOCAL1 = 17 # reserved for local use
[743] Fix | Delete
LOG_LOCAL2 = 18 # reserved for local use
[744] Fix | Delete
LOG_LOCAL3 = 19 # reserved for local use
[745] Fix | Delete
LOG_LOCAL4 = 20 # reserved for local use
[746] Fix | Delete
LOG_LOCAL5 = 21 # reserved for local use
[747] Fix | Delete
LOG_LOCAL6 = 22 # reserved for local use
[748] Fix | Delete
LOG_LOCAL7 = 23 # reserved for local use
[749] Fix | Delete
[750] Fix | Delete
priority_names = {
[751] Fix | Delete
"alert": LOG_ALERT,
[752] Fix | Delete
"crit": LOG_CRIT,
[753] Fix | Delete
"critical": LOG_CRIT,
[754] Fix | Delete
"debug": LOG_DEBUG,
[755] Fix | Delete
"emerg": LOG_EMERG,
[756] Fix | Delete
"err": LOG_ERR,
[757] Fix | Delete
"error": LOG_ERR, # DEPRECATED
[758] Fix | Delete
"info": LOG_INFO,
[759] Fix | Delete
"notice": LOG_NOTICE,
[760] Fix | Delete
"panic": LOG_EMERG, # DEPRECATED
[761] Fix | Delete
"warn": LOG_WARNING, # DEPRECATED
[762] Fix | Delete
"warning": LOG_WARNING,
[763] Fix | Delete
}
[764] Fix | Delete
[765] Fix | Delete
facility_names = {
[766] Fix | Delete
"auth": LOG_AUTH,
[767] Fix | Delete
"authpriv": LOG_AUTHPRIV,
[768] Fix | Delete
"cron": LOG_CRON,
[769] Fix | Delete
"daemon": LOG_DAEMON,
[770] Fix | Delete
"ftp": LOG_FTP,
[771] Fix | Delete
"kern": LOG_KERN,
[772] Fix | Delete
"lpr": LOG_LPR,
[773] Fix | Delete
"mail": LOG_MAIL,
[774] Fix | Delete
"news": LOG_NEWS,
[775] Fix | Delete
"security": LOG_AUTH, # DEPRECATED
[776] Fix | Delete
"syslog": LOG_SYSLOG,
[777] Fix | Delete
"user": LOG_USER,
[778] Fix | Delete
"uucp": LOG_UUCP,
[779] Fix | Delete
"local0": LOG_LOCAL0,
[780] Fix | Delete
"local1": LOG_LOCAL1,
[781] Fix | Delete
"local2": LOG_LOCAL2,
[782] Fix | Delete
"local3": LOG_LOCAL3,
[783] Fix | Delete
"local4": LOG_LOCAL4,
[784] Fix | Delete
"local5": LOG_LOCAL5,
[785] Fix | Delete
"local6": LOG_LOCAL6,
[786] Fix | Delete
"local7": LOG_LOCAL7,
[787] Fix | Delete
}
[788] Fix | Delete
[789] Fix | Delete
#The map below appears to be trivially lowercasing the key. However,
[790] Fix | Delete
#there's more to it than meets the eye - in some locales, lowercasing
[791] Fix | Delete
#gives unexpected results. See SF #1524081: in the Turkish locale,
[792] Fix | Delete
#"INFO".lower() != "info"
[793] Fix | Delete
priority_map = {
[794] Fix | Delete
"DEBUG" : "debug",
[795] Fix | Delete
"INFO" : "info",
[796] Fix | Delete
"WARNING" : "warning",
[797] Fix | Delete
"ERROR" : "error",
[798] Fix | Delete
"CRITICAL" : "critical"
[799] Fix | Delete
}
[800] Fix | Delete
[801] Fix | Delete
def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
[802] Fix | Delete
facility=LOG_USER, socktype=None):
[803] Fix | Delete
"""
[804] Fix | Delete
Initialize a handler.
[805] Fix | Delete
[806] Fix | Delete
If address is specified as a string, a UNIX socket is used. To log to a
[807] Fix | Delete
local syslogd, "SysLogHandler(address="/dev/log")" can be used.
[808] Fix | Delete
If facility is not specified, LOG_USER is used. If socktype is
[809] Fix | Delete
specified as socket.SOCK_DGRAM or socket.SOCK_STREAM, that specific
[810] Fix | Delete
socket type will be used. For Unix sockets, you can also specify a
[811] Fix | Delete
socktype of None, in which case socket.SOCK_DGRAM will be used, falling
[812] Fix | Delete
back to socket.SOCK_STREAM.
[813] Fix | Delete
"""
[814] Fix | Delete
logging.Handler.__init__(self)
[815] Fix | Delete
[816] Fix | Delete
self.address = address
[817] Fix | Delete
self.facility = facility
[818] Fix | Delete
self.socktype = socktype
[819] Fix | Delete
[820] Fix | Delete
if isinstance(address, str):
[821] Fix | Delete
self.unixsocket = True
[822] Fix | Delete
# Syslog server may be unavailable during handler initialisation.
[823] Fix | Delete
# C's openlog() function also ignores connection errors.
[824] Fix | Delete
# Moreover, we ignore these errors while logging, so it not worse
[825] Fix | Delete
# to ignore it also here.
[826] Fix | Delete
try:
[827] Fix | Delete
self._connect_unixsocket(address)
[828] Fix | Delete
except OSError:
[829] Fix | Delete
pass
[830] Fix | Delete
else:
[831] Fix | Delete
self.unixsocket = False
[832] Fix | Delete
if socktype is None:
[833] Fix | Delete
socktype = socket.SOCK_DGRAM
[834] Fix | Delete
host, port = address
[835] Fix | Delete
ress = socket.getaddrinfo(host, port, 0, socktype)
[836] Fix | Delete
if not ress:
[837] Fix | Delete
raise OSError("getaddrinfo returns an empty list")
[838] Fix | Delete
for res in ress:
[839] Fix | Delete
af, socktype, proto, _, sa = res
[840] Fix | Delete
err = sock = None
[841] Fix | Delete
try:
[842] Fix | Delete
sock = socket.socket(af, socktype, proto)
[843] Fix | Delete
if socktype == socket.SOCK_STREAM:
[844] Fix | Delete
sock.connect(sa)
[845] Fix | Delete
break
[846] Fix | Delete
except OSError as exc:
[847] Fix | Delete
err = exc
[848] Fix | Delete
if sock is not None:
[849] Fix | Delete
sock.close()
[850] Fix | Delete
if err is not None:
[851] Fix | Delete
raise err
[852] Fix | Delete
self.socket = sock
[853] Fix | Delete
self.socktype = socktype
[854] Fix | Delete
[855] Fix | Delete
def _connect_unixsocket(self, address):
[856] Fix | Delete
use_socktype = self.socktype
[857] Fix | Delete
if use_socktype is None:
[858] Fix | Delete
use_socktype = socket.SOCK_DGRAM
[859] Fix | Delete
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
[860] Fix | Delete
try:
[861] Fix | Delete
self.socket.connect(address)
[862] Fix | Delete
# it worked, so set self.socktype to the used type
[863] Fix | Delete
self.socktype = use_socktype
[864] Fix | Delete
except OSError:
[865] Fix | Delete
self.socket.close()
[866] Fix | Delete
if self.socktype is not None:
[867] Fix | Delete
# user didn't specify falling back, so fail
[868] Fix | Delete
raise
[869] Fix | Delete
use_socktype = socket.SOCK_STREAM
[870] Fix | Delete
self.socket = socket.socket(socket.AF_UNIX, use_socktype)
[871] Fix | Delete
try:
[872] Fix | Delete
self.socket.connect(address)
[873] Fix | Delete
# it worked, so set self.socktype to the used type
[874] Fix | Delete
self.socktype = use_socktype
[875] Fix | Delete
except OSError:
[876] Fix | Delete
self.socket.close()
[877] Fix | Delete
raise
[878] Fix | Delete
[879] Fix | Delete
def encodePriority(self, facility, priority):
[880] Fix | Delete
"""
[881] Fix | Delete
Encode the facility and priority. You can pass in strings or
[882] Fix | Delete
integers - if strings are passed, the facility_names and
[883] Fix | Delete
priority_names mapping dictionaries are used to convert them to
[884] Fix | Delete
integers.
[885] Fix | Delete
"""
[886] Fix | Delete
if isinstance(facility, str):
[887] Fix | Delete
facility = self.facility_names[facility]
[888] Fix | Delete
if isinstance(priority, str):
[889] Fix | Delete
priority = self.priority_names[priority]
[890] Fix | Delete
return (facility << 3) | priority
[891] Fix | Delete
[892] Fix | Delete
def close(self):
[893] Fix | Delete
"""
[894] Fix | Delete
Closes the socket.
[895] Fix | Delete
"""
[896] Fix | Delete
self.acquire()
[897] Fix | Delete
try:
[898] Fix | Delete
self.socket.close()
[899] Fix | Delete
logging.Handler.close(self)
[900] Fix | Delete
finally:
[901] Fix | Delete
self.release()
[902] Fix | Delete
[903] Fix | Delete
def mapPriority(self, levelName):
[904] Fix | Delete
"""
[905] Fix | Delete
Map a logging level name to a key in the priority_names map.
[906] Fix | Delete
This is useful in two scenarios: when custom levels are being
[907] Fix | Delete
used, and in the case where you can't do a straightforward
[908] Fix | Delete
mapping by lowercasing the logging level name because of locale-
[909] Fix | Delete
specific issues (see SF #1524081).
[910] Fix | Delete
"""
[911] Fix | Delete
return self.priority_map.get(levelName, "warning")
[912] Fix | Delete
[913] Fix | Delete
ident = '' # prepended to all messages
[914] Fix | Delete
append_nul = True # some old syslog daemons expect a NUL terminator
[915] Fix | Delete
[916] Fix | Delete
def emit(self, record):
[917] Fix | Delete
"""
[918] Fix | Delete
Emit a record.
[919] Fix | Delete
[920] Fix | Delete
The record is formatted, and then sent to the syslog server. If
[921] Fix | Delete
exception information is present, it is NOT sent to the server.
[922] Fix | Delete
"""
[923] Fix | Delete
try:
[924] Fix | Delete
msg = self.format(record)
[925] Fix | Delete
if self.ident:
[926] Fix | Delete
msg = self.ident + msg
[927] Fix | Delete
if self.append_nul:
[928] Fix | Delete
msg += '\000'
[929] Fix | Delete
[930] Fix | Delete
# We need to convert record level to lowercase, maybe this will
[931] Fix | Delete
# change in the future.
[932] Fix | Delete
prio = '<%d>' % self.encodePriority(self.facility,
[933] Fix | Delete
self.mapPriority(record.levelname))
[934] Fix | Delete
prio = prio.encode('utf-8')
[935] Fix | Delete
# Message is a string. Convert to bytes as required by RFC 5424
[936] Fix | Delete
msg = msg.encode('utf-8')
[937] Fix | Delete
msg = prio + msg
[938] Fix | Delete
if self.unixsocket:
[939] Fix | Delete
try:
[940] Fix | Delete
self.socket.send(msg)
[941] Fix | Delete
except OSError:
[942] Fix | Delete
self.socket.close()
[943] Fix | Delete
self._connect_unixsocket(self.address)
[944] Fix | Delete
self.socket.send(msg)
[945] Fix | Delete
elif self.socktype == socket.SOCK_DGRAM:
[946] Fix | Delete
self.socket.sendto(msg, self.address)
[947] Fix | Delete
else:
[948] Fix | Delete
self.socket.sendall(msg)
[949] Fix | Delete
except Exception:
[950] Fix | Delete
self.handleError(record)
[951] Fix | Delete
[952] Fix | Delete
class SMTPHandler(logging.Handler):
[953] Fix | Delete
"""
[954] Fix | Delete
A handler class which sends an SMTP email for each logging event.
[955] Fix | Delete
"""
[956] Fix | Delete
def __init__(self, mailhost, fromaddr, toaddrs, subject,
[957] Fix | Delete
credentials=None, secure=None, timeout=5.0):
[958] Fix | Delete
"""
[959] Fix | Delete
Initialize the handler.
[960] Fix | Delete
[961] Fix | Delete
Initialize the instance with the from and to addresses and subject
[962] Fix | Delete
line of the email. To specify a non-standard SMTP port, use the
[963] Fix | Delete
(host, port) tuple format for the mailhost argument. To specify
[964] Fix | Delete
authentication credentials, supply a (username, password) tuple
[965] Fix | Delete
for the credentials argument. To specify the use of a secure
[966] Fix | Delete
protocol (TLS), pass in a tuple for the secure argument. This will
[967] Fix | Delete
only be used when authentication credentials are supplied. The tuple
[968] Fix | Delete
will be either an empty tuple, or a single-value tuple with the name
[969] Fix | Delete
of a keyfile, or a 2-value tuple with the names of the keyfile and
[970] Fix | Delete
certificate file. (This tuple is passed to the `starttls` method).
[971] Fix | Delete
A timeout in seconds can be specified for the SMTP connection (the
[972] Fix | Delete
default is one second).
[973] Fix | Delete
"""
[974] Fix | Delete
logging.Handler.__init__(self)
[975] Fix | Delete
if isinstance(mailhost, (list, tuple)):
[976] Fix | Delete
self.mailhost, self.mailport = mailhost
[977] Fix | Delete
else:
[978] Fix | Delete
self.mailhost, self.mailport = mailhost, None
[979] Fix | Delete
if isinstance(credentials, (list, tuple)):
[980] Fix | Delete
self.username, self.password = credentials
[981] Fix | Delete
else:
[982] Fix | Delete
self.username = None
[983] Fix | Delete
self.fromaddr = fromaddr
[984] Fix | Delete
if isinstance(toaddrs, str):
[985] Fix | Delete
toaddrs = [toaddrs]
[986] Fix | Delete
self.toaddrs = toaddrs
[987] Fix | Delete
self.subject = subject
[988] Fix | Delete
self.secure = secure
[989] Fix | Delete
self.timeout = timeout
[990] Fix | Delete
[991] Fix | Delete
def getSubject(self, record):
[992] Fix | Delete
"""
[993] Fix | Delete
Determine the subject for the email.
[994] Fix | Delete
[995] Fix | Delete
If you want to specify a subject line which is record-dependent,
[996] Fix | Delete
override this method.
[997] Fix | Delete
"""
[998] Fix | Delete
return self.subject
[999] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function