We are using multiple solr instances on tomcat but want that they log into different log files. How could we do this?
We are using the follwing xml file under tomcat/conf/Catalina/localhost to make it working:
<Context docBase="/pathtosolr/dist/apache-solr-1.4.0.war" debug="0" crossContext="true" >
<Environment name="solr/home" type="java.lang.String" value="/pathtosolr/solr" override="true" />
</Context>
Update: From Jems answer I found this documentation:
Tomcat offers a choice between settings for all applications or settings specifically for the Solr application.
To change logging settings for Solr only, edit tomcat/webapps/solr/WEB-INF/classes/logging.properties. You will need to create the classes directory and the logging.properties file. You can set levels from FINEST to SEVERE for a class or an entire package. Here are a couple of examples:
org.apache.commons.digester.Digester.level = FINEST
org.apache.solr.level = WARNING
Alternately, if you wish to change Tomcat’s JDK Logging API settings for every application in this instance of Tomcat, edit tomcat/conf/logging.properties.
See the documentation for the SLF4J Logging API for more information:
http://slf4j.org/docs.html
You might wanna take a look at this page: http://globalgateway.wordpress.com/2010/01/06/configuring-solr-1-4-logging-with-log4j-in-tomcat/
There seems to be no good solution:
2008 and 2010
except repacking the solr.war file with a different logging configuration file.
Update: see accepted answer!
Related
We are migrating our application from WAS 6.1 to Liberty. Our application uses third party jars that read property files byInputStream is = ClassLoader.getSystemResource("myproperty.properties").
In WAS 6.1, we set server classpath to the location of myproperty.properties. We tried the below approaches to set classpath in Liberty, but nothing works
Approach 1: Set the below in jvm.options (D:\ConfigFiles\DEV\ - path containing myproperty.properties)
-Djava.class.path=D:\\ConfigFiles\\DEV\\
Approach 2: Setting the classloader in server.xml,
<library id="config">
<folder dir="${server.config.dir}/config/" includes="*.properties" scanInterval="5s"/>
</library>
<enterpriseApplication id="applicationEAR" location="application.ear" name="application">
<classloader privateLibraryRef="config"/>
</enterpriseApplication>
Please let us know if there is any other ways to override/set classpath in Liberty profile?
Try setting this property in jvm.options (instead of -Djava.class.path=path/to/propertyDir):
-Xbootclasspath/a:path/to/propertyDir
This will append the path of the property directory (containing your resource file) to the JVM's bootstrap classpath. Because this is an append, it should also work in Java 9+ (some related options have been removed in Java 9).
I suspect that the reason -Djava.class.path=... doesn't work is that the JVM gets the classpath from the WLP server script - so the system property is essentially applied too late in the startup of the server JVM.
You might also be able to put the properties file(s) in your JVM's lib/ext directory, but I haven't tested that. The -Xbootclasspath/a:path approach works for me on Mac - I assume it will also work on Windows.
HTH, Andy
If your end goal is to load a properties file, a more straightforward way to do this would be using a bootstrap/env/system property or <jndiEntry> in server.xml to store the location of the properties file, and then load it. For example, using an environment variable:
(in server.xml file)
<server>
<featureManager>
<feature>jndi-1.0</feature>
...
</featureManager>
<jndiEntry jndiName="configDir" value="D:\\ConfigFiles\\Dev"/>
</server>
Then, you can load the resource in your application like this:
#Resource(lookup = "configDir")
String configDir;
InputStream is = new FileInputStream(configDir + "/myproperty.properties");
Or, if you will always put your config property files somewhere under ${server.config.dir}, then you can utilize the built-in SERVER_CONFIG_DIR environment variable in Liberty:
String configDir = System.getenv("SERVER_CONFIG_DIR"); // equivalent to ${server.config.dir} in server.xml
InputStream is = new FileInputStream(configDir + "/myproperty.properties");
On the topic of managing configuration, check out MicroProfile Config (e.g. <feature>microProfile-1.2</feature>) which you may find useful: Configuring microservices with Liberty
I know that we can change log level by putting it in vertx-default-jul-logging.properties file.
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level=FINER
java.util.logging.FileHandler.limit=10000000
java.util.logging.FileHandler.count=10
java.util.logging.FileHandler.level=FINER
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
But I need to restart the application when we change log level in this file as it gets built with application. Is there any way to change the log level without restarting the application like we can do in jboss by jboss cli.
This file doesn't have to be built with the application. It just has to be on the classpath.
But anyway, I don't believe JDK logging supports hot reload of a configuration file. There are other logging tools which do though. Like Logback-classic.
Logback-classic can scan for changes in its configuration file and automatically reconfigure itself when the configuration file changes.
For example, to reload every five seconds:
<configuration scan="true" scanPeriod="5 seconds" >
...
</configuration>
Vert.x can be configured to use different logging frameworks. To do so, you must set the vertx.logger-delegate-factory-class-name system property. As Logback-classic is an slf4j implementation, you need:
-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory
I am using JSF2 with Websphere 7 . I have created a shared lib successfully and have pointed application using Webpsphere Admin Console and it works successfully . But what we really want to do is to not have to point to that Shared Lib via WAS Admin Console but have some sort of application level configuration e.g in deployment.xml etc which we can point to the name of that Shared Isolated Lib and use it . I have gone through SO and google but not found any thing doing that . I however know that there are commercial application doing it but do not know how . This question from How can I specify a shared library reference at the web module level in Websphere 6.1 deployment descriptors? is closely what I am after but I not want to specify version numbers or jar names as the answer states
I found a way by simply following what WAS Admin Console was actually doing.
Create a deployment.xml in your EAR file if you do not have one already .
You will find a reference to class loader like below
<classloader xmi:id="Classloader_1311552732281" mode="PARENT_FIRST">
Modify it and add reference to the shared Liberary created on server like below
<classloader xmi:id="Classloader_1311552732281" mode="PARENT_FIRST">
<libraries libraryName="JSF2_SHARED_LIB" sharedClassloader="true"/>
</classloader>
#dbreaux has also shown a way .Accpeting my own answer as fits my needs better but big thanks to dbreaux too for advice.
Is the issue just that you don't want to have to configure each application separately, or that you don't want to use the admin console at all? You can associate a shared library with an entire server, which might be preferable to doing it for each app.
The other way to create those application associations is in the WebSphere-specific .xmi deployment files. These are created when you deploy but can also be included in WAR/EAR files. I don't know if that would help you at all. If it would, the official way to create them ahead of time is using one of the Deployment Tools, but since they're just XML, you may feel comfortable creating them manually.
To append extra details to Shahzeb's answer:
My environment: Websphere 8.5; Windows 7;(Eclipse Luna to generate testing .war file)
I have installed the war file exported from eclipse on websphere server by websphere console.
Then exported it again and unpack it to see what websphere automatically add to it to generate EAR.
[folder]META-INF
[folder]ibmconfig
[file]application.xml
[file]ibm-application-bnd.xmi
[file]ibm-application-runtime.props
[file]MANIFEST.MF
[file]was.module
[file]was.policy
[file]was.webmodule
[file]myWAR.war
And the file deployment.xml is placed in
..\ibmconfig\cells\defaultCell\applications\defaultApp\deployments\defaultApp\
whose content in form of
<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1417052686904">
<deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1417052686904" deploymentId="0" startingWeight="1" binariesURL="$(APP_INSTALL_ROOT)/[server service name]Cell/myWAR.ear" useMetadataFromBinaries="false" enableDistribution="true" createMBeansForResources="true" reloadEnabled="false" appContextIDForSecurity="href:[server service name]Cell/myWAR" filePermission=".*\.dll=755#.*\.so=755#.*\.a=755#.*\.sl=755" allowDispatchRemoteInclude="false" allowServiceRemoteInclude="false" asyncRequestDispatchType="DISABLED" standaloneModule="true" enableClientModule="false">
<targetMappings xmi:id="DeploymentTargetMapping_1417052686904" enable="true" target="ServerTarget_1417052686904"/>
<classloader xmi:id="Classloader_1417052686904" mode="PARENT_FIRST"/>
<modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1417052686904" deploymentId="1" startingWeight="10000" uri="myWAR.war" containsEJBContent="0">
<targetMappings xmi:id="DeploymentTargetMapping_1417052686905" target="ServerTarget_1417052686904"/>
<classloader xmi:id="Classloader_1417052686905"/>
</modules>
<properties xmi:id="Property_1417052686904" name="metadata.complete" value="true"/>
</deployedObject>
<deploymentTargets xmi:type="appdeployment:ServerTarget" xmi:id="ServerTarget_1417052686904" name="server1" nodeName="[server service name]"/>
</appdeployment:Deployment>
(Since I have no reputation, I have to do it all in text.. )
For some applications I use ZK, others Hibernate, other Apache Commons, etc.
I don't want to deploy a 75MB war file, just because it uses lots of libraries.
I don't want to add the libraries to my tomcat lib folder, or nor the classpath to it's configuration as I may have an old application using library x.1 and another application using library x.2
For this reason, it would be great to have something in the web.xml or context.xml where I say something like:
<classpath>/usr/local/tomcat/custom-libs/zk-5.0.4</classpath>
Note: The above is pseudo-code
From Tomcat 7 there is no mention of not being able to use the VirtualWebappLoader in production. I tried it and it works like a dream. Simply add the following to META-INF/context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/websandbox">
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="/usr/.../*.jar;/usr/.../*.jar"/>
</Context>
In Netbeans, under packaging, I just untick all the packages, taking the .war size down to nothing, make sure the dependencies are in the correct folders on the server and upload. Yey! No more 100 MB WAR file.
Addition #Spider answer.
Tomcat Context hold Loader element. According to docs deployment descriptor (what in <Context> tag) can be placed in:
$CATALINA_BASE/conf/server.xml - bad - require server restarts in order to reread config
$CATALINA_BASE/conf/context.xml - bad - shared across all applications
$CATALINA_BASE/work/$APP.war:/META-INF/context.xml - bad - require repackaging in order to change config
$CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml - nice, but see last option!!
$CATALINA_BASE/webapps/$APP/META-INF/context.xml - nice, but see last option!!
$CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml - best - completely out of application and automatically scanned for changes!!!
Here my config which demonstrate how to use development version of project files out of $CATALINA_BASE hierarchy (note that I place this file into src/test/resources dir and intruct Maven to preprocess ${basedir} placeholders through pom.xml <filtering>true</filtering> so after build in new environment I copy it to $CATALINA_BASE/conf/Catalina/localhost/$APP.xml):
<Context docBase="${basedir}/src/main/webapp"
reloadable="true">
<!-- http://tomcat.apache.org/tomcat-7.0-doc/config/context.html -->
<Resources className="org.apache.naming.resources.VirtualDirContext"
extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<JarScanner scanAllDirectories="true"/>
<!-- Use development version of JS/CSS files. -->
<Parameter name="min" value="dev"/>
<Environment name="app.devel.ldap" value="USER" type="java.lang.String" override="true"/>
<Environment name="app.devel.permitAll" value="true" type="java.lang.String" override="true"/>
</Context>
UPDATE Tomcat 8 change syntax for <Resources> and <Loader> elements, corresponding part now look like:
<Resources>
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>
Another a bit hacky alternative.
You can write a 5-6 line custom class loader which derives from urlclassloader, and simply adds your classpath jars using addUrl() method.
Then set it as the context class loader of the thread in your application code.
Thread.setContextClassLoader(new CustomClassloader(path, parentClassLoader)
where parent class loader typically is
Thread.getContextClassloader()
This is what the META-INF/context.xml file can be used for. You defined your own WebappLoader, which loads classes for your particular webapp. This is the reference I used: http://tomcat.apache.org/tomcat-5.5-doc/config/loader.html (Edit: for Tomcat 6: http://tomcat.apache.org/tomcat-6.0-doc/config/loader.html, for Tomcat 7: http://tomcat.apache.org/tomcat-7.0-doc/config/loader.html)
Also this fellow here seems to post a solution to your exact problem (example included): http://java.dzone.com/articles/extending-tomcat-webapploader
According to the documentation for Google App Engine for Java:
The App Engine Java SDK includes a
template logging.properties file, in
the appengine-java-sdk/config/user/
directory. To use it, copy the file to
your WEB-INF/classes directory (or
elsewhere in the WAR), then the system
property java.util.logging.config.file
to
"WEB-INF/classes/logging.properties"
(or whichever path you choose,
relative to the application root). You
can set system properties in the
appengine-web.xml file, as follows:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
...
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties" />
</system-properties>
</appengine-web-app>
The Google Plugin for Eclipse new
project wizard creates these logging
configuration files for you, and
copies them to WEB-INF/classes/
automatically. For java.util.logging,
you must set the system property to
use this file.
If your write to standard out or standard error, that will automatically get logged as INFO or WARNING.
So, why do you need to use a logging.properties file?
Does this give you some additional control over your logging?
If you want to use more specific logging info, like some DEBUG.
This way you can log more info during development, and you don't need to change your code when you put your code in production.
Personal example: When I code, I log a lot of info ( logging Level FINE, and FINEST). When I send my application to tester, they use DEBUG level. In production (to public) only INFO, WARNING and SEVERE are log.
In conclusion , this give you more control, and you don't have to change any line of code.
For more info about logging in java : here