Tuesday, 30 November 2010

a Custom Log4j appender to create a logfile for each User

you don't want to have a cumulative log file for all usages of your client applications (e.g. Swing), but create a log file for each user? the answer is extend the RollingFileAppender and inject your own filename handling to it.

here is how you can do it:




public class UserLog4jFileAppender extends RollingFileAppender {
    /**
     * A default file path if no value is set in the log4j.xml.
     */
    private static final String defaultFilePath = ".";

    /**
     * A default date pattern if no value is set in the log4j.xml.
     */
    private static final String defaultDatePattern = "yyMMdd";

    /**
     * This is the absolute path were the logger-structure should be created.
     */
    protected String filePath = null;

    /**
     * This is the filename of the log-file.
     */
    protected String file = null;

    /**
     * This is a date pattern used to create a directory for each day.
     
     @see SimpleDateFormat
     */
    protected String datePattern = null;

    /**
     * The default maximum file size is 10MB.
     */
    protected long maxFileSize;

    /**
     * There is one backup file by default.
     */
    protected int maxBackupIndex;

    /**
     * The default constructor does nothing.
     */
    public UserLog4jFileAppender() {
        maxFileSize = 10485760L;
        maxBackupIndex = 1;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void activateOptions() {
        setupLogFile();
        super.activateOptions();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setFile(final String file) {
        this.file = file;
    }

    /**
     * Gets the date pattern.
     
     @return the date pattern.
     */
    public String getDatePattern() {
        return datePattern;
    }

    /**
     * Sets the date pattern.
     
     @param datePattern
     * the date pattern to set.
     */
    public void setDatePattern(final String datePattern) {
        this.datePattern = datePattern;
    }

    /**
     * Gets the file path.
     
     @return the file path.
     */
    public String getFilePath() {
        return filePath;
    }

    /**
     * Sets the file path.
     
     @param filePath
     * the file path to set.
     */
    public void setFilePath(final String filePath) {
        this.filePath = filePath;
    }

    /**
     * This method sets up the logfile structure. This method creates the needed
     * directories and builds the log-filename.
     */
    private void setupLogFile() {
        if (file != null) {
            if (filePath == null) {
                filePath = defaultFilePath;
            }

            if (datePattern == null) {
                datePattern = defaultDatePattern;
            }

            // build logfile-path
            final String userName = System.getProperty("user.name");
            final String fileName = file.replace("@username@", userName);

            // create file if not exists
            final String parentName = new File(fileName).getParent();
            if (parentName != null) {
                final File parentDir = new File(parentName);
                if (!parentDir.exists()) {
                    parentDir.mkdirs();
                }
            }

            // find first not existing logfile
            final File f = new File(fileName);

            super.setFile(f.getAbsoluteFile().toString());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void reset() {
        filePath = null;
        file = null;
        datePattern = null;
        super.reset();
    }
}




all we need now is to define this appender in our log4j.xml file:




    <appender name="file"

        class="com.xxx.UserLog4jFileAppender">

        <param name="File"

            value="logs/myapp-gui-@username@.log" />

        <param name="MaxFileSize" value="100MB" />

        <param name="MaxBackupIndex" value="10" />

        <param name="Append" value="true" />

        <layout class="org.apache.log4j.PatternLayout">

            <param name="ConversionPattern"

                value="%d{yyMMdd HH\:mm\:ss.SSS} [%t] %-5p %c %x - %m%n" />

        </layout>

    </appender>


No comments:

Post a Comment