[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