[Kimchi-devel] [PATCH] [Wok] User Request Log backend improvements
Paulo Vital
pvital at linux.vnet.ibm.com
Mon Mar 7 17:07:50 UTC 2016
Tested-by: Paulo Vital <pvital at linux.vnet.ibm.com>
Reviewed-by: Paulo Vital <pvital at linux.vnet.ibm.com>
On 03/07/2016 11:02 AM, Lucio Correia wrote:
> - Use log_args attribute to improve message quality
> - Fix handling of utf8 vs str messages
>
> Signed-off-by: Lucio Correia <luciojhc at linux.vnet.ibm.com>
> ---
> src/wok/control/base.py | 59 ++++++++++++++++++++++++-------------------------
> src/wok/reqlogger.py | 5 +++--
> src/wok/utils.py | 23 +++++++++++++++++++
> 3 files changed, 55 insertions(+), 32 deletions(-)
>
> diff --git a/src/wok/control/base.py b/src/wok/control/base.py
> index 79dd22c..be2e35e 100644
> --- a/src/wok/control/base.py
> +++ b/src/wok/control/base.py
> @@ -33,13 +33,15 @@ from wok.exception import InvalidOperation, InvalidParameter
> from wok.exception import MissingParameter, NotFoundError
> from wok.exception import OperationFailed, UnauthorizedError, WokException
> from wok.reqlogger import RequestRecord
> -from wok.utils import get_plugin_from_request
> +from wok.utils import get_plugin_from_request, utf8_dict
>
>
> # Default request log messages
> COLLECTION_DEFAULT_LOG = "request on collection"
> RESOURCE_DEFAULT_LOG = "request on resource"
>
> +LOG_DISABLED_METHODS = ['GET']
> +
>
> class Resource(object):
> """
> @@ -66,6 +68,9 @@ class Resource(object):
> self.role_key = None
> self.admin_methods = []
> self.log_map = {}
> + self.log_args = {
> + 'ident': self.ident.encode('utf-8') if self.ident else '',
> + }
>
> def _redirect(self, action_result, code=303):
> uri_params = []
> @@ -129,12 +134,10 @@ class Resource(object):
> action_fn = getattr(self.model, model_fn(self, action_name))
> action_result = action_fn(*model_args)
>
> - params = {}
> - if model_args:
> - params = {'ident': model_args[0].encode('utf-8')}
> -
> + # log request
> + reqParams = utf8_dict(self.log_args, request)
> RequestRecord(
> - self.getRequestMessage(method, action_name) % params,
> + self.getRequestMessage(method, action_name) % reqParams,
> app=get_plugin_from_request(),
> req=method,
> user=cherrypy.session.get(USER_NAME, 'N/A')
> @@ -175,18 +178,6 @@ class Resource(object):
> fn = getattr(self.model, model_fn(self, 'delete'))
> fn(*self.model_args)
> cherrypy.response.status = 204
> -
> - method = 'DELETE'
> - params = {}
> - if self.model_args:
> - params = {'ident': self.model_args[0].encode('utf-8')}
> -
> - RequestRecord(
> - self.getRequestMessage(method, 'default') % params,
> - app=get_plugin_from_request(),
> - req=method,
> - user=cherrypy.session.get(USER_NAME, 'N/A')
> - ).log()
> except AttributeError:
> e = InvalidOperation('WOKAPI0002E', {'resource':
> get_class_name(self)})
> @@ -206,9 +197,9 @@ class Resource(object):
> if not self.is_authorized():
> raise UnauthorizedError('WOKAPI0009E')
>
> - return {'GET': self.get,
> - 'DELETE': self.delete,
> - 'PUT': self.update}[method](*args, **kargs)
> + result = {'GET': self.get,
> + 'DELETE': self.delete,
> + 'PUT': self.update}[method](*args, **kargs)
> except InvalidOperation, e:
> raise cherrypy.HTTPError(400, e.message)
> except InvalidParameter, e:
> @@ -222,6 +213,17 @@ class Resource(object):
> except WokException, e:
> raise cherrypy.HTTPError(500, e.message)
>
> + # log request
> + if method not in LOG_DISABLED_METHODS:
> + RequestRecord(
> + self.getRequestMessage(method) % self.log_args,
> + app=get_plugin_from_request(),
> + req=method,
> + user=cherrypy.session.get(USER_NAME, 'N/A')
> + ).log()
> +
> + return result
> +
> def is_authorized(self):
> user_name = cherrypy.session.get(USER_NAME, '')
> user_groups = cherrypy.session.get(USER_GROUPS, [])
> @@ -249,14 +251,6 @@ class Resource(object):
>
> args = list(self.model_args) + [params]
> ident = update(*args)
> -
> - method = 'PUT'
> - RequestRecord(
> - self.getRequestMessage(method) % params,
> - app=get_plugin_from_request(),
> - req=method,
> - user=cherrypy.session.get(USER_NAME, 'N/A')
> - ).log()
> self._redirect(ident)
> self.lookup()
> return self.get()
> @@ -323,6 +317,7 @@ class Collection(object):
> self.role_key = None
> self.admin_methods = []
> self.log_map = {}
> + self.log_args = {}
>
> def create(self, params, *args):
> try:
> @@ -413,12 +408,16 @@ class Collection(object):
> elif method == 'POST':
> params = parse_request()
> result = self.create(params, *args)
> +
> + # log request
> + reqParams = utf8_dict(self.log_args, params)
> RequestRecord(
> - self.getRequestMessage(method) % params,
> + self.getRequestMessage(method) % reqParams,
> app=get_plugin_from_request(),
> req=method,
> user=cherrypy.session.get(USER_NAME, 'N/A')
> ).log()
> +
> return result
> except InvalidOperation, e:
> raise cherrypy.HTTPError(400, e.message)
> diff --git a/src/wok/reqlogger.py b/src/wok/reqlogger.py
> index 3e79377..1294be1 100644
> --- a/src/wok/reqlogger.py
> +++ b/src/wok/reqlogger.py
> @@ -29,7 +29,7 @@ from tempfile import NamedTemporaryFile
>
> from wok.config import config, get_log_download_path
> from wok.exception import InvalidParameter, OperationFailed
> -from wok.utils import remove_old_files
> +from wok.utils import ascii_dict, remove_old_files
>
>
> # Log search setup
> @@ -89,7 +89,8 @@ class RequestParser(object):
>
> with fd:
> for record in sortedList:
> - fd.write(LOG_FORMAT % record)
> + asciiRecord = ascii_dict(record)
> + fd.write(LOG_FORMAT % asciiRecord)
>
> fd.close()
> except IOError as e:
> diff --git a/src/wok/utils.py b/src/wok/utils.py
> index e3a4124..7e9a928 100644
> --- a/src/wok/utils.py
> +++ b/src/wok/utils.py
> @@ -21,6 +21,7 @@
> #
>
> import cherrypy
> +import copy
> import glob
> import grp
> import os
> @@ -135,6 +136,28 @@ def get_plugin_from_request():
> return 'wok'
>
>
> +def ascii_dict(base, overlay=None):
> + result = copy.deepcopy(base)
> + result.update(overlay or {})
> +
> + for key, value in result.iteritems():
> + if isinstance(value, unicode):
> + result[key] = str(value.decode('utf-8'))
> +
> + return result
> +
> +
> +def utf8_dict(base, overlay=None):
> + result = copy.deepcopy(base)
> + result.update(overlay or {})
> +
> + for key, value in result.iteritems():
> + if isinstance(value, unicode):
> + result[key] = value.encode('utf-8')
> +
> + return result
> +
> +
> def import_class(class_path):
> module_name, class_name = class_path.rsplit('.', 1)
> try:
>
More information about the Kimchi-devel
mailing list