Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita2695be

Browse files
miss-islingtonvsajipambv
authored
[3.10] Improve logging documentation with example and additional cookbook re… (GH-93644) (GH-93648)
(cherry picked from commite974b3e)Co-authored-by: Vinay Sajip <vinay_sajip@yahoo.co.uk>Co-authored-by: Łukasz Langa <lukasz@langa.pl>
1 parent5b2ad48 commita2695be

File tree

3 files changed

+101
-2
lines changed

3 files changed

+101
-2
lines changed

‎Doc/howto/logging-cookbook.rst‎

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3002,6 +3002,95 @@ refer to the comments in the code snippet for more detailed information.
30023002
if __name__=='__main__':
30033003
main()
30043004
3005+
Logging to syslog with RFC5424 support
3006+
--------------------------------------
3007+
3008+
Although:rfc:`5424` dates from 2009, most syslog servers are configured by detault to
3009+
use the older:rfc:`3164`, which hails from 2001. When ``logging`` was added to Python
3010+
in 2003, it supported the earlier (and only existing) protocol at the time. Since
3011+
RFC5424 came out, as there has not been widespread deployment of it in syslog
3012+
servers, the:class:`~logging.handlers.SysLogHandler` functionality has not been
3013+
updated.
3014+
3015+
RFC 5424 contains some useful features such as support for structured data, and if you
3016+
need to be able to log to a syslog server with support for it, you can do so with a
3017+
subclassed handler which looks something like this::
3018+
3019+
import datetime
3020+
import logging.handlers
3021+
import re
3022+
import socket
3023+
import time
3024+
3025+
class SysLogHandler5424(logging.handlers.SysLogHandler):
3026+
3027+
tz_offset = re.compile(r'([+-]\d{2})(\d{2})$')
3028+
escaped = re.compile(r'([\]"\\])')
3029+
3030+
def __init__(self, *args, **kwargs):
3031+
self.msgid = kwargs.pop('msgid', None)
3032+
self.appname = kwargs.pop('appname', None)
3033+
super().__init__(*args, **kwargs)
3034+
3035+
def format(self, record):
3036+
version = 1
3037+
asctime = datetime.datetime.fromtimestamp(record.created).isoformat()
3038+
m = self.tz_offset.match(time.strftime('%z'))
3039+
has_offset = False
3040+
if m and time.timezone:
3041+
hrs, mins = m.groups()
3042+
if int(hrs) or int(mins):
3043+
has_offset = True
3044+
if not has_offset:
3045+
asctime += 'Z'
3046+
else:
3047+
asctime += f'{hrs}:{mins}'
3048+
try:
3049+
hostname = socket.gethostname()
3050+
except Exception:
3051+
hostname = '-'
3052+
appname = self.appname or '-'
3053+
procid = record.process
3054+
msgid = '-'
3055+
msg = super().format(record)
3056+
sdata = '-'
3057+
if hasattr(record, 'structured_data'):
3058+
sd = record.structured_data
3059+
# This should be a dict where the keys are SD-ID and the value is a
3060+
# dict mapping PARAM-NAME to PARAM-VALUE (refer to the RFC for what these
3061+
# mean)
3062+
# There's no error checking here - it's purely for illustration, and you
3063+
# can adapt this code for use in production environments
3064+
parts = []
3065+
3066+
def replacer(m):
3067+
g = m.groups()
3068+
return '\\' + g[0]
3069+
3070+
for sdid, dv in sd.items():
3071+
part = f'[{sdid}'
3072+
for k, v in dv.items():
3073+
s = str(v)
3074+
s = self.escaped.sub(replacer, s)
3075+
part += f' {k}="{s}"'
3076+
part += ']'
3077+
parts.append(part)
3078+
sdata = ''.join(parts)
3079+
return f'{version} {asctime} {hostname} {appname} {procid} {msgid} {sdata} {msg}'
3080+
3081+
You'll need to be familiar with RFC 5424 to fully understand the above code, and it
3082+
may be that you have slightly different needs (e.g. for how you pass structural data
3083+
to the log). Nevertheless, the above should be adaptable to your speciric needs. With
3084+
the above handler, you'd pass structured data using something like this::
3085+
3086+
sd = {
3087+
'foo@12345': {'bar': 'baz', 'baz': 'bozz', 'fizz': r'buzz'},
3088+
'foo@54321': {'rab': 'baz', 'zab': 'bozz', 'zzif': r'buzz'}
3089+
}
3090+
extra = {'structured_data': sd}
3091+
i = 1
3092+
logger.debug('Message %d', i, extra=extra)
3093+
30053094

30063095
.. patterns-to-avoid:
30073096

‎Doc/library/logging.rst‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,17 @@ is that all Python modules can participate in logging, so your application log
3030
can include your own messages integrated with messages from third-party
3131
modules.
3232

33+
The simplest example:
34+
35+
..code-block::none
36+
37+
>>> import logging
38+
>>> logging.warning('Watch out!')
39+
WARNING:root:Watch out!
40+
3341
The module provides a lot of functionality and flexibility. If you are
34-
unfamiliar with logging, the best way to get to grips with it is tosee the
35-
tutorials (see the links on the right).
42+
unfamiliar with logging, the best way to get to grips with it is toview the
43+
tutorials (**see the linksabove andon the right**).
3644

3745
The basic classes defined by the module, together with their functions, are
3846
listed below.

‎Doc/tools/susp-ignored.csv‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ library/ipaddress,,::,2001:db00::0/ffff:ff00::
171171
library/itertools,,:step,elements from seq[start:stop:step]
172172
library/itertools,,::,kernel = tuple(kernel)[::-1]
173173
library/itertools,,:stop,elements from seq[start:stop:step]
174+
library/logging,,:root,WARNING:root:Watch out!
175+
library/logging,,:Watch,WARNING:root:Watch out!
174176
library/logging.handlers,,:port,host:port
175177
library/mmap,,:i2,obj[i1:i2]
176178
library/multiprocessing,,`,# Add more tasks using `put()`

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp