Proposal: replace logging by log4j

2008-05-23
2013-05-08
  • André Pestana

    André Pestana - 2008-05-23

    Hi,

    I was just trying to find a solution for supporting mapped diagnostic context (org.apache.log4j.MDC) in java.util.logging but it seems that it's impossible. log4j with this feature has more flexibility and could allow us to separate important data when using xml and database stored logs.

    Example: If we log in a database, it would be interesting to separate the user who caused the event, the action did by the user and if it was successfuly done or not. With org.apache.log4j.MDC we can do sth like this in a loggerManager:

    ...

    // Add user name for logging
    MDC.put("user", login);
                   
    // Add action parameters for logging
    MDC.put("parameters", parameters);
               
    // Add TRUE or FALSE
    MDC.put("success", success);

    // Log audit action in JG_AUDIT level
    logger.log(JGLevel.JG_AUDIT, action );               

    ...

    and in log4j.properties:

    #SQL statement to be used (with multiple columns formated)
    log4j.appender.jdbc.sql=insert into jg_log (application, user, action, parameters, success, priority, log_date) values ('jGuard_Portal', '%X{user}', '%m', '%X{parameters}', '%X{success}', '%p', NOW());

    With this strategy we could filter the log doing sql statements to filter a specific user or action we would like to audit.

    What do you think?
    Why not to choose log4j?

    cheers,

    André

     
    • André Pestana

      André Pestana - 2008-05-23

      There's another solution for decoupling log process from jGuard: Creating a loggerDelegate. In jGuard classes we only call a method from loggerDelegate class and the delegate will log it for us. So the delegate can be implemented using java.util.logging, log4j or whatelse.

      Suggestions?

      André

       
      • Charles Lescot

        Charles Lescot - 2008-05-25

        Hi,
        i prefer the last solution you propose , which does not imply a change on logging library.
        java.util.logging is not a perfect implementation but has got some advantages:
        - it is the official java logging implementation
        - it is based on java security architecture (logging when securitymanager is set requires a loggingpermission, to prevent for example logging some credit card numbers)
        => other implementation lacks on this topic
        - it does not require one more dependency (yes, its not the most important)

        about MDC: in the Audit feature, authentication audit information is localized in one location (near the JAAS authentication process in the AuthenticationServicePoint), and authorization audit also is located in one location (in AuditPermissionCollection).

        in each of these locations, we can grab the Subject object.
        so, we can call the delegate class with it inparameter to uniquely identify the user which has caused the event.

        in the case where multiple humans log with the same account, the Subject object is not the same.
        we can use the hashcode of the subject to have an identifier bound to the user.

        maybe we should also insert into credentials a session ID to correlate this unique Subject object to a session id, in the case of a webapp.

        note also that an extension of java.util.logging exists:
        X4juli(www.x4juli.org) which has got many useful features like MDC and NDC and others; but it does not seems to be very active and implies one more dependency.

        hope it helps,

        Charles.

         
    • André Pestana

      André Pestana - 2008-05-25

      hi, Charles!

      Ok. Let's implement a delegate class that will log for us. By default, jGuard will use this class to log using java.util.logging and if there's the need of using another log api the jGuard user could implement his own logger class. The question now is how it would be configured to jGuard use the custom class? My suggestion is that we create a convention for the custom logger class name and in jGuard initialization jGuard look up for the custom class name conventioned in classpath and save it in jGuard configuration. If it can't find the custom logger class it will automatically use the default logger class. What do you think?

      Both the default and custom logger classes must implement the interface:

      public interface JGuardLogger{

        public static void log(Class clazz, Subject user, String action, Object parameters, boolean success);

      }

      X4juli: I've heard about it but didn't think it could be a good idea.

      In the case of two people logged with the same login it couldn't happen but in the case of guest user. In a webapp it's important to log IP address of the client to discover which is the machine the user is trying to access the system.

      Cheers,

      André

       
      • Charles Lescot

        Charles Lescot - 2008-05-27

        Hi Andre,

        - about the custom logger implementation:
        what is the need fullfilled?
        is it to ouptut the information through another logging system?
        if its the case, why do we use 'java.util.logging' for some debug information, and another logging framework for the sensitive information?
        or if it's to use the logging framework used in the webapp, have you experienced some troubleshootings with the SLF4J way,which make a bridge between java.util.logging and many other logging system?

        in conclusion on this point, if there is a need (not fullfilled by an already provided option), we should implement your proposal.

        - about the JGuardLogger interface signature:
        'action' seems to be the message logged
        - Object 'params' shoudn't be object[]?

        it semes that java.util.logging and log4j support message localization with resourceBundle.
        does the JGuardLogger implementation should support it in its method, internally , or not?

        about X4juli, i've never used it, but the solution it tries to solve is a good approach:
        java.util.logging is oriented in its default implementation, for standalone applications, i.e does not support well multiple classloaders like in j2ee (one classloader per webapp).
        X4juli provides a multiple classloader isolation support.

        - about the guest user:
        when two users are automatically logged as guest, their subject object are different (same credentials from database, but IP address detected inserted in subject is different).
        but i acknowledge that if ip address cannot be resolved , subject will have the same hashcode and will be equals

        what is your feedback on my comments?

        cheers,

        Charles.

        ps: sorry for the delay to answer

         
        • Charles Lescot

          Charles Lescot - 2008-05-27

          Hi,
          about logging authentication events, there is a log mechanism which should use the feature you develop:
          it is localized in the 'AuthenticationUtils' class, in the 'login' method (in the finally clause).
          it use actually an authNManager.persistUserAccessAttempt method (which hasn't got any implementations except an empty one....).
          hope it helps,

          Charles.

           
    • André Pestana

      André Pestana - 2008-05-27

      What do you think about my last message?

      André

       
    • André Pestana

      André Pestana - 2008-05-28

      Hi, Charles...

      Sorry for asking a faster answer but I want to decide it and implement it soon.

      The need is: to provide more data for logging. I'd like to log: the user who caused the event, a message, parameters (can be an array of objects, a list) and if the event or action was successfuly done.

      For example: if I want to audit the system for actions done by the user's system I would log: "andre" => the user, "register contract" => the message, ["contractNumber","12345"] => parameters, true => success.
      With java.util.logging we can only concatenate all in a single string to log and that's what I don't want. I need the separated data.

      About resourceBundle: I think the logger class wouldn't have any implication on it cause it would only log the messages you send to it.

      About the guest user: I agree and think that's ok.

      I don't think it's a good idea to log through more than one framework. I think that using the logger class we will lost the dependency of SL4J unless someone want to use it. If we do the way I said we will use the logger class and implement it using java.util.logging. If the developer needs to use another log framework he will only need to add the new class with a conventioned class name.

      ok?

      Thanks for being patient!

      Cheers,

      André

       
      • Charles Lescot

        Charles Lescot - 2008-05-28

        Hi André,
        this kind of thread is needed to have better features.
        :-)
        about your last thread:
        i understand  your proposition and i'm agree with you that this feature will be useful for many users.

        so, my answer is:
        ok, you've got a great idea!

        cheers,

        Charles.

         

Log in to post a comment.