How to retrieve path of catalina.out in java program? - java

I need to get the path of catalina.out file which is configured in the logging.properties.
Is there a way to retrieve the property "1catalina.org.apache.juli.FileHandler.directory" via java without knowing the path to the properties file?

If I have understood you correctly, then you want to read an attribute of the Tomcat logging.properties file. As you can see here in the Tomcat FAQ for Logging, java.util.logging.config.file is used to define the path to the property file.
You can then retrieve this path via Java System Properties:
String pathLogProps = System.getProperty("java.util.logging.config.file");
Properties properties = new Properties();
try {
properties.load(new FileInputStream(pathLogProps));
System.out.println(prop.getProperty("database"));
} catch (IOException ex) {
ex.printStackTrace();
}
If this is not set, I would follow the hints from the Apache Tomcat 7 Logging Documentation:
JULI is enabled by default, and supports per classloader
configuration, in addition to the regular global java.util.logging
configuration. This means that logging can be configured at the
following layers:
Globally. That is usually done in the ${catalina.base}/conf/logging.properties file. The file is specified
by the java.util.logging.config.file System property which is set by
the startup scripts.
If it is not readable or is not configured, the default is to use the ${java.home}/lib/logging.properties file in the JRE. In the web
application. The file will be WEB-INF/classes/logging.properties
Per default the path to the logging.properties file should be available over the environment variable catalina.base, respectively CATALINA_BASE.

The file catalina.out is specified neither in any system property, nor is is specified in logging.properties (take a look, it isn't there).
Instead, catalina.out is created by the launching script's shell-based output redirection from within bin/catalina.sh (or bin/catalina.bat). That means that this file is only available if you have launched Tomcat using those scripts, or scripts that emulate this behavior. For example, if you use jsvc on a *NIX platform, or the Tomcat Windows Service, then the file logs/catalina.out does not get created (at least not by default).
If you want to take a peek to see if the file exists, you can bet on it being in $CATALINA_BASE/logs/catalina.out. Recent versions of Tomcat define the catalina.base system property so you can easily take a look like this:
File catalinaOut = new File(System.getProperty("catalina.base"), "logs/catalina.out");
if(catalinaOut.exists())
{
// Do whatever you want
}

Related

Are there other ways to provide `-D` java configs?

I have a usecase to provide a logging.properties file to change the log levels. In logging frameworks like, slf4j-simple, we can directly provide the properties file in resources and it will pick it up. But when using slf4j-jdk14 we need to provide the properties file path as a run config.
java -Djava.util.logging.config.file=logging.properties -jar test.jar
I need a way to provide this -Djava.util.logging.config.file=logging.properties config to the jar in another way.
There is also an option as follows,
static {
System.setProperty("java.util.logging.config.file",
"logging.properties");
}
But I want to know, if there is a way to provide this config to jar in any other ways. Maybe specifying this config in another config file which would be automatically picked up.

Different properties files on the same server

We have a database library that gets the connection information (user, host, etc) from a properties file. This file can be a config.properties file located in the classpath, or next to the execution jar or can be passed as an argument -Dproperties=/path/to/myConfig.properties.
We also have several applications that use this library, so each one has its own config.properties file used in its own execution.
But now I'm creating two web applications that use the same library. So, if I deploy them in Tomcat (war file), I have two options (to my knowledge):
1.- Include each config inside the WAR file. But with this, every time I need to tweak something in the config.properties I'll have to repack the war.
2.- Pass the -Dproperties parameter as an execution argument of Tomcat. But different war deployments will have to share the same properties file.
Is there a way around this?
Can I pass the -D argument to a specific deployment in Tomcat (or any other server)?
PS: This is one of the scenarios we have, but is not constraint to database connection info. We have other libraries that get parameters through config.properties file.
EDIT: I want to be able to have different config.properties file for each deployment. Not the same properties shared among them.
I think I found a way around using self contained webserver inside the application, like Jetty.
We've a similar requirement in which we share a common property file between different applications deployed into JBoss EAP server.
In $JBOSS_HOME/bin/standalone.conf file you can add configuration file path as below:
JAVA_OPTS="$JAVA_OPTS -DCONFIG_LOCATION=/external/config/configuration.properties"
Start the server with above specified property and within your application you can read this property file with apache commons-configuration api as below:
try {
props = new PropertiesConfiguration(System.getProperty("CONFIG_LOCATION"));
FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
// Delay 30s
// strategy.setRefreshDelay(30000);
props.setReloadingStrategy(strategy);
} catch (ConfigurationException e) {
e.printStackTrace();
}
With this reload strategy you can change your properties while your server is running. Also you can specify the interval after which all properties specified in the external file needs to be refreshed within your application without bouncing it. Hope this helps!
You can create an environment variable whose value will be the path where the properties file are located. Later use this environment variable will creating bean for property placeholder config.
for UNIX, you can add in your bash profile file
export CONF_DIR=/path/to/conf
And in spring context file, add this
<context:property-placeholder
location="file:///${CONF_DIR}/path/myConfig1.properties,
file:///${CONF_DIR}/path/myConfig2.properties"
properties-ref="applicationDefaultProperties" ignore-resource-not-found="false"
ignore-unresolvable="false"/>
So, when you want to change any thing in the properties file, you can change at one location, and then restart the application to load the new values in your app.
So, if your config file is this
db.user=username
db.password=password
Inside java class, you can use the keys as like this
#Value("${db.user")
private String username;
#Value("${db.password")
private String password;
The solution I found for my problem is using an embedded web server in my application. In my case, I'm using Jetty.
Now I pack my application as an executable jar and pass the system parameters as -D arguments and they live inside the instance of the application.
Like this:
java -Dproperties=config.properties -jar java_app_with_embedded_server.jar

Set custom property in Tomcat7

We are running our application using Tomcat-7 in Windows environment. We are using Shibboleth IDP for our application, due to this we need to set system property at the container level to identify one new property called "idp.home". So we found that the property can be set in "catalina.properties". We set it and it was running successfully by using "idp.home" property but the problem is that if we use the same compiled war file in another machine, the property "idp.home" is not working.
cataline.properties
idp.home=../../IdP
Structure:
Build --> IdP
--> tomcat-->conf-->catalina.properties
Queries:
1) Is custom property "idp.home" cached in tomcat some where?
2) do we need to set "idp.home" property in any file along with the "catalina.properties" in tomcat.
3) Is there any other way to inform tomcat about "idp.home"?
Thanks in advance.
We can pass system properties with the -D parameter as VM arguments to tomcat, for example "-Dmy.prop.name=value"
or
Place system properties in a property file and specify the path of the property file in VM arguments, for example -Dcom.propertyfiles="path of the property File"

How to reference ${catalina.base} in logback.groovy config?

I am trying to deploy a webapp that uses logback's groovy config files.
I saw that in xml files you can reference ${catalina.base}
Is there a way to reference that from logback.groovy? I want a reference to tomcat home or logs folder. I want it to work even if I don't have the environment variable set.
If I write it as is I get "No such property: catalina"
I am trying to make my logs go to tomcat/logs/... regardless of the hostname. I want to make it webapp specific, not in tomcat/conf/
catalina.base is a system property which is set by Tomcat startup scripts (catalina.sh, catalina.bat).
When working with logback's groovy config files you can simply read the value of this system property into a variable and use it, for example:
def catalinaBase = System.properties['catalina.base']
appender("FILE", FileAppender) {
file = "${catalinaBase}/mylog.log"
...
}

java.util.logging with Websphere

I created a dynamic web project using IBM Rational Application Developer (RAD). I used java.util.logging as the logging framework. I put the logging.properties in WEB-INF/classes directly.
The problem which I am facing is, the application could not load the logging.properties even I put it in the WEB-INF/classes. I add the following generic JVM arguments in the WebSphere Application Server Administrator's Console
-Djava.util.logging.config.file="logging.properties"
I add the following code snippet in the servlet init method.
Properties prop = System.getProperties();
prop.setProperty("java.util.logging.config.file", "logging.properties");
System.out.println("Is file exists " + file.exists());
try {
LogManager.getLogManager().readConfiguration();
} catch (IOException ex) {
ex.printStackTrace();
}
I off the console level debug in logging.properties, so I should not get the logging in console. But currently I am getting the logs in console not in log files which I mentioned in logging.properits.
logging.properties
#------------------------------------------
# Handlers
#-----------------------------------------
handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler
# Default global logging level
.level=ALL
# ConsoleHandler
java.util.logging.ConsoleHandler.level=OFF
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
# FileHandler
java.util.logging.FileHandler.level=FINE
# Naming style for the output file:
java.util.logging.FileHandler.pattern=${SERVER_LOG_ROOT}/nyllogs/loadData.log
# Name of the character set encoding to use
java.util.logging.FileHandler.encoding=UTF8
# Limiting size of output file in bytes:
java.util.logging.FileHandler.limit=25000000
# Number of output files to cycle through
java.util.logging.FileHandler.count=2
# Style of output (Simple or XML):
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
Please let me know why the application couldnt pick up the logging.properties file?
In a WebSphere server, the effect of what you are trying to do would be to change the logging configuration not only of the application, but the entire server. Since WebSphere itself uses java.util.logging, this would mean that everything that is logged internally by WebSphere goes to the same file as the application logs. That would be pointless because then you may as well use the standard WebSphere log files (SystemOut.log and trace.log).
In addition, since WebSphere installs its own LogHandler, it is likely that it will forbid usage of the readConfiguration() method.
Read the configuration from an inputstream using readConfiguration(is). Your code sets a property with relative path but the JVM cannot look into it.
Properties prop = System.getProperties();
prop.setProperty("java.util.logging.config.file", "logging.properties");
Calling the readConfiguration() method without arguments only reloads the properties, which may not be loaded since your path is relative.
public void readConfiguration()
throws IOException,SecurityException
Reinitialize the logging properties and reread the logging configuration.
Use an absolute path for the property or pass an Inputstream. Here's an example loading the properties from a file and using an InputStream.

Categories

Resources