Почему существует два метода setlevel java
Перейти к содержимому

Почему существует два метода setlevel java

  • автор:

Логирование в Java / quick start

В ходе моей работы в компании DataArt я, в числе прочего, занимаюсь менторской деятельностью. В частности это включает в себя проверку учебных заданий сделанных практикантами. В последнее время в заданиях наметилась тенденция «странного» использования логеров. Мы с коллегами решили включить в текст задания ссылку на статью с описанием java logging best practices, но оказалось, что такой статьи в которой бы просто и без лишних деталей на практике объяснялось бы как надо писать в лог на Java, вот так вот с ходу не находится.

Данная статья не содержит каких-то откровений, в ней не рассматриваются тонкости какого либо из многочисленных java logging frameworks. Здесь рассказываю как записать в лог так, чтобы это не вызвало удивления у Ваших коллег, основная цель написания включить ее в список обязательного чтения для практикантов. Если все еще интересно, читайте дальше

  • Весь код примеров использует java.util.logging framework. Вопрос «Какой из фреймворков логирования ниболее кошерен» я оставлю за кадром. Скажу только что до java.util.logging проще всего дотянуться ибо он уже идет вместе с JRE и на самом деле рассказанное в данной статье с минимальными косметическими правками верно для подавляющего большинства систем логирования.
  • В целом рецепты приведенные в данной статье не являются единственно верными, есть моменты о которых можно поспорить, но в целом эти рецепты используются многие годы, многими разработчиками, во многих проектах и они достаточно хороши чтобы им следовать если у Вас нет каких-то совсем уже серьезных возражений.
  • В статье не рассматриваются такие «продвинутые» топики как:
    • Конфигурирование уровней для отдельных логеров
    • Форматирования логов
    • Асинхронное логирование
    • Создание собственных уровней логирования в Log4J
    • Контекстное логирование
    • И многое другое
    Пример №1
    Хорошо
    public class SomeClass < private static Logger log = Logger.getLogger(SomeClass.class.getName()); public void someMethod() < log.info("Some message"); >. 
    1. Логер это статическое поле класса инициализируемое при загрузке класса, имеет простое, короткое имя, важно чтобы во всех Ваших классах переменная логера называлась одинаково (это диктуется общим правилом, одинаковые вещи в программе должны делаться одинаковым образом).
    2. В качестве имени логера я использую имя класса, на самом деле это не единственный способ, можно пытаться организовать какую-то свою иерархию логирования (например transport layer/app layer для подсистем имеющих дело с обменом данными), но как показывает практика выдумывать и главное потом неукоснительно следовать такой иерархии крайне сложно, а вариант с именами логеров совпадающими с именами классов весьма хорош и используется в 99% проектов
    3. Здесь для записи в лог я использую короткий метод .info, а не более общий метод .log, так много лаконичнее
    4. Имя логера берется как SomeClass.class.getName(), а не как «com.dataart.demo.java.logging.SomeClass», оба способа по идее одинаковы, но первый защищает Вас от сюрпризов при рефакторинге имени/пакета класса
    Плохо
    public class SomeClass < public void someMethod() < Logger.getLogger("com.dataart.demo.java.logging.SomeClass").log(Level.INFO,"Some message"); >. 

    По сути тоже самое но букв больше и читается не так легко.

    Замечание между примерами

    Вы наверное обратили внимание, что все сообщения в примерах на английском языке. Это не случайно. Дело в том, что даже если все-все кто работает и будет работать с Вашим кодом говорят по русски, есть вероятность, что Вам придется просматривать лог сообщения на удаленном компьютере например через ssh при этом в большом количестве случаев Вы увидите примерно такое сообщение «. . . » (я безусловно знаю что через ssh можно протащить русские буквы, но вот почему-то далеко не всегда все оказывается настроенным должным образом).
    Или даже на локальной машине в cmd вы можете увидеть что вот такое:
    INFO: ╨Ъ╨░╨║╨╛╨╡-╤В╨╛ ╤Б╨╛╨╛╨▒╤Й╨╡╨╜╨╕╨╡ ╨▓ ╨╗╨╛╨│

    С этим безусловно тоже можно бороться. Но не всегда легко объяснить заказчику на том конце телефонной трубки, как сделать так чтобы вместо крякозябр были видны русские буквы.
    Совет: Пишите лог сообщения на английском языке, ну или в крайнем случае латинскими буквами.

    Пример №2
    Хорошо
     try < throw new Exception("Some exception"); >catch (Exception ex) < log.log(Level.SEVERE, "Exception: ", ex); >//В стандартной лог конфигурации вы это сообщение не увидите log.fine("some minor, debug message"); /* Иногда вывод лог сообщений требует достаточно больших ресурсов (например дамп какого-то пакета данных и т.п.). В таких случаях стоит проверить выведется ли в лог сообщение для этого уровня логирования */ if (log.isLoggable(Level.FINE))
    1. Если Вам необходимо залогировать исключение, для этого служит метод .log(level,message,exception)
    2. Если вы специально не настроили конфигурацию лог системы, сообщения с уровнем ниже info, например fine выводиться не будут. Но писать их по крайней мере для важных частей системы стоит. Когда что-то пойдет не так, Вы настроите более подробный уровень логирования и увидите много интересного.
    3. Слишком много лог сообщений, даже если они физически не пишутся в лог файл из-за своего слишком маленького уровня, могут существенно замедлить выполнение программы. Особенно если для подготовки самого сообщения надо потратить много ресурсов. Для этого есть метод .isLoggable(level) — он позволяет узнать пропустит ли текущая конфигурация логера данное сообщение
    Плохо
     try < throw new Exception("Some exception"); >catch (Exception ex) < log.severe("Exception: " + ex.toString() ); >log.fine("Some CPU consuming message: " + itTakes500MillisecondsToPrepageThisMessage()); 

    Если логировать только ex.toString(), то потом Вы не сможете понять в какой строке изначально сработало исключение.

    Пример №3

    Логер надо конфигурировать. Есть конфигурация по умолчанию она выводит в консоль все сообщения с уровнем INFO и выше. Она достаточно хороша, для разработки из IDE, но для реального приложения ее обычно неплохо бы подправить.

    Какие тут есть варианты

    По умолчанию: Файл logging.properties для уровня INFO, вывод в консоль

    #Console handler
    handlers= java.util.logging.ConsoleHandler
    .level=INFO

    Делаем логирование более подробным выводим еще и сообщения уровня FINE

    #Console handler
    handlers= java.util.logging.ConsoleHandler
    .level=FINE
    java.util.logging.ConsoleHandler.level = FINE

    • Установили уровень FINE для корневого логера, просто чтобы сообщения пролезали внутрь лог системы.
    • И сказали что все что пролезет через лог систему надо выводить на консоль от уровня FINE и выше.
    Выводим лог сообщения куда-то еще
    • Если приложение запускается с помощью javaw Вы вообще ничего не увидите.
    • Если вывод идет в консоль и нужное вам сообщение промелькнуло 4 часа назад буфер консоли его уже съел, информация пропала.
    • Если вывод консоли направлен в файл java com.yourcompanyname.EntryClass 2>>application_log.txt и приложение работает не останавливаясь несколько недель — файл будет весьма и весьма большим, рискуя занять весь диск.

    Чтобы решить эти проблемы был придуман java.util.logging.FileHandler — хэндлер который выводит лог сообщения в файл. При этом он умеет ротировать файлы, т.е. после достижения максимально допустимого размера, он дописывает в файл текщуее лог сообщение и открывает новый файл с инкрементальным префиксом. И так по кругу. Например

    handlers= java.util.logging.FileHandler java.util.logging.FileHandler.pattern = application_log.txt java.util.logging.FileHandler.limit = 50 java.util.logging.FileHandler.count = 7 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

    создаст вот такие файлы (последняя колонка — размер в байтах)

    application_log.txt.0 │ 0 application_log.txt.1 │ 79 application_log.txt.2 │ 79 application_log.txt.3 │ 676 application_log.txt.4 │ 87 application_log.txt.5 │ 114

    Мы указали максимальный размер 50 байтов, в реальной жизни надо скорее указывать не меньше мегабайта, например вот так (я знаю, что 1000000 это чуть меньше мегабайта, но кому охота по памяти писать 1048576, если суть дела это фактически не меняет)

    java.util.logging.FileHandler.limit = 1000000

    В примере, как мы видим, файлы получились больше 50 байт потому что размер по сути округляется вверх до последнего целого лог сообщения. Т.е. если Вы укажете размер 1 байт и запишете лог сообщение размером в 1000 байт то размер файла станет 1000 байт и после этого лог сообщения файл закроется и откроется следующий.

    copy & paste конфиг для реальной жизни, его вполне хватает для большинства service, console и desktop приложений.

    handlers= java.util.logging.FileHandler java.util.logging.FileHandler.pattern = application_log.txt java.util.logging.FileHandler.limit = 1000000 java.util.logging.FileHandler.count = 5 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
    Последняя часть магии
    1. Из командной строки запуска приложения
    2. В первых строчках кода Вашего приложения

    Первый чуть более правильный ибо он декларативный и работает сразу, до того как начал работать код Вашего приложения.

    Вот так

    java Djava.util.logging.config.file=logging.properties com.dataart.application.ClassName

    Но к сожалению менять строку запуска не всегда можно или не всегда удобно. Второй способ тоже неплохо работает.

     public static void main(String[] args) < try < LogManager.getLogManager().readConfiguration( MainApplicationEntryClass.class.getResourceAsStream("/logging.properties")); >catch (IOException e) < System.err.println("Could not setup logger configuration: " + e.toString()); >. 

    • Здесь MainApplicationEntryClass — это класс — точка входа в Ваше приложение, видимо имя класса у Вас будет другое
    • Сам файл logging.properties как правило в таких случаях кладется в корень иерархии классов и выглядит это например вот так

    Что осталось за кадром
    • Log4J
    • JULI logger (строго говоря это не вполне самостоятельный фреймворк, а своего рода надстройка над java.util.logging)
    • SLF4J
    • Commons Logging
    • Tomcat
    • JBoss
    • Resin

    Почему существует два метода setlevel java

    Инициализация этого поля является склонной к мертвым блокировкам. Поле должно быть инициализировано инициализацией класса Регистратора, которая может вызвать мертвые блокировки с инициализацией класса LogManager. В таких случаях две инициализации класса ожидают друг друга, чтобы завершиться. Привилегированный способ получить глобальный объект регистратора через вызов Logger.getGlobal() . Для совместимости со старыми версиями JDK, где Logger.getGlobal() не доступное использование вызов Logger.getLogger(Logger.GLOBAL_LOGGER_NAME) или Logger.getLogger(«global») .

    GLOBAL_LOGGER_NAME является именем для глобального регистратора.

    Сводка конструктора

    Конструкторы

    Модификатор Конструктор и Описание
    protected Logger(String name, String resourceBundleName)

    Защищенный метод, чтобы создать регистратор для именованной подсистемы.

    Сводка метода

    Методы

    Модификатор и Тип Метод и Описание
    void addHandler(Handler handler)

    Добавьте Обработчик журнала, чтобы получить сообщения журналирования.
    Зарегистрируйте сообщение КОНФИГУРАЦИИ.
    Зарегистрируйте запись метода.
    Зарегистрируйте запись метода с одним параметром.
    Зарегистрируйте запись метода с массивом параметров.
    Зарегистрируйте возврат метода.
    Зарегистрируйте возврат метода с объектом результата.
    Зарегистрируйте ПРЕКРАСНОЕ сообщение.
    Зарегистрируйте БОЛЕЕ ПРЕКРАСНОЕ сообщение.
    Зарегистрируйте САМОЕ ПРЕКРАСНОЕ сообщение.
    Создайте анонимный Регистратор.
    Создайте анонимный Регистратор.
    Получите текущий фильтр для этого Регистратора.
    Возвратите глобальный объект регистратора с Регистратором имени. GLOBAL_LOGGER_NAME.
    Свяжите Обработчики с этим регистратором.
    Получите Уровень журнала, который был определен для этого Регистратора.
    Найдите или создайте регистратор для именованной подсистемы.
    Найдите или создайте регистратор для именованной подсистемы.
    Завоюйте репутацию для этого регистратора.
    Возвратите родителя для этого Регистратора.
    Получите пакет ресурса локализации для этого регистратора для текущей локали по умолчанию.
    Получите имя пакета ресурса локализации для этого регистратора.
    Обнаружьте, отправляет ли этот регистратор свой вывод его родительскому регистратору.
    Зарегистрируйте сообщение ИНФОРМАЦИИ.
    Проверьте, было ли сообщение данного уровня бы фактически зарегистрировано этим регистратором.
    Зарегистрируйте сообщение без параметров.
    Зарегистрируйте сообщение с одним объектным параметром.
    Зарегистрируйте сообщение с массивом объектных параметров.
    Зарегистрируйте сообщение со связанной информацией о Throwable.
    Зарегистрируйте LogRecord.
    Зарегистрируйте сообщение, определяя исходный класс и метод, без параметров.

    Зарегистрируйте сообщение, определяя исходный класс и метод, с единственным объектным параметром к сообщению журнала.

    Зарегистрируйте сообщение, определяя исходный класс и метод, с массивом объектных параметров.
    Зарегистрируйте сообщение, определяя исходный класс и метод, со связанной информацией о Throwable.
    Зарегистрируйте сообщение, определяя исходный класс, метод, и имя пакета ресурса без параметров.

    Зарегистрируйте сообщение, определяя исходный класс, метод, и имя пакета ресурса, с единственным объектным параметром к сообщению журнала.

    Зарегистрируйте сообщение, определяя исходный класс, метод, и имя пакета ресурса, с массивом объектных параметров.

    Зарегистрируйте сообщение, определяя исходный класс, метод, и имя пакета ресурса, со связанной информацией о Throwable.

    Удалите Обработчик журнала.
    Установите фильтр, чтобы управлять выводом на этом Регистраторе.

    Установите уровень журнала, определяющий, какие уровни сообщения будут зарегистрированы этим регистратором.

    Установите родителя для этого Регистратора.
    Определите, должен ли этот регистратор отправить свой вывод его родительскому Регистратору.
    Зарегистрируйте СЕРЬЕЗНОЕ сообщение.
    Журнал, выдающий исключение.
    Зарегистрируйте Предупреждающее сообщение.

    Методы java.lang унаследованный от класса. Объект

    Полевая Деталь

    GLOBAL_LOGGER_NAME
    public static final String GLOBAL_LOGGER_NAME

    GLOBAL_LOGGER_NAME является именем для глобального регистратора.

    глобальная переменная
    @Deprecated public static final Logger global

    Осуждаемый. Инициализация этого поля является склонной к мертвым блокировкам. Поле должно быть инициализировано инициализацией класса Регистратора, которая может вызвать мертвые блокировки с инициализацией класса LogManager. В таких случаях две инициализации класса ожидают друг друга, чтобы завершиться. Привилегированный способ получить глобальный объект регистратора через вызов Logger.getGlobal() . Для совместимости со старыми версиями JDK, где Logger.getGlobal() не доступное использование вызов Logger.getLogger(Logger.GLOBAL_LOGGER_NAME) или Logger.getLogger(«global») .

    «Глобальный» объект Регистратора предоставляется как удобство разработчикам, которые делают случайное использование пакета Журналирования. Разработчики, которые делают серьезное использование пакета журналирования (например в продуктах) должны создать и использовать свои собственные объекты Регистратора с соответствующими именами, так, чтобы журналированием можно было управлять на подходящей гранулярности на регистратор. Разработчики также должны сохранить сильную ссылку на свои объекты Регистратора препятствовать тому, чтобы они были собраны «мусор».

    Деталь конструктора

    Регистратор
    protected Logger(String name, String resourceBundleName)

    Защищенный метод, чтобы создать регистратор для именованной подсистемы. Регистратор будет первоначально сконфигурирован с нулевым Уровнем и с набором useParentHandlers к истине.

    Деталь метода

    getGlobal
    public static final Logger getGlobal()

    Возвратите глобальный объект регистратора с Регистратором имени. GLOBAL_LOGGER_NAME.

    getLogger
    public static Logger getLogger(String name)

    Найдите или создайте регистратор для именованной подсистемы. Если регистратор был уже создан с именем, это возвращается. Иначе новый регистратор создается. Если новый регистратор будет создаваться, то его уровень журнала будет сконфигурирован основанный на конфигурации LogManager, и это будет сконфигурированный, чтобы также отправить вывод журналирования Обработчикам его родителя. Это будет зарегистрировано в глобальном пространстве имен LogManager. Отметьте: LogManager может только сохранить слабую ссылку на недавно создаваемый Регистратор. Важно понять, что ранее создаваемый Регистратор с именем может быть собран «мусор» в любое время, если нет никакой сильной ссылки на Регистратор. В частности это означает что два компенсационных вызова как getLogger(«MyLogger»).log(. ) может использовать различные объекты Регистратора по имени «MyLogger», если нет никакой сильной ссылки на Регистратор по имени «MyLogger» в другом месте в программе.

    getLogger
    public static Logger getLogger(String name, String resourceBundleName)

    Найдите или создайте регистратор для именованной подсистемы. Если регистратор был уже создан с именем, это возвращается. Иначе новый регистратор создается. Если новый регистратор будет создаваться, то его уровень журнала будет сконфигурирован основанный на LogManager, и это будет сконфигурированный, чтобы также отправить вывод журналирования Обработчикам его родителя. Это будет зарегистрировано в глобальном пространстве имен LogManager. Отметьте: LogManager может только сохранить слабую ссылку на недавно создаваемый Регистратор. Важно понять, что ранее создаваемый Регистратор с именем может быть собран «мусор» в любое время, если нет никакой сильной ссылки на Регистратор. В частности это означает что два компенсационных вызова как getLogger(«MyLogger», . ).log(. ) может использовать различные объекты Регистратора по имени «MyLogger», если нет никакой сильной ссылки на Регистратор по имени «MyLogger» в другом месте в программе. Если именованный Регистратор уже существует и еще не имеет пакета ресурса локализации тогда, данное имя пакета ресурса используется. Если именованный Регистратор уже существует и имеет различное имя пакета ресурса тогда, IllegalArgumentException бросается.

    getAnonymousLogger
    public static Logger getAnonymousLogger()

    Создайте анонимный Регистратор. Недавно создаваемый Регистратор не регистрируется в пространстве имен LogManager. Не будет никаких проверок прав доступа на обновлениях к регистратору. Этот метод фабрики прежде всего предназначается для использования от апплетов. Поскольку получающийся Регистратор является анонимным, это может быть сохранено частным классом создания. Это устраняет потребность для нормальных проверок безопасности, которая поочередно позволяет недоверяемому коду апплета обновлять состояние управления Регистратора. Например апплет может сделать setLevel или addHandler на анонимном Регистраторе. Даже если новый регистратор является анонимным, он конфигурируется, чтобы иметь корневой регистратор («») как его родитель. Это означает, что по умолчанию наследовало свой эффективный уровень и обработчики от корневого регистратора.

    getAnonymousLogger
    public static Logger getAnonymousLogger(String resourceBundleName)

    Создайте анонимный Регистратор. Недавно создаваемый Регистратор не регистрируется в пространстве имен LogManager. Не будет никаких проверок прав доступа на обновлениях к регистратору. Этот метод фабрики прежде всего предназначается для использования от апплетов. Поскольку получающийся Регистратор является анонимным, это может быть сохранено частным классом создания. Это устраняет потребность для нормальных проверок безопасности, которая поочередно позволяет недоверяемому коду апплета обновлять состояние управления Регистратора. Например апплет может сделать setLevel или addHandler на анонимном Регистраторе. Даже если новый регистратор является анонимным, он конфигурируется, чтобы иметь корневой регистратор («») как его родитель. Это означает, что по умолчанию наследовало свой эффективный уровень и обработчики от корневого регистратора.

    getResourceBundle
    public ResourceBundle getResourceBundle()

    Получите пакет ресурса локализации для этого регистратора для текущей локали по умолчанию. Отметьте что, если результатом будет нуль, то Регистратор будет использовать пакет ресурса, наследованный от его родителя.

    getResourceBundleName
    public String getResourceBundleName()

    Получите имя пакета ресурса локализации для этого регистратора. Отметьте что, если результатом будет нуль, то Регистратор будет использовать имя пакета ресурса, наследованное от его родителя.

    setFilter
    public void setFilter(Filter newFilter) throws SecurityException

    Установите фильтр, чтобы управлять выводом на этом Регистраторе. После передачи начальной проверки «уровня» Регистратор вызовет этот Фильтр, чтобы проверить, должна ли запись журнала действительно быть опубликована.

    getFilter
    public Filter getFilter()

    Получите текущий фильтр для этого Регистратора.

    журнал
    public void log(LogRecord record)

    Зарегистрируйте LogRecord. Все другие методы журналирования в этом классе вызывают через этот метод, чтобы фактически выполнить любое журналирование. Подклассы могут переопределить этот единственный метод, чтобы получить все действие журнала.

    журнал
    public void log(Level level, String msg)

    Зарегистрируйте сообщение без параметров. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    журнал
    public void log(Level level, String msg, Object param1)

    Зарегистрируйте сообщение с одним объектным параметром. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, соответствующий LogRecord создается и передается всем зарегистрированным выходным Объектам-обработчикам.

    журнал
    public void log(Level level, String msg, Object[] params)

    Зарегистрируйте сообщение с массивом объектных параметров. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, соответствующий LogRecord создается и передается всем зарегистрированным выходным Объектам-обработчикам.

    журнал
    public void log(Level level, String msg, Throwable thrown)

    Зарегистрируйте сообщение со связанной информацией о Throwable. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, данные параметры сохранены в LogRecord, который передается всем зарегистрированным выходным обработчикам. Отметьте, что брошенный параметр сохранен в LogRecord брошенное свойство, а не свойство параметров LogRecord. Таким образом обработанное особенно выходными Средствами форматирования и не обрабатывается как параметр форматирования к свойству сообщения LogRecord.

    logp
    public void logp(Level level, String sourceClass, String sourceMethod, String msg)

    Зарегистрируйте сообщение, определяя исходный класс и метод, без параметров. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    logp
    public void logp(Level level, String sourceClass, String sourceMethod, String msg, Object param1)

    Зарегистрируйте сообщение, определяя исходный класс и метод, с единственным объектным параметром к сообщению журнала. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, соответствующий LogRecord создается и передается всем зарегистрированным выходным Объектам-обработчикам.

    logp
    public void logp(Level level, String sourceClass, String sourceMethod, String msg, Object[] params)

    Зарегистрируйте сообщение, определяя исходный класс и метод, с массивом объектных параметров. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, соответствующий LogRecord создается и передается всем зарегистрированным выходным Объектам-обработчикам.

    logp
    public void logp(Level level, String sourceClass, String sourceMethod, String msg, Throwable thrown)

    Зарегистрируйте сообщение, определяя исходный класс и метод, со связанной информацией о Throwable. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, данные параметры сохранены в LogRecord, который передается всем зарегистрированным выходным обработчикам. Отметьте, что брошенный параметр сохранен в LogRecord брошенное свойство, а не свойство параметров LogRecord. Таким образом обработанное особенно выходными Средствами форматирования и не обрабатывается как параметр форматирования к свойству сообщения LogRecord.

    logrb
    public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg)

    Зарегистрируйте сообщение, определяя исходный класс, метод, и имя пакета ресурса без параметров. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам. Строка сообщения локализуется, используя именованный пакет ресурса. Если имя пакета ресурса является нулем, или пустой Строкой или недопустимый тогда, строка сообщения не локализуется.

    logrb
    public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg, Object param1)

    Зарегистрируйте сообщение, определяя исходный класс, метод, и имя пакета ресурса, с единственным объектным параметром к сообщению журнала. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, соответствующий LogRecord создается и передается всем зарегистрированным выходным Объектам-обработчикам. Строка сообщения локализуется, используя именованный пакет ресурса. Если имя пакета ресурса является нулем, или пустой Строкой или недопустимый тогда, строка сообщения не локализуется.

    logrb
    public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg, Object[] params)

    Зарегистрируйте сообщение, определяя исходный класс, метод, и имя пакета ресурса, с массивом объектных параметров. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, соответствующий LogRecord создается и передается всем зарегистрированным выходным Объектам-обработчикам. Строка сообщения локализуется, используя именованный пакет ресурса. Если имя пакета ресурса является нулем, или пустой Строкой или недопустимый тогда, строка сообщения не локализуется.

    logrb
    public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg, Throwable thrown)

    Зарегистрируйте сообщение, определяя исходный класс, метод, и имя пакета ресурса, со связанной информацией о Throwable. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, данные параметры сохранены в LogRecord, который передается всем зарегистрированным выходным обработчикам. Строка сообщения локализуется, используя именованный пакет ресурса. Если имя пакета ресурса является нулем, или пустой Строкой или недопустимый тогда, строка сообщения не локализуется. Отметьте, что брошенный параметр сохранен в LogRecord брошенное свойство, а не свойство параметров LogRecord. Таким образом обработанное особенно выходными Средствами форматирования и не обрабатывается как параметр форматирования к свойству сообщения LogRecord.

    ввод
    public void entering(String sourceClass, String sourceMethod)

    Зарегистрируйте запись метода. Это — метод удобства, который может использоваться, чтобы зарегистрировать запись в метод. LogRecord с сообщением «ЗАПИСЬ», БОЛЕЕ ПРЕКРАСНЫЙ уровень журнала, и данный sourceMethod и sourceClass регистрируется.

    ввод
    public void entering(String sourceClass, String sourceMethod, Object param1)

    Зарегистрируйте запись метода с одним параметром. Это — метод удобства, который может использоваться, чтобы зарегистрировать запись в метод. LogRecord с сообщением «ЗАПИСЬ <0>«, БОЛЕЕ ПРЕКРАСНЫЙ уровень журнала, и данный sourceMethod, sourceClass, и параметр регистрируется.

    ввод
    public void entering(String sourceClass, String sourceMethod, Object[] params)

    Зарегистрируйте запись метода с массивом параметров. Это — метод удобства, который может использоваться, чтобы зарегистрировать запись в метод. Регистрируется LogRecord с сообщением «ЗАПИСЬ» (сопровождаемый индикатором формата для каждой записи в массиве параметра), БОЛЕЕ ПРЕКРАСНЫЙ уровень журнала, и данный sourceMethod, sourceClass, и параметры.

    выход
    public void exiting(String sourceClass, String sourceMethod)

    Зарегистрируйте возврат метода. Это — метод удобства, который может использоваться, чтобы зарегистрировать возврат из метода. LogRecord с сообщением «ВОЗВРАТ», БОЛЕЕ ПРЕКРАСНЫЙ уровень журнала, и данный sourceMethod и sourceClass регистрируется.

    выход
    public void exiting(String sourceClass, String sourceMethod, Object result)

    Зарегистрируйте возврат метода с объектом результата. Это — метод удобства, который может использоваться, чтобы зарегистрировать возврат из метода. LogRecord с сообщением «ВОЗВРАТ <0>«, БОЛЕЕ ПРЕКРАСНЫЙ уровень журнала, и давание sourceMethod, sourceClass, и объект результата регистрируется.

    бросок
    public void throwing(String sourceClass, String sourceMethod, Throwable thrown)

    Журнал, выдающий исключение. Это — метод удобства, чтобы зарегистрировать это, метод завершается, выдавая исключение. Журналирование делается, используя БОЛЕЕ ПРЕКРАСНЫЙ уровень. Если регистратор в настоящий момент включается для данного уровня сообщения тогда, данные параметры сохранены в LogRecord, который передается всем зарегистрированным выходным обработчикам. Сообщение LogRecord устанавливается «БРОСИТЬ». Отметьте, что брошенный параметр сохранен в LogRecord брошенное свойство, а не свойство параметров LogRecord. Таким образом обработанное особенно выходными Средствами форматирования и не обрабатывается как параметр форматирования к свойству сообщения LogRecord.

    серьезный

    Зарегистрируйте СЕРЬЕЗНОЕ сообщение. Если регистратор в настоящий момент включается для СЕРЬЕЗНОГО уровня сообщения тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    предупреждение

    Зарегистрируйте Предупреждающее сообщение. Если регистратор в настоящий момент включается для уровня Предупреждающего сообщения тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    информация

    Зарегистрируйте сообщение ИНФОРМАЦИИ. Если регистратор в настоящий момент включается для уровня сообщения ИНФОРМАЦИИ тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    конфигурация

    Зарегистрируйте сообщение КОНФИГУРАЦИИ. Если регистратор в настоящий момент включается для уровня сообщения КОНФИГУРАЦИИ тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    прекрасный

    Зарегистрируйте ПРЕКРАСНОЕ сообщение. Если регистратор в настоящий момент включается для ПРЕКРАСНОГО уровня сообщения тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    более прекрасный

    Зарегистрируйте БОЛЕЕ ПРЕКРАСНОЕ сообщение. Если регистратор в настоящий момент включается для БОЛЕЕ ПРЕКРАСНОГО уровня сообщения тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    самый прекрасный

    Зарегистрируйте САМОЕ ПРЕКРАСНОЕ сообщение. Если регистратор в настоящий момент включается для САМОГО ПРЕКРАСНОГО уровня сообщения тогда, данное сообщение передается ко всем зарегистрированным выходным Объектам-обработчикам.

    setLevel
    public void setLevel(Level newLevel) throws SecurityException

    Установите уровень журнала, определяющий, какие уровни сообщения будут зарегистрированы этим регистратором. Уровни сообщения ниже чем это значение будут отброшены. Уровень значения уровня. ПРОЧЬ может использоваться, чтобы выключить журналирование. Если новый уровень является нулем, это означает, что этот узел должен наследовать свой уровень от его самого близкого предка с определенным (ненулевым) значением уровня.

    getLevel
    public Level getLevel()

    Получите Уровень журнала, который был определен для этого Регистратора. Результатом может быть нуль, что означает, что эффективный уровень этого регистратора будет наследован от его родителя.

    isLoggable
    public boolean isLoggable(Level level)

    Проверьте, было ли сообщение данного уровня бы фактически зарегистрировано этим регистратором. Эта проверка основана на Регистраторах эффективный уровень, который может быть наследован от его родителя.

    getName
    public String getName()

    Завоюйте репутацию для этого регистратора.

    addHandler
    public void addHandler(Handler handler) throws SecurityException

    Добавьте Обработчик журнала, чтобы получить сообщения журналирования. По умолчанию Регистраторы также отправляют свой вывод их родительскому регистратору. Обычно корневой Регистратор конфигурируется с рядом Обработчиков, которые по существу действуют как обработчики по умолчанию для всех регистраторов.

    removeHandler
    public void removeHandler(Handler handler) throws SecurityException

    Удалите Обработчик журнала. Возвраты тихо, если данный Обработчик не находится или является нулем

    getHandlers
    public Handler[] getHandlers()

    Свяжите Обработчики с этим регистратором.

    setUseParentHandlers
    public void setUseParentHandlers(boolean useParentHandlers)

    Определите, должен ли этот регистратор отправить свой вывод его родительскому Регистратору. Это означает, что любой LogRecords будет также записан Обработчикам родителя, и потенциально его родителю, рекурсивно пространство имен.

    getUseParentHandlers
    public boolean getUseParentHandlers()

    Обнаружьте, отправляет ли этот регистратор свой вывод его родительскому регистратору.

    getParent
    public Logger getParent()

    Возвратите родителя для этого Регистратора. Этот метод возвращает самого близкого существующего родителя в пространстве имен. Таким образом, если Регистратор вызовут «a.b.c.d», и Регистратор, названный «a.b», был создан, но никакой регистратор «a.b.c» существует, то вызов getParent на Регистраторе «a.b.c.d» возвратит Регистратор «a.b». Результатом будет нуль, если это вызовут на корневом Регистраторе в пространстве имен.

    setParent
    public void setParent(Logger parent)

    Установите родителя для этого Регистратора. Этот метод используется LogManager, чтобы обновить Регистратор, когда пространство имен изменяется. Это нельзя вызвать от кода программы.

    Платформа Java™
    Стандарт Эд. 7

    Представьте ошибку или функцию
    Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE . Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
    Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.

    Почему существует два метода setlevel java

    Скачай курс
    в приложении

    Перейти в приложение
    Открыть мобильную версию сайта

    © 2013 — 2023. Stepik

    Наши условия использования и конфиденциальности

    Get it on Google Play

    Public user contributions licensed under cc-wiki license with attribution required

    Логирование в разные файлы

    Вопрос, можно ли как-то развести по разным файлам логи от my.name1 и my.name2 ? Или только написанием наследника FileHandler с перекрытием метода publish ?

    Отслеживать
    задан 19 июн 2018 в 9:16
    Anton Shchyrov Anton Shchyrov
    33.1k 2 2 золотых знака 33 33 серебряных знака 61 61 бронзовый знак

    1 ответ 1

    Сортировка: Сброс на вариант по умолчанию

    В общем случае конфигурацией вы вашу задачу не решите. Если вы конфигурируете логирование Tomcat, то там такая возможность есть. Если нет — можно этого добиться, сконфигурировав логгеры в Java:

    Logger log1 = Logger.getLogger("my.name1"); log1.addHandler(new FileHandler("my.name1.log")); Logger log2 = Logger.getLogger("my.name2"); log2.addHandler(new FileHandler("my.name2.log")); 

    Если есть такая возможность, постарайтесь отказаться от java.util.logging в пользу более гибкой библиотеки логирования. В log4j и Logback возможность разводить разные логи в разные файлы есть из коробки. А если вы воспользуетесь slf4j, то сможете при необходимости относительно безболезненно сменить библиотеку логирования, не модифицируя код.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *