319caf3cf7fcec4883d73f67f729a887e5d0a4b4
[portal/sdk.git] /
1 /*-
2  * ================================================================================
3  * eCOMP Portal SDK
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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  * ================================================================================
19  */
20 package org.openecomp.portalsdk.core.logging.logic;
21
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;
29
30 import java.net.InetAddress;
31 import java.text.MessageFormat;
32 import java.util.concurrent.ConcurrentHashMap;
33 import java.util.concurrent.ConcurrentMap;
34
35 import javax.servlet.http.HttpServletRequest;
36
37 import org.openecomp.portalsdk.core.domain.User;
38 import org.openecomp.portalsdk.core.logging.aspect.EELFLoggerAdvice;
39 import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum;
40 import org.openecomp.portalsdk.core.logging.format.AppMessagesEnum;
41 import org.openecomp.portalsdk.core.logging.format.ErrorSeverityEnum;
42 import org.openecomp.portalsdk.core.util.SystemProperties;
43 import org.openecomp.portalsdk.core.web.support.UserUtils;
44 import org.slf4j.MDC;
45
46 import com.att.eelf.configuration.EELFLogger;
47 import com.att.eelf.configuration.EELFManager;
48 import com.att.eelf.configuration.SLF4jWrapper;
49
50 public class EELFLoggerDelegate extends SLF4jWrapper implements EELFLogger {
51
52         public static EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();
53         public static EELFLogger applicationLogger = EELFManager.getInstance().getApplicationLogger();
54         public static EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger();
55         public static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
56         public static EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger();
57         private String className;
58         private static ConcurrentMap<String, EELFLoggerDelegate> classMap = new ConcurrentHashMap<String, EELFLoggerDelegate>();
59
60         public EELFLoggerDelegate(String _className) {
61                 super(_className);
62                 className = _className;
63         }
64
65         /**
66          * Convenience method that gets a logger for the specified class.
67          * 
68          * @see #getLogger(String)
69          * 
70          * @param clazz
71          * @return Instance of EELFLoggerDelegate
72          */
73         public static EELFLoggerDelegate getLogger(Class<?> clazz) {
74                 return getLogger(clazz.getName());
75         }
76
77         /**
78          * Gets a logger for the specified class name. If the logger does not
79          * already exist in the map, this creates a new logger.
80          * 
81          * @param className
82          *            If null or empty, uses EELFLoggerDelegate as the class name.
83          * @return Instance of EELFLoggerDelegate
84          */
85         public static EELFLoggerDelegate getLogger(String className) {
86                 if (className == null || className == "")
87                         className = EELFLoggerDelegate.class.getName();
88                 EELFLoggerDelegate delegate = classMap.get(className);
89                 if (delegate == null) {
90                         delegate = new EELFLoggerDelegate(className);
91                         classMap.put(className, delegate);
92                 }
93                 return delegate;
94         }
95
96         /**
97          * Logs a message at the lowest level: trace.
98          * 
99          * @param logger
100          * @param msg
101          */
102         public void trace(EELFLogger logger, String msg) {
103                 if (logger.isTraceEnabled()) {
104                         MDC.put(SystemProperties.MDC_CLASS_NAME, className);
105                         logger.trace(msg);
106                         MDC.remove(SystemProperties.MDC_CLASS_NAME);
107                 }
108         }
109
110         /**
111          * Logs a message with parameters at the lowest level: trace.
112          * 
113          * @param logger
114          * @param msg
115          * @param arguments
116          */
117         public void trace(EELFLogger logger, String msg, Object... arguments) {
118                 if (logger.isTraceEnabled()) {
119                         MDC.put(SystemProperties.MDC_CLASS_NAME, className);
120                         logger.trace(msg, arguments);
121                         MDC.remove(SystemProperties.MDC_CLASS_NAME);
122                 }
123         }
124
125         /**
126          * Logs a message and throwable at the lowest level: trace.
127          * 
128          * @param logger
129          * @param msg
130          * @param th
131          */
132         public void trace(EELFLogger logger, String msg, Throwable th) {
133                 if (logger.isTraceEnabled()) {
134                         MDC.put(SystemProperties.MDC_CLASS_NAME, className);
135                         logger.trace(msg, th);
136                         MDC.remove(SystemProperties.MDC_CLASS_NAME);
137                 }
138         }
139
140         /**
141          * Logs a message at the second-lowest level: debug.
142          * 
143          * @param logger
144          * @param msg
145          */
146         public void debug(EELFLogger logger, String msg) {
147                 if (logger.isDebugEnabled()) {
148                         MDC.put(SystemProperties.MDC_CLASS_NAME, className);
149                         logger.debug(msg);
150                         MDC.remove(SystemProperties.MDC_CLASS_NAME);
151                 }
152         }
153
154         /**
155          * Logs a message with parameters at the second-lowest level: debug.
156          * 
157          * @param logger
158          * @param msg
159          * @param arguments
160          */
161         public void debug(EELFLogger logger, String msg, Object... arguments) {
162                 if (logger.isDebugEnabled()) {
163                         MDC.put(SystemProperties.MDC_CLASS_NAME, className);
164                         logger.debug(msg, arguments);
165                         MDC.remove(SystemProperties.MDC_CLASS_NAME);
166                 }
167         }
168
169         /**
170          * Logs a message and throwable at the second-lowest level: debug.
171          * 
172          * @param logger
173          * @param msg
174          * @param th
175          */
176         public void debug(EELFLogger logger, String msg, Throwable th) {
177                 if (logger.isDebugEnabled()) {
178                         MDC.put(SystemProperties.MDC_CLASS_NAME, className);
179                         logger.debug(msg, th);
180                         MDC.remove(SystemProperties.MDC_CLASS_NAME);
181                 }
182         }
183
184         /**
185          * Logs a message at info level.
186          * 
187          * @param logger
188          * @param msg
189          */
190         public void info(EELFLogger logger, String msg) {
191                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
192                 logger.info(msg);
193                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
194         }
195
196         /**
197          * Logs a message with parameters at info level.
198          *
199          * @param logger
200          * @param msg
201          * @param arguments
202          */
203         public void info(EELFLogger logger, String msg, Object... arguments) {
204                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
205                 logger.info(msg, arguments);
206                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
207         }
208
209         /**
210          * Logs a message and throwable at info level.
211          * 
212          * @param logger
213          * @param msg
214          * @param th
215          */
216         public void info(EELFLogger logger, String msg, Throwable th) {
217                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
218                 logger.info(msg, th);
219                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
220         }
221
222         /**
223          * Logs a message at warn level.
224          * 
225          * @param logger
226          * @param msg
227          */
228         public void warn(EELFLogger logger, String msg) {
229                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
230                 logger.warn(msg);
231                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
232         }
233
234         /**
235          * Logs a message with parameters at warn level.
236          * 
237          * @param logger
238          * @param msg
239          * @param arguments
240          */
241         public void warn(EELFLogger logger, String msg, Object... arguments) {
242                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
243                 logger.warn(msg, arguments);
244                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
245         }
246
247         /**
248          * Logs a message and throwable at warn level.
249          * 
250          * @param logger
251          * @param msg
252          * @param th
253          */
254         public void warn(EELFLogger logger, String msg, Throwable th) {
255                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
256                 logger.warn(msg, th);
257                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
258         }
259
260         /**
261          * Logs a message at error level.
262          * 
263          * @param logger
264          * @param msg
265          */
266         public void error(EELFLogger logger, String msg) {
267                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
268                 logger.error(msg);
269                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
270         }
271
272         /**
273          * Logs a message with parameters at error level.
274          * 
275          * @param logger
276          * @param msg
277          * @param arguments
278          */
279         public void error(EELFLogger logger, String msg, Object... arguments) {
280                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
281                 logger.warn(msg, arguments);
282                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
283         }
284
285         /**
286          * Logs a message and throwable at error level.
287          * 
288          * @param logger
289          * @param msg
290          * @param th
291          */
292         public void error(EELFLogger logger, String msg, Throwable th) {
293                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
294                 logger.warn(msg, th);
295                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
296         }
297
298         /**
299          * Logs a message with the associated alarm severity at error level.
300          * 
301          * @param logger
302          * @param msg
303          * @param severtiy
304          */
305         public void error(EELFLogger logger, String msg, AlarmSeverityEnum severtiy) {
306                 MDC.put(MDC_ALERT_SEVERITY, severtiy.name());
307                 MDC.put(SystemProperties.MDC_CLASS_NAME, className);
308                 logger.error(msg);
309                 MDC.remove(MDC_ALERT_SEVERITY);
310                 MDC.remove(SystemProperties.MDC_CLASS_NAME);
311         }
312
313         /**
314          * Initializes the logger context.
315          */
316         public void init() {
317                 setGlobalLoggingContext();
318                 final String msg = "############################ Logging is started. ############################";
319                 // These loggers emit the current date-time without being told.
320                 info(applicationLogger, msg);
321                 error(errorLogger, msg);
322                 debug(debugLogger, msg);
323                 // Audit and metrics logger must be told start AND stop times
324                 final String currentDateTime = EELFLoggerAdvice.getCurrentDateTimeUTC();
325                 // Set the MDC with audit properties
326                 MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, currentDateTime);
327                 MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, currentDateTime);
328                 info(auditLogger, msg);
329                 MDC.remove(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
330                 MDC.remove(SystemProperties.AUDITLOG_END_TIMESTAMP);
331                 // Set the MDC with metrics properties
332                 MDC.put(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP, currentDateTime);
333                 MDC.put(SystemProperties.METRICSLOG_END_TIMESTAMP, currentDateTime);
334                 info(metricsLogger, msg);
335                 MDC.remove(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
336                 MDC.remove(SystemProperties.METRICSLOG_END_TIMESTAMP);
337         }
338
339         /**
340          * Logs a standard message identified by the specified enum, using the
341          * specified parameters, at error level. Alarm and error severity are taken
342          * from the specified enum argument.
343          * 
344          * @param epMessageEnum
345          * @param param
346          */
347         public void logEcompError(AppMessagesEnum epMessageEnum, String... param) {
348                 try {
349                         AlarmSeverityEnum alarmSeverityEnum = epMessageEnum.getAlarmSeverity();
350                         ErrorSeverityEnum errorSeverityEnum = epMessageEnum.getErrorSeverity();
351
352                         MDC.put(MDC_ALERT_SEVERITY, alarmSeverityEnum.name());
353                         MDC.put("ErrorCode", epMessageEnum.getErrorCode());
354                         MDC.put("ErrorDescription", epMessageEnum.getErrorDescription());
355
356                         String resolution = this.formatMessage(epMessageEnum.getDetails() + " " + epMessageEnum.getResolution(),
357                                         (Object[]) param);
358                         if (errorSeverityEnum == ErrorSeverityEnum.WARN) {
359                                 errorLogger.warn(resolution);
360                         } else if (errorSeverityEnum == ErrorSeverityEnum.INFO) {
361                                 errorLogger.info(resolution);
362                         } else {
363                                 errorLogger.error(resolution);
364                         }
365                 } catch (Exception e) {
366                         errorLogger.error("Failed to log the error code. Details: " + UserUtils.getStackTrace(e));
367                 } finally {
368                         MDC.remove("ErrorCode");
369                         MDC.remove("ErrorDescription");
370                         MDC.remove(MDC_ALERT_SEVERITY);
371                 }
372         }
373
374         /**
375          * Builds a message using a template string and the arguments.
376          * 
377          * @param message
378          * @param args
379          * @return
380          */
381         private String formatMessage(String message, Object... args) {
382                 StringBuilder sbFormattedMessage = new StringBuilder();
383                 if (args != null && args.length > 0 && message != null && message != "") {
384                         MessageFormat mf = new MessageFormat(message);
385                         sbFormattedMessage.append(mf.format(args));
386                 } else {
387                         sbFormattedMessage.append(message);
388                 }
389
390                 return sbFormattedMessage.toString();
391         }
392
393         /**
394          * Loads all the default logging fields into the MDC context.
395          */
396         private void setGlobalLoggingContext() {
397                 MDC.put(MDC_SERVICE_INSTANCE_ID, "");
398                 MDC.put(MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.toString());
399                 try {
400                         MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
401                         MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
402                         MDC.put(MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID));
403                 } catch (Exception e) {
404                 }
405         }
406
407         public static void mdcPut(String key, String value) {
408                 MDC.put(key, value);
409         }
410
411         public static String mdcGet(String key) {
412                 return MDC.get(key);
413         }
414
415         public static void mdcRemove(String key) {
416                 MDC.remove(key);
417         }
418
419         /**
420          * Loads the RequestId/TransactionId into the MDC which it should be
421          * receiving with an each incoming REST API request. Also, configures few
422          * other request based logging fields into the MDC context.
423          * 
424          * @param req
425          * @param appName
426          */
427         public void setRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req, String appName) {
428                 // Load the default fields
429                 setGlobalLoggingContext();
430
431                 // Load the request based fields
432                 if (req != null) {
433                         // Load the Request into MDC context.
434                         String requestId = UserUtils.getRequestId(req);
435                         MDC.put(MDC_KEY_REQUEST_ID, requestId);
436
437                         // Load user agent into MDC context, if available.
438                         String accessingClient = "Unknown";
439                         accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME);
440                         if (accessingClient != null && accessingClient != "" && (accessingClient.contains("Mozilla")
441                                         || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) {
442                                 accessingClient = appName + "_FE";
443                         }
444                         MDC.put(SystemProperties.PARTNER_NAME, accessingClient);
445
446                         // Protocol, Rest URL & Rest Path
447                         String restURL = "";
448                         MDC.put(SystemProperties.FULL_URL, SystemProperties.UNKNOWN);
449                         MDC.put(SystemProperties.PROTOCOL, SystemProperties.HTTP);
450                         restURL = UserUtils.getFullURL(req);
451                         if (restURL != null && restURL != "") {
452                                 MDC.put(SystemProperties.FULL_URL, restURL);
453                                 if (restURL.toLowerCase().contains("https")) {
454                                         MDC.put(SystemProperties.PROTOCOL, SystemProperties.HTTPS);
455                                 }
456                         }
457
458                         // Rest Path
459                         MDC.put(MDC_SERVICE_NAME, req.getServletPath());
460
461                         // Client IPAddress i.e. IPAddress of the remote host who is making
462                         // this request.
463                         String clientIPAddress = "";
464                         clientIPAddress = req.getHeader("X-FORWARDED-FOR");
465                         if (clientIPAddress == null) {
466                                 clientIPAddress = req.getRemoteAddr();
467                         }
468                         MDC.put(SystemProperties.CLIENT_IP_ADDRESS, clientIPAddress);
469
470                         // Load loginId into MDC context.
471                         MDC.put(SystemProperties.MDC_LOGIN_ID, "Unknown");
472                         
473                         String loginId = "";
474                                 User user = UserUtils.getUserSession(req);
475                                 if (user != null) {
476                                         loginId = user.getLoginId();
477                                 }
478
479                         if (loginId != null && loginId != "") {
480                                 MDC.put(SystemProperties.MDC_LOGIN_ID, loginId);
481                         }
482                 }
483         }
484 }