Commit 67bce190 authored by Mathieu Giraud's avatar Mathieu Giraud

Merge branch 'feature-s/more_access_logs' into 'dev'

Feature s/more access logs

See merge request !339
parents 7c3fd62e 7e869fca
Pipeline #48393 passed with stages
in 6 minutes and 25 seconds
......@@ -19,6 +19,9 @@ def index():
used_query = db(db.results_file.config_id > 0).select(db.results_file.config_id, distinct=True)
used_configs = [row.config_id for row in used_query]
mes = u"Access config list"
log.info(mes, extra={'user_id': auth.user.id, 'record_id': -1, 'table_name': 'config'})
return dict(message=T('Configs'),
query=query,
used_configs=used_configs,
......@@ -63,6 +66,9 @@ def add_form():
table_name='config',
record_id=config_id)
mes = u"Added config"
log.info(mes, extra={'user_id': auth.user.id, 'record_id': config_id, 'table_name': 'config'})
res = {"redirect": "config/index",
"message": "config '%s' added" % request.vars['config_name']}
log.info(res)
......@@ -76,6 +82,8 @@ def add_form():
def edit():
if (auth.can_modify_config(request.vars['id'])):
mes = u"Load config edit form"
log.info(mes, extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'config'})
return dict(message=T('edit config'))
return error_message(ACCESS_DENIED)
......@@ -104,6 +112,8 @@ def edit_form():
"message": "config '%s' updated" % request.vars['config_name']}
log.admin(res)
mes = u"Submit config edit form"
log.info(mes, extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'config'})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
......@@ -127,6 +137,8 @@ def delete():
res = {"redirect": "config/index",
"message": "config '%s' deleted" % request.vars["id"]}
log.admin(res)
mes = u"Delete config"
log.info(mes, extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'config'})
else:
res = {"redirect": "config/index",
"success": "false",
......@@ -190,7 +202,7 @@ def change_permission():
res = {"message" : "c%s: access '%s' granted to '%s'" % (request.vars["config_id"],
PermissionEnum.access.value, db.auth_group[request.vars["group_id"]].role)}
log.admin(res)
log.admin(res, extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'config'})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
res = {"message": "incomplete request : "+error }
......
......@@ -139,6 +139,7 @@ def run_request():
if error == "" :
res = schedule_run(request.vars["sequence_file_id"], id_config, grep_reads)
log.info("run requested", extra={'user_id': auth.user.id, 'record_id': request.vars['sequence_file_id'], 'table_name': 'sequence_file'})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
......@@ -340,6 +341,7 @@ def get_data():
data["samples"]["id"].append("")
log.debug("get_data (%s) c%s -> %s (%s)" % (request.vars["sample_set_id"], request.vars["config"], fused_file, "downloaded" if download else "streamed"))
log.info("load sample", extra={'user_id': auth.user.id, 'record_id': request.vars['sample_set_id'], 'table_name': 'sample_set'})
dumped_json = gluon.contrib.simplejson.dumps(data, separators=(',',':'))
......@@ -408,6 +410,8 @@ def get_custom_data():
data["samples"]["info"].append(db.sequence_file[sequence_file_id].info)
data["samples"]["commandline"].append(db.config[config_id].command)
log.info("load custom data #TODO log db")
return gluon.contrib.simplejson.dumps(data, separators=(',',':'))
else :
......@@ -452,6 +456,8 @@ def get_analysis():
#analysis_data["info_patient"] = db.patient[request.vars["patient"]].info
dumped_json = gluon.contrib.simplejson.dumps(analysis_data, separators=(',',':'))
log.info("load analysis", extra={'user_id': auth.user.id, 'record_id': request.vars['sample_id'], 'table_name': 'sample_set'})
if download:
return response.stream(StringIO.StringIO(dumped_json), attachment = True, filename = request.vars['filename'])
......@@ -516,6 +522,8 @@ def save_analysis():
res = {"success" : "true",
"message" : "(%s): analysis saved" % (sample_set_id)}
log.info(res, extra={'user_id': auth.user.id})
log.info("save analysis", extra={'user_id': auth.user.id, 'record_id': request.vars['samples_id'], 'table_name': 'sample_set'})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
res = {"success" : "false",
......
......@@ -154,6 +154,9 @@ def form():
relevant_ids[stype] = []
relevant_ids[stype].append(row.id)
action = 'add'
log.debug("load add form", extra={'user_id': auth.user.id,
'record_id': request.vars['sample_set_id'],
'table_name': "sample_set"})
# edit file
elif 'file_id' in request.vars:
......@@ -174,6 +177,9 @@ def form():
action = 'edit'
sample_type = request.vars["sample_type"]
log.debug("load edit form", extra={'user_id': auth.user.id,
'record_id': request.vars['file_id'],
'table_name': "sequence_file"})
else:
return error_message("missing sample_set or file id")
......@@ -283,8 +289,8 @@ def submit():
link_to_sample_sets(fid, id_dict)
log.info(mes, extra={'user_id': auth.user.id,\
'record_id': f['id'],\
log.info(mes, extra={'user_id': auth.user.id,
'record_id': f['id'],
'table_name': "sequence_file"})
if not error:
......@@ -388,6 +394,7 @@ def upload():
log.error(res)
else:
log.info(res)
log.debug("#TODO log all relevant info to database")
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......@@ -494,6 +501,9 @@ def restart_pre_process():
db.sequence_file[sequence_file.id] = dict(pre_process_flag = 'WAIT')
db.commit()
res = schedule_pre_process(sequence_file.id, pre_process.id)
log.debug("restart pre process", extra={'user_id': auth.user.id,
'record_id': sequence_file.id,
'table_name': "sequence_file"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
def match_filetype(filename, extension):
......
......@@ -36,6 +36,10 @@ def index():
permissions = auth.get_group_permissions(table_name='sample_set', group_id=row.id, myfilter=permissions_list)
row.access = ''.join([PermissionLetterMapping[p].value for p in permissions])
log.info("access group list", extra={'user_id': auth.user.id,
'record_id': None,
'table_name': "group"})
return dict(message=T('Groups'), query=query, count=count)
## return an html form to add a group
......@@ -44,6 +48,10 @@ def add():
groups = db(db.auth_group).select()
else:
groups = auth.get_user_groups()
log.info('access group add form', extra={'user_id': auth.user.id,
'record_id': None,
'table_name': "group"})
return dict(message=T('New group'), groups=groups)
......@@ -87,6 +95,10 @@ def add_form():
res = {"redirect": "group/index",
"message" : "group '%s' (%s) created" % (id, request.vars["group_name"])}
log.info(res, extra={'user_id': auth.user.id,
'record_id': id,
'table_name': "group"})
log.admin(res)
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......@@ -99,6 +111,10 @@ def edit():
if auth.is_admin() or auth.has_permission(PermissionsEnum.admin.value, db.auth_group, request.vars["id"]):
group = db.auth_group[request.vars["id"]]
return dict(message=T('Edit group'), group=group)
log.info('access group edit form', extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "group"})
return error_message(ACCESS_DENIED)
def edit_form():
......@@ -116,6 +132,10 @@ def edit_form():
res = {"redirect": "group/index",
"message" : "group '%s' modified" % request.vars["id"]}
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars['id'],
'table_name': "group"})
log.admin(res)
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......@@ -143,6 +163,9 @@ def delete():
res = {"redirect": "group/index",
"message": "group '%s' deleted" % request.vars["id"]}
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "group"})
log.admin(res)
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......@@ -151,6 +174,9 @@ def delete():
## need ["id"]
def info():
if auth.can_view_group(request.vars["id"]):
log.info("access user list", extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "group"})
return dict(message=T('group info'))
return error_message(ACCESS_DENIED)
......@@ -159,6 +185,9 @@ def info():
## need ["id"]
def permission():
if auth.can_modify_group(request.vars["id"]):
log.info("view permission page", extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "group"})
return dict(message=T('permission'))
return error_message(ACCESS_DENIED)
......@@ -181,7 +210,9 @@ def remove_permission():
"args" : { "id" : request.vars["group_id"]},
"message": "user '%s' is not anymore owner of the group '%s'" % (request.vars["user_id"], request.vars["group_id"])
}
log.info(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "group"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
## give admin right to a group member
......@@ -194,6 +225,9 @@ def change_permission():
res = {"redirect" : "group/permission" , "args" : { "id" : request.vars["group_id"]},
"message": "user '%s' is now owner of the group '%s'" % (request.vars["user_id"], request.vars["group_id"]) }
log.admin(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "group"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
## invite an user to join the group
......@@ -206,6 +240,9 @@ def invite():
"args" : { "id" : request.vars["group_id"]},
"message" : "user '%s' added to group '%s'" % (request.vars["user_id"], request.vars["group_id"])}
log.admin(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["group_id"],
'table_name': "group"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else:
......@@ -225,6 +262,9 @@ def kick():
"args" : { "id" : request.vars["group_id"]},
"message" : "user '%s' removed from group '%s'" % (request.vars["user_id"], request.vars["group_id"])}
log.admin(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["group_id"],
'table_name': "group"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else:
......@@ -250,6 +290,9 @@ def rights():
"args" : {"id" : group_id },
"message": msg}
log.admin(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "group"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
res = {"message": "admin only"}
......
......@@ -85,7 +85,9 @@ def add_form():
res = {"redirect": "notification/index",
"args" : { "id" : id },
"message": "notification added"}
log.info(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': id,
'table_name': "notification"})
# Clear cache of all notifications
cache.ram.clear(regex=NOTIFICATION_CACHE_PREFIX + '*')
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......@@ -141,7 +143,9 @@ def edit_form():
res = {"redirect": "notification/index",
"args" : { "id" : request.vars['id'] },
"message": "notification updated"}
log.info(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "notification"})
# Clear cache of all notifications
cache.ram.clear(regex=NOTIFICATION_CACHE_PREFIX + '*')
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......@@ -166,7 +170,9 @@ def delete():
res = {"redirect": "notification/index",
"success": "true",
"message": "notification " + request.vars['id'] + " deleted"}
log.info(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "notification"})
# Clear cache of all notifications
cache.ram.clear(regex=NOTIFICATION_CACHE_PREFIX + '*')
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......
......@@ -14,6 +14,9 @@ def index():
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
query = db((auth.vidjil_accessible_query(PermissionEnum.read_pre_process.value, db.pre_process) | auth.vidjil_accessible_query(PermissionEnum.admin_pre_process.value, db.pre_process) ) ).select(orderby=~db.pre_process.name)
log.info("view pre process list", extra={'user_id': auth.user.id,
'record_id': None,
'table_name': "pre_process"})
return dict(message=T('Pre-process list'),
query=query,
......@@ -48,6 +51,9 @@ def add_form():
res = {"redirect": "pre_process/index",
"message": "pre_process '%s' added" % request.vars['pre_process_name']}
log.admin(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': pre_proc_id,
'table_name': "pre_process"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
......@@ -83,6 +89,9 @@ def edit_form():
"message": "pre_process '%s' updated" % request.vars['pre_process_name']}
log.admin(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "pre_process"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
......@@ -105,12 +114,18 @@ def delete():
res = {"redirect": "pre_process/index",
"message": "pre_process '%s' deleted" % request.vars["id"]}
log.admin(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "pre_process"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
## need ["sequence_file_id"]
## need ["sample_set_id"]
def info():
if (auth.can_modify_sample_set(request.vars["sample_set_id"])):
log.info("view pre process info", extra={'user_id': auth.user.id,
'record_id': request.vars["sample_set_id"],
'table_name': "sample_set_id"})
return dict(message=T('result info'))
else :
res = {"message": "acces denied"}
......@@ -175,6 +190,9 @@ def change_permission():
PermissionEnum.access.value, db.auth_group[request.vars["group_id"]].role)}
log.admin(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["pre_process_id"],
'table_name': "pre_process"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
res = {"message": "incomplete request : "+error }
......
......@@ -65,6 +65,9 @@ def index():
row.string = [row.sequence_file.filename, row.config.name, row.patient.last_name, row.patient.first_name, row.sequence_file.producer, str(row.results_file.run_date), row.status]
query = query.find(lambda row : vidjil_utils.advanced_filter(row.string,request.vars["filter"]) )
log.info("access results file admin panel", extra={'user_id': auth.user.id,
'record_id': None,
'table_name': "results_file"})
return dict(query = query,
reverse=reverse)
......@@ -89,6 +92,9 @@ def run_all_patients():
def info():
sample_set_id = get_sample_set_id(request.vars["results_file_id"])
if (auth.can_modify_sample_set(sample_set_id)):
log.info("access results file info", extra={'user_id': auth.user.id,
'record_id': request.vars["results_file_id"],
'table_name': "results_file"})
return dict(message=T('result info'))
else :
res = {"message": "acces denied"}
......@@ -107,6 +113,9 @@ def output():
file_size = vidjil_utils.format_size(os.stat(output_directory + f).st_size)
file_dicts.append({'filename': f, 'size': file_size})
log.info("view output files", extra={'user_id': auth.user.id,
'record_id': request.vars["results_file_id"],
'table_name': "results_file"})
return dict(message="output files",
results_file_id = results_id,
files=file_dicts)
......@@ -120,6 +129,9 @@ def download():
directory = defs.DIR_OUT_VIDJIL_ID % results_id
filepath = directory + os.path.basename(request.vars['filename'])
try:
log.info("Downloaded results file", extra={'user_id': auth.user.id,
'record_id': request.vars["results_file_id"],
'table_name': "results_file"})
return response.stream(open(filepath), attachment = True, filename = request.vars['filename'], chunk_size=10**6)
except IOError:
return error_message("File could not be read")
......@@ -166,7 +178,9 @@ def delete():
"config_id" : config_id},
"success": "true",
"message": "[%s] (%s) c%s: process deleted " % (request.vars["results_file_id"], sample_set_id, config_id)}
log.info(res)
log.info(res, extra={'user_id': auth.user.id,
'record_id': request.vars["results_file_id"],
'table_name': "results_file"})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
res = {"message": "acces denied"}
......
......@@ -84,7 +84,9 @@ def info():
log.debug('patient (%s)' % request.vars["id"])
log.info('run (%s)' % request.vars["id"], extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "run"})
if (auth.can_view('patient', request.vars["id"]) ):
return dict(query=query,
patient=patient,
......
......@@ -128,7 +128,9 @@ def index():
for row in query_pre_process:
pre_process_list[row.id] = row.name
log.debug('sample_set (%s)' % request.vars["id"])
log.info('sample_set (%s)' % request.vars["id"], extra={'user_id': auth.user.id,
'record_id': request.vars["id"],
'table_name': "sample_set"})
#if (auth.can_view_patient(request.vars["id"]) ):
return dict(query=query,
pre_process_list=pre_process_list,
......@@ -204,7 +206,10 @@ def all():
result = sorted(result, key = lambda row : row.id, reverse=not reverse)
result = helper.filter(search, result)
log.debug("%s list (%.3fs) %s" % (request.vars["type"], time.time()-start, search))
log.info("%s list %s" % (request.vars["type"], search), extra={'user_id': auth.user.id,
'record_id': None,
'table_name': "sample_set"})
log.debug("sample_set list (%.3fs)" % (time.time()-start))
return dict(query = result,
......@@ -256,7 +261,10 @@ def stats():
result = sorted(result, key = lambda row : row.id, reverse=not reverse)
result = helper.filter(search, result)
log.debug("%s stat list (%.3fs) %s" % (request.vars["type"], time.time()-start, search))
log.info("%s stat list %s" % (request.vars["type"], search), extra={'user_id': auth.user.id,
'record_id': None,
'table_name': "sample_set"})
log.debug("stat list (%.3fs)" % time.time()-start)
return dict(query = result,
fields = fields,
......@@ -329,6 +337,9 @@ def result_files():
response.headers['Content-Type'] = "application/zip"
response.headers['Content-Disposition'] = 'attachment; filename=%s' % filename# to force download as attachment
log.info("extract results files (%s)" % sample_set_ids, extra={'user_id': auth.user.id,
'record_id': None,
'table_name': "sample_set"})
return response.stream(open(filedir), chunk_size=4096)
except:
......@@ -379,14 +390,19 @@ def mystats():
d['stats'] = res
d['f_samples'] = f_samples # TMP, for debug
#TODO can we get a record id here ?
log.info('stats (%s)' % request.vars["id"], extra={'user_id': auth.user.id,
'record_id': None,
'table_name': "results_file"})
log.debug("mystats (%.3fs) %s" % (time.time()-start, request.vars["filter"]))
# Return
log.debug("stats (%.3fs) %s" % (time.time()-start, request.vars["filter"]))
return gluon.contrib.simplejson.dumps(d, separators=(',',':'))
## return form to create new set
def form():
denied = False
# edit set
extra = {'user_id': auth.user.id, 'record_id': None, 'table_name': "sample_set"}
if("id" in request.vars):
sample_set = db.sample_set[request.vars["id"]]
set_type = sample_set.sample_type
......@@ -397,6 +413,7 @@ def form():
max_group = None
else:
denied = True
extra['record_id'] = request.vars["id"]
# new set
elif (auth.can_create_patient()):
......@@ -422,6 +439,7 @@ def form():
}
# We add a None object to the desired set type to initialise an empty form in the template.
sets[set_type].append(sset)
log.info("load form " + message, extra=extra)
return dict(message=T(message),
groups=groups,
group_ids = get_involved_groups(),
......@@ -509,7 +527,7 @@ def submit():
p['message'] = []
mes = u"%s (%s) %s %sed" % (set_type, id_sample_set, name, action)
p['message'].append(mes)
log.info(mes, extra={'user_id': auth.user.id, 'record_id': p['id'], 'table_name': 'patient'})
log.info(mes, extra={'user_id': auth.user.id, 'record_id': id_sample_set, 'table_name': 'sample_set'})
if register:
register_tags(db, set_type, p["id"], p["info"], group_id, reset=reset)
......@@ -647,6 +665,7 @@ def custom():
query = query.find(lambda row : ( row.results_file.config_id==config_id or (str(row.results_file.id) in request.vars["custom_list"])) )
tag_decorator = TagDecorator(get_tag_prefix())
log.info("load compare list", extra={'user_id': auth.user.id, 'record_id': None, 'table_name': "results_file"})
log.debug("sample_set/custom (%.3fs) %s" % (time.time()-start, search))
return dict(query=query,
......@@ -857,6 +876,8 @@ def multi_sample_stats():
results = getStatData(custom_result)
data['results'] = results
log.info("load multi sample stats (%s)" % str(custom_result),
extra={'user_id': auth.user.id, 'record_id': None, 'table_name': 'results_file'})
return dict(data=data)
def confirm():
......@@ -938,6 +959,8 @@ def permission():
row.parent_access = ', '.join(str(value) for value in auth.get_access_groups(db[stype], request.vars['id'], group=row.id))
row.read = auth.get_group_access(sample_set.sample_type, data.id, row.id)
log.info("load permission page for sample_set (%s)" % request.vars["id"],
extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': "sample_set"})
return dict(query=query,
helper=helper,
data=data)
......@@ -971,7 +994,7 @@ def change_permission():
auth.add_permission(request.vars["group_id"], PermissionEnum.access.value, db[sample_type], data_id)
res = {"message" : "access '%s' granted to '%s'" % (PermissionEnum.access.value, db.auth_group[request.vars["group_id"]].role)}
log.info(res)
log.info(res, extra={'user_id': auth.user.id, 'record_id': request.vars['sample_set_id'], 'table_name': 'sample_set'})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
res = {"message": "incomplete request : "+error }
......
......@@ -71,6 +71,7 @@ def segment_sequences(sequences):
else:
return response.json({'error': 'Error while processing the file'})
log.debug("segment sequences %s" % str(sequences))
return response.json(gluon.contrib.simplejson.loads(text_result))
def check_sequences(sequences):
......
......@@ -52,13 +52,15 @@ def index():
else:
query = sorted(query, key = lambda row : row.id, reverse=False)
log.info("view user list", extra={'user_id': auth.user.id, 'record_id': None, 'table_name': 'auth_user'})
return dict(query=query,
reverse=reverse)
def edit():
if auth.is_admin():
user = db.auth_user[request.vars["id"]]
log.info("load edit form for user",
extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'auth_user'})
return dict(message=T("Edit user"), user=user)
return error_message(ACCESS_DENIED)
......@@ -91,7 +93,8 @@ def edit_form():
db.commit()
res = {"redirect": "back",
"message": "%s (%s) user edited" % (request.vars["email"], request.vars["id"])}
log.info(res)
log.info(res,
extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'auth_user'})
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
......@@ -108,4 +111,6 @@ def edit_form():
def info():
if "id" not in request.vars:
request.vars["id"] = db().select(db.auth_user.ALL, orderby=~db.auth_user.id)[0].id
log.info("view info for user (%d)" % int(request.vars['id']),
extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'auth_user'})
return dict(message=T('user info'))
......@@ -321,8 +321,8 @@ class MsgUserAdapter(logging.LoggerAdapter):
vidjil_utils.safe_decoding(msg))
return new_msg, kwargs
def admin(self, msg):
self.log(logging.ADMIN, msg)
def admin(self, msg, extra=None):
self.log(logging.ADMIN, msg, extra)
#
class UserLogHandler(logging.Handler):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment