logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Erskine <michael.ersk...@ketech.com>
Subject RE: expiry of DailyRollingFileAppender old logs
Date Mon, 10 Dec 2007 12:27:51 GMT
> From: dirk ooms [mailto:dirk@onesparrow.com] 10 December 2007 10:53
> your script could just look at the 'last edit' time of the file, without
> having to look at the name of the file.

That's a good idea Dirk but I'd prefer to stick to the spec (since that's what the customer's
acceptance tests will be doing!).

The following is my first attempt and it seems to work well for my DailyRollingFileAppender
with the default DatePattern but I suspect it may work with any since the pattern is delegated
to SimpleDateFormat. The following two methods are static and portable but will need to be
backported to 1.4 and earlier JRE's since they use generics and foreach...

---------------- 8< ---- cut here ---- 8< -------------------


    /**
     * Get logfiles produced by log4j's DailyRollingFileAppender that are older
     * than the given date.
     *
     * @param fileNameRoot
     *            Start of the logfile name as per "file" property of a
     *            DailyRollingFileAppender.
     * @param datePattern
     *            Date pattern for the logfiles as per "DatePattern" property of
     *            a DailyRollingFileAppender.
     * @param sdf
     *            Reusable date format constructed with the datePattern as
     *            <code>new SimpleDateFormat(datePattern)</code>. If null is
     *            passed the method will create one for internal use but this is
     *            less efficient of course.
     * @param maxAge
     *            Maximum age of files to be retained
     * @return Files with names that are older than the given maximum
     */
    private static File[] getExpiredLogfiles(String fileNameRoot,
            String datePattern, SimpleDateFormat sdf, Date maxAge) {
        // Start by finding the intended directory from the fileNameRoot which
        // isn't a real file but represents the start of the path to the
        // logfiles and can be either relative or absolute...
        File fake = new File(fileNameRoot);
        String leaf = fake.getName();
        // Get the parent directory of this fake file name...
        File dir = null;
        try {
            dir = new File((new File(fake.getCanonicalPath())).getParent());
        } catch (IOException e) {
            log.error("bad path for '" + fileNameRoot + "': " + e.getMessage());
            return null;
        }
        if (!dir.exists()) {
            log.error("dir does not exist '" + dir + "'");
            return null;
        }
        log.debug("parsing contents of '" + dir + "'");
        // Bootstrap a SimpleDateFormat if necessary...
        if (sdf == null) {
            sdf = new SimpleDateFormat(datePattern);
        }
        // Create list for matching files...
        List<File> oldies = new LinkedList<File>();

        // TODO take care of huge directory
        String[] fa = dir.list();
        log.debug(Arrays.asList(fa).toString());
        for (String fn : fa) {
            Date d = fileNameMatch(fn, leaf, sdf);
            if (d == null)
                continue;
            if (d.after(maxAge)) {
                continue;
            }
            File f = new File(dir, fn);
            oldies.add(f);
        }
        return (File[]) oldies.toArray();
    }

    /**
     * Check if the given filename matches the given date format.
     *
     * @param fname
     *            File name to check
     * @param leaf
     *            Start of the name to check against - a fixed portion
     * @param sdf
     *            Date format to check against
     * @return Date from matching filename or null if no match
     */
    private static Date fileNameMatch(String fname, String leaf,
            SimpleDateFormat sdf) {
        if (fname == null || leaf == null || sdf == null)
            return null;
        if (!fname.startsWith(leaf))
            return null;
        log.debug("start matches: '" + fname + "'");
        // get the dated portion of the filename...
        String datedPart = fname.substring(leaf.length());
        log.debug("datedPart: '" + datedPart + "'");
        try {
            Date d = sdf.parse(datedPart);
            return d;
        } catch (ParseException e) {
            log
                    .debug("failed to parse '" + datedPart + "' : "
                            + e.getMessage());
        }
        return null;
    }

---------------- 8< ---- cut here ---- 8< -------------------

I get the Appender by name as follows...

    private static void checkViaAppender(String appenderName) {
        Appender app = Logger.getRootLogger().getAppender(appenderName);
        if (app == null) {
            log.debug("no appender named '" + appenderName + "'");
            return;
        }
        if (!(app instanceof DailyRollingFileAppender)) {
            log.debug("appender named '" + appenderName
                    + "' is not a DailyRollingFileAppender");
            return;
        }
        DailyRollingFileAppender drfa = (DailyRollingFileAppender) app;
        String datePattern = drfa.getDatePattern();
        String fileNameRoot = drfa.getFile();
        log.debug("OK, got drfa with " + datePattern + " and " + fileNameRoot);

        long now = System.currentTimeMillis();
        File[] files = getExpiredLogfiles(fileNameRoot, datePattern, null,
                new Date(now + maxage));
        // Delete the files...
        for (File f : files) {
            try {
                if (!f.exists()) {
                    log.debug("huh? found file does not exist:" + f.toString());
                    continue;
                }
                if (!f.delete()) {
                    log.debug("failed to delete logfile " + f);
                }
            } catch (RuntimeException e) {
                log.error("problem accessing file to delete: " + f);
            }

        }
    }



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Mime
View raw message