Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F8393609
logger.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Subscribers
None
logger.py
View Options
# Copyright (C) 2015 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
import
datetime
import
logging
from
typing
import
Any
,
Dict
,
Generator
,
List
,
Tuple
from
systemd.journal
import
JournalHandler
as
_JournalHandler
from
systemd.journal
import
send
try
:
from
celery
import
current_task
except
ImportError
:
current_task
=
None
EXTRA_LOGDATA_PREFIX
=
"swh_"
LOGGED_TASK_KWARGS
=
(
"url"
,
"instance"
)
def
db_level_of_py_level
(
lvl
):
"""convert a log level of the logging module to a log level suitable for the
logging Postgres DB
"""
return
logging
.
getLevelName
(
lvl
)
.
lower
()
def
get_extra_data
(
record
:
logging
.
LogRecord
)
->
Dict
[
str
,
Any
]:
"""Get the extra data to send to the log handler from the logging record.
This gets the following data:
- all fields in the record data starting with `EXTRA_LOGDATA_PREFIX`
- arguments to the logging call (which can either be a tuple, or a dict
if the arguments were named)
- if this is called within a celery task, the following data:
- the (uu)id of the task
- the name of the task
- any task keyword arguments named for values in `LOGGED_TASK_KWARGS`
"""
log_data
=
record
.
__dict__
extra_data
=
{
k
[
len
(
EXTRA_LOGDATA_PREFIX
)
:]:
v
for
k
,
v
in
log_data
.
items
()
if
k
.
startswith
(
EXTRA_LOGDATA_PREFIX
)
}
args
=
log_data
.
get
(
"args"
)
if
args
:
extra_data
[
"logging_args"
]
=
args
# Retrieve Celery task info
if
current_task
and
current_task
.
request
:
extra_data
[
"task"
]
=
{
"id"
:
current_task
.
request
.
id
,
"name"
:
current_task
.
name
,
}
for
task_arg
in
LOGGED_TASK_KWARGS
:
if
task_arg
in
current_task
.
request
.
kwargs
:
try
:
value
=
stringify
(
current_task
.
request
.
kwargs
[
task_arg
])
except
Exception
:
continue
extra_data
[
"task"
][
f
"kwarg_{task_arg}"
]
=
value
return
extra_data
def
flatten
(
data
:
Any
,
separator
:
str
=
"_"
)
->
Generator
[
Tuple
[
str
,
Any
],
None
,
None
]:
"""Flatten the data dictionary into a flat structure"""
def
inner_flatten
(
data
:
Any
,
prefix
:
List
[
str
]
)
->
Generator
[
Tuple
[
List
[
str
],
Any
],
None
,
None
]:
if
isinstance
(
data
,
dict
):
if
all
(
isinstance
(
key
,
str
)
for
key
in
data
):
for
key
,
value
in
data
.
items
():
yield from
inner_flatten
(
value
,
prefix
+
[
key
])
else
:
yield
prefix
,
str
(
data
)
elif
isinstance
(
data
,
(
list
,
tuple
)):
for
key
,
value
in
enumerate
(
data
):
yield from
inner_flatten
(
value
,
prefix
+
[
str
(
key
)])
else
:
yield
prefix
,
data
for
path
,
value
in
inner_flatten
(
data
,
[]):
yield
separator
.
join
(
path
),
value
def
stringify
(
value
:
Any
)
->
str
:
"""Convert value to string"""
if
isinstance
(
value
,
datetime
.
datetime
):
return
value
.
isoformat
()
return
str
(
value
)
class
JournalHandler
(
_JournalHandler
):
def
emit
(
self
,
record
):
"""Write `record` as a journal event.
MESSAGE is taken from the message provided by the user, and PRIORITY,
LOGGER, THREAD_NAME, CODE_{FILE,LINE,FUNC} fields are appended
automatically. In addition, record.MESSAGE_ID will be used if present.
This also records all the extra data fetched by `get_extra_data`.
"""
try
:
extra_data
=
flatten
(
get_extra_data
(
record
))
extra_data
=
{
(
EXTRA_LOGDATA_PREFIX
+
key
)
.
upper
():
stringify
(
value
)
for
key
,
value
in
extra_data
}
msg
=
self
.
format
(
record
)
pri
=
self
.
mapPriority
(
record
.
levelno
)
send
(
msg
,
PRIORITY
=
format
(
pri
),
LOGGER
=
record
.
name
,
THREAD_NAME
=
record
.
threadName
,
CODE_FILE
=
record
.
pathname
,
CODE_LINE
=
record
.
lineno
,
CODE_FUNC
=
record
.
funcName
,
**
extra_data
,
)
except
Exception
:
self
.
handleError
(
record
)
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Wed, Jun 4, 7:15 PM (1 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3239697
Attached To
rDCORE Foundations and core functionalities
Event Timeline
Log In to Comment