2 * ================================================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ================================================================================
20 package org.openecomp.portalapp.portal.logging.aop;
22 import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY;
23 import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID;
24 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
25 import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
26 import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
27 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID;
28 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
30 import java.net.InetAddress;
31 import java.text.SimpleDateFormat;
32 import java.util.Date;
33 import java.util.UUID;
35 import javax.servlet.http.HttpServletRequest;
37 import org.openecomp.portalapp.portal.domain.EPUser;
38 import org.openecomp.portalapp.portal.utils.EPSystemProperties;
39 import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
40 import org.openecomp.portalapp.util.EPUserUtils;
41 import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum;
42 import org.openecomp.portalsdk.core.logging.format.AuditLogFormatter;
43 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
44 import org.openecomp.portalsdk.core.util.SystemProperties;
45 import org.openecomp.portalsdk.core.util.SystemProperties.SecurityEventTypeEnum;
46 import org.openecomp.portalsdk.core.web.support.UserUtils;
49 import com.att.eelf.configuration.Configuration;
51 @org.springframework.context.annotation.Configuration
52 public class EPEELFLoggerAdvice {
54 EELFLoggerDelegate adviceLogger = EELFLoggerDelegate.getLogger(EPEELFLoggerAdvice.class);
55 //DateTime Format according to the ECOMP Application Logging Guidelines.
56 private static final SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
58 public void loadServletRequestBasedDefaults(HttpServletRequest req, SecurityEventTypeEnum securityEventType) {
60 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, req.getServletPath());
61 } catch(Exception e) {
62 adviceLogger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
66 public Object[] before(SecurityEventTypeEnum securityEventType, Object[] args, Object[] passOnArgs) {
67 String className = "";
68 if (passOnArgs[0]!=null) {
69 className = passOnArgs[0].toString();
72 String methodName = "";
73 if (passOnArgs[1]!=null) {
74 methodName = passOnArgs[1].toString();
77 //Initialize Request defaults only for controller methods.
78 MDC.put(className + methodName + EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC());
79 MDC.put(EPSystemProperties.TARGET_ENTITY, EPSystemProperties.ECOMP_PORTAL_BE);
80 MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, methodName);
81 if (securityEventType!=null) {
82 MDC.put(className + methodName + EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC());
83 HttpServletRequest req = null;
84 if (args[0]!=null && args[0] instanceof HttpServletRequest ) {
85 req = (HttpServletRequest)args[0];
86 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
90 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
92 //StopWatch stopWatch = new StopWatch("Metrics for " + className + "." + methodName);
95 logger.debug(EELFLoggerDelegate.debugLogger, "Entered executing " + methodName +".");
97 return new Object[] {""};
100 public void after(SecurityEventTypeEnum securityEventType, String statusCode, String responseCode, Object[] args, Object[] returnArgs, Object[] passOnArgs) {
102 String className = "";
103 if (passOnArgs[0]!=null) {
104 className = passOnArgs[0].toString();
108 String methodName = "";
109 if (passOnArgs[1]!=null) {
110 methodName = passOnArgs[1].toString();
113 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
115 StopWatch stopWatch = (StopWatch)returnArgs[0];
116 if (stopWatch!=null && stopWatch.isRunning()) {
118 MDC.put(SystemProperties.MDC_TIMER, stopWatch.getTotalTimeMillis() + "ms");
122 if (MDC.get(EPSystemProperties.TARGET_SERVICE_NAME) == null || MDC.get(EPSystemProperties.TARGET_SERVICE_NAME) == "") {
123 MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, methodName);
126 if (MDC.get(EPSystemProperties.TARGET_ENTITY) == null || MDC.get(EPSystemProperties.TARGET_ENTITY) == "") {
127 MDC.put(EPSystemProperties.TARGET_ENTITY, EPSystemProperties.ECOMP_PORTAL_BE);
130 MDC.put(EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP, MDC.get(className + methodName + EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP));
131 MDC.put(EPSystemProperties.METRICSLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
132 this.calculateDateTimeDifference(MDC.get(EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP), MDC.get(EPSystemProperties.METRICSLOG_END_TIMESTAMP));
134 //Making sure to reload the INCOMING request MDC defaults if they have
135 //been wiped out by either Outgoing or LDAP Phone book search operations.
136 if (securityEventType!=null && args[0]!=null && args[0] instanceof HttpServletRequest &&
137 securityEventType==SecurityEventTypeEnum.INCOMING_REST_MESSAGE &&
138 (MDC.get(EPSystemProperties.FULL_URL)==null || MDC.get(EPSystemProperties.FULL_URL)=="")) {
139 HttpServletRequest req = (HttpServletRequest)args[0];
140 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
143 //Use external API response code in case if it resulted in an error.
144 String externalAPIResponseCode = MDC.get(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE);
145 if (externalAPIResponseCode==null || externalAPIResponseCode=="" || externalAPIResponseCode.trim().equalsIgnoreCase("200")) {
146 MDC.put(EPSystemProperties.RESPONSE_CODE, responseCode);
147 MDC.put(EPSystemProperties.STATUS_CODE, statusCode);
149 MDC.put(EPSystemProperties.RESPONSE_CODE, externalAPIResponseCode);
150 MDC.put(EPSystemProperties.STATUS_CODE, "ERROR");
153 logger.debug(EELFLoggerDelegate.debugLogger, "Finished executing " + methodName + ".");
154 logger.info(EELFLoggerDelegate.metricsLogger, methodName + " operation is completed.");
156 //Log security message, if necessary
157 if (securityEventType!=null) {
158 MDC.put(EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP, MDC.get(className + methodName + EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP));
159 MDC.put(EPSystemProperties.AUDITLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
160 this.calculateDateTimeDifference(MDC.get(EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP), MDC.get(EPSystemProperties.AUDITLOG_END_TIMESTAMP));
162 this.logSecurityMessage(logger, securityEventType, methodName);
164 //Outgoing & LDAP messages are part of Incoming requests so,
165 //keep "RequestId", "PartnerName", "ServiceName", "LoginId" &
166 //"ResponseCode" etc. in memory and remove it only when
167 //finished processing the parent incoming message.
168 if (securityEventType!=SecurityEventTypeEnum.OUTGOING_REST_MESSAGE &&
169 securityEventType!=SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
170 MDC.remove(MDC_KEY_REQUEST_ID);
171 MDC.remove(EPSystemProperties.PARTNER_NAME);
172 MDC.remove(Configuration.MDC_SERVICE_NAME);
173 MDC.remove(EPSystemProperties.MDC_LOGIN_ID);
174 MDC.remove(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE);
177 //clear when finishes audit logging
178 MDC.remove(EPSystemProperties.FULL_URL);
179 MDC.remove(EPSystemProperties.PROTOCOL);
180 MDC.remove(EPSystemProperties.STATUS_CODE);
181 MDC.remove(className + methodName + EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
182 MDC.remove(EPSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
183 MDC.remove(EPSystemProperties.AUDITLOG_END_TIMESTAMP);
184 MDC.remove(EPSystemProperties.RESPONSE_CODE);
186 MDC.remove(className + methodName + EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
187 MDC.remove(EPSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
188 MDC.remove(EPSystemProperties.METRICSLOG_END_TIMESTAMP);
189 MDC.remove(EPSystemProperties.MDC_TIMER);
190 MDC.remove(EPSystemProperties.TARGET_ENTITY);
191 MDC.remove(EPSystemProperties.TARGET_SERVICE_NAME);
194 private void logSecurityMessage(EELFLoggerDelegate logger, SecurityEventTypeEnum securityEventType, String restMethod) {
195 StringBuilder additionalInfoAppender = new StringBuilder();
196 String auditMessage = "";
198 if (securityEventType == SecurityEventTypeEnum.OUTGOING_REST_MESSAGE) {
199 additionalInfoAppender.append(String.format("%s '%s' request was initiated.",
200 restMethod, MDC.get(EPSystemProperties.TARGET_SERVICE_NAME)));
201 } else if (securityEventType==SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
202 additionalInfoAppender.append("LDAP Phonebook search operation is performed.");
204 additionalInfoAppender.append(String.format("%s request was received.", restMethod));
206 if (securityEventType == SecurityEventTypeEnum.FE_LOGIN_ATTEMPT) {
208 String additionalMessage = " Successfully authenticated.";
209 loginId = MDC.get(EPSystemProperties.MDC_LOGIN_ID);
210 if (loginId==null || loginId=="" || loginId== EPSystemProperties.UNKNOWN) {
211 additionalMessage = " No cookies are found.";
213 additionalInfoAppender.append(additionalMessage);
214 } else if (securityEventType == SecurityEventTypeEnum.FE_LOGOUT) {
215 additionalInfoAppender.append(" User has been successfully logged out.");
219 String fullURL = MDC.get(EPSystemProperties.FULL_URL);
220 if (fullURL!=null && fullURL!="") {
221 additionalInfoAppender.append(" Request-URL:" + MDC.get(EPSystemProperties.FULL_URL));
224 auditMessage = AuditLogFormatter.getInstance().createMessage( MDC.get(EPSystemProperties.PROTOCOL),
225 securityEventType.name(),
226 MDC.get(EPSystemProperties.MDC_LOGIN_ID),
227 additionalInfoAppender.toString());
229 logger.info(EELFLoggerDelegate.auditLogger, auditMessage);
232 private void setHttpRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req, SecurityEventTypeEnum securityEventType, String restMethod) {
233 //No need to load the request based defaults for the following security messages
234 //since either they are initiated by the Portal BE or not Http request based.
236 if (securityEventType!=SecurityEventTypeEnum.OUTGOING_REST_MESSAGE &&
237 securityEventType!=SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH &&
238 securityEventType!=SecurityEventTypeEnum.INCOMING_UEB_MESSAGE) {
239 //Load the RequestID (aka TrasactionId) into MDC context.
240 String requestId = UserUtils.getRequestId(req);
241 if (requestId=="" || requestId==null) {
242 requestId = UUID.randomUUID().toString();
244 MDC.put(MDC_KEY_REQUEST_ID, requestId);
246 //Load user agent into MDC context, if available.
247 String accessingClient = "Unknown";
248 accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME);
249 if (accessingClient!=null && accessingClient!="" &&
250 (accessingClient.contains("Mozilla") || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) {
251 accessingClient = EPSystemProperties.ECOMP_PORTAL_FE;
253 MDC.put(EPSystemProperties.PARTNER_NAME, accessingClient);
255 //Load loginId into MDC context.
258 loginId = UserUtils.getUserIdFromCookie(req);
259 } catch (Exception e) {
260 adviceLogger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
262 if (loginId == null || loginId == "") {
263 EPUser user = EPUserUtils.getUserSession(req);
265 loginId = user.getLoginId();
268 if (loginId==null || loginId=="") {
272 MDC.put(EPSystemProperties.MDC_LOGIN_ID, loginId);
274 //Rest URL & Protocol
276 MDC.put(EPSystemProperties.FULL_URL, EPSystemProperties.UNKNOWN);
277 MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTP);
278 restURL = UserUtils.getFullURL(req);
279 if (restURL!=null && restURL!="") {
280 MDC.put(EPSystemProperties.FULL_URL, restURL);
281 if (restURL.toLowerCase().contains("https")) {
282 MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTPS);
287 MDC.put(MDC_SERVICE_NAME, restMethod);
288 String restPath = req.getServletPath();
289 if (restPath!=null && restPath!="") {
290 MDC.put(MDC_SERVICE_NAME, restPath);
293 //Client IPAddress i.e. IPAddress of the remote host who is making this request.
294 String clientIPAddress = "";
295 clientIPAddress = req.getHeader("X-FORWARDED-FOR");
296 if (clientIPAddress == null) {
297 clientIPAddress = req.getRemoteAddr();
299 MDC.put(EPSystemProperties.CLIENT_IP_ADDRESS, clientIPAddress);
300 } else if(securityEventType==SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
301 MDC.put(EPSystemProperties.TARGET_ENTITY, "Phonebook");
302 MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, "search");
305 MDC.put(MDC_SERVICE_NAME, restMethod);
306 MDC.put(EPSystemProperties.PARTNER_NAME, EPSystemProperties.ECOMP_PORTAL_FE);
309 MDC.put(MDC_SERVICE_INSTANCE_ID, "");
310 MDC.put(MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.toString());
312 MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
313 MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
314 MDC.put(MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID));
315 } catch (Exception e) {
316 adviceLogger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
320 private String getCurrentDateTimeUTC() {
321 String currentDateTime = ecompLogDateFormat.format(new Date());
322 return currentDateTime;
325 private void calculateDateTimeDifference(String beginDateTime, String endDateTime) {
326 if (beginDateTime!=null && endDateTime!=null) {
328 Date beginDate = ecompLogDateFormat.parse(beginDateTime);
329 Date endDate = ecompLogDateFormat.parse(endDateTime);
330 String timeDifference = String.format("%d ms", endDate.getTime() - beginDate.getTime());
331 MDC.put(SystemProperties.MDC_TIMER, timeDifference);
332 } catch(Exception e) {
333 adviceLogger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
338 public String getInternalResponseCode() {
339 return MDC.get(EPSystemProperties.RESPONSE_CODE);