Page 1 of 3 123 LastLast
Results 1 to 10 of 30

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

  1. #1

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

    i am doing a Spring web application and
    i have a design/implementation question. i have
    not figured out how to do it the best way.

    the requriement is to record WHO(which user)
    did WHAT (save, delete...) in the application.

    i have seen a few Spring web apps)
    but they only record WHAT.
    this can be accomplished in the service tier
    easily. specifically, when an operation is done,
    a service method simply writes a log entry.

    however, i have two issues with this
    approach. first, how can the service tier
    get User information (the WHO part)?
    i can make each method in a service manager
    take a parameter of user information, but
    this would service interface ugly. on the
    other hand, i think the logging/auditing is
    NOT a service manager's job.

    the other option for me is to write
    log entries (through an audit service manager)
    in web controllers. specifically,
    writing a log entry after a service method
    is called successfully. however, this approach
    is not ideal either, since the same method
    may be called in many places and i have
    to write logging statements the same way
    repeatedly. besides, i have to wire
    audit service manager with almost each
    web controller.

    then, the AOP approach? i dont know how
    Spring AOP can help me log WHO did WHAT.
    i have seen some examples, but they
    are really simplistic, most often missing
    both the WHO part and detailed information
    about WHAT.

    other approaches? somehow, i would like
    to do the logging in service managers.
    but i dont know how to make user information
    available to service managers in an
    elegant way.

    anybody has the same problem as i do?
    any advice? any solution?

    thanks!
    pete

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

    Default

    the requriement is to record WHO(which user)
    did WHAT (save, delete...) in the application.
    Which part of the application is responsible for this requirement? Is it a key requirement or not? Which layer of the responsible sub-modules is affected? Is it affected within it's business or presentation layer?

    You might want to also take a look on the wikipedia code http://sourceforge.net/projects/wikipedia/. You may find valuable informations within the doc section of the current release, that keep you thinking. In the wikipedia world, knowing 'who did what' apears to be a key requirement.


    The other option for me is to write log entries (through an audit service manager) in web controllers. specifically, writing a log entry after a service method is called successfully. however, this approach is not ideal either, since the same method may be called in many places and i have to write logging statements the same way repeatedly. besides, i have to wire audit service manager with almost each web controller.
    The jMock people use an interface looking like this:

    Code:
    public interface SelfDescribing {
        StringBuffer describeTo( StringBuffer buffer );
    }
    In your case it might be preferable to use something similar. So seperate what is logged and if it is logged and how. You might already use the command/action pattern to implement the various parts of the chain of responsibility (decomposing processing of requests using highly focused sub-parts). So logging becomes like checking, if the current command is selfdescribing and log the description the command/action provides. And this checking and the actual logging can be done by using AOP for instance.


    [qote] other approaches? somehow, i would like to do the logging in service managers. but i dont know how to make user information available to service managers in an elegant way. [/quote]

    To log 'who is doing what', you surely need to identify the current user being logged into the system. This information is normaly part of the session (session datas). Optaining and tracking a session is a key issue of the J2EE domain. (very good introduction: http://java.sun.com/j2ee/1.4/docs/tu...1.html#wp64744)

    Also most web-tiers feature a single thread for a single request approach. In this case you might use a solution based on ThreadLocal to make the current implementation visible without the need of passing the sessionId or the HttpRequest along.


    Cheers,

    Martin (Kersten)

  3. #3
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    You could bind the user information to a threadlocal and 'advice' your services with a logging aspect (that uses the userinformation from the threadlocal).

    Maybe you could have a look at:
    http://acegisecurity.sourceforge.net

    [edit]
    THe ThreadLocal solution was also mentioned by Martin (the reply above this one)

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

    Default

    Also most web-tiers feature a single thread for a single request approach. In this case you might use a solution based on ThreadLocal to make the current implementation visible without the need of passing the sessionId or the HttpRequest along.
    I don't mean the current implementation but the current session datas.

  5. #5
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    There are already some good posts in here so I'm going to be short.
    The answer to the problem depends a lot of your requirements and frameworks that you use.
    From my experience, security is best implemented in the java world through some sort of AOP (be it filter, interceptor or smth else).
    +WHO+
    If you are using spring and don't have a complex framework in place then Acegi might be the thing for you.
    If you don't want to use it (thing well about this one) you can use the already mentioned functionality from the HttpRequest API.
    +WHAT+
    This depends a lot of what type of persistence do you use. In case of Hibernate at least there are interceptors which make saving changes a breeze - take a look at this example: http://www.hibernate.org/195.html
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

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

    Default

    The net.sf.acegisecurity.context package has been explicity designed to be usable by people who don't want to use the rest of Acegi Security at all. The package provides a comprehensive solution to ThreadLocal binding of context information and worries about cleanup etc after each request.

    ThreadLocal is a good solution, as many others pointed out. You can use the Acegi Security context package or write your own, but either approach is vastly superior to method arguments. On the Hibernate interceptor approach, that's more a case of which technology should be used to perform the advice. I'd personally use Hibernate extensively, but apply AOP using Spring. It's a more portable approach, and you have fewer Hibernate Session management complexities.

  7. #7

    Default

    hi, thanks so much to all of you for expert advice and thoughts.

    +WHAT+ This depends a lot of what type of persistence do you use. In case of Hibernate at least...
    i think where to log user activities depends on what you want to log
    and at what granularity. if log detailed database access, then log
    them at hibernate level. however, once caveat: on business method
    could invoke many database calls.

    i am going to use LocalThread to pass WHO information, and then use
    AOP approach to capture WHAT information at the business service tier
    (apply AOP to methods of service managers). There is issue i am still
    struggling with: generate meaningful WHAT information. Suppose, the
    activity format i want to capture is the following:

    John Smith (WHO) create user (WHAT-1), user ID is 100 (WHAT-2)

    Using AOP, I can at least get WHAT-1 information by getting the method
    name. But how can I generate MEANINFUL WHAT-2 information,
    considering there are many different methods which have different
    arguments? How do you address this need effectively?

    One solution in my mind is at the web tier, I also put WHAT-2 information
    in ThreadLocal and then AOP interceptor will not only get WHO but also
    get WHAT info. However, I don’t like this approach very much. This
    means that in almost all web controllers I need to write a line of code to
    put in ThreadLocal WHAT-2 information before calls to methods of service
    managers (I can use AOP approach to put WHO info in ThreadLocal when
    controller methods are called and save one or two lines of code for each
    business method call).

    I think this issue also applies to the AOP approach at the Hibernate level if
    the logged info conforms to the above format.

    Please advise.

    Regards, Pete

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

    Default

    John Smith (WHO) create user (WHAT-1), user ID is 100 (WHAT-2)

    Using AOP, I can at least get WHAT-1 information by getting the method
    name.
    If you have control about the environment / requirements you might want to go for a true aspect oriented solution and try out AspectJ. Just advice the service interfaces forumlating advices on a single method base, so you can easily investigate the parameters and formulate usefull logging informations (also using AspectJ you can use polymorphism for the logging aspects).

    Another idea would be using the Command/Action pattern and let the command implement an interface making it possible for the command to describe itself. (see the second post in this thread).

    [edit]
    Please take a look at the BeforeMethodAdvice (or AfterMethodAdvice) within the AOP framework. It features the following abstract method:

    void before(Method method, Object[] args, Object target) throws Throwable;

    So you can catch the method being called, the WHO information and also the parameters. So you don't need to switch to AspectJ to just investigate the parameters also.

    So for your task it might look like:

    Code:
    void before(Method method, Object[] args, Object target) {
       if(isAddUserMethod(method)) 
           log("The user '"+getUser()+"' added a new user with the id "+args[0]+" and the name '"+args[1]+"'");
    }
    This looks ugly and can be improved for readabilty for sure but I think you get the meaning.

    [/edit]


    Cheers,

    Martin (Kersten)

  9. #9

    Default

    Martin,

    Thanks for your input. As mentioned in other posts, I dont
    want to include WHO as a parameter in method signitures because
    that gets interface ugly.
    Futher, investigating parameter is difficult to create a meaningful
    WHAT-2, because there are many methods with different
    parameters in different modules of an application...

    i am thinking about using:

    Command/Action pattern and let the command implement an interface making it possible for the command to describe itself.
    in a web controller which calls a business method, i create a
    logging Command object and put it in ThreadLocal, then
    apply an AOP interceptor to all business methods. This interceptor
    grabs the Command object from ThreadLocal and write a log
    entry after a method call.

    Please take a look at the BeforeMethodAdvice (or AfterMethodAdvice) within the AOP framework
    that is what i am going to do.

    does it sound good to you?

    regards, pete

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

    Default

    Thanks for your input. As mentioned in other posts, I dont
    want to include WHO as a parameter in method signitures because
    that gets interface ugly.
    You misunderstood me here, I guess. Please check out the method signature. I only referred to the user by using getUser(). It is up to you to decide how to implement this getUser method (ThreadLocal if you like, or anyother per session solution).


    WHAT-2, because there are many methods with different
    parameters in different modules of an application...
    That's why I actually considered the above illustration as ugly. It was just to illustrate, that the use of AspectJ is preferred but not necessarily. Maybe using a plugable way, would solve you something.

    I was thinking about the setup of the logging advice. Since logging is mostly referred as a default usecase, there should be something already out there.

    But anyways, the best that I came up in a little break was:

    1. Set up the advice by registering all methods that should be logged,

    Code:
    LoggingAspect {
       void registerMethodToLog(String methodName, String loggingMessagePattern);
    }
    2. Using any logging message pattern format you might like (check out the internationalization support or the capabilites of Java 1.5), you may end up with something like this:

    loggingAspect.registerMethodToLog("addUser", "The user '${user}' added a new user named '${param1}' with userId='${param0}'");

    (for BusinessInterface.addUser(int userId, String userName))

    Since now you can set up this advice dynamically, you may declare your logging messages using the usuall Spring way (using a xml declaration etc.) So you can easily edit your logging messages, if you need to.

    So thinking about this, I guess I would go for the formatted messages instead of the command approach. For the pattern format you might want to use, it is up to you but I am very certain that there is a solution already out there.

    [note]
    By the way I didn't ment to push a Command about loggin in a ThreadLocal. I was referring to dispatch each web action into a command and pass this command into the business layer. (Command driven approach). (http://www.javaworld.com/javaworld/j...javatip68.html, http://www.leocrawford.org.uk/work/j...s.html#command)
    [/note]


    Cheers,

    Martin (Kersten)

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
  •