Tag: Web Container

Install and Run Tomcat on Openshift

Hi,

Nikhil Mone

Nikhil Mone

In this article we will discuss how to run Tomcat server on Openshift using Do It Yourself cartridges.

A lot of developers like to test their code by deploying it to web-containers, such as Tomcat, due to less complexities, less overhead and less files to tweak 🙂

We can use our own customized Tomcat server to achieve a simple web-hosting over OpenShift.

Lets check how ??

Step-1 : We will create a simple application “mytomcatapp” using diy (do it yourself) cartridge, which allows us a lot of tweak options. Run below command from your project directory:

$ rhc app create -a mytomcatapp -t diy0.1 -l youropenshiftaccount@blah.com

Step-2 : Above creates a directory as “mytomcatapp”, navigate inside up to “action_hooks”:

$Project_DIR/.openshift/action_hooks

for eg : /home/userone/mytomcatapp/.openshift/action_hooks

Step-3 : By default diy cartridge has a ruby server installed, which can be stop/start using start and stop scripts, lets do a “ls -ltra” here :

..
[userone@userone action_hooks]$ ls -ltra
total 32
-rwxrwxr-x. 1 userone userone  178 Jul  2 15:03 stop
-rwxrwxr-x. 1 userone userone  295 Jul  2 15:03 start
-rwxrwxr-x. 1 userone userone  257 Jul  2 15:03 pre_build
-rwxrwxr-x. 1 userone userone  186 Jul  2 15:03 post_deploy
-rwxrwxr-x. 1 userone userone  249 Jul  2 15:03 deploy
-rwxrwxr-x. 1 userone userone  264 Jul  2 15:03 build
drwxrwxr-x. 2 userone userone 4096 Jul  2 15:03 .
drwxrwxr-x. 4 userone userone 4096 Jul  2 15:03 ..

Step-4 : Now lets remove stop and start scripts from here :

$ rm stop start

for eg:

..
[userone@userone action_hooks]$ rm stop start
[userone@userone action_hooks]$ ls -ltra
total 24
-rwxrwxr-x. 1 userone userone  257 Jul  2 15:03 pre_build
-rwxrwxr-x. 1 userone userone  186 Jul  2 15:03 post_deploy
-rwxrwxr-x. 1 userone userone  249 Jul  2 15:03 deploy
-rwxrwxr-x. 1 userone userone  264 Jul  2 15:03 build
drwxrwxr-x. 4 userone userone 4096 Jul  2 15:03 ..
drwxrwxr-x. 2 userone userone 4096 Jul  2 15:11 .
[userone@userone action_hooks]$ pwd
/home/userone/tomcat/.openshift/action_hooks

Step-5 : Now recreate stop and start files :

$ touch stop start

for eg :

..
[userone@userone action_hooks]$ touch stop start
[userone@userone action_hooks]$ ls -ltra
total 24
-rwxrwxr-x. 1 userone userone  257 Jul  2 15:03 pre_build
-rwxrwxr-x. 1 userone userone  186 Jul  2 15:03 post_deploy
-rwxrwxr-x. 1 userone userone  249 Jul  2 15:03 deploy
-rwxrwxr-x. 1 userone userone  264 Jul  2 15:03 build
drwxrwxr-x. 4 userone userone 4096 Jul  2 15:03 ..
-rw-rw-r--. 1 userone userone    0 Jul  2 15:12 stop
-rw-rw-r--. 1 userone userone    0 Jul  2 15:12 start
drwxrwxr-x. 2 userone userone 4096 Jul  2 15:12 .

but here we can see the permissions are different from previous ls output, so lets give 775 permission as the earlier scripts had:

..
[userone@userone action_hooks]$ chmod 775 stop start
[userone@userone action_hooks]$ ls -ltra
total 24
-rwxrwxr-x. 1 userone userone  257 Jul  2 15:03 pre_build
-rwxrwxr-x. 1 userone userone  186 Jul  2 15:03 post_deploy
-rwxrwxr-x. 1 userone userone  249 Jul  2 15:03 deploy
-rwxrwxr-x. 1 userone userone  264 Jul  2 15:03 build
drwxrwxr-x. 4 userone userone 4096 Jul  2 15:03 ..
-rwxrwxr-x. 1 userone userone    0 Jul  2 15:12 stop
-rwxrwxr-x. 1 userone userone    0 Jul  2 15:12 start
drwxrwxr-x. 2 userone userone 4096 Jul  2 15:12 .

Step-6 : Once done lets commit the changes to git repository :

..
[userone@userone action_hooks]$ git commit -a -m "removing scripts"
[master e150ea0] removing scripts
2 files changed, 0 insertions(+), 9 deletions(-)

Step-7 : Lets push the changes to Openshift server now :

..
[userone@userone action_hooks]$ git push
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 471 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: Stopping application...
remote: Done
remote: ~/git/tomcat.git ~/git/tomcat.git
remote: ~/git/tomcat.git
remote: Running .openshift/action_hooks/pre_build
remote: Running .openshift/action_hooks/build
remote: Running .openshift/action_hooks/deploy
remote: Starting application...
remote: Done
remote: Running .openshift/action_hooks/post_deploy
To ssh://420ne8xz7pq64949861a99ea941c8ab3@mytomcatapp-mydomain.rhcloud.com/~/git/tomcat.git/
67f5592..e150ea0  master -> master

Step-8 : Let us login to OpenShift server via ssh :

$ ssh 420ne8xz7pq64949861a99ea941c8ab3@mytomcatapp-mydomain.rhcloud.com

From you home directory navigate to : mytomcatapp/data/

$ cd mytomcatapp/data/

Make sure you do it, because on other directories you won’t have write permission.

Step-9 : Now lets download Apache-Tomcat server, directly on OpenShift :

..
[mytomcatapp-mydomain.rhcloud.com data]> wget http://apache.techartifact.com/mirror/tomcat/tomcat-7/v7.0.28/bin/apache-tomcat-7.0.28.tar.gz
--2012-07-02 05:51:42--  http://apache.techartifact.com/mirror/tomcat/tomcat-7/v7.0.28/bin/apache-tomcat-7.0.28.tar.gz
Resolving apache.techartifact.com... 101.153.143.60
Connecting to apache.techartifact.com|101.153.143.60|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7674156 (7.3M) [application/x-gzip]
Saving to: “apache-tomcat-7.0.28.tar.gz”

100%[==================================================================================================================================================================================================>] 7,674,156   60.5K/s   in 3m 5s

2012-07-02 05:54:48 (40.6 KB/s) - “apache-tomcat-7.0.28.tar.gz” saved [7674156/7674156]

Step-10 : unzip the downloaded file :

..
tar zxvf apache-tomcat-7.0.28.tar.gz
..

Step 11 : Once done remove “apache-tomcat-7.0.28.tar.gz” as it will unneccesarily consume disk space.

..
[mytomcatapp-mydomain.rhcloud.com data]> rm -f apache-tomcat-7.0.28.tar.gz
[mytomcatapp-mydomain.rhcloud.com data]> cd apache-tomcat-7.0.28/
[mytomcatapp-mydomain.rhcloud.com apache-tomcat-7.0.28]> ls -ltra
total 124
drwxr-xr-x. 2 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jun 15 03:52 work
drwxr-xr-x. 2 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jun 15 03:52 logs
drwxr-xr-x. 7 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jun 15 03:53 webapps
-rw-r--r--. 1 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3 15557 Jun 15 03:54 RUNNING.txt
-rw-r--r--. 1 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  8826 Jun 15 03:54 RELEASE-NOTES
-rw-r--r--. 1 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  1192 Jun 15 03:54 NOTICE
-rw-r--r--. 1 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3 56812 Jun 15 03:54 LICENSE
drwxr-xr-x. 2 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jun 15 03:54 conf
drwxr-xr-x. 9 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jul  2 06:30 .
drwxr-xr-x. 2 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jul  2 06:30 bin
drwxr-xr-x. 2 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jul  2 06:30 lib
drwxr-xr-x. 2 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jul  2 06:30 temp
drwxr-x---. 3 420ne8xz7pq64949861a99ea941c8ab3 420ne8xz7pq64949861a99ea941c8ab3  4096 Jul  2 06:31 ..

Step-12 : Now navigate to tomcat’s “conf” directory and edit server.xml file as below :

<!--?xml version='1.0' encoding='utf-8'?-->
<!--   Licensed to the Apache Software Foundation (ASF) under one or more   contributor license agreements.  See the NOTICE file distributed with   this work for additional information regarding copyright ownership.   The ASF licenses this file to You under the Apache License, Version 2.0   (the "License"); you may not use this file except in compliance with   the License.  You may obtain a copy of the License at       http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. -->
<!-- Note:  A "Server" is not itself a "Container", so you may not      define subcomponents such as "Valves" at this level.      Documentation at /docs/config/server.html  -->

  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->

  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->

  <!-- Prevent memory leaks due to use of particular java/javax APIs-->

  <!-- Global JNDI resources        Documentation at /docs/jndi-resources-howto.html   -->

    <!-- Editable user database that can also be used by          UserDatabaseRealm to authenticate users     -->

  <!-- A "Service" is a collection of one or more "Connectors" that share        a single "Container" Note:  A "Service" is not itself a "Container",        so you may not define subcomponents such as "Valves" at this level.        Documentation at /docs/config/service.html    -->

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"         maxThreads="150" minSpareThreads="4" />
    -->

    <!-- A "Connector" represents an endpoint by which requests are received          and responses are returned. Documentation at :          Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)          Java AJP  Connector: /docs/config/ajp.html          APR (HTTP/AJP) Connector: /docs/apr.html          Define a non-SSL HTTP/1.1 Connector on port 8080     -->

    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"                port="8080" protocol="HTTP/1.1"                connectionTimeout="20000"                redirectPort="8443" />
    -->
    <!-- Define a SSL HTTP/1.1 Connector on port 8443          This connector uses the JSSE configuration, when using APR, the          connector should be using the OpenSSL style configuration          described in the APR documentation -->
    <!--
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"                maxThreads="150" scheme="https" secure="true"                clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->

    <!-- An Engine represents the entry point (within Catalina) that processes          every request.  The Engine implementation for Tomcat stand alone          analyzes the HTTP headers included with the request, and passes them          on to the appropriate Host (virtual host).          Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->

      <!--For clustering, please take a look at documentation at:           /docs/cluster-howto.html  (simple how to)           /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" />
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords            via a brute-force attack -->

        <!-- This Realm uses the UserDatabase configured in the global JNDI              resources under the key "UserDatabase".  Any edits              that are performed against this UserDatabase are immediately              available for use by the Realm.  -->

        <!-- SingleSignOn valve, share authentication between web applications              Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.              Documentation at: /docs/config/valve.html              Note: The pattern used is equivalent to using pattern="common" -->

Here the changes made are :

1. Server port is changed to 15005 :

<Server port="15005" shutdown="SHUTDOWN">

2. “address=”127.3.45.2” has been added to :

..
[mytomcatapp-mydomain.rhcloud.com conf]> env | grep -i internal
OPENSHIFT_INTERNAL_PORT=8080
OPENSHIFT_INTERNAL_IP=127.3.45.2

3. Changed the AJP connector port as well :

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="15009" protocol="AJP/1.3" redirectPort="8443" />

4. In “Engine name” default host has been changed :

<Engine name="Catalina" defaultHost="127.3.45.2">

5. In host name we will put:

<Host name="mytomcatapp-mydomain.rhcloud.com"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

which is our “application-namespace.rhcloud.com”

Note : OpenShift doesn’t allow allocating ports below 15000, except 8080 and that is by default.

Step-13 : Start tomcat server from bin directory using “startup.sh”

Step-14 : Navigate to the URL :

http://mytomcatapp-mydomain.rhcloud.com/

Step-15 : I know all would be interested to click on “Manager App” tab, but it will ask for credentials 🙂

Edit “tomcat-users.xml” file inside tomcat’s conf directory as below :

..
<!--?xml version='1.0' encoding='utf-8'?-->
<!--   Licensed to the Apache Software Foundation (ASF) under one or more   contributor license agreements.  See the NOTICE file distributed with   this work for additional information regarding copyright ownership.   The ASF licenses this file to You under the Apache License, Version 2.0   (the "License"); you may not use this file except in compliance with   the License.  You may obtain a copy of the License at       http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. -->

<!--   NOTE:  By default, no user is included in the "manager-gui" role required   to operate the "/manager/html" web application.  If you wish to use this app,   you must define such a user - the username and password are arbitrary. -->
<!--
  NOTE:  The sample user and role entries below are wrapped in a comment
  and thus are ignored when reading this file. Do not forget to remove
  <!.. ..> that surrounds them.
-->
<!--
  <role rolename="tomcat" />
  <role rolename="role1" />
  <user username="tomcat" password="tomcat" roles="tomcat" />
  <user username="both" password="tomcat" roles="tomcat,role1" />
  <user username="role1" password="tomcat" roles="role1" />
-->

Here :

<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui"/>

provides us access to “Manager App“, from here you can manage your applications/jvm.

Regards,
Middleware Magic Team 🙂


Accessing “jboss.web:type=*” MBeans Programmatically in JBossAS7.1.1

Hi,

During various builds of JBoss AS7 the MBean access methodology was kee changing, even the JMX subsystem XSD “jboss-as-jmx_1_1.xsd” also changed a lot from JBossAS7.0 till JBossAS7.1.1 Final. So here we are going to see How can we access the JBoss MBeans Remotely & Programatically. Here are the following points which we will notice as part of this article:

Point-1). Accessing MBeans using the JBoss Native Management port 9999 on JBoss AS7.1.1.Final.

Point-2). The jmx subsystem inside our JBoss configuration file like “standalone-full.xml” should look something like following:

        <subsystem xmlns="urn:jboss:domain:jmx:1.1">
            <show-model value="true"/>
             <remoting-connector  use-management-endpoint="true" />
        </subsystem>

Here If the value of “use-management-endpoint” is “true” then this connector will use the management endpoint, otherwise it will use the remoting subsystem endpoint.

Point-3). Here we will also need to make sure that we enable the following System Property in the JBoss Cofiguration file (standalone*.xml) So that JBoss will make the “jboss.web:type=Manager” access available for the remote JMX Clients.

    <system-properties>
        <property name="org.apache.tomcat.util.ENABLE_MODELER" value="true"/>
    </system-properties>

***NOTE***: If you will not add the above System property for your JBoss then JBoss will not expose some of the MBeans which are available as part of “jboss.web:type=*”

Accessing MBeans Programatically Remotely/Locally

Step-1). After enabling the System property org.apache.tomcat.util.ENABLE_MODELER=true on your JBoss, Start your JBoss AS7.1.1 Final like following

     ./standalone.sh  -c standalone-full.xml

You can also start it in a particular Bind address as well.

Step-2). Write a Simple Class “JBossJMXClient.java” inside “/home/userone/JmxDemo/” as following:

import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.*;

public class JBossJMXClient {
    public static void main(String[] args) throws Exception {
        String host = "localhost";  // Your JBoss Bind Address default is localhost
        int port = 9999;  // management-native port

        String urlString ="service:jmx:remoting-jmx://" + host + ":" + port;
        System.out.println("		nnt****  urlString: "+urlString);

        JMXServiceURL serviceURL = new JMXServiceURL(urlString);
        JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceURL, null);
        MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();

        //Invoke on the JBoss AS MBean server
        int count = connection.getMBeanCount();
        System.out.println(count);

        ObjectName objectName=new ObjectName("jboss.web:type=Manager,path=/Log4jDemo,host=default-host");
        Integer sessionMaxAliveTime=(Integer)connection.getAttribute(objectName, "sessionMaxAliveTime");
        Integer maxInactiveInterval=(Integer)connection.getAttribute(objectName, "maxInactiveInterval");
        Integer activeSessions=(Integer)connection.getAttribute(objectName, "activeSessions");
        Integer sessionCounter=(Integer)connection.getAttribute(objectName, "sessionCounter");
        Integer sessionAverageAliveTime=(Integer)connection.getAttribute(objectName, "sessionAverageAliveTime");
        Long processingTime=(Long)connection.getAttribute(objectName, "processingTime");
        Integer sessionIdLength=(Integer)connection.getAttribute(objectName, "sessionIdLength");
        Integer maxActive=(Integer)connection.getAttribute(objectName, "maxActive");
        Integer maxActiveSessions=(Integer)connection.getAttribute(objectName, "maxActiveSessions");
        Integer expiredSessions=(Integer)connection.getAttribute(objectName, "expiredSessions");
        Integer rejectedSessions=(Integer)connection.getAttribute(objectName, "rejectedSessions");

        System.out.println("	maxInactiveInterval     = "+maxInactiveInterval);
        System.out.println("	activeSessions          = "+activeSessions);
        System.out.println("	sessionCounter          = "+sessionCounter);
        System.out.println("	sessionAverageAliveTime = "+sessionAverageAliveTime);
        System.out.println("	sessionAverageAliveTime = "+sessionAverageAliveTime);
        System.out.println("	processingTime          = "+processingTime);
        System.out.println("	sessionIdLength         = "+sessionIdLength);
        System.out.println("	maxActiveSessions       = "+maxActiveSessions);
        System.out.println("	maxActive               = "+maxActive);
        System.out.println("	expiredSessions         = "+expiredSessions);

        jmxConnector.close();
    }
}

/*  Make sure that the following System property is enable in your JBoss

    <system-properties>
        <property name="org.apache.tomcat.util.ENABLE_MODELER" value="true"/>
    </system-properties>
*/

***NOTE***: In the above program we are trying to access various attributes present inside the ObjectName “jboss.web:type=Manager,path=/Log4jDemo,host=default-host” where “Log4jDemo” is the Context-Root of My WebApplication which i wanted to monitor. And th edefault Host-Name is “default-host”, In your case these values might be different so better use the JConsole to connect to JBoss Locally and then get the exact Object name from it.

Step-3). Now oipen a Terminal where we need to set the PATh and CLASSPATH like following:

For UNIX Based Operating System:

export PATH=/home/userone/jdk1.6.0_21/bin:$PATH
export CLASSPATH=/home/userone/jboss-as-7.1.1.Final/bin/client/jboss-client.jar:$CLASSPATH:.:

++++++++++++++++++++++++++++++++
For Windows Based Operating System

set PATH=C:jdk1.6.0_21bin;%PATH%
set CLASSPATH=c:jboss-as-7.1.1.Finalbinclientjboss-client.jar;%CLASSPATH%;.;

***NOTE***: It is must that your JMX Client should include the “jboss-client.jar” in it’s classpath as above.

Step-4). Now compile and run the above program:

[userone@localhost JmxDemo]$ javac JBossJMXClient.java
[userone@localhost JmxDemo]$ java JBossJMXClient

	****  urlString: service:jmx:remoting-jmx://localhost:9999

May 20, 2012 9:54:12 AM org.xnio.Xnio <clinit>
INFO: XNIO Version 3.0.3.GA
May 20, 2012 9:54:12 AM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.0.3.GA
May 20, 2012 9:54:12 AM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 3.2.3.GA
243
	maxInactiveInterval     = 1800
	activeSessions          = 3
	sessionCounter          = 3
	sessionAverageAliveTime = 0
	sessionAverageAliveTime = 0
	processingTime          = 0
	sessionIdLength         = 18
	maxActiveSessions       = -1
	maxActive               = 3
	expiredSessions         = 0

Accessing MBeans using JConsole Locally

As mentioned earlier that If you will not add the above System property (org.apache.tomcat.util.ENABLE_MODELER=true) for your JBoss then JBoss will not expose some of the MBeans which are available as part of “jboss.web:type=*” So after enabling it Just start the Server and Open the “$JAVA_HOME/bin/jconsole” . jconsole will be able to detect any locally running JAVA process just connect to your JBoss process through it then you will be able to see the following kind of JBoss MBeans inside jconsole:

JConsole_WebContainerMBean_Access_JBossAS711

.
.
Thanks 🙂
Middleware Magic Team


Fetching Client IP Address and Header information in JBoss AS7 access log

Hi,

Many times and usually in production environments it is desired to generate the “access.log” file separately for different web applications so that we can monitor how the users are accessing the application, from what all IP Addresses/Hostnames the clients are accessing the application. We also want to monitor sometimes that how much time was taken by JBoss in order to process a clients request in milliseconds or in seconds.

The most desired things the cookie, incoming header, outgoing response headers, the Session or something else in the ServletRequest. So to fulfil all these requirements JBoss provides a valve “org.apache.catalina.valves.AccessLogValve” which can be enabled at an individual application level as well with the help of jboss specific deployment descriptor “jboss-web.xml”.

The AccessLogValve creates log files in the same format as those created by standard web servers. These logs can later be analyzed by standard log analysis tools to track page hit counts, user session activity, and so on. The files produces by this Valve are rolled over nightly at midnight. More informations about this Valve can be found in the following link: http://tomcat.apache.org/tomcat-5.5-doc/config/valve.html#Access_Log_Valve
Some of the useful patterns which can be used along with this valve are following:

%a - Remote IP address
%A - Local IP address
%b - Bytes sent, excluding HTTP headers, or '-' if zero
%B - Bytes sent, excluding HTTP headers
%h - Remote host name (or IP address if resolveHosts is false)
%H - Request protocol
%l - Remote logical username from identd (always returns '-')
%m - Request method (GET, POST, etc.)
%p - Local port on which this request was received
%q - Query string (prepended with a '?' if it exists)
%r - First line of the request (method and request URI)
%s - HTTP status code of the response
%S - User session ID
%t - Date and time, in Common Log Format
%u - Remote user that was authenticated (if any), else '-'
%U - Requested URL path
%v - Local server name
%D - Time taken to process the request, in millis
%T - Time taken to process the request, in seconds
%I - current request thread name (can compare later with stacktraces)

Step1). Create a directory somewhere in your file system like “/home/userone/DemoRemoteAddrValve”

Step2). Now create a directory with name “src” inside the “/home/userone/DemoRemoteAddrValve” and then place the following kind of “web.xml” file inside the “src” folder.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

        <!-- There is nothing much to write here for this demonstration. -->

</web-app>

Step3). Now write a JBoss specific we application deployment descriptor “jboss-web.xml” file inside “/home/userone/DemoRemoteAddrValve/src” directory as following:

<jboss-web>
 <valve>
   <class-name>org.apache.catalina.valves.AccessLogValve</class-name>
     <param>
        <param-name>prefix</param-name>
        <param-value>TestAccessLogValveWebApp</param-value>
     </param>
     <param>
        <param-name>suffix</param-name>
        <param-value>.log</param-value>
     </param>
     <param>
        <param-name>pattern</param-name>
        <param-value>%h %l %u %t "%r" %s %b %{User-Agent}i %{JSESSIONID}c</param-value>
     </param>
     <param>
        <param-name>directory</param-name>
        <param-value>../standalone/log</param-value>
     </param>
     <param>
        <param-name>resolveHosts</param-name>
        <param-value>false</param-value>
     </param>
   </valve>
</jboss-web>

NOTE: There is also support to write information from the cookie, incoming header, outgoing response headers, the Session or something else in the ServletRequest. It is modeled after the apache syntax:

%{xxx}i for incoming request headers
%{xxx}o for outgoing response headers
%{xxx}c for a specific request cookie
%{xxx}r xxx is an attribute in the ServletRequest
%{xxx}s xxx is an attribute in the HttpSession

Example:

     <param>
        <param-name>pattern</param-name>
        <param-value>%h %l %u %t "%r" %s %b %{User-Agent}i %{JSESSIONID}c</param-value>
     </param>

So the above pattern will also display the JSESSIONID cookie information and the User-Agent (clients browser) informations as well.

Step4). Now we will simply write a Simle JSP “index.jsp” So that we can see as soon as user will hit 10-15 request to this application the access logging will happen. Place the following JSP file inside “/home/userone/DemoRemoteAddrValve/src”

<html>
<body bgcolor=maroon>
<center><h1> Welcome Page </h1>
<font color=white>
    <h1> Check the "/home/userone/jboss-as-7.0.1.Final/standalone/log" directory</h1>
    <h3>The access log for the application might be created with the name specified in the jboss-web.xml file. </h3>
</font>
</body>
</html>

NOTE: The access log data is not immediately written in the access log …it is buffered in order to improve the performance so hit the page atleast 10-15 times and then check the access log.

Step5). Now we will write a Simple ANT Build script “build.xml” file to build the WAR file and then to deploy the application on JBoss AS7. place the following “build.xml” file inside “/home/userone/DemoRemoteAddrValve”

<project name="SingletonStartupService" default="deploy">
<property name="jboss.home" value="/home/jsenshar/JBoss_All/jboss-as-7.0.1.Final" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="output.dir" value="build" />
<property name="src.dir" value="src" />
<property name="war.name" value="TestAccessLogValveWebApp.war" />

   <path id="jboss.classpath">
     <fileset dir="${jboss.module.dir}">
        <include name="**/*.jar"/>
     </fileset>
   </path>

        <target name="init">
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
        </target>

        <target name="build" depends="init">
           <copy todir="${tmp.dir}/WEB-INF">
                <fileset dir="${src.dir}/">
                  <include name="web.xml"/>
                  <include name="jboss-web.xml"/>
                </fileset>
           </copy>
          <mkdir dir="${tmp.dir}/WEB-INF/lib" />
          <copy file="${src.dir}/index.jsp" tofile="${tmp.dir}/index.jsp"/>
          <copy file="${src.dir}/jbossweb-7.0.1.Final.jar" tofile="${tmp.dir}/WEB-INF/lib/jbossweb-7.0.1.Final.jar"/>
          <jar jarfile="${tmp.dir}/${war.name}" basedir="${tmp.dir}" compress="true" />
          <copy file="${tmp.dir}/${war.name}" tofile="${output.dir}/${war.name}"/>
          <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}"/>
          </delete>
        </target>

        <target name="deploy" depends="build">
            <echo message="*******************  Deploying the WAR file ${war.name} *********************" />
            <echo message="********** ${output.dir}/${war.name} to ${jboss.home}/standalone/deployments **********" />
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${war.name}"/>
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />
        </target>
</project>

Step6). Now open a Shell prompt and then set the PATH pointing to the ANT bin directory and the JDK bin directory … like following and the just run the “ant” command:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH

OR

For Windows Based OS:
set PATH=C:jdk1.6.0_21bin:C:org.apache.ant_1.6.5bin:%PATH%

[userone@localhost TestEE6Feature]$ ant
Buildfile: build.xml

init:
   [delete] Deleting directory /home/userone/TestAccessLogValve/build
    [mkdir] Created dir: /home/userone/TestAccessLogValve/build
    [mkdir] Created dir: /home/userone/TestAccessLogValve/tmp

build:
     [copy] Copying 2 files to /home/userone/TestAccessLogValve/tmp/WEB-INF
    [mkdir] Created dir: /home/userone/TestAccessLogValve/tmp/WEB-INF/lib
     [copy] Copying 1 file to /home/userone/TestAccessLogValve/tmp
     [copy] Copying 1 file to /home/userone/TestAccessLogValve/tmp/WEB-INF/lib
      [jar] Building jar: /home/userone/TestAccessLogValve/tmp/TestAccessLogValveWebApp.war
     [copy] Copying 1 file to /home/userone/TestAccessLogValve/build
   [delete] Deleting 5 files from /home/userone/TestAccessLogValve/tmp
   [delete] Deleted 3 directories from /home/userone/TestAccessLogValve/tmp

deploy:
     [echo] *******************  Deploying the WAR file TestAccessLogValveWebApp.war *********************
     [echo] ********** build/TestAccessLogValveWebApp.war to /home/userone/jboss-as-7.0.1.Final/standalone/deployments **********
     [copy] Copying 1 file to /home/userone//deployments
     [echo] *******************  Deployed Successfully   *********************

BUILD SUCCESSFUL
Total time: 0 seconds

NOTE: The only change you will need to make is to change the “jboss.home” value in the above ANT build.xml file to point to your own JBoss AS& directory.

Step7). Start the JBoss AS& like following from inside your “/home/userone/jboss-as-7.0.1.Final/bin” directory.

   ./standalone.sh --server-config standalone-preview.xml

NOTE: Due to some reasons if you find that access log is not getting generated after deploying/redeploying your application then  Undeploy the application then clear the “data” and “tmp” directory and then freshly deploy your application. or check the path of the access log which you entered is correct or not?

<param>
<param-name>directory</param-name>
<param-value>../standalone/log</param-value>
</param>

Enabling Access Log Valve at Whole JBossAS 7.1.2 level

Similarly if you want to configure Access Log Valve at whole server level then you can add the tag inside the “web” subsystem of your server. AS 7.1.1 or AS 7.1.2

[standalone@localhost:9999 /] /subsystem=web/virtual-server=default-host/access-log=configuration:add(pattern="%h %l %u %t "%r" %s %b %{User-Agent}i %{JSESSIONID}c")
{"outcome" => "success"}


[standalone@localhost:9999 /] /subsystem=web/virtual-server=default-host/access-log=configuration/directory=configuration:add(path="TestAccessLog", relative-to="jboss.server.log.dir")
{"outcome" => "success"}


[standalone@localhost:9999 /] /subsystem=web/virtual-server=default-host/access-log=configuration/:read-resource(recursive=true,proxies=false,include-runtime=false,include-defaults=true)
{
    "outcome" => "success",
    "result" => {
        "extended" => false,
        "pattern" => "%h %l %u %t "%r" %s %b %{User-Agent}i %{JSESSIONID}c",
        "prefix" => false,
        "resolve-hosts" => false,
        "rotate" => true,
        "directory" => {"configuration" => {
            "path" => "TestAccessLog",
            "relative-to" => "jboss.server.log.dir"
        }}
    }
}

It will generate the following kind of configuration inside your “web” subsystem:

        <subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
            <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
            <virtual-server name="default-host" enable-welcome-root="true">
                <alias name="localhost"/>
                <alias name="example.com"/>

                <access-log pattern="%h %l %u %t "%r" %s %b %{User-Agent}i %{JSESSIONID}c">
                    <directory path="TestAccessLog"/>
                </access-log>

            </virtual-server>
        </subsystem>

.
.
Thanks
Middleware Magic Team


Copyright © 2010-2012 Middleware Magic. All rights reserved. |