Как вставить имя папки текущего веб-приложения в имя файла log4j - PullRequest
9 голосов
/ 22 февраля 2011

Я пишу веб-приложение на Java для развертывания в Tomcat и использую log4j для ведения журнала. Мне нравится автоматически вставлять имя папки веб-приложения в имя сгенерированного файла журнала.

В настоящее время настройка имени файла выглядит так в log4j.properties:

log4j.appender.R.File=${catalina.home}/logs/mywebapp.log

и мне нужно что-то вроде этого:

log4j.appender.R.File=${catalina.home}/logs/${current.webapp.folder}.log

Существует ли какая-либо переменная окружения для этого, чтобы указать в файле свойств, или я должен создать экземпляр регистратора из кода?

Ответы [ 3 ]

2 голосов
/ 23 февраля 2011

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

Я переименовал log4j.properties в myapp-log4j.properties и изменил свойство имени файла журнала следующим образом:

log4j.appender.R.File=${catalina.base}/logs/#{context.name}.log

Поскольку у меня есть сервлет, который загружается при запуске, я инициализирую log4j в функции init ().

String contextPath = getServletContext().getContextPath();

// First reconfigure log4j
String contextName = contextPath.substring(1);
if (!configureLog4J(contextName)) {
  return;
}

Функция для этого:

  public static final String LOG4JAPPENDERRFILE = "log4j.appender.R.File";

  private boolean configureLog4J(String contextName) {
    Properties props = new Properties();
    try {
       InputStream configStream = getClass().getResourceAsStream("/myapp-log4j.properties");
       props.load(configStream);
       configStream.close();
    } catch(IOException e) {
       System.out.println("FATAL! Cannot load log4j configuration file from classpath.");
       e.printStackTrace(System.out);
       return false;
    }

    String logFile = props.getProperty(LOG4JAPPENDERRFILE);
    logFile=logFile.replace("#{context.name}", contextName);
    props.setProperty(LOG4JAPPENDERRFILE, logFile);
    LogManager.resetConfiguration();
    PropertyConfigurator.configure(props);
    return true;
  }

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

1 голос
/ 17 мая 2018

Этого можно добиться, используя прослушиватель контекста для настройки системного свойства, а затем использовать это свойство в конфигурации log4j.

Шаг 1: настроить системное свойство

Сначала вы можете установить системное свойство (например, contextPath) в значение пути контекста Tomcat приложения. Вы можете сделать это в контексте слушателя.

package my.package.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
    }

    @Override
    public void contextInitialized(ServletContextEvent event) {
        defineContextPath(event);
    }

    private void defineContextPath(ServletContextEvent event) {
        ServletContext context = event.getServletContext();
        String contextPath = context.getContextPath();

        if (contextPath != null) {
            String pattern = ".*/(.*)";
            String contex = contextPath.replaceAll(pattern, "$1");
            System.setProperty("contextPath", contex);
            System.out.println("contextPath: " + contex);
        } else {
            System.out.println("contextPath not found");
        }
    }

}

Объявите слушателя в вашем web.xml:

<!-- Be sure to keep my.package.ContextListener as the first listener 
     if you have more listeners as below --> 
<listener>
    <listener-class>my.package.ContextListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Шаг 2: используйте системное свойство, чтобы установить имя файла log4j

Затем в файле конфигурации log4j вы можете использовать системное свойство contextPath, чтобы задать имя файла log4j.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern="%d %5p %c{1}:%L - %m%n" />
        </Console>
        <RollingFile name="RollingFile" fileName="${catalina.base}/logs/${tomcat.hostname}/${contextPath}.log" 
            filePattern="${catalina.base}/logs/${tomcat.hostname}/$${date:yyyy-MM}/${contextPath}-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n" />
            <TimeBasedTriggeringPolicy />
            <SizeBasedTriggeringPolicy size="500 MB" />
        </RollingFile>
    </Appenders>
    <Loggers>
        <Logger name="org.apache.log4j.xml" level="info" />
        <Root level="info">
            <AppenderRef ref="STDOUT" />
            <AppenderRef ref="RollingFile"/> 
        </Root>
    </Loggers>
</Configuration>

Ссылки

https://blog.oio.de/2013/06/10/using-the-context-path-of-a-web-app-as-log-filename-with-log4j/

0 голосов
/ 23 февраля 2011

Сначала попробуйте добавить свои "log4j.properties".

current.webapp.folder=myapp

Во-вторых, если вы использовали "PropertyConfigurator" ...

Properties props = new Property();
/* Read "log4j.properties" */

Properties webappProps = new Property();
/* Read setting ex."current.webapp.folder=myapp" */

Enumeration<Object> e = props.propertyNames();
while (e.hasMoreElements()) {
    String key = (String) e.nextElement();
    // used org.apache.log4j.helpers.OptionConverter
    props.setProperty(
            key, 
            OptionConverter.substVars(props.getProperty(key), webappProps));
}

PropertyConfigurator.configure(props);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...