java - qué - Tomcat WAR-Configurar Logback para usar el nombre de la aplicación en la ruta
logback levels (4)
Tengo logback implementado en mi carpeta war file lib y tengo el siguiente logback.xml en la carpeta de clases.
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<property name="destination" value="${catalina.base:-./temp}/logs/${appName:-myapp}" />
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${destination}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${destination}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- Keep logs for 7 days -->
<maxHistory>7</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="error">
<appender-ref ref="ROLLING" />
</root>
</configuration>
En la línea 3 tengo algunas sustituciones de variables que crean la ruta para mi archivo de registro.
<property name="destination" value="${catalina.base:-./temp}/logs/${appName:-myapp}" />
Quiero que sea así para que ${appName}
evalúe el nombre actual del archivo war implementado.
Entonces, si mi carpeta de aplicaciones web se veía así
webapps
- myapp.war
- myapp-dev.war
La propiedad ${destination}
para myapp.war evaluaría a .../logs/myapp
y myapp-dev.war evaluaría a .../logs/myapp-dev
. ¿Hay alguna propiedad JNDI o algo a lo que pueda acceder para acceder a appName?
Me gustaría evitar tener que reconfigurar manualmente el registrador.
¡Gracias!
Esto se basa en la respuesta de Michael-O. Teniendo en cuenta que catalina.base
siempre es una propiedad del sistema definida cuando se ejecuta bajo Tomcat, solo tenemos que preocuparnos por definir appName
. Logback ofrece soporte para recuperar variables de JNDI . Si appName se define en JNDI, su archivo de configuración se convierte en:
<configuration>
<!-- retrieve appName from JNDI to set the variable appName -->
<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />
<!-- let the context name be the applicaiton name -->
<contextName>${appName}</contextName>
<property name="destination"
value="${catalina.base:-./temp}/logs/${CONTEXT_NAME:-myapp}" />
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${destination}.log</file>
... remainder of config file omitted for brevity
</appender>
</configuration>
Me gustaría mencionar que también puedes definir appName directamente en logback.xml en lugar de hacerlo en JNDI. (Después de todo, el archivo logback.xml se envía con su aplicación web, donde su nombre ya está establecido. Sin embargo, su pregunta excluye explícitamente esta hipótesis). Por lo tanto, su archivo logback.xml podría simplificarse a:
<configuration>
<contextName>the_name_of_your_webapp</contextName>
<property name="destination"
value="${catalina.base:-./temp}/logs/${CONTEXT_NAME:-myapp}" />
... the rest omitted for brevity
</configuration?
Por cierto, una vez que encuentre una solución satisfactoria, no dude en compartirla publicando en la lista de usuarios de logback.
maxHistory no significa la cantidad de archivos de registro. Significa la cantidad de meses.
EDIT 2013-06 : He hecho que este Listener
esté disponible como OSS en Maven Central. Mira la página de inicio del proyecto .
Sí, esto es factible. Antes que nada, siempre puedes confiar en catalina.base
porque sin eso Tomcat no se ejecutará. Para inyectar el nombre del contexto como propiedad. Escriba un oyente de contexto que colocará el nombre de contexto en el contexto JNDI y lo eliminará al apagarlo. Después de haber hecho eso, puede recuperar el valor con JNDI directamente con logback. Hay apoyo directo para eso. Escriba eso en el elemento contextName y listo.
Ya lo he implementado por mi cuenta y funciona para todos mis proyectos. Puedo compartir el código completo el lunes si usted o alguien más está interesado.
Editar, aquí está el código:
import org.apache.catalina.Context;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.deploy.ContextEnvironment;
import org.apache.commons.lang.StringUtils;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
public class LogbackContextNameListener implements LifecycleListener {
private static final Log logger = LogFactory
.getLog(LogbackContextNameListener.class);
private Context context;
private String name = "logback/contextName";
@Override
public void lifecycleEvent(LifecycleEvent le) {
if (le.getLifecycle() instanceof Context)
context = (Context) le.getLifecycle();
else
return;
if (le.getType().equals(Lifecycle.START_EVENT)) {
ContextEnvironment ce = new ContextEnvironment();
ce.setName(getName());
ce.setOverride(false);
ce.setType("java.lang.String");
String value = StringUtils.remove(context.getServletContext()
.getContextPath(), ''/'');
ce.setValue(value);
logger.debug(String.format("Adding env entry ''%s'' with value ''%s''",
getName(), value));
context.getNamingResources().addEnvironment(ce);
}
if (le.getType().equals(Lifecycle.STOP_EVENT)) {
logger.debug(String.format("Removing env entry ''%s''", getName()));
context.getNamingResources().removeEnvironment(name);
}
}
public String getName() {
return name;
}
public void setName(String name) {
if (StringUtils.isEmpty(name))
throw new IllegalArgumentException(
"Parameter ''name'' cannot be empty");
this.name = name;
}
}
Una configuración adecuada se ve así:
<configuration scan="true" scanPeriod="30 minutes">
<insertFromJNDI env-entry-name="java:comp/env/logback/contextName" as="contextName" />
<contextName>${contextName}</contextName>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${catalina.base}/logs/${CONTEXT_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${catalina.base}/logs/${CONTEXT_NAME}.log.%d.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-27(%d{HH:mm:ss.SSS} [%.-12thread]) %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO"><!-- WARN -->
<appender-ref ref="FILE" />
</root>
</configuration>
Esto funciona sin problemas en Tomcat 6. Supongo que funcionará en Tomcat 7 sin cambios.
¿No es ese el ContextSelector? Puede echar un vistazo a ContextJNDISelector y aquí http://logback.qos.ch/manual/contextSelector.html