Путаница в Tomcat - PullRequest
       38

Путаница в Tomcat

0 голосов
/ 04 мая 2018

У меня свежая установка tomcat.

Для улучшения регистрации я редактирую conf/logging.properties.

Шаг 1

Я изменяю линию

java.util.logging.ConsoleHandler.level = FINE

до

java.util.logging.ConsoleHandler.level = FINER

Шаг 2

и добавить строку

org.apache.catalina.level = FINER

Шаг 3

Затем я запускаю сервер и, если мне не удается пройти аутентификацию на http://localhost:8080/manager/ с именем пользователя MyUsername и MyPassword, я вижу этот вывод:

FINE [http-bio-443-exec-2] org.apache.catalina.authenticator.AuthenticatorBase.invoke Security checking request GET /manager/html
FINE [http-bio-443-exec-2] org.apache.catalina.loader.WebappClassLoaderBase.loadClass loadClass(org.apache.catalina.manager.HTMLManagerServlet, false)
FINE [http-bio-443-exec-2] org.apache.catalina.loader.WebappClassLoaderBase.loadClass   Delegating to parent classloader1 java.net.URLClassLoader@1218025c
FINE [http-bio-443-exec-2] org.apache.catalina.loader.WebappClassLoaderBase.loadClass   Loading class from parent
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[Status interface]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[JMX Proxy interface]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[Text Manager interface (for scripts)]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[HTML Manager interface (for humans)]' against GET /html --> true
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[Status interface]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[JMX Proxy interface]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[Text Manager interface (for scripts)]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[HTML Manager interface (for humans)]' against GET /html --> true
FINE [http-bio-443-exec-2] org.apache.catalina.authenticator.AuthenticatorBase.invoke  Calling hasUserDataPermission()
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.hasUserDataPermission   User data constraint has no restrictions
FINE [http-bio-443-exec-2] org.apache.catalina.authenticator.AuthenticatorBase.invoke  Calling authenticate()
FINER [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.authenticate Username MyUsername NOT successfully authenticated
FINE [http-bio-443-exec-2] org.apache.catalina.authenticator.AuthenticatorBase.invoke  Failed authenticate() test
FINE [http-bio-443-exec-2] org.apache.catalina.core.StandardHostValve.custom Processing ErrorPage[errorCode=401, location=/WEB-INF/jsp/401.jsp]
FINER [http-bio-443-exec-2] org.apache.catalina.core.StandardWrapper.allocate   Returning non-STM instance
FINE [http-bio-443-exec-2] org.apache.catalina.core.ApplicationDispatcher.doForward  Disabling the response for futher output
FINE [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.session.ManagerBase.processExpires Start expire sessions StandardManager at 1525428004090 sessioncount 0
FINE [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.session.ManagerBase.processExpires End expire sessions StandardManager processingTime 4 expired sessions: 0

Вопрос

Теперь я изменяю Шаг 2 и добавляю пакет realm к определению. Теперь Шаг 2 добавляет эту строку вместо:

org.apache.catalina.realm.level = FINER

Почему исчезают FINER-Loggings? Я имею в виду, org.apache.catalina.realm более конкретно, верно?

1 Ответ

0 голосов
/ 04 мая 2018

Если я правильно понимаю, вы в конечном итоге получите свойства ведения журнала, которые выглядят так:

java.util.logging.ConsoleHandler.level = FINER
org.apache.catalina.realm.level = FINER

В разделе Обзор ведения журнала Java 1.1 указано:

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

При чтении имен регистратора родительские регистраторы находятся слева от точек. Следовательно, org.apache.catalina является родителем org.apache.catalina.realm и org.apache.catalina.realm и org.apache.catalina.core.

Код исполняющего кода должен требовать регистратор , чтобы он существовал. Простое добавление строк в файл свойств не создает логгеры. Если бы это было так, они бы просто собрали мусор в любом случае. Это означает, что у вас есть дерево логгеров A <- B <- C. Вы хотите установить уровень для B и, следовательно, для всех B дочерних элементов, чтобы добавить строку A.B.level в файл свойств. Однако во время выполнения требуются следующие регистраторы: A и C

.

Так что вам нужно работать с "" <- A <- A.B.C, когда вы ожидаете "" <- A <- A.B <- A.B.C

Собирая все это вместе, я думаю, что во время выполнения ваши логгеры будут выглядеть так:

"" <- org.apache.catalina <- org.apache.catalina.realm.RealmBase, и никакой код Tomcat не создал фактического регистратора с именем org.apache.catalina.realm.

Вы можете проверить, подключив JConsole к запуску JVM и проверке вкладки MBean и перечислению имен регистратора. В Tomcat это не сработает, поскольку возвращаемые средства ведения журнала зависят от вызывающего загрузчика классов.

Чтобы обойти это, вы можете использовать опцию config для запроса и удержания регистратора в памяти. Вам просто нужно установить это в пользовательском коде по системному классу path .

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

Первая идея: если мы посмотрим на специфику CSS, мы знаем, что .mydiv {color: red} не так специфичен, как div.mydiv {color: green}, поэтому div.mydiv содержит текст красного цвета? Под наследованием понимается, если не указано, что такое анти-наследование.

В отличие от CSS, JUL имеет дерево логгера времени выполнения и файл свойств. Это дерево логгера времени выполнения динамически корректируется, поскольку выполнение кода требует регистраторов. Свойства используются всегда, только если код требует регистратора. Указание имени регистратора в файле свойств ничего не значит, если регистратор не создан кодом. Это может изменить родителей регистратора и, следовательно, уровень. Дайте ему вращение:

package so;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class TheMissingParent {

    private static final Logger[] LAZY_ONE;
    static {
        LAZY_ONE = new Logger[] { Logger.getLogger("org.apache.catalina"),
                Logger.getLogger("org.apache.catalina.realm.RealmBase") };
    }

    private static volatile Logger[] LAZY_TWO;

    public static void main(String[] args) {
        loadProperties();
        printAncestors(LAZY_ONE);
        findlLongLostParents();
        System.out.println("====");
        printAncestors(LAZY_ONE);
    }

    private static void loadProperties() {
        Properties props = new Properties();
        props.put("org.apache.catalina.realm.level", "FINER");

        try(ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            props.store(out, "");
            LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray()));
        } catch (IOException ioe) {
            throw new AssertionError(ioe);
        }
    }

    private static void findlLongLostParents() {
        LAZY_TWO = new Logger[] {Logger.getLogger("org.apache.catalina.realm") };
    }

    private static void printAncestors(Logger[] loggers) {
        // System.out.println(loggers.toString());
        for (Logger l : loggers) {
            printAncestors(l);
            System.out.println();
        }
    }

    private static void printAncestors(Logger l) {
        if (l != null) {
            printAncestors(l.getParent());
            System.out.print("<-");
            String name = l.getName();
            if (name != null && name.isEmpty()) {
                System.out.append("\"\"");
            } else {
                System.out.append(name);
            }

            for(Logger p = l; p != null; p = p.getParent()) {
                Level lvl = p.getLevel();
                if (lvl != null) {
                    System.out.append('{').append(lvl.getName()).append('}');
                    break;
                }
            }
        }
    }
}

Будет выведено:

<-""{INFO}<-org.apache.catalina{INFO}
<-""{INFO}<-org.apache.catalina{INFO}<-org.apache.catalina.realm.RealmBase{INFO}
====
<-""{INFO}<-org.apache.catalina{INFO}
<-""{INFO}<-org.apache.catalina{INFO}<-org.apache.catalina.realm{FINER}<-org.apache.catalina.realm.RealmBase{FINER}

Это основная проблема. Если Tomcat (или некоторый пользовательский код) никогда не требует регистратора org.apache.catalina.realm, то строка в файле свойств - просто мертвый код.

Во-вторых, если вы так говорите, ни для org.apache.catalina, ни для org.apache, ни для org, ни для `` не должно быть уровня INFO, если вы так говорите, так откуда же берется значение INFO?

Это поведение описано в документах уровня класса LoggerManager :

Если ни одно из этих свойств не определено, то, как описано выше, LogManager будет считывать свою первоначальную конфигурацию из файла свойств "lib / logging.properties" в каталоге JRE.

Корневой регистратор с именем пустой строки "" является родителем всех регистраторов. Корневой регистратор всегда создается.

...