implemented user_logger decorators in API
Merge branch 'PR63' into developpull/64/head
commit
eabce3c42c
|
@ -1243,6 +1243,6 @@ USE `myems_system_db`;
|
||||||
INSERT INTO `myems_system_db`.`tbl_versions`
|
INSERT INTO `myems_system_db`.`tbl_versions`
|
||||||
(`id`, `version`, `release_date`)
|
(`id`, `version`, `release_date`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, '1.2.1', '2021-08-19');
|
(1, '1.2.2', '2021-08-28');
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
|
@ -66,15 +66,18 @@ DROP TABLE IF EXISTS `myems_user_db`.`tbl_logs` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `myems_user_db`.`tbl_logs` (
|
CREATE TABLE IF NOT EXISTS `myems_user_db`.`tbl_logs` (
|
||||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||||
`user_id` BIGINT NOT NULL,
|
`user_uuid` CHAR(36) NOT NULL,
|
||||||
`utc_date_time` DATETIME NOT NULL,
|
`request_datetime_utc` DATETIME NOT NULL,
|
||||||
`activity` VARCHAR(256) 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`));
|
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`
|
-- Table `myems_user_db`.`tbl_notifications`
|
||||||
-- ----------------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------------------------------------------------
|
||||||
DROP TABLE IF EXISTS `myems_user_db`.`tbl_notifications` ;
|
DROP TABLE IF EXISTS `myems_user_db`.`tbl_notifications` ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `myems_user_db`.`tbl_notifications` (
|
CREATE TABLE IF NOT EXISTS `myems_user_db`.`tbl_notifications` (
|
||||||
|
|
|
@ -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;
|
|
@ -3,6 +3,7 @@ import simplejson as json
|
||||||
import mysql.connector
|
import mysql.connector
|
||||||
import config
|
import config
|
||||||
import uuid
|
import uuid
|
||||||
|
from core.userlogger import user_logger
|
||||||
|
|
||||||
|
|
||||||
class EquipmentCollection:
|
class EquipmentCollection:
|
||||||
|
@ -58,6 +59,7 @@ class EquipmentCollection:
|
||||||
resp.body = json.dumps(result)
|
resp.body = json.dumps(result)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_post(req, resp):
|
def on_post(req, resp):
|
||||||
"""Handles POST requests"""
|
"""Handles POST requests"""
|
||||||
try:
|
try:
|
||||||
|
@ -200,6 +202,7 @@ class EquipmentItem:
|
||||||
resp.body = json.dumps(meta_result)
|
resp.body = json.dumps(meta_result)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_delete(req, resp, id_):
|
def on_delete(req, resp, id_):
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||||
|
@ -286,6 +289,7 @@ class EquipmentItem:
|
||||||
resp.status = falcon.HTTP_204
|
resp.status = falcon.HTTP_204
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_put(req, resp, id_):
|
def on_put(req, resp, id_):
|
||||||
"""Handles PUT requests"""
|
"""Handles PUT requests"""
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
|
@ -382,6 +386,7 @@ class EquipmentItem:
|
||||||
|
|
||||||
# Clone an Equipment
|
# Clone an Equipment
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_post(req, resp, id_):
|
def on_post(req, resp, id_):
|
||||||
"""Handles PUT requests"""
|
"""Handles PUT requests"""
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
|
@ -658,6 +663,7 @@ class EquipmentParameterCollection:
|
||||||
resp.body = json.dumps(result)
|
resp.body = json.dumps(result)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_post(req, resp, id_):
|
def on_post(req, resp, id_):
|
||||||
"""Handles POST requests"""
|
"""Handles POST requests"""
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
|
@ -841,6 +847,7 @@ class EquipmentParameterCollection:
|
||||||
|
|
||||||
class EquipmentParameterItem:
|
class EquipmentParameterItem:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def __init__():
|
def __init__():
|
||||||
"""Initializes EquipmentParameterItem"""
|
"""Initializes EquipmentParameterItem"""
|
||||||
pass
|
pass
|
||||||
|
@ -966,6 +973,7 @@ class EquipmentParameterItem:
|
||||||
resp.body = json.dumps(meta_result)
|
resp.body = json.dumps(meta_result)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_delete(req, resp, id_, pid):
|
def on_delete(req, resp, id_, pid):
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||||
|
@ -1012,6 +1020,7 @@ class EquipmentParameterItem:
|
||||||
resp.status = falcon.HTTP_204
|
resp.status = falcon.HTTP_204
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_put(req, resp, id_, pid):
|
def on_put(req, resp, id_, pid):
|
||||||
"""Handles POST requests"""
|
"""Handles POST requests"""
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
|
@ -1270,6 +1279,7 @@ class EquipmentMeterCollection:
|
||||||
resp.body = json.dumps(result)
|
resp.body = json.dumps(result)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_post(req, resp, id_):
|
def on_post(req, resp, id_):
|
||||||
"""Handles POST requests"""
|
"""Handles POST requests"""
|
||||||
try:
|
try:
|
||||||
|
@ -1350,6 +1360,7 @@ class EquipmentMeterItem:
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_delete(req, resp, id_, mid):
|
def on_delete(req, resp, id_, mid):
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||||
|
@ -1457,6 +1468,7 @@ class EquipmentOfflineMeterCollection:
|
||||||
resp.body = json.dumps(result)
|
resp.body = json.dumps(result)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_post(req, resp, id_):
|
def on_post(req, resp, id_):
|
||||||
"""Handles POST requests"""
|
"""Handles POST requests"""
|
||||||
try:
|
try:
|
||||||
|
@ -1537,6 +1549,7 @@ class EquipmentOfflineMeterItem:
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_delete(req, resp, id_, mid):
|
def on_delete(req, resp, id_, mid):
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||||
|
@ -1645,6 +1658,7 @@ class EquipmentVirtualMeterCollection:
|
||||||
resp.body = json.dumps(result)
|
resp.body = json.dumps(result)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_post(req, resp, id_):
|
def on_post(req, resp, id_):
|
||||||
"""Handles POST requests"""
|
"""Handles POST requests"""
|
||||||
try:
|
try:
|
||||||
|
@ -1725,6 +1739,7 @@ class EquipmentVirtualMeterItem:
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@user_logger
|
||||||
def on_delete(req, resp, id_, mid):
|
def on_delete(req, resp, id_, mid):
|
||||||
if not id_.isdigit() or int(id_) <= 0:
|
if not id_.isdigit() or int(id_) <= 0:
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue