Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 30

Thread: best way for logging WHO did WHAT in spring web apps?

  1. #11

    Default

    martin,

    thanks very much for your info and thoughts. i will think about
    it again and play with it and will come back to this thread
    to report my experence.

    thanks again!
    pete

  2. #12
    Join Date
    Mar 2005
    Posts
    3

    Default

    Here is what we did in our project.

    1. Each method in business object, we have only one argument which is a container, let is call it BizRequest
    2. In the BizRequest, we have a Identirybean defined which holds all the creditional info for the user, such as roles, userId, ...
    3. We use AOP to intercept the bo method invocation, before the method, we capture the VO data ,action which couldbe methodName,userId, time, after the method invoication. if sucessful, capture the data returned, if there are exception, capture the exceptin info,
    4. store the caputred data in to the database,

    it works pretty well.

  3. #13

    Default

    Vinson,

    thanks for your input. glad to know it works for you.
    however,

    Each method in business object, we have only one argument which is a container, let is call it BizReq
    what you did in your project contradicts what i know about "good" design:
    interface for business objects which should, if possible,
    be independent on specific technologies such as servlets.

    your comment? maybe i have some misunderstanding about your approach.

    thanks, pete

  4. #14
    Join Date
    Mar 2005
    Posts
    3

    Default

    I don't know what do you mean 'good' design.

    There are two approach to design the interface signature to the presention tier.

    1. classic. something like
    List getUserList(Integer userId, String firstName, String lastName)
    the advantage is it is strongly type-safe, but it is not flexible.

    2. another way is user an argument container.
    BizResponse getUserList(BizRequest bizRequest)
    it is something like command pattern. the disadvantage is it is not strong type safe,
    but with JDK5 , it is not a problem.
    <Response, Request> Response getUserList(Request bizRequest)

    3. if we don't use JDK5. we have a trade-off solution.

    List getUserList(IdentiryBean idBean,Integer userId, String firstName, String lastName)

    IdentiryBean can hold all the creditional info.

    we need to follow some code convention.
    the first argument must be IdentiryBean for each biz method. may with the exception userLogon.

    Hope it helps.

  5. #15

    Default

    vinson,

    thanks for your clarification and sorry my possible misunderstanding.
    passing creditional info as argument (one or more) in business methods is
    considered a bit "ugly" design and it is the theme of the messages in this thread.
    i understand that this approach definitely works.
    i like to hear your thoughts.

    regards,
    pete

  6. #16
    Join Date
    Mar 2005
    Posts
    3

    Default

    The problem is how you get the user creditional info in the business method.

    1. get it from method signatue,
    2. get it from the instance variable , or thread local varible.
    3. store it in the global hash table with the current thread as key, and the userInfo as a value , and later you can get it from this repository.

    Do you have other approachs?


    Since the business method often works a service, so it is better have one instance of business per jvm.

  7. #17
    Join Date
    Aug 2004
    Location
    Germany, Magdeburg
    Posts
    279

    Default

    BizResponse getUserList(BizRequest bizRequest)
    I dont know your actuall design, but assuming BizRequest is a parameter for many diffrent bussines methods, I wouldn't like it that much, I guess. I think this is much likely to impose the same problems using the HttpRequest has. Using HttpRequest (or something similar), I often find it hard to controll the the informational flow and do preconditional validations.

    I think it is nothing wrong to replace a bunch of parameters by a single object (in terms you find a good naming methaphor for it - like events for instance). But using the same object for diffrent needs extends the problem space of a single needs in an unsufficient mannor (in my oppinion). I experienced a lot of unit-testing related problems using such a powerfull object (powerfull in terms of polimorphy).

    Another issue is, that BizRequest is much likely to be a strong parameter (parameter that dominats the implementation (replacing the object will cause the whole implementation to change)) - this is mostly a sign, that a new object waits to be described / discovered. Till the end of such scenarios I often find my restructurizing the whole modul by utilizing the Command pattern.

    Maybe this is why pjydc dislikes this approach.


    Cheers,

    Martin (Kersten)

    PS: Vision, can you post me a private message telling me the concrete use of your BizRequest? I would like to take a more detailed look, if it is possible.

  8. #18

    Default

    Hi. I'll jump in this discussion because I just wanted to post something like this recently...

    The basic thing is that we don't want to add additional arguments to each secured business method, such as User user, or String username and String password. I agree that I also dismissed this idea at first because it looks really ugly.
    BUT, more I'm thinking about what is required for alternative, more it seems to me that it could even be best solution after all.
    Yeah, your business interface will look a bit more ugly, but hey, you have strong typing, method-specific logic such as instance-based security - ACL and specific logging such as you desire, are located exactly where you expect it to be - in implementation of this very method.
    I know that we would like it to be treated as separate aspect, but just consider the tradeoff. When you use service exporters, such as Hessian/Burlap/HttpInvoker, it is suddenly not enough to plainly copy-paste piece of exmaple, and ta-dah!- service is exported, because now you have to place security/logging context arguments into remote call, and that means examining these remoting APIs. If these additional arguments were part of service interface, you would need none of this.
    Using AOP seems as great thing for generic transparent stuff (such as transactioning), but not specific one. And what we have here is clearly very method-specific stuff.
    And there is one more thing - I always judge quality of some code also per :
    - how would newbie programmer understand this?
    - how would newcomer most easily jump in and take this app?
    And maybe you would laugh, but you have to consider that AOP is still considered exotic stuff, mostly never used by majority of programmers out there. ThreadLocal stuff also. Having strong typing is especially important for such developers.

    Cheers,
    Vjeran

  9. #19
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    For Acegi Security users out there, the recommended approach with 0.8.1 (heck, we might improve it in the future) is to use an AfterInvocationManager that does the logging. An AfterInvocationManager provides this interface method:

    /**
    * Given the details of a secure object invocation including its returned
    * <code>Object</code>, make an access control decision or optionally
    * modify the returned <code>Object</code>.
    *
    * @param authentication the caller that invoked the method
    * @param object the secured object that was called
    * @param config the configuration attributes associated with the secured
    * object that was invoked
    * @param returnedObject the <code>Object</code> that was returned from the
    * secure object invocation
    *
    * @return the <code>Object</code> that will ultimately be returned to the
    * caller (if an implementation does not wish to modify the object
    * to be returned to the caller, the implementation should simply
    * return the same object it was passed by the
    * <code>returnedObject</code> method argument)
    *
    * @throws AccessDeniedException if access is denied
    */
    public Object decide(Authentication authentication, Object object,
    ConfigAttributeDefinition config, Object returnedObject)
    throws AccessDeniedException;
    As such the type of audit logging desired can be specified against your MethodSecurityInterceptor.objectDefinitionSource (there's nice PropertyEditors to make this simple). Your current Authentication is passed as a strictly typed object. The passed Object is actually a MethodInvocation or JoinPoint, depending on if you're using AOP Alliance or AspectJ respectively. The config is the full configuration attribute source, and returnedObject is there if you want to log anything to do with what is being returned.

    Note that AfterInvocationProviderManager allows you to chain a series of AfterInvocationProviders. That way you can use this logging/auditing mechanism in addition to other AfterInvocationProviders that do ACL filter or whatever.

  10. #20
    Join Date
    Dec 2004
    Location
    Bucuresti, Romania
    Posts
    72

    Default

    Hi,

    If you are using log4j here is a solution: Just use log4j Mapped Diagnostic Context. This is thread local based, like most of the other options already mentioned. You just need to create a filter that puts in the required info (WHO, WHAT) in the log4j MDC. You also need to adjust you message layout to look something like this:

    Code:
    log4j.appender.file.layout.ConversionPattern=%X&#123;who&#125; %X&#123;what&#125; %d&#123;ABSOLUTE&#125; %-5p %c&#58;%L - %m%n
    Although this is a log4j specific solution, it seems simple to me. I suppose you could do something similar if you use other logging frameworks. Additionally, if you want to record this audit info in some database, you could use a DB appender.

    I am also planning to do this for a project I am working on.


    Mircea

Similar Threads

  1. Spring MVC Web Framework versus Struts
    By biguniverse in forum Web Flow
    Replies: 27
    Last Post: Aug 29th, 2012, 03:57 AM
  2. A Spring Class Loader?
    By azzoti in forum Architecture
    Replies: 8
    Last Post: May 7th, 2005, 04:02 AM
  3. Replies: 14
    Last Post: Feb 21st, 2005, 05:41 PM
  4. Generating Spring Apps with AndroMDA
    By jpwinans in forum Architecture
    Replies: 0
    Last Post: Dec 16th, 2004, 03:38 PM
  5. Using spring for standalone apps
    By tv in forum Architecture
    Replies: 1
    Last Post: Sep 29th, 2004, 05:47 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •