[Kimchi-devel] [PATCH] [Wok 5/6] Log failed user requests

Aline Manera alinefm at linux.vnet.ibm.com
Wed Jun 8 21:05:33 UTC 2016



On 06/08/2016 04:27 PM, Lucio Correia wrote:
> Signed-off-by: Lucio Correia <luciojhc at linux.vnet.ibm.com>
> ---
>   src/wok/control/base.py | 158 ++++++++++++++++++++++++++++++------------------
>   1 file changed, 98 insertions(+), 60 deletions(-)
>
> diff --git a/src/wok/control/base.py b/src/wok/control/base.py
> index 9b34c55..f1cce11 100644
> --- a/src/wok/control/base.py
> +++ b/src/wok/control/base.py
> @@ -119,6 +119,10 @@ class Resource(object):
>       def _generate_action_handler_base(self, action_name, render_fn,
>                                         destructive=False, action_args=None):
>           def wrapper(*args, **kwargs):
> +            # status must be always set in order to request be logged.
> +            # use 500 as fallback for "exception not handled" cases.
> +            status = 500
> +
>               method = 'POST'
>               validate_method((method), self.role_key, self.admin_methods)
>               try:
> @@ -138,7 +142,36 @@ class Resource(object):
>
>                   action_fn = getattr(self.model, model_fn(self, action_name))
>                   action_result = action_fn(*model_args)
> +                status = 200
>
> +                if destructive is False or \
> +                    ('persistent' in self.info.keys() and
> +                     self.info['persistent'] is True):
> +                    result = render_fn(self, action_result)
> +                    status = cherrypy.response.status
> +                    return result

> +            except MissingParameter, e:
> +                status = 400
> +                raise cherrypy.HTTPError(status, e.message)
> +            except InvalidParameter, e:
> +                status = 400
> +                raise cherrypy.HTTPError(status, e.message)
> +            except InvalidOperation, e:
> +                status = 400
> +                raise cherrypy.HTTPError(status, e.message)
> +            except UnauthorizedError, e:
> +                status = 403
> +                raise cherrypy.HTTPError(status, e.message)
> +            except NotFoundError, e:
> +                status = 404
> +                raise cherrypy.HTTPError(status, e.message)
> +            except OperationFailed, e:
> +                status = 500
> +                raise cherrypy.HTTPError(status, e.message)
> +            except WokException, e:
> +                status = 500
> +                raise cherrypy.HTTPError(status, e.message)
> +

Is not possible to do a map exception: code to avoid the multiple except 
statements?

Something like:

except Exception, e:
     status = map.get(type(e), 500)
     raise cherrypy.HTTPError(status, e.message)

Then you can reuse that map when needed and we guarantee all exceptions 
will have the same error code.

>              finally:
>                   # log request
>                   code = self.getRequestMessage(method, action_name)
>                   reqParams = utf8_dict(self.log_args, request)
> @@ -147,29 +180,11 @@ class Resource(object):
>                       msg,
>                       app=get_plugin_from_request(),
>                       req=method,
> +                    status=status,
>                       user=cherrypy.session.get(USER_NAME, 'N/A'),
>                       ip=cherrypy.request.remote.ip
>                   ).log()
>
> -                if destructive is False or \
> -                    ('persistent' in self.info.keys() and
> -                     self.info['persistent'] is True):
> -                    return render_fn(self, action_result)
> -            except MissingParameter, e:
> -                raise cherrypy.HTTPError(400, e.message)
> -            except InvalidParameter, e:
> -                raise cherrypy.HTTPError(400, e.message)
> -            except InvalidOperation, e:
> -                raise cherrypy.HTTPError(400, e.message)
> -            except UnauthorizedError, e:
> -                raise cherrypy.HTTPError(403, e.message)
> -            except NotFoundError, e:
> -                raise cherrypy.HTTPError(404, e.message)
> -            except OperationFailed, e:
> -                raise cherrypy.HTTPError(500, e.message)
> -            except WokException, e:
> -                raise cherrypy.HTTPError(500, e.message)
> -
>           wrapper.__name__ = action_name
>           wrapper.exposed = True
>           return wrapper
> @@ -190,13 +205,13 @@ class Resource(object):
>               e = InvalidOperation('WOKAPI0002E', {'resource':
>                                                    get_class_name(self)})
>               raise cherrypy.HTTPError(405, e.message)
> -        except OperationFailed, e:
> -            raise cherrypy.HTTPError(500, e.message)
> -        except InvalidOperation, e:
> -            raise cherrypy.HTTPError(400, e.message)
>
>       @cherrypy.expose
>       def index(self, *args, **kargs):
> +        # status must be always set in order to request be logged.
> +        # use 500 as fallback for "exception not handled" cases.
> +        status = 500
> +
>           method = validate_method(('GET', 'DELETE', 'PUT'),
>                                    self.role_key, self.admin_methods)
>
> @@ -208,30 +223,42 @@ class Resource(object):
>               result = {'GET': self.get,
>                         'DELETE': self.delete,
>                         'PUT': self.update}[method](*args, **kargs)
> +
> +            status = cherrypy.response.status
>           except InvalidOperation, e:
> -            raise cherrypy.HTTPError(400, e.message)
> +            status = 400
> +            raise cherrypy.HTTPError(status, e.message)
>           except InvalidParameter, e:
> -            raise cherrypy.HTTPError(400, e.message)
> +            status = 400
> +            raise cherrypy.HTTPError(status, e.message)
>           except UnauthorizedError, e:
> -            raise cherrypy.HTTPError(403, e.message)
> +            status = 403
> +            raise cherrypy.HTTPError(status, e.message)
>           except NotFoundError, e:
> -            raise cherrypy.HTTPError(404, e.message)
> +            status = 404
> +            raise cherrypy.HTTPError(status, e.message)
>           except OperationFailed, e:
> -            raise cherrypy.HTTPError(500, e.message)
> +            status = 500
> +            raise cherrypy.HTTPError(status, e.message)
>           except WokException, e:
> -            raise cherrypy.HTTPError(500, e.message)
> -
> -        # log request
> -        if method not in LOG_DISABLED_METHODS:
> -            code = self.getRequestMessage(method)
> -            msg = WokMessage(code, self.log_args).get_text(prepend_code=False)
> -            RequestRecord(
> -                msg,
> -                app=get_plugin_from_request(),
> -                req=method,
> -                user=cherrypy.session.get(USER_NAME, 'N/A'),
> -                ip=cherrypy.request.remote.ip
> -            ).log()
> +            status = 500
> +            raise cherrypy.HTTPError(status, e.message)
> +        except cherrypy.HTTPError, e:
> +            status = e.status
> +            raise
> +        finally:
> +            # log request
> +            if method not in LOG_DISABLED_METHODS:
> +                code = self.getRequestMessage(method)
> +                msg = WokMessage(code, self.log_args)
> +                RequestRecord(
> +                    msg.get_text(prepend_code=False),
> +                    app=get_plugin_from_request(),
> +                    req=method,
> +                    status=status,
> +                    user=cherrypy.session.get(USER_NAME, 'N/A'),
> +                    ip=cherrypy.request.remote.ip
> +                ).log()
>
>           return result
>
> @@ -311,10 +338,6 @@ class AsyncResource(Resource):
>               e = InvalidOperation('WOKAPI0002E', {'resource':
>                                                    get_class_name(self)})
>               raise cherrypy.HTTPError(405, e.message)
> -        except OperationFailed, e:
> -            raise cherrypy.HTTPError(500, e.message)
> -        except InvalidOperation, e:
> -            raise cherrypy.HTTPError(400, e.message)
>
>           cherrypy.response.status = 202
>           return wok.template.render("Task", task)
> @@ -437,6 +460,10 @@ class Collection(object):
>
>       @cherrypy.expose
>       def index(self, *args, **kwargs):
> +        # status must be always set in order to request be logged.
> +        # use 500 as fallback for "exception not handled" cases.
> +        status = 500
> +
>           params = {}
>           method = validate_method(('GET', 'POST'),
>                                    self.role_key, self.admin_methods)
> @@ -449,7 +476,31 @@ class Collection(object):
>               elif method == 'POST':
>                   params = parse_request()
>                   result = self.create(params, *args)
> -
> +                status = cherrypy.response.status
> +                return result
> +        except InvalidOperation, e:
> +            status = 400
> +            raise cherrypy.HTTPError(status, e.message)
> +        except InvalidParameter, e:
> +            status = 400
> +            raise cherrypy.HTTPError(status, e.message)
> +        except MissingParameter, e:
> +            status = 400
> +            raise cherrypy.HTTPError(status, e.message)
> +        except NotFoundError, e:
> +            status = 404
> +            raise cherrypy.HTTPError(status, e.message)
> +        except OperationFailed, e:
> +            status = 500
> +            raise cherrypy.HTTPError(status, e.message)
> +        except WokException, e:
> +            status = 500
> +            raise cherrypy.HTTPError(status, e.message)
> +        except cherrypy.HTTPError, e:
> +            status = e.status
> +            raise
> +        finally:
> +            if method not in LOG_DISABLED_METHODS:
>                   # log request
>                   code = self.getRequestMessage(method)
>                   reqParams = utf8_dict(self.log_args, params)
> @@ -458,24 +509,11 @@ class Collection(object):
>                       msg,
>                       app=get_plugin_from_request(),
>                       req=method,
> +                    status=status,
>                       user=cherrypy.session.get(USER_NAME, 'N/A'),
>                       ip=cherrypy.request.remote.ip
>                   ).log()
>
> -                return result
> -        except InvalidOperation, e:
> -            raise cherrypy.HTTPError(400, e.message)
> -        except InvalidParameter, e:
> -            raise cherrypy.HTTPError(400, e.message)
> -        except MissingParameter, e:
> -            raise cherrypy.HTTPError(400, e.message)
> -        except NotFoundError, e:
> -            raise cherrypy.HTTPError(404, e.message)
> -        except OperationFailed, e:
> -            raise cherrypy.HTTPError(500, e.message)
> -        except WokException, e:
> -            raise cherrypy.HTTPError(500, e.message)
> -
>
>   class AsyncCollection(Collection):
>       """




More information about the Kimchi-devel mailing list