001
014
015 package com.liferay.portal.servlet.filters.monitoring;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.messaging.DestinationNames;
020 import com.liferay.portal.kernel.messaging.MessageBusUtil;
021 import com.liferay.portal.kernel.monitoring.RequestStatus;
022 import com.liferay.portal.kernel.monitoring.statistics.DataSampleThreadLocal;
023 import com.liferay.portal.kernel.servlet.HttpHeaders;
024 import com.liferay.portal.kernel.util.AutoResetThreadLocal;
025 import com.liferay.portal.kernel.util.GetterUtil;
026 import com.liferay.portal.kernel.util.ParamUtil;
027 import com.liferay.portal.kernel.util.WebKeys;
028 import com.liferay.portal.model.Layout;
029 import com.liferay.portal.monitoring.statistics.portal.PortalRequestDataSample;
030 import com.liferay.portal.monitoring.statistics.service.ServiceMonitorAdvice;
031 import com.liferay.portal.service.LayoutLocalServiceUtil;
032 import com.liferay.portal.servlet.filters.BasePortalFilter;
033 import com.liferay.portal.util.PortalUtil;
034 import com.liferay.portal.util.PropsValues;
035 import com.liferay.portlet.MonitoringPortlet;
036
037 import java.io.IOException;
038
039 import java.lang.reflect.Method;
040
041 import java.util.concurrent.atomic.AtomicInteger;
042
043 import javax.servlet.FilterChain;
044 import javax.servlet.ServletException;
045 import javax.servlet.http.HttpServletRequest;
046 import javax.servlet.http.HttpServletResponse;
047
048
052 public class MonitoringFilter extends BasePortalFilter {
053
054 public static boolean isMonitoringPortalRequest() {
055 return _monitoringPortalRequest;
056 }
057
058 public static void setMonitoringPortalRequest(
059 boolean monitoringPortalRequest) {
060
061 _monitoringPortalRequest = monitoringPortalRequest;
062 }
063
064 @Override
065 public boolean isFilterEnabled() {
066 if (!super.isFilterEnabled()) {
067 return false;
068 }
069
070 if (!_monitoringPortalRequest &&
071 !MonitoringPortlet.isMonitoringPortletActionRequest() &&
072 !MonitoringPortlet.isMonitoringPortletEventRequest() &&
073 !MonitoringPortlet.isMonitoringPortletRenderRequest() &&
074 !MonitoringPortlet.isMonitoringPortletResourceRequest() &&
075 !ServiceMonitorAdvice.isActive()) {
076
077 return false;
078 }
079
080 return true;
081 }
082
083 protected int decrementProcessFilterCount() {
084 AtomicInteger processFilterCount = _processFilterCount.get();
085
086 return processFilterCount.decrementAndGet();
087 }
088
089 protected long getGroupId(HttpServletRequest request) {
090 long groupId = ParamUtil.getLong(request, "groupId");
091
092 if (groupId > 0) {
093 return groupId;
094 }
095
096 Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
097
098 if (layout != null) {
099 return layout.getGroupId();
100 }
101
102 long plid = ParamUtil.getLong(request, "p_l_id");
103
104 if (plid > 0) {
105 try {
106 layout = LayoutLocalServiceUtil.getLayout(plid);
107
108 groupId = layout.getGroupId();
109 }
110 catch (Exception e) {
111 if (_log.isDebugEnabled()) {
112 _log.debug("Unable to retrieve layout " + plid, e);
113 }
114 }
115 }
116
117 return groupId;
118 }
119
120 protected String getRemoteUser(HttpServletRequest request) {
121 String remoteUser = request.getRemoteUser();
122
123 if (remoteUser == null) {
124 remoteUser = String.valueOf(request.getAttribute(WebKeys.USER_ID));
125 }
126
127 return remoteUser;
128 }
129
130 protected void incrementProcessFilterCount() {
131 AtomicInteger processFilterCount = _processFilterCount.get();
132
133 processFilterCount.incrementAndGet();
134 }
135
136 @Override
137 protected void processFilter(
138 HttpServletRequest request, HttpServletResponse response,
139 FilterChain filterChain)
140 throws IOException, ServletException {
141
142 long companyId = PortalUtil.getCompanyId(request);
143 long groupId = getGroupId(request);
144 String remoteUser = getRemoteUser(request);
145
146 PortalRequestDataSample portalRequestDataSample = null;
147
148 incrementProcessFilterCount();
149
150 if (_monitoringPortalRequest) {
151 portalRequestDataSample = new PortalRequestDataSample(
152 companyId, groupId, request.getHeader(HttpHeaders.REFERER),
153 request.getRemoteAddr(), remoteUser, request.getRequestURI(),
154 GetterUtil.getString(request.getRequestURL()),
155 request.getHeader(HttpHeaders.USER_AGENT));
156
157 DataSampleThreadLocal.initialize();
158 }
159
160 try {
161 if (portalRequestDataSample != null) {
162 portalRequestDataSample.prepare();
163 }
164
165 processFilter(
166 MonitoringFilter.class, request, response, filterChain);
167
168 if (portalRequestDataSample != null) {
169 portalRequestDataSample.capture(RequestStatus.SUCCESS);
170
171 portalRequestDataSample.setGroupId(getGroupId(request));
172
173 try {
174 Method getStatusMethod =
175 HttpServletResponse.class.getDeclaredMethod(
176 "getStatus");
177
178 int status = (Integer)getStatusMethod.invoke(response);
179
180 portalRequestDataSample.setStatusCode(status);
181 }
182 catch (Exception e) {
183 if (_log.isDebugEnabled()) {
184 _log.debug(e, e);
185 }
186 }
187 }
188 }
189 catch (Exception e) {
190 if (portalRequestDataSample != null) {
191 portalRequestDataSample.capture(RequestStatus.ERROR);
192 }
193
194 if (e instanceof IOException) {
195 throw (IOException)e;
196 }
197 else if (e instanceof ServletException) {
198 throw (ServletException)e;
199 }
200 else {
201 throw new ServletException("Unable to execute request", e);
202 }
203 }
204 finally {
205 if (portalRequestDataSample != null) {
206 DataSampleThreadLocal.addDataSample(portalRequestDataSample);
207 }
208
209 if (decrementProcessFilterCount() == 0) {
210 MessageBusUtil.sendMessage(
211 DestinationNames.MONITORING,
212 DataSampleThreadLocal.getDataSamples());
213
214 _processFilterCount.remove();
215 }
216 }
217 }
218
219 private static Log _log = LogFactoryUtil.getLog(MonitoringFilter.class);
220
221 private static final ThreadLocal<AtomicInteger> _processFilterCount =
222 new AutoResetThreadLocal<AtomicInteger>(
223 MonitoringFilter.class + "._processFilterCount",
224 new AtomicInteger(0));
225
226 private static boolean _monitoringPortalRequest =
227 PropsValues.MONITORING_PORTAL_REQUEST;
228
229 }