每天如何将日志文件存储在目录(具有当前日期的目录名称)中

时间:2018-06-22 05:55:08

标签: java date logging directory logfile

以下代码创建一个名称为当前日期的目录并将日志文件存储在该目录中,但是第二天日志文件将数据存储在同一目录中...我想每天创建一个与当前名称相同的新目录日期并在其中存储新的日志文件....

私有静态日期dir1 = new java.util.Date(System.currentTimeMillis());

私有静态日期dir = new java.util.Date(System.currentTimeMillis());

私有静态字符串baseDir1 =“ / home / gaurav / flinklogs /”;

私有静态字符串newDir1 = createDateBasedDirectory(baseDir1,dir1);

私有静态FileHandler fh1;

  static {

                try {

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

                } catch (IOException | SecurityException e) {

                }
            }

公共静态void main(String args [])引发异常{

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;
        }

2 个答案:

答案 0 :(得分:1)

这里的问题是,您已将所有变量声明为静态变量,并且还在静态块中执行文件处理程序分配。

static {

        try {

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

        } catch (IOException | SecurityException e) {

        }
    }

因此,一旦您的程序启动,它将初始化所有内容,然后第二天就没有重新初始化,因为该程序已从前一天开始运行。 您需要随着日期的变化重新分配文件处理程序。

此外,我建议您看一下log4j,因为您可以根据需要轻松配置它。

答案 1 :(得分:1)

您的日期时间处理可能会有所帮助。

首先,您使用的是麻烦的旧日期时间类(DateSimpleDateFormat),而这些类早已被 java.time 类所取代。并且您忽略了时区的关键问题(在下面进一步讨论)。

  • java.util.Date替换为java.time.Instant
  • SimpleDateFormat替换为java.time.format.DateTimeFormatter

所需的YYYY-MM-DD格式由ISO 8601标准定义。生成/解析字符串时,默认情况下java.time类使用标准格式。因此,无需指定格式设置模式。

Instant

  

新的java.util.Date(System.currentTimeMillis())

您的代码是多余的。简单地调用new Date()具有相同的效果,捕获自1970 UTC 1970年1月1日的第一时刻的纪元参考以来的毫秒数。

现代代码将Date替换为InstantInstant类表示UTC中时间轴上的时刻,分辨率为nanoseconds(十进制小数的九(9)位)。

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

但是我们真的不需要Instant来回答您的问题。请改用LocalDate

LocalDate

LocalDate类表示没有日期和时区的仅日期值。

时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,Paris France午夜之后的几分钟是新的一天,而Montréal Québec仍然是“昨天”。

如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将您的[期望/期望时区] [2]明确指定为参数。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用3-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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

如果要使用JVM的当前默认时区,请提出要求并作为参数传递。如果省略,则会隐式应用JVM的当前默认值。最好明确一点,因为默认值可能会在运行时的任何时候被JVM中任何应用程序的任何线程中的任何代码更改。

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

或者您可以选择始终使用UTC,因为人们确实在运行Stack Overflow。请注意您的每日声誉如何累积,例如,如果在美国西海岸时间下午4点左右。

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

字符串

要生成标准ISO 8601格式的String,只需调用LocalDate::toString

String output = today.toString() ; 

日志记录框架

正如其他建议一样,您不应将宝贵的时间用于重新创建日志记录框架来每天翻转文件夹。任何体面的日志记录框架都可以为您做到这一点。

尤其是,我建议您首先考虑使用slf4jfaçadeAPI。在要向日志发送信息的代码中,调用 slf4j slf4j 后面有许多不同的日志记录框架。您以后可以将一个日志记录框架切换为另一个日志记录框架,而无需更改应用程序的代码。

如果尚未使用日志记录框架,请采用Logback Logback 项目是 slf4j API的直接实现。因此,无需适配器。

slf4j Logback 都是由发明 log4j 的同一人编写的。因此,他在这一领域具有丰富的经验。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?