implemented user_logger decorators in API

Merge branch 'PR63' into develop
pull/64/head
13621160019@163.com 2021-08-27 17:21:15 +08:00
commit eabce3c42c
5 changed files with 147 additions and 7 deletions

View File

@ -1243,6 +1243,6 @@ USE `myems_system_db`;
INSERT INTO `myems_system_db`.`tbl_versions`
(`id`, `version`, `release_date`)
VALUES
(1, '1.2.1', '2021-08-19');
(1, '1.2.2', '2021-08-28');
COMMIT;

View File

@ -66,15 +66,18 @@ DROP TABLE IF EXISTS `myems_user_db`.`tbl_logs` ;
CREATE TABLE IF NOT EXISTS `myems_user_db`.`tbl_logs` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`user_id` BIGINT NOT NULL,
`utc_date_time` DATETIME NOT NULL,
`activity` VARCHAR(256) NOT NULL,
`user_uuid` CHAR(36) NOT NULL,
`request_datetime_utc` DATETIME NOT NULL,
`request_method` VARCHAR(256) NOT NULL,
`resource_type` VARCHAR(256) NOT NULL,
`resource_id` BIGINT NULL,
`request_body` JSON NULL,
PRIMARY KEY (`id`));
CREATE INDEX `tbl_logs_index_1` ON `myems_user_db`.`tbl_logs` (`user_uuid`, `request_datetime_utc`, `request_method`);
-- ----------------------------------------------------------------------------------
-- ---------------------------------------------------------------------------------------------------------------------
-- Table `myems_user_db`.`tbl_notifications`
-- ----------------------------------------------------------------------------------
-- ---------------------------------------------------------------------------------------------------------------------
DROP TABLE IF EXISTS `myems_user_db`.`tbl_notifications` ;
CREATE TABLE IF NOT EXISTS `myems_user_db`.`tbl_notifications` (

View File

@ -0,0 +1,15 @@
DROP TABLE IF EXISTS `myems_user_db`.`tbl_logs` ;
CREATE TABLE IF NOT EXISTS `myems_user_db`.`tbl_logs` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`user_uuid` CHAR(36) NOT NULL,
`request_datetime_utc` DATETIME NOT NULL,
`request_method` VARCHAR(256) NOT NULL,
`resource_type` VARCHAR(256) NOT NULL,
`resource_id` BIGINT NULL,
`request_body` JSON NULL,
PRIMARY KEY (`id`));
CREATE INDEX `tbl_logs_index_1` ON `myems_user_db`.`tbl_logs` (`user_uuid`, `request_datetime_utc`, `request_method`);
-- UPDATE VERSION NUMBER
UPDATE myems_system_db.tbl_versions SET version='1.2.2', release_date='2021-08-28' WHERE id=1;

View File

@ -3,6 +3,7 @@ import simplejson as json
import mysql.connector
import config
import uuid
from core.userlogger import user_logger
class EquipmentCollection:
@ -58,6 +59,7 @@ class EquipmentCollection:
resp.body = json.dumps(result)
@staticmethod
@user_logger
def on_post(req, resp):
"""Handles POST requests"""
try:
@ -200,6 +202,7 @@ class EquipmentItem:
resp.body = json.dumps(meta_result)
@staticmethod
@user_logger
def on_delete(req, resp, id_):
if not id_.isdigit() or int(id_) <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
@ -286,6 +289,7 @@ class EquipmentItem:
resp.status = falcon.HTTP_204
@staticmethod
@user_logger
def on_put(req, resp, id_):
"""Handles PUT requests"""
if not id_.isdigit() or int(id_) <= 0:
@ -382,6 +386,7 @@ class EquipmentItem:
# Clone an Equipment
@staticmethod
@user_logger
def on_post(req, resp, id_):
"""Handles PUT requests"""
if not id_.isdigit() or int(id_) <= 0:
@ -658,6 +663,7 @@ class EquipmentParameterCollection:
resp.body = json.dumps(result)
@staticmethod
@user_logger
def on_post(req, resp, id_):
"""Handles POST requests"""
if not id_.isdigit() or int(id_) <= 0:
@ -841,6 +847,7 @@ class EquipmentParameterCollection:
class EquipmentParameterItem:
@staticmethod
@user_logger
def __init__():
"""Initializes EquipmentParameterItem"""
pass
@ -966,6 +973,7 @@ class EquipmentParameterItem:
resp.body = json.dumps(meta_result)
@staticmethod
@user_logger
def on_delete(req, resp, id_, pid):
if not id_.isdigit() or int(id_) <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
@ -1012,6 +1020,7 @@ class EquipmentParameterItem:
resp.status = falcon.HTTP_204
@staticmethod
@user_logger
def on_put(req, resp, id_, pid):
"""Handles POST requests"""
if not id_.isdigit() or int(id_) <= 0:
@ -1270,6 +1279,7 @@ class EquipmentMeterCollection:
resp.body = json.dumps(result)
@staticmethod
@user_logger
def on_post(req, resp, id_):
"""Handles POST requests"""
try:
@ -1350,6 +1360,7 @@ class EquipmentMeterItem:
resp.status = falcon.HTTP_200
@staticmethod
@user_logger
def on_delete(req, resp, id_, mid):
if not id_.isdigit() or int(id_) <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
@ -1457,6 +1468,7 @@ class EquipmentOfflineMeterCollection:
resp.body = json.dumps(result)
@staticmethod
@user_logger
def on_post(req, resp, id_):
"""Handles POST requests"""
try:
@ -1537,6 +1549,7 @@ class EquipmentOfflineMeterItem:
resp.status = falcon.HTTP_200
@staticmethod
@user_logger
def on_delete(req, resp, id_, mid):
if not id_.isdigit() or int(id_) <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
@ -1645,6 +1658,7 @@ class EquipmentVirtualMeterCollection:
resp.body = json.dumps(result)
@staticmethod
@user_logger
def on_post(req, resp, id_):
"""Handles POST requests"""
try:
@ -1725,6 +1739,7 @@ class EquipmentVirtualMeterItem:
resp.status = falcon.HTTP_200
@staticmethod
@user_logger
def on_delete(req, resp, id_, mid):
if not id_.isdigit() or int(id_) <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',

View File

@ -0,0 +1,107 @@
import os
from functools import wraps
import config
import mysql.connector
from datetime import datetime
import uuid
from gunicorn.http.body import Body
import simplejson as json
def write_log(user_uuid, request_method, resource_type, resource_id, request_body):
"""
:param user_uuid: user_uuid
:param request_method: 'POST', 'PUT', 'DELETE'
:param resource_type: class_name
:param resource_id: int
:param request_body: json in raw string
"""
cnx = None
cursor = None
try:
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
add_row = (" INSERT INTO tbl_logs "
" (user_uuid, request_datetime_utc, request_method, resource_type, resource_id, request_body) "
" VALUES (%s, %s, %s, %s, %s , %s) ")
cursor.execute(add_row, (user_uuid,
datetime.utcnow(),
request_method,
resource_type,
resource_id if resource_id else None,
request_body if request_body else None,
))
cnx.commit()
except Exception as e:
print(str(e))
finally:
if cnx:
cnx.disconnect()
if cursor:
cursor.close()
def user_logger(func):
@wraps(func)
def logger(*args, **kwargs):
qualified_name = func.__qualname__
class_name = qualified_name.split(".")[0]
func_name = qualified_name.split(".")[1]
if func_name not in ("on_post", "on_put", "on_delete"):
# do not log for other HTTP Methods
func(*args, **kwargs)
return
req, resp = args
cookies = req.cookies
if cookies is not None and 'user_uuid' in cookies.keys():
user_uuid = cookies['user_uuid']
else:
# todo: deal with requests with NULL user_uuid
print('user_logger: user_uuid is NULL')
# do not log for NULL user_uuid
func(*args, **kwargs)
return
if func_name == "on_post":
try:
file_name = str(uuid.uuid4())
with open(file_name, "wb") as fw:
reads = req.stream.read()
fw.write(reads)
raw_json = reads.decode('utf-8')
with open(file_name, "rb") as fr:
req.stream = Body(fr)
func(*args, **kwargs)
write_log(user_uuid=user_uuid, request_method='POST', resource_type=class_name,
resource_id=kwargs.get('id_'), request_body=raw_json)
os.remove(file_name)
except Exception as e:
print('user_logger:' + str(e))
return
elif func_name == "on_put":
try:
file_name = str(uuid.uuid4())
with open(file_name, "wb") as fw:
reads = req.stream.read()
fw.write(reads)
raw_json = reads.decode('utf-8')
with open(file_name, "rb") as fr:
req.stream = Body(fr)
func(*args, **kwargs)
write_log(user_uuid=user_uuid, request_method="POST", resource_type=class_name,
resource_id=kwargs.get('id_'), request_body=raw_json)
os.remove(file_name)
except Exception as e:
print('user_logger:' + str(e))
return
elif func_name == "on_delete":
try:
func(*args, **kwargs)
write_log(user_uuid=user_uuid, request_method="DELETE", resource_type=class_name,
resource_id=kwargs.get('id_'), request_body=json.dumps(kwargs))
except Exception as e:
print('user_logger:' + str(e))
return
return logger