Gaurav
Gaurav

Reputation: 173

how to store log files in directory (directory name having current date) every day

The following code creates a directory with name as current date and stores the log files in that directory. But next the log files of the next days keep are also stored in same directory. I want create a new directory every day having the same name as current date and store new log file in it.

private static Date dir1 = new java.util.Date(System.currentTimeMillis());
private static Date dir = new java.util.Date(System.currentTimeMillis());
private static String baseDir1 = "/home/gaurav/flinklogs/";
private static String newDir1 = createDateBasedDirectory(baseDir1, dir1);

private static FileHandler fh1;

static {
    try {
        fh1 = new FileHandler(newDir1 + "/data.log", 0, 1, true);
    } catch (IOException | SecurityException e) {

    }
}

public static void main(String args[]) throws Exception {
    Logger logger = Logger.getLogger("MyLog");
    // This block configure the logger with handler and formatter
    logger.addHandler(fh);

    SimpleFormatter formatter = new SimpleFormatter();
    fh.setFormatter(formatter);

    // the following statement is used to log any messages
    logger.info(e.getMessage());
}

public static String createDateBasedDirectory(String baseDirectory, Date argDate) {
    String newDir = null;
    if (baseDirectory != null && argDate != null) {
        try {
            String format = "yyyy-MM-dd";
            DateFormat dateFormatter = new SimpleDateFormat(format);
            String date = dateFormatter.format(argDate);

            // check if the directory exists:
            String todaysLogDir = baseDirectory + "\\" + date;

            Path todaysDirectoryPath = Paths.get(todaysLogDir);
            // and check if this Path exists
            if (Files.exists(todaysDirectoryPath)) {
                // if present, just return it in order to write (into) a log file there
                return todaysDirectoryPath.toUri().toString();
            } else {
                newDir = baseDirectory + date;
                new File(newDir).mkdir();
                return newDir.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return newDir;
}

Upvotes: 0

Views: 1141

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338680

Your date-time handling could use some help.

First, you are using troublesome old date-time classes (Date, SimpleDateFormat) that were supplanted years ago by the java.time classes. And you are ignoring the crucial issue of time zone (discussed further down below).

  • java.util.Date is replaced by java.time.Instant
  • SimpleDateFormat is replaced by java.time.format.DateTimeFormatter

Your desired format of YYYY-MM-DD is defined by the ISO 8601 standard. The java.time classes use the standard formats by default when generating/parsing strings. So no need to specify a formatting pattern.

Instant

new java.util.Date(System.currentTimeMillis())

That code of yours is redundant. Simply calling new Date() has the same effect, capturing a count of the number of milliseconds since the epoch reference of first moment of 1970 UTC, 1970-01-01T00:00:00Z.

Modern code replaces Date with Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

But we really do not need Instant for your Question. Use LocalDate instead.

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your [desired/expected time zone][2] explicitly as an argument.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Or you might choose to always use UTC, as the people do running Stack Overflow. Notice how your daily reputation points roll-over, for example around 4 PM if on west coast US time.

LocalDate today = LocalDate.now( ZoneOffset.UTC ) ;

String

To generate a String in standard ISO 8601 format, simply call LocalDate::toString.

String output = today.toString() ; 

Logging framework

As other suggested, you should not use your valuable time re-inventing a logging framework to rollover folders daily. Any decent logging framework can do that for you.

In particular, I suggest you consider first using the slf4j façade API. In your code where you want to make send info to logs, make calls to slf4j. Behind slf4j sits any of many different logging frameworks. You can later switch out one logging framework for another without changing your app’s code.

If not already using a logging framework, adopt Logback. The Logback project is a direct implementation of the slf4j API. So no need for an adapter.

Both slf4j and Logback were written by the same man who invented log4j. So he has much experience in this field.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

Upvotes: 2

skelwa
skelwa

Reputation: 585

The problem here is you have declared all your variables as static and performing file handler assignment in static block as well.

static {

        try {

            fh1 = new FileHandler(newDir1 + "/data.log", 0, 1, true);

        } catch (IOException | SecurityException e) {

        }
    }

So, once your program starts it initialises everything and then next day there is no re-initialisation as the program is already running from previous day. You need to reassign the file-handler with change of day.

Also, may I suggest having a look at log4j as you can easily configure it as per your requirement.

Upvotes: 1

Related Questions