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 java.net.InetAddress;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 import java.util.UUID;
27 import javax.servlet.http.HttpServletRequest;
29 import org.openecomp.portalapp.portal.domain.EPUser;
30 import org.openecomp.portalapp.portal.utils.EPCommonSystemProperties;
31 import org.openecomp.portalapp.util.EPUserUtils;
32 import org.openecomp.portalsdk.core.exception.SessionExpiredException;
33 import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum;
34 import org.openecomp.portalsdk.core.logging.format.AuditLogFormatter;
35 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
36 import org.openecomp.portalsdk.core.util.SystemProperties;
37 import org.openecomp.portalsdk.core.util.SystemProperties.SecurityEventTypeEnum;
38 import org.openecomp.portalsdk.core.web.support.UserUtils;
41 import com.att.eelf.configuration.Configuration;
43 @org.springframework.context.annotation.Configuration
44 public class EPEELFLoggerAdvice {
46 private EELFLoggerDelegate adviceLogger = EELFLoggerDelegate.getLogger(EPEELFLoggerAdvice.class);
49 * DateTime Format according to the ECOMP Application Logging Guidelines.
51 private static final SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
54 * @return Current date and time in the format specified by the ECOMP
55 * Application Logging Guidelines.
57 public static String getCurrentDateTimeUTC() {
58 String currentDateTime = ecompLogDateFormat.format(new Date());
59 return currentDateTime;
63 * Sets logging context with values from HttpServletRequest object.
67 * @param securityEventType
68 * SecurityEventTypeEnum
70 public void loadServletRequestBasedDefaults(HttpServletRequest req, SecurityEventTypeEnum securityEventType) {
72 setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, req.getServletPath());
73 } catch (Exception e) {
74 adviceLogger.error(EELFLoggerDelegate.errorLogger, "loadServletRequestBasedDefaults failed", e);
80 * @param securityEventType
85 public Object[] before(SecurityEventTypeEnum securityEventType, Object[] args, Object[] passOnArgs) {
86 String className = "";
87 if (passOnArgs[0] != null) {
88 className = passOnArgs[0].toString();
91 String methodName = "";
92 if (passOnArgs[1] != null) {
93 methodName = passOnArgs[1].toString();
96 // Initialize Request defaults only for controller methods.
97 MDC.put(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC());
98 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, EPCommonSystemProperties.ECOMP_PORTAL_BE);
99 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, methodName);
100 if (securityEventType != null) {
101 MDC.put(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,
102 getCurrentDateTimeUTC());
103 HttpServletRequest req = null;
104 if (args[0] != null && args[0] instanceof HttpServletRequest) {
105 req = (HttpServletRequest) args[0];
106 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
110 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
111 logger.debug(EELFLoggerDelegate.debugLogger, "EPEELFLoggerAdvice#before: entering {}", methodName);
112 return new Object[] { "" };
117 * @param securityEventType
119 * @param responseCode
124 public void after(SecurityEventTypeEnum securityEventType, String statusCode, String responseCode, Object[] args,
125 Object[] returnArgs, Object[] passOnArgs) {
126 String className = "";
127 if (passOnArgs[0] != null)
128 className = passOnArgs[0].toString();
131 String methodName = "";
132 if (passOnArgs[1] != null)
133 methodName = passOnArgs[1].toString();
135 if (MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME) == null
136 || MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME) == "")
137 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, methodName);
139 if (MDC.get(EPCommonSystemProperties.TARGET_ENTITY) == null
140 || MDC.get(EPCommonSystemProperties.TARGET_ENTITY) == "")
141 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, EPCommonSystemProperties.ECOMP_PORTAL_BE);
143 MDC.put(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP,
144 MDC.get(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP));
145 MDC.put(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
146 this.calculateDateTimeDifference(MDC.get(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP),
147 MDC.get(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP));
149 // Making sure to reload the INCOMING request MDC defaults if they have
150 // been wiped out by either Outgoing or LDAP Phone book search
152 if (securityEventType != null && args[0] != null && args[0] instanceof HttpServletRequest
153 && securityEventType == SecurityEventTypeEnum.INCOMING_REST_MESSAGE
154 && (MDC.get(EPCommonSystemProperties.FULL_URL) == null
155 || MDC.get(EPCommonSystemProperties.FULL_URL) == "")) {
156 HttpServletRequest req = (HttpServletRequest) args[0];
157 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(req, securityEventType, methodName);
160 // Use external API response code in case if it resulted in an error.
161 String externalAPIResponseCode = MDC.get(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
162 if (externalAPIResponseCode == null || externalAPIResponseCode == ""
163 || externalAPIResponseCode.trim().equalsIgnoreCase("200")) {
164 MDC.put(EPCommonSystemProperties.RESPONSE_CODE, responseCode);
165 MDC.put(EPCommonSystemProperties.STATUS_CODE, statusCode);
167 MDC.put(EPCommonSystemProperties.RESPONSE_CODE, externalAPIResponseCode);
168 MDC.put(EPCommonSystemProperties.STATUS_CODE, "ERROR");
171 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
172 logger.debug(EELFLoggerDelegate.debugLogger, "EPEELFLoggerAdvice#after: finished {}", methodName);
173 // add the metrics log
174 logger.info(EELFLoggerDelegate.metricsLogger, methodName + " operation is completed.");
176 // Log security message, if necessary
177 if (securityEventType != null) {
178 MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,
179 MDC.get(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP));
180 MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
181 this.calculateDateTimeDifference(MDC.get(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP),
182 MDC.get(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP));
184 this.logSecurityMessage(logger, securityEventType, methodName);
186 // Outgoing & LDAP messages are part of Incoming requests so,
187 // keep "RequestId", "PartnerName", "ServiceName", "LoginId" &
188 // "ResponseCode" etc. in memory and remove it only when
189 // finished processing the parent incoming message.
190 if (securityEventType != SecurityEventTypeEnum.OUTGOING_REST_MESSAGE
191 && securityEventType != SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
192 MDC.remove(Configuration.MDC_KEY_REQUEST_ID);
193 MDC.remove(EPCommonSystemProperties.PARTNER_NAME);
194 MDC.remove(Configuration.MDC_SERVICE_NAME);
195 MDC.remove(EPCommonSystemProperties.MDC_LOGIN_ID);
196 MDC.remove(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
199 // clear when finishes audit logging
200 MDC.remove(EPCommonSystemProperties.FULL_URL);
201 MDC.remove(EPCommonSystemProperties.PROTOCOL);
202 MDC.remove(EPCommonSystemProperties.STATUS_CODE);
203 MDC.remove(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
204 MDC.remove(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
205 MDC.remove(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP);
206 MDC.remove(EPCommonSystemProperties.RESPONSE_CODE);
208 MDC.remove(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
209 MDC.remove(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
210 MDC.remove(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP);
211 MDC.remove(EPCommonSystemProperties.MDC_TIMER);
212 MDC.remove(EPCommonSystemProperties.TARGET_ENTITY);
213 MDC.remove(EPCommonSystemProperties.TARGET_SERVICE_NAME);
219 * @param securityEventType
222 private void logSecurityMessage(EELFLoggerDelegate logger, SecurityEventTypeEnum securityEventType,
224 StringBuilder additionalInfoAppender = new StringBuilder();
225 String auditMessage = "";
227 if (securityEventType == SecurityEventTypeEnum.OUTGOING_REST_MESSAGE) {
228 additionalInfoAppender.append(String.format("%s '%s' request was initiated.", restMethod,
229 MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME)));
230 } else if (securityEventType == SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
231 additionalInfoAppender.append("LDAP Phonebook search operation is performed.");
233 additionalInfoAppender.append(String.format("%s request was received.", restMethod));
235 if (securityEventType == SecurityEventTypeEnum.FE_LOGIN_ATTEMPT) {
237 String additionalMessage = " Successfully authenticated.";
238 loginId = MDC.get(EPCommonSystemProperties.MDC_LOGIN_ID);
239 if (loginId == null || loginId == "" || loginId == EPCommonSystemProperties.UNKNOWN) {
240 additionalMessage = " No cookies are found.";
242 additionalInfoAppender.append(additionalMessage);
243 } else if (securityEventType == SecurityEventTypeEnum.FE_LOGOUT) {
244 additionalInfoAppender.append(" User has been successfully logged out.");
248 String fullURL = MDC.get(EPCommonSystemProperties.FULL_URL);
249 if (fullURL != null && fullURL != "") {
250 additionalInfoAppender.append(" Request-URL:" + MDC.get(EPCommonSystemProperties.FULL_URL));
253 auditMessage = AuditLogFormatter.getInstance().createMessage(MDC.get(EPCommonSystemProperties.PROTOCOL),
254 securityEventType.name(), MDC.get(EPCommonSystemProperties.MDC_LOGIN_ID),
255 additionalInfoAppender.toString());
257 logger.info(EELFLoggerDelegate.auditLogger, auditMessage);
263 * @param securityEventType
266 private void setHttpRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req,
267 SecurityEventTypeEnum securityEventType, String restMethod) {
269 * No need to load the request based defaults for the following security
270 * messages since either they are initiated by the Portal BE or not Http
274 if (securityEventType != SecurityEventTypeEnum.OUTGOING_REST_MESSAGE
275 && securityEventType != SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH
276 && securityEventType != SecurityEventTypeEnum.INCOMING_UEB_MESSAGE) {
277 // Load the RequestID (aka TrasactionId) into MDC context.
278 String requestId = UserUtils.getRequestId(req);
279 if (requestId == "" || requestId == null) {
280 requestId = UUID.randomUUID().toString();
282 MDC.put(Configuration.MDC_KEY_REQUEST_ID, requestId);
284 // Load user agent into MDC context, if available.
285 String accessingClient = "Unknown";
286 accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME);
287 if (accessingClient != null && accessingClient != "" && (accessingClient.contains("Mozilla")
288 || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) {
289 accessingClient = EPCommonSystemProperties.ECOMP_PORTAL_FE;
291 MDC.put(EPCommonSystemProperties.PARTNER_NAME, accessingClient);
293 // Load loginId into MDC context.
296 user = EPUserUtils.getUserSession(req);
297 } catch (SessionExpiredException se) {
298 adviceLogger.debug(EELFLoggerDelegate.debugLogger,
299 "setHttpRequestBasedDefaultsIntoGlobalLoggingContext: No user found in session");
302 MDC.put(EPCommonSystemProperties.MDC_LOGIN_ID, (user != null ? user.getOrgUserId() : "NoUser"));
304 // Rest URL & Protocol
306 MDC.put(EPCommonSystemProperties.FULL_URL, EPCommonSystemProperties.UNKNOWN);
307 MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTP);
308 restURL = UserUtils.getFullURL(req);
309 if (restURL != null && restURL != "") {
310 MDC.put(EPCommonSystemProperties.FULL_URL, restURL);
311 if (restURL.toLowerCase().contains("https")) {
312 MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTPS);
317 MDC.put(Configuration.MDC_SERVICE_NAME, restMethod);
318 String restPath = req.getServletPath();
319 if (restPath != null && restPath != "") {
320 MDC.put(Configuration.MDC_SERVICE_NAME, restPath);
323 // Client IPAddress i.e. IPAddress of the remote host who is
324 // making this request.
325 String clientIPAddress = "";
326 clientIPAddress = req.getHeader("X-FORWARDED-FOR");
327 if (clientIPAddress == null) {
328 clientIPAddress = req.getRemoteAddr();
330 MDC.put(EPCommonSystemProperties.CLIENT_IP_ADDRESS, clientIPAddress);
331 } else if (securityEventType == SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
332 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, "Phonebook");
333 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, "search");
336 MDC.put(Configuration.MDC_SERVICE_NAME, restMethod);
337 MDC.put(EPCommonSystemProperties.PARTNER_NAME, EPCommonSystemProperties.ECOMP_PORTAL_FE);
340 MDC.put(Configuration.MDC_SERVICE_INSTANCE_ID, "");
341 MDC.put(Configuration.MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.toString());
343 MDC.put(Configuration.MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
344 MDC.put(Configuration.MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
345 MDC.put(Configuration.MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID));
346 } catch (Exception e) {
347 adviceLogger.error(EELFLoggerDelegate.errorLogger,
348 "setHttpRequestBasedDefaultsIntoGlobalLoggingContext failed", e);
354 * @param beginDateTime
357 private void calculateDateTimeDifference(String beginDateTime, String endDateTime) {
358 if (beginDateTime != null && endDateTime != null) {
360 Date beginDate = ecompLogDateFormat.parse(beginDateTime);
361 Date endDate = ecompLogDateFormat.parse(endDateTime);
362 String timeDifference = String.format("%d", endDate.getTime() - beginDate.getTime());
363 MDC.put(SystemProperties.MDC_TIMER, timeDifference);
364 } catch (Exception e) {
365 adviceLogger.error(EELFLoggerDelegate.errorLogger, "calculateDateTimeDifference failed", e);
370 public String getInternalResponseCode() {
371 return MDC.get(EPCommonSystemProperties.RESPONSE_CODE);