Ответ 1
У меня была такая же потребность, как и вы, различая поток связанных записей, чередующихся с другими несвязанными записями в журнале. Я пробовал все три предложенных вами подхода. Мой опыт был в 4D, а не Java, но аналогичен.
Date-Time
В моем случае я использовал значение даты и времени, определенное на целые секунды. Это просто слишком большая зернистость. Я легко столкнулся с конфликтами, когда в течение одной секунды началось несколько событий. Проклятье этих быстрых компьютеров!
В вашем случае с комплектом java.util.Date или Joda-Time (рекомендуется для других целей), оба разрешают миллисекунды. Миллисекунда долгое время находится в современных компьютерах, поэтому я не рекомендую это.
В Java 8 новый java.time. * package (вдохновленный Joda-Time, определяемый JSR 310) разрешает наносекунды. Это может показаться лучшим идентификатором, но нет. Во-первых, ваши физические часы физического времени вашего компьютера могут не поддерживать такое прекрасное разрешение. Другое дело, что компьютеры продолжают расти. Наконец, компьютерные часы могут быть reset, действительно, это reset часто, поскольку компьютерные часы дрейфуют совсем немного. Современные ОС reset их часы часто проверяются с помощью сервера времени локально или через Интернет.
Кроме того, журналы уже имеют временную метку, поэтому мы не получаем никакой дополнительной выгоды, используя дату-время в качестве нашего идентификатора. Действительно, наличие второй даты в записи журнала может фактически вызвать путаницу.
Серийный номер
Под "Atomic Integer", я предполагаю, что вы имеете в виду серийный номер, увеличивающийся до увеличения числа.
Это кажется излишним для вашей цели.
- Вы не заботитесь о последовательности, это не имеет значения для этой цели группировки записей журнала. Вам все равно, если одна группа заняла n-е число до или после другой группы.
- Поддержание последовательности - это боль, точка потенциального отказа. Я всегда сталкивался с административными проблемами, поддерживая последовательность.
Таким образом, этот подход добавляет риск, не добавляя особых преимуществ.
UUID
Бинго! Только то, что вам нужно.
A UUID легко сгенерирован с использованием либо возможности класса java.util.UUID для генерации Версии 3, либо 4 UUID, или используя стороннюю библиотеку или доступ к инструменту командной строки uuidgen
.
Для очень большого объема лучше всего использовать UUID [Version 1] (MAC + дата-время + случайное число). Для ведения журнала, Версия 4 UUID (полностью случайный) абсолютно приемлем.
Наличие столкновения не представляет собой реалистичную проблему. Специально для ограниченного числа значений, которые вы будете генерировать для журналов. Меня поражают люди, которые, не понимая числа, говорят, что они никогда не заменит последовательность UUID. Но при нажатии каждый программист и системный администратор, которых я знаю, испытывали сбои хотя бы с одной последовательностью.
Отсутствует проблема безопасности потоков. Никаких опасений по поводу споров (см. Мои результаты теста на еще один мой ответ).
Другим преимуществом UUID является его обычный hexadecimal, например:
6536ca53-BCAD-4552-977f-16945fee13e2
... легко узнаваем. Когда распознано, читатель сразу знает, что строка должна быть уникальным идентификатором. Таким образом, присутствие в вашем журнале самодокументируется.
Я обнаружил, что UUID являются канальной машиной. Я продолжаю искать для них новые возможности.
Итак, в начале рассматриваемого кода сгенерируйте UUID, а затем вставьте его в каждую из связанных записей журнала.
В то время как представление шестнадцатеричной строки UUID трудно читать и писать, на практике вам нужно лишь отсканировать несколько цифр в начале или конце. Или используйте copy-paste с функциями поиска и фильтрации в наших современных консольных инструментах.
Несколько фактоидов
- UUID известен в мире Microsoft как GUID.
- UUID - это не строка, а 128-битное значение. Биты, только бит в памяти, "on"/ "off" значения. Некоторые базы данных, такие как Postgres, умеют обрабатывать и хранить UUID как таковые 128-битные значения. Если мы хотим показать эти биты людям, мы можем использовать серию из 128 цифр "1" и "0". Но люди не очень хорошо читают или пишут 128 цифр единиц и нулей. Поэтому мы используем шестнадцатеричное представление. Но даже 32 шестнадцатеричных цифры слишком много для людей, поэтому мы разбиваем строку на группы, разделенные дефисом, как показано выше, всего 36 символов.
- Спецификация для UUID совершенно ясно, что шестнадцатеричное представление должно быть строчным. Спектр говорит, что при создании UUID из строкового ввода верхний регистр должен допускаться. Но при генерации шестнадцатеричной строки она должна быть строчной. Многие реализации UUID игнорируют это требование. Я предлагаю придерживаться спецификации и преобразовывать шестнадцатеричные строки UUID в нижний регистр.
MDC - отображаемый контекст диагностики
Я еще не использовал MDC, но хочу указать на это...
Некоторые фреймворки регистрации добавляют поддержку этой идеи помечания связанных записей журнала. Такая поддержка называется Mapped Diagnostic Context (MDC). MDC управляет контекстной информацией по каждому потоку.
Быстрая вводная статья Log4j MDC (контекстный диагностический контекст): что и почему.
Лучший каротажный фасад, SLF4J, предлагает функция MDC. Лучшая реализация этого фасада Logback имеет глава документируя его функцию MDC.