View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.monitoring.servlet;
19  
20  import javax.servlet.ServletContext;
21  import javax.servlet.ServletContextEvent;
22  import javax.servlet.ServletContextListener;
23  
24  import org.apache.commons.monitoring.Monitor;
25  import org.apache.commons.monitoring.Monitoring;
26  import org.apache.commons.monitoring.Repository;
27  import org.apache.commons.monitoring.Unit;
28  import org.apache.commons.monitoring.impl.repositories.DefaultRepository;
29  import org.apache.commons.monitoring.listeners.HistorizedRepositoryDecorator;
30  
31  /**
32   * A Servlet Context Listener to configure Monitoring, used to setup optional
33   * monitoring features
34   * <p>
35   * To enable repository historization, set the servlet context parameter
36   * <tt>org.apache.commons.monitoring.History</tt> using the format :
37   * <tt>[historization period][unit]:[size]</tt>
38   * <p>
39   * for example, to setup a 30 items history of 10 minutes periods  :
40   * <pre>
41   *  &lt;context-param&gt;
42   *  &lt;description&gt;enable monitoring history&lt;/description&gt;
43   *  &lt;param-name&gt;org.apache.commons.monitoring.History&lt;/param-name&gt;
44   *  &lt;param-value&gt;10min:30&lt;/param-value&gt;
45   *  &lt;/context-param&gt;
46   * </pre>
47   *
48   * </p>
49   *
50   * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
51   */
52  public class MonitoringListener
53      implements ServletContextListener
54  {
55  
56      public static final String HISTORY = "org.apache.commons.monitoring.History";
57  
58      public static final String HISTORY_PERIOD = "org.apache.commons.monitoring.History.period";
59  
60      public static final String HISTORY_SIZE = "org.apache.commons.monitoring.History.size";
61  
62      /**
63       * {@inheritDoc}
64       *
65       * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
66       */
67      public void contextInitialized( ServletContextEvent event )
68      {
69          ServletContext sc = event.getServletContext();
70          Repository repository = createRepository( sc );
71  
72          String history = sc.getInitParameter( HISTORY );
73          if ( history != null )
74          {
75              repository = setupHistory( repository, history );
76          }
77  
78          sc.setAttribute( ServletContextUtil.REPOSITORY_KEY, repository );
79          Monitoring.setRepository( repository );
80      }
81  
82      /**
83       * Create the repository to be used in this web application.
84       * <p>
85       * User can override this method to change the repository instanciation strategy and/or to
86       * supply a custom implementation.
87       * @param sc
88       * @return
89       */
90      protected Repository createRepository( ServletContext sc )
91      {
92          Repository repository;
93          String name = sc.getInitParameter( ServletContextUtil.REPOSITORY_KEY );
94          if ( name != null )
95          {
96              try
97              {
98                  @SuppressWarnings( "unchecked" )
99                  Class repositoryClass = Class.forName( name );
100                 if ( !Repository.class.isAssignableFrom( repositoryClass ) )
101                 {
102                     throw new IllegalStateException( "The class " + name + " does not implements "
103                         + Repository.class.getName() );
104                 }
105                 repository = (Repository) repositoryClass.newInstance();
106             }
107             catch ( ClassNotFoundException e )
108             {
109                 throw new IllegalStateException( "The repository class name " + name + " is not a valid class" );
110             }
111             catch ( InstantiationException e )
112             {
113                 throw new IllegalStateException( "Failed to create repository instance from class " + name );
114             }
115             catch ( IllegalAccessException e )
116             {
117                 throw new IllegalStateException( "Failed to create repository instance from class " + name );
118             }
119         }
120         else
121         {
122             repository = new DefaultRepository();
123         }
124         return repository;
125     }
126 
127     /**
128      * Setup the historization feature on the repository
129      *
130      * @param repository the (observable) repository to historize
131      * @param history the historization configuration, in format
132      * [period][unit]:[size]
133      * @return
134      */
135     protected Repository setupHistory( Repository repository, String history )
136     {
137         Repository.Observable observable = (Repository.Observable) repository;
138         int idx = history.indexOf( ':' );
139         char[] ch = history.toCharArray();
140         int period = 0;
141         for ( int i = 0; i < idx; i++ )
142         {
143             if ( Character.isDigit( ch[i] ) )
144                 continue;
145             period = Integer.parseInt( history.substring( 0, i ) );
146             String unit = history.substring( i, idx );
147             if ( unit != null )
148             {
149                 Unit u = Unit.NANOS.getDerived( unit );
150                 period *= u.getScale() / Unit.MILLIS.getScale();
151                 break;
152             }
153         }
154 
155         int size = Integer.parseInt( history.substring( idx + 1 ) );
156         repository = new HistorizedRepositoryDecorator( period, size, observable );
157         return repository;
158     }
159 
160     /**
161      * {@inheritDoc}
162      *
163      * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
164      */
165     public void contextDestroyed( ServletContextEvent event )
166     {
167         // TODO Auto-generated method stub
168 
169     }
170 }