View Javadoc

1   /*
2    * Copyright 2000-2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.jetspeed.services.portletstats;
18  
19  // turbine stuff
20  import org.apache.turbine.util.RunData;
21  import org.apache.turbine.services.TurbineServices;
22  import org.apache.turbine.services.TurbineBaseService;
23  import org.apache.turbine.services.InitializationException;
24  import org.apache.turbine.services.resources.ResourceService;
25  
26  // jetspeed stuff
27  import org.apache.jetspeed.portal.Portlet;
28  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
29  import org.apache.jetspeed.services.logging.JetspeedLogger;
30  
31  // javax stuff
32  import javax.servlet.ServletConfig;
33  import javax.servlet.http.HttpServletRequest;
34  
35  // java stuff
36  import java.text.MessageFormat;
37  import java.text.SimpleDateFormat;
38  import java.util.Date;
39  
40  /***
41   * Simple implementation of the PortletStatsService. This implementation
42   * uses <A HREF="http://httpd.apache.org/docs/logs.html">Apache Common Log Format (CLF)</A> as its default log format.
43   * This format uses the following pattern string: "%h %l %u %t \"%r\" %>s %b",
44   * where:
45   * <UL>
46   * <LI><B>%h</B> - remote host</LI>
47   * <LI><B>%l</B> - remote log name</LI>
48   * <LI><B>%u</B> - remote user</LI>
49   * <LI><B>%t</B> - time in common log time format</LI>
50   * <LI><B>%r</B> - first line of request</LI>
51   * <LI><B>%s</B> - status (either 200 or 401)</LI>
52   * <LI><B>%b</B> - bytes sent (always "-" for no bytes sent). Optionally, portlet load time may be logged (see logLoadTime property)</LI>
53   * </UL>
54   * <P>
55   * Here's an example log entry:
56   * <P>
57   * <CODE>127.0.0.1 - turbine [26/Aug/2002:11:44:40 -0500] "GET /jetspeed/DatabaseBrowserTest HTTP/1.1" 200 -</CODE>
58   * <P>
59   * TODO:
60   * <UL>
61   * <LI>Statistics cache (by portlet and by user)</LI>
62   * <LI>Portlet exclusion</LI>
63   * <LI>Configurable format pattern</LI>
64   * </UL>
65   * 
66   * @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a>
67   * @version $Id: JetspeedPortletStatsService.java,v 1.6 2004/04/06 21:34:01 morciuch Exp $
68   */
69  public class JetspeedPortletStatsService extends TurbineBaseService
70      implements PortletStatsService
71  {
72      /***
73       * Static initialization of the logger for this class
74       */    
75      protected static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(JetspeedPortletStatsService.class.getName());
76      
77      /***
78       * The default log format pattern string to use with the following elements:
79       * <OL START="0">
80       * <LI>remote address</LI>
81       * <LI>always "-"</LI>
82       * <LI>user name</LI>
83       * <LI>timestamp</LI>
84       * <LI>request method</LI>
85       * <LI>context</LI>     
86       * <LI>portlet name</LI>
87       * <LI>request protocol</LI>
88       * <LI>status code</LI>
89       * <LI>always "-" unless logLoadTime is true</LI>
90       * </OL>
91       */
92      protected static final String defaultLogFormat = "{0} {1} {2} [{3}] \"{4} {5}/{6} {7}\" {8} {9}";
93  
94      /***
95       * Logging enabled flag. If TRUE, the logging will occur. To improve performance,
96       * the application should use isEnabled() method before calling logAccess().
97       */
98      private boolean enabled = false;
99  
100     /***
101      * Date format to use in the log entry. Should conform to standard
102      * format used by the SimpleDateFormat class.
103      */
104     protected String dateFormat = null;
105 
106     /*** Date formatter */
107     protected SimpleDateFormat formatter = null;
108 
109     /*** Log portlet load time instead of bytes sent (which is always zero) */
110     protected boolean logLoadTime = false;
111 
112     /***
113      * This is the early initialization method called by the 
114      * Turbine <code>Service</code> framework
115      */
116     public void init( ServletConfig conf ) throws InitializationException
117     {
118 
119         ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
120                                                      .getResources(PortletStatsService.SERVICE_NAME);
121 
122         this.enabled = serviceConf.getBoolean("enabled");
123         this.dateFormat = serviceConf.getString("dateFormat", "dd/MM/yyyy:hh:mm:ss z");
124         this.formatter = new SimpleDateFormat(this.dateFormat);
125         this.logLoadTime = serviceConf.getBoolean("logLoadTime", false);
126         
127         setInit(true);
128 
129     }
130             
131     /***
132      * @see org.apache.jetspeed.services.portletstats.PortletStatsService#isEnabled
133      */
134     public boolean isEnabled()
135     {
136         return this.enabled;
137     }
138 
139     /***
140      * @see org.apache.jetspeed.services.portletstats.PortletStatsService#setEnabled
141      */
142     public boolean setEnabled(boolean state)
143     {
144         boolean oldState = this.enabled;
145         this.enabled = state;
146 
147         return oldState;
148     }
149 
150     /***
151      * @see org.apache.jetspeed.services.portletstats.PortletStatsService#logAccess
152      */
153     public void logAccess(RunData data, Portlet portlet, String statusCode, long time)
154     {
155         
156         if (!this.isEnabled())
157         {
158             return;
159         }
160         
161         try 
162         {
163             logger.info(this.getLogMessage(data, portlet, statusCode, time));
164         }
165         catch (Exception e)
166         {
167             logger.error("Exception", e);
168         }
169     }
170 
171     /***
172      * Formats log message
173      * 
174      * @param data
175      * @param portlet
176      * @param statusCode
177      * @param time
178      * @return Formatted message
179      * @exception Exception
180      */
181     protected String getLogMessage(RunData data, Portlet portlet, String statusCode, long time) 
182     throws Exception
183     {        
184  
185         HttpServletRequest req = data.getRequest();
186         Object[] args = {
187             req.getRemoteAddr(),
188             "-",
189             data.getUser().getUserName(),
190             this.formatter.format(new Date()),
191             req.getMethod(),
192             req.getContextPath(),
193             portlet.getName(),
194             req.getProtocol(),
195             statusCode,
196             this.logLoadTime == true ? String.valueOf(time) : "-"
197         }; 
198 
199         return MessageFormat.format(defaultLogFormat, args).toString();
200 
201     }
202 
203     /***
204      * Formats log message using default load time
205      * 
206      * @param data
207      * @param portlet
208      * @param statusCode
209      */
210     public void logAccess(RunData data, Portlet portlet, String statusCode) 
211     {
212         logAccess(data, portlet, statusCode, 0);
213     }
214     
215 }
216