Как хранить файлы журналов в каталоге (имя каталога с текущей датой) каждый день
В следующем коде создайте каталог с именем в качестве текущей даты и сохраните файлы журнала в этом каталоге, но на следующий день файлы журнала сохранят данные хранилища в том же каталоге... я хочу каждый день создавать новый каталог, имя которого совпадает с именем текущей даты и хранить новый лог-файл в нем....
приватная статическая дата dir1 = new java.util.Date(System.currentTimeMillis());
приватная статическая дата dir = new java.util.Date (System.currentTimeMillis ());
private static String baseDir1 = "/ home / gaurav / flinklogs /";
private static String newDir1 = createDateBasedDirectory (baseDir1, dir1);
приватный статический FileHandler fh1;
static {
try {
fh1 = new FileHandler(newDir1 + "/data.log", 0, 1, true);
} catch (IOException | SecurityException e) {
}
}
public static void main (String args []) выдает 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;
}
2 ответа
Ваша обработка времени и даты может использовать некоторую помощь.
Во-первых, вы используете проблемные старые классы даты и времени (Date
, SimpleDateFormat
), которые были вытеснены несколько лет назад классами 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-01-01T00:00:00Z.
Современный код заменяет Date
с Instant
, Instant
класс представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Но нам действительно не нужно Instant
на ваш вопрос. использование LocalDate
вместо.
LocalDate
LocalDate
класс представляет значение только для даты без времени суток и без часового пояса.
Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париже Франция - новый день, а в Монреале-Квебеке все еще "вчера".
Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент во время выполнения (!), Поэтому ваши результаты могут отличаться. Лучше явно указать свой [желаемый / ожидаемый часовой пояс][2] в качестве аргумента.
Укажите правильное название часового пояса в формате continent/region
, такие как America/Montreal
, Africa/Casablanca
, или же Pacific/Auckland
, Никогда не используйте 3-4 буквенное сокращение, такое как EST
или же IST
поскольку они не являются истинными часовыми поясами, не стандартизированы и даже не уникальны (!).
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. Обратите внимание, что ваша ежедневная репутация указывает на переворачивание, например, около 16:00, если по западному побережью США
LocalDate today = LocalDate.now( ZoneOffset.UTC ) ;
строка
Для генерации String
в стандартном формате ISO 8601 просто позвоните LocalDate::toString
,
String output = today.toString() ;
Каркас ведения журнала
Как и предполагалось, вы не должны тратить свое драгоценное время на переизобретение каркаса ведения журналов для ежедневного переноса папок. Любая приличная система регистрации может сделать это для вас.
В частности, я предлагаю вам сначала рассмотреть вопрос об использовании фасадного API slf4j. В своем коде, куда вы хотите отправить информацию в журналы, звоните на slf4j. Позади slf4j находится любая из множества различных структур журналирования. Позже вы можете переключить одну платформу журналирования на другую без изменения кода вашего приложения.
Если вы еще не используете каркас журналирования, примите Logback. Проект Logback является прямой реализацией API slf4j. Так что нет необходимости в адаптере.
И slf4j, и Logback были написаны одним и тем же человеком, который изобрел log4j. Так что он имеет большой опыт в этой области.
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые классы даты и времени, такие как java.util.Date
, Calendar
& SimpleDateFormat
,
Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.
Чтобы узнать больше, смотрите Oracle Tutorial. И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
классы.
Где взять классы java.time?
- Java SE 8, Java SE 9, Java SE 10 и более поздние версии
- Встроенный.
- Часть стандартного Java API со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
- Android
- Более поздние версии Android связывают реализации классов java.time.
- Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP….
Проблема здесь в том, что вы объявили все свои переменные как статические и выполнили присвоение обработчика файлов в статическом блоке.
static {
try {
fh1 = new FileHandler(newDir1 + "/data.log", 0, 1, true);
} catch (IOException | SecurityException e) {
}
}
Итак, как только ваша программа запускается, она все инициализирует, а затем на следующий день не происходит повторной инициализации, так как программа уже запущена с предыдущего дня. Вам нужно переназначить файл-обработчик со сменой дня.
Кроме того, позвольте мне взглянуть на log4j, так как вы можете легко настроить его в соответствии с вашими требованиями.