Merge "Reorder modifiers"
[so.git] / common / src / main / java / org / openecomp / mso / logger / MsoLogger.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.mso.logger;
23
24 import java.io.BufferedReader;
25 import java.io.BufferedWriter;
26 import java.io.File;
27 import java.io.FileReader;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.io.PrintWriter;
31 import java.io.StringWriter;
32 import java.net.InetAddress;
33 import java.net.UnknownHostException;
34 import java.util.UUID;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
37
38 import org.slf4j.MDC;
39
40 import org.openecomp.mso.entity.MsoRequest;
41 import com.att.eelf.configuration.EELFLogger;
42 import com.att.eelf.configuration.EELFManager;
43 import com.att.eelf.i18n.EELFResolvableErrorEnum;
44
45 import java.text.DateFormat;
46 import java.text.SimpleDateFormat;
47 import java.util.Date;
48
49 /**
50  * Simple wrapper around the EELF Logger class for MSO usage. This class
51  * supports all of the normal logging functions (debug, info, etc.), prepending
52  * a string of format "[<requestId>|<serviceId]" to each message.
53  *
54  * MSO code should initialize with these IDs when available, so that individual
55  * requests and/or services can be tracked throughout the various MSO component
56  * logs (API Handler, BPEL, and Adapters).
57  *
58  *
59  */
60 public class MsoLogger {
61     // MDC parameters
62     public static final String  REQUEST_ID                  = "RequestId";
63     public static final String  SERVICE_INSTANCE_ID         = "ServiceInstanceId";
64     public static final String  SERVICE_NAME                = "ServiceName";
65     private static final String SERVICE_NAME_IS_METHOD_NAME = "ServiceNameIsMethodName";
66     private static final String INSTANCE_UUID               = "InstanceUUID";
67     private static final String SERVER_IP                   = "ServerIPAddress";
68     private static final String FQDN                        = "ServerFQDN";
69     public static final String  REMOTE_HOST                 = "RemoteHost";
70     public static final String  ALERT_SEVERITY              = "AlertSeverity";
71     public static final String  TIMER                       = "Timer";
72     private static final String USER                        = "User";
73     private static final String DUMMY_VALUE                 = "trace-#";
74     public static final String  UNKNOWN                     = "UNKNOWN";
75     //For getting an identity of calling application
76     public static final String HEADER_FROM_APP_ID           = "X-FromAppId";
77     public static final String FROM_APP_ID                  = "FromAppId";
78     // Audit/Metric log specific
79     private static final String BEGINTIME                   = "BeginTimestamp";
80     private static final String ENDTIME                     = "EndTimestamp";
81     public static final String  PARTNERNAME                 = "PartnerName";
82     private static final String STATUSCODE                  = "StatusCode";
83     private static final String RESPONSECODE                = "ResponseCode";
84     private static final String RESPONSEDESC                = "ResponseDesc";
85     // Metric log specific
86     private static final String TARGETENTITY                = "TargetEntity";
87     private static final String TARGETSERVICENAME           = "TargetServiceName";
88     private static final String TARGETVIRTUALENTITY         = "TargetVirtualEntity";
89
90     private static final String FATAL_LEVEL                 = "FATAL";
91     private static final String ERROR_LEVEL                 = "ERROR";
92     private static final String WARN_LEVEL                  = "WARN";
93     private static final String INFO_LEVEL                  = "INFO";
94     private static final String DEBUG_LEVEL                 = "DEBUG";
95
96     private static final String ERRORCODE                   = "ErrorCode";
97     private static final String ERRORDESC                   = "ErrorDesc";
98
99     public enum Catalog {
100         APIH, BPEL, RA, ASDC, GENERAL
101     }
102
103     public enum StatusCode {
104         COMPLETE, ERROR
105     }
106
107     public enum ResponseCode {
108         Suc(0), PermissionError(100), DataError(300), DataNotFound(301), BadRequest(302), SchemaError(
109                 400), BusinessProcesssError(500), ServiceNotAvailable(501), InternalError(
110                         502), Conflict(503), DBAccessError(504), CommunicationError(505), UnknownError(900);
111
112         private int value;
113
114         public int getValue() {
115             return this.value;
116         }
117
118         ResponseCode(int value) {
119             this.value = value;
120         }
121     }
122
123     public enum ErrorCode {
124         PermissionError(100), AvailabilityError(200), DataError(300), SchemaError(400), BusinessProcesssError(
125                 500), UnknownError(900);
126
127         private int value;
128
129         public int getValue() {
130             return this.value;
131         }
132
133         ErrorCode(int value) {
134             this.value = value;
135         }
136     }
137
138     private EELFLogger          logger, auditLogger, metricsLogger;
139     private static final String CONFIG_FILE = System.getProperty("jboss.home.dir") + "/mso-config/uuid/uuid_"
140             + System.getProperty("jboss.server.name");
141     private static String       instanceUUID, serverIP, serverName;
142     private MessageEnum         exceptionArg, defaultException, defaultWarning, defaultAudit, defaultMetrics;
143
144     // For internal logging of the initialization of MSO logs
145     private static final Logger LOGGER      = Logger.getLogger(MsoLogger.class.getName());
146
147
148     // Since four adaptors are using the instance of  MsoLogger which will be referenced everywhere
149     // hence limiting the number of MsoLogger instances to five.
150     private static final MsoLogger generalMsoLogger = new MsoLogger(Catalog.GENERAL);
151     private static final MsoLogger apihLogger = new MsoLogger(Catalog.APIH);
152     private static final MsoLogger asdcLogger = new MsoLogger(Catalog.ASDC);
153     private static final MsoLogger raLogger = new MsoLogger(Catalog.RA);
154     private static final MsoLogger bpelLogger = new MsoLogger(Catalog.BPEL);
155
156     static {
157         if (instanceUUID == null || ("").equals(instanceUUID)) {
158             instanceUUID = getInstanceUUID();
159         }
160
161         if (serverIP == null || serverName == null || ("").equals(serverIP) || ("").equals(serverName)) {
162             try {
163                 InetAddress server = InetAddress.getLocalHost();
164                 serverIP = server.getHostAddress();
165                 serverName = server.getHostName();
166             } catch (UnknownHostException e) {
167                 LOGGER.log(Level.SEVERE, "Could not get local hostname", e);
168                 serverIP = "";
169                 serverName = "";
170             }
171         }
172     }
173
174     // Singleton instances of the EELFLogger of all types are referenced by MsoLogger
175     private MsoLogger(Catalog cat) {
176         this.logger = EELFManager.getInstance().getErrorLogger();
177         this.auditLogger = EELFManager.getInstance().getAuditLogger();
178         this.metricsLogger = EELFManager.getInstance().getMetricsLogger();
179         this.setDefaultLogCatalog(cat);
180     }
181
182
183
184     /**
185      * Get the MsoLogger based on the catalog
186      * This method is fixed now to resolve the total number of objects that are getting created
187      * everytime this function gets called. Its supposed to have fixed number of instance per java process.
188      *
189      * @param cat
190      *            Catalog of the logger
191      * @return the MsoLogger
192      */
193     public static synchronized MsoLogger getMsoLogger(MsoLogger.Catalog cat) {
194         switch (cat) {
195             case GENERAL:
196                 return generalMsoLogger;
197             case APIH:
198                 return apihLogger;
199             case RA:
200                 return raLogger;
201             case BPEL:
202                 return bpelLogger;
203             case ASDC:
204                 return asdcLogger;
205             default:
206                 return generalMsoLogger;
207         }
208     }
209
210     /**
211      * Record the Metrics event with no argument
212      * 
213      * @param startTime
214      *            Transaction starting time in millieseconds
215      * @param statusCode
216      *            StatusCode of the transaction, either COMPLETE or ERROR
217      * @param responseCode
218      *            The response code returned by the sub-components
219      * @param responseDesc
220      *            Human redable description of the response code
221      * @param targetEntity
222      *            The component which is invoked for this sub-operation
223      * @param targetServiceName
224      *            API invoked on the TargetEntity
225      * @param targetVEntity
226      *            Target VNF or VM acted opon by the component, if available
227      */
228     public void recordMetricEvent(Long startTime, StatusCode statusCode, ResponseCode responseCode, String responseDesc,
229             String targetEntity, String targetServiceName, String targetVEntity) {
230         prepareMetricMsg(startTime, statusCode, responseCode.getValue(), responseDesc, targetEntity, targetServiceName,
231                 targetVEntity);
232         metricsLogger.info("");
233         MDC.remove(TIMER);
234         MDC.remove(TARGETENTITY);
235         MDC.remove(TARGETSERVICENAME);
236     }
237
238     /**
239      * Record the Audit event
240      *
241      * @param startTime
242      *            Transaction starting time in millieseconds
243      * @param statusCode
244      *            StatusCode of the transaction, either COMPLETE or ERROR
245      * @param responseCode
246      *            The application specific response code
247      * @param responseDesc
248      *            Human redable description of the application response code
249      */
250     public void recordAuditEvent(Long startTime, StatusCode statusCode, ResponseCode responseCode,
251             String responseDesc) {
252         prepareAuditMsg(startTime, statusCode, responseCode.getValue(), responseDesc);
253         auditLogger.info("");
254         MDC.remove(TIMER);
255     }
256
257     // Debug methods
258     /**
259      * Record the Debug event
260      *
261      * @param msg
262      *            The log message to put
263      */
264     public void debug(String msg) {
265         prepareMsg(DEBUG_LEVEL);
266         logger.debug(msg);
267     }
268
269     /**
270      * Record the Debug event
271      *
272      * @param msg
273      *            The log message to put
274      * @param t
275      *            The exception to put
276      */
277     public void debug(String msg, Throwable t) {
278         prepareMsg(DEBUG_LEVEL);
279         logger.debug(msg, t);
280     }
281
282     /**
283      * Log error message with the details of the exception that caused the error.
284      * @param msg
285      * @param throwable
286      */
287     public void error(String msg, Throwable throwable) {
288         prepareMsg(ERROR_LEVEL);
289         logger.error(msg, throwable);
290     }
291
292     // Info methods
293     /**
294      * Record the Info event
295      *
296      * @param msg
297      *            The log message to put
298      */
299     public void info(EELFResolvableErrorEnum msg, String targetEntity, String targetServiceName) {
300         prepareErrorMsg(INFO_LEVEL, targetEntity, targetServiceName, null, "");
301
302         logger.info(msg);
303         MDC.remove(TARGETENTITY);
304         MDC.remove(TARGETSERVICENAME);
305     }
306
307     /**
308      * Record the Info event with 1 argument
309      *
310      * @param msg
311      *            The log message to put
312      * @param arg0
313      *            The argument used in the log message
314      */
315     public void info(EELFResolvableErrorEnum msg, String arg0, String targetEntity, String targetServiceName) {
316         prepareErrorMsg(INFO_LEVEL, targetEntity, targetServiceName, null, "");
317
318         logger.info(msg, normalize(arg0));
319         MDC.remove(TARGETENTITY);
320         MDC.remove(TARGETSERVICENAME);
321     }
322
323     /**
324      * Record the Info event with 2 arguments
325      *
326      * @param msg
327      *            The log message to put
328      * @param arg0,arg1
329      *            The arguments used in the log message
330      */
331     public void info(EELFResolvableErrorEnum msg, String arg0, String arg1, String targetEntity,
332             String targetServiceName) {
333         prepareErrorMsg(INFO_LEVEL, targetEntity, targetServiceName, null, "");
334
335         logger.info(msg, normalize(arg0), normalize(arg1));
336         MDC.remove(TARGETENTITY);
337         MDC.remove(TARGETSERVICENAME);
338     }
339
340     /**
341      * Record the Info event with 3 arguments
342      *
343      * @param msg
344      *            The log message to put
345      * @param arg0,arg1,arg2
346      *            The arguments used in the log message
347      */
348     public void info(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String targetEntity,
349             String targetServiceName) {
350         prepareErrorMsg(INFO_LEVEL, targetEntity, targetServiceName, null, "");
351
352         logger.info(msg, normalize(arg0), normalize(arg1), normalize(arg2));
353         MDC.remove(TARGETENTITY);
354         MDC.remove(TARGETSERVICENAME);
355     }
356
357     /**
358      * Record the Info event with 4 arguments
359      *
360      * @param msg
361      *            The log message to put
362      * @param arg0,arg1,arg2,arg3
363      *            The arguments used in the log message
364      */
365     public void info(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3,
366             String targetEntity, String targetServiceName) {
367         prepareErrorMsg(INFO_LEVEL, targetEntity, targetServiceName, null, "");
368
369         logger.info(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3));
370         MDC.remove(TARGETENTITY);
371         MDC.remove(TARGETSERVICENAME);
372     }
373
374     /**
375      * Record the Info event with 5 arguments
376      *
377      * @param msg
378      *            The log message to put
379      * @param arg0,arg1,arg2,arg3,arg4
380      *            The arguments used in the log message
381      */
382     public void info(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3, String arg4,
383             String targetEntity, String targetServiceName) {
384         prepareErrorMsg(INFO_LEVEL, targetEntity, targetServiceName, null, "");
385
386         logger.info(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3), normalize(arg4));
387         MDC.remove(TARGETENTITY);
388         MDC.remove(TARGETSERVICENAME);
389     }
390
391     /**
392      * Record the Info event with 6 arguments
393      *
394      * @param msg
395      *            The log message to put
396      * @param arg0,arg1,arg2,arg3,arg4,arg5
397      *            The arguments used in the log message
398      */
399     public void info(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3, String arg4,
400             String arg5, String targetEntity, String targetServiceName) {
401         prepareErrorMsg(INFO_LEVEL, targetEntity, targetServiceName, null, "");
402
403         logger.info(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3), normalize(arg4),
404                 normalize(arg5));
405         MDC.remove(TARGETENTITY);
406         MDC.remove(TARGETSERVICENAME);
407     }
408
409     // Warning methods
410     /**
411      * Record the Warning event
412      *
413      * @param msg
414      *            The log message to put
415      */
416     public void warn(EELFResolvableErrorEnum msg, String targetEntity, String targetServiceName, ErrorCode errorCode,
417             String errorDesc) {
418         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
419
420         logger.warn(msg);
421         MDC.remove(TARGETENTITY);
422         MDC.remove(TARGETSERVICENAME);
423     }
424
425     /**
426      * Record the Warning event
427      *
428      * @param msg
429      *            The log message to put
430      * @param t
431      *            The exception info
432      */
433     public void warn(EELFResolvableErrorEnum msg, String targetEntity, String targetServiceName, ErrorCode errorCode,
434             String errorDesc, Throwable t) {
435         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
436         logger.warn(msg);
437         logger.warn("Exception raised: " + getNormalizedStackTrace(t));
438         logger.debug("Exception raised", t);
439         MDC.remove(TARGETENTITY);
440         MDC.remove(TARGETSERVICENAME);
441     }
442
443     /**
444      * Record the Warn event with 1 argument
445      *
446      * @param msg
447      *            The log message to put
448      * @param arg
449      *            The argument used in the log message
450      */
451     public void warn(EELFResolvableErrorEnum msg, String arg, String targetEntity, String targetServiceName,
452             ErrorCode errorCode, String errorDesc) {
453         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
454         logger.warn(msg, arg);
455         MDC.remove(TARGETENTITY);
456         MDC.remove(TARGETSERVICENAME);
457     }
458
459     /**
460      * Record the Warn event with 1 argument
461      *
462      * @param msg
463      *            The log message to put
464      * @param arg
465      *            The arguments used in the log message
466      * @param t
467      *            The exception info
468      */
469     public void warn(EELFResolvableErrorEnum msg, String arg, String targetEntity, String targetServiceName,
470             ErrorCode errorCode, String errorDesc, Throwable t) {
471         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
472         logger.warn(msg, arg);
473         logger.warn("Exception raised: " + getNormalizedStackTrace(t));
474         logger.debug("Exception raised", t);
475         MDC.remove(TARGETENTITY);
476         MDC.remove(TARGETSERVICENAME);
477     }
478
479     /**
480      * Record the Warn event with 2 arguments
481      *
482      * @param msg
483      *            The log message to put
484      * @param arg0,arg1
485      *            The arguments used in the log message
486      */
487     public void warn(EELFResolvableErrorEnum msg, String arg0, String arg1, String targetEntity,
488             String targetServiceName, ErrorCode errorCode, String errorDesc) {
489         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
490         logger.warn(msg, normalize(arg0), normalize(arg1));
491         MDC.remove(TARGETENTITY);
492         MDC.remove(TARGETSERVICENAME);
493     }
494
495     /**
496      * Record the Warn event with 2 arguments
497      *
498      * @param msg
499      *            The log message to put
500      * @param arg0,arg1
501      *            The arguments used in the log message
502      * @param t
503      *            The exception info
504      */
505     public void warn(EELFResolvableErrorEnum msg, String arg0, String arg1, String targetEntity,
506             String targetServiceName, ErrorCode errorCode, String errorDesc, Throwable t) {
507         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
508         logger.warn(msg, normalize(arg0), normalize(arg1));
509         logger.warn("Exception raised: " + getNormalizedStackTrace(t));
510         logger.debug("Exception raised", t);
511         MDC.remove(TARGETENTITY);
512         MDC.remove(TARGETSERVICENAME);
513     }
514
515     /**
516      * Record the Warn event with 3 arguments
517      *
518      * @param msg
519      *            The log message to put
520      * @param arg0,arg1,arg2
521      *            The arguments used in the log message
522      */
523     public void warn(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String targetEntity,
524             String targetServiceName, ErrorCode errorCode, String errorDesc) {
525         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
526         logger.warn(msg, normalize(arg0), normalize(arg1), normalize(arg2));
527         MDC.remove(TARGETENTITY);
528         MDC.remove(TARGETSERVICENAME);
529     }
530
531     /**
532      * Record the Warn event with 3 arguments
533      *
534      * @param msg
535      *            The log message to put
536      * @param arg0,arg1,arg2
537      *            The arguments used in the log message
538      * @param t
539      *            The exception info
540      */
541     public void warn(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String targetEntity,
542             String targetServiceName, ErrorCode errorCode, String errorDesc, Throwable t) {
543         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
544         logger.warn(msg, normalize(arg0), normalize(arg1), normalize(arg2));
545         logger.warn("Exception raised: " + getNormalizedStackTrace(t));
546         logger.debug("Exception raised", t);
547         MDC.remove(TARGETENTITY);
548         MDC.remove(TARGETSERVICENAME);
549     }
550
551     /**
552      * Record the Warn event with 4 arguments
553      *
554      * @param msg
555      *            The log message to put
556      * @param arg0,arg1,arg2,arg3
557      *            The arguments used in the log message
558      */
559     public void warn(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3,
560             String targetEntity, String targetServiceName, ErrorCode errorCode, String errorDesc) {
561         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
562         logger.warn(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3));
563         MDC.remove(TARGETENTITY);
564         MDC.remove(TARGETSERVICENAME);
565     }
566
567     /**
568      * Record the Warn event with 4 arguments
569      *
570      * @param msg
571      *            The log message to put
572      * @param arg0,arg1,arg2,
573      *            arg3 The arguments used in the log message
574      * @param t
575      *            The exception info
576      */
577     public void warn(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3,
578             String targetEntity, String targetServiceName, ErrorCode errorCode, String errorDesc, Throwable t) {
579         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
580         logger.warn(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3));
581         logger.warn("Exception raised: " + getNormalizedStackTrace(t));
582         logger.debug("Exception raised", t);
583         MDC.remove(TARGETENTITY);
584         MDC.remove(TARGETSERVICENAME);
585     }
586
587     /**
588      * Record the Warn event with 5 arguments
589      *
590      * @param msg
591      *            The log message to put
592      * @param arg0,arg1,arg2,arg3,arg4
593      *            The arguments used in the log message
594      */
595     public void warn(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3, String arg4,
596             String targetEntity, String targetServiceName, ErrorCode errorCode, String errorDesc) {
597         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
598         logger.warn(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3), normalize(arg4));
599         MDC.remove(TARGETENTITY);
600         MDC.remove(TARGETSERVICENAME);
601     }
602
603     /**
604      * Record the Warn event with 5 arguments
605      *
606      * @param msg
607      *            The log message to put
608      * @param arg0,arg1,arg2,arg3,arg4
609      *            The arguments used in the log message
610      * @param t
611      *            The exception info
612      */
613     public void warn(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3, String arg4,
614             String targetEntity, String targetServiceName, ErrorCode errorCode, String errorDesc, Throwable t) {
615         prepareErrorMsg(WARN_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
616         logger.warn(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3), normalize(arg4));
617         logger.warn("Exception raised: " + getNormalizedStackTrace(t));
618         logger.debug("Exception raised", t);
619         MDC.remove(TARGETENTITY);
620         MDC.remove(TARGETSERVICENAME);
621     }
622
623     // Error methods
624     /**
625      * Record the Error event
626      *
627      * @param msg
628      *            The log message to put
629      */
630     public void error(EELFResolvableErrorEnum msg, String targetEntity, String targetServiceName, ErrorCode errorCode,
631             String errorDesc) {
632         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
633         logger.error(msg);
634         MDC.remove(TARGETENTITY);
635         MDC.remove(TARGETSERVICENAME);
636     }
637
638     /**
639      * Record the Error event
640      *
641      * @param msg
642      *            The log message to put
643      * @param t
644      *            The exception info
645      */
646     public void error(EELFResolvableErrorEnum msg, String targetEntity, String targetServiceName, ErrorCode errorCode,
647             String errorDesc, Throwable t) {
648         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
649         logger.error(msg);
650         logger.error(exceptionArg, getNormalizedStackTrace(t));
651         logger.debug("Exception raised", t);
652         MDC.remove(TARGETENTITY);
653         MDC.remove(TARGETSERVICENAME);
654     }
655
656     /**
657      * Record the Error event with 1 argument
658      *
659      * @param msg
660      *            The log message to put
661      * @param arg0
662      *            The arguments used in the log message
663      */
664     public void error(EELFResolvableErrorEnum msg, String arg0, String targetEntity, String targetServiceName,
665             ErrorCode errorCode, String errorDesc) {
666         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
667         logger.error(msg, normalize(arg0));
668         MDC.remove(TARGETENTITY);
669         MDC.remove(TARGETSERVICENAME);
670     }
671
672     /**
673      * Record the Error event with 1 argument
674      *
675      * @param msg
676      *            The log message to put
677      * @param arg0
678      *            The arguments used in the log message
679      * @param t
680      *            The exception info
681      */
682     public void error(EELFResolvableErrorEnum msg, String arg0, String targetEntity, String targetServiceName,
683             ErrorCode errorCode, String errorDesc, Throwable t) {
684         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
685         logger.error(msg, normalize(arg0));
686         logger.error(exceptionArg, getNormalizedStackTrace(t));
687         logger.debug("Exception raised", t);
688         MDC.remove(TARGETENTITY);
689         MDC.remove(TARGETSERVICENAME);
690     }
691
692     /**
693      * Record the Error event with 2 arguments
694      *
695      * @param msg
696      *            The log message to put
697      * @param arg0,arg1
698      *            The arguments used in the log message
699      */
700     public void error(EELFResolvableErrorEnum msg, String arg0, String arg1, String targetEntity,
701             String targetServiceName, ErrorCode errorCode, String errorDesc) {
702         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
703         logger.error(msg, normalize(arg0), normalize(arg1));
704         MDC.remove(TARGETENTITY);
705         MDC.remove(TARGETSERVICENAME);
706     }
707
708     /**
709      * Record the Error event with 2 arguments
710      *
711      * @param msg
712      *            The log message to put
713      * @param arg0,arg1
714      *            The arguments used in the log message
715      * @param t
716      *            The exception info
717      */
718     public void error(EELFResolvableErrorEnum msg, String arg0, String arg1, String targetEntity,
719             String targetServiceName, ErrorCode errorCode, String errorDesc, Throwable t) {
720         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
721         logger.error(msg, normalize(arg0), normalize(arg1));
722         logger.error(exceptionArg, getNormalizedStackTrace(t));
723         logger.debug("Exception raised", t);
724         MDC.remove(TARGETENTITY);
725         MDC.remove(TARGETSERVICENAME);
726     }
727
728     /**
729      * Record the Error event with 3 arguments
730      *
731      * @param msg
732      *            The log message to put
733      * @param arg0,arg1,arg2
734      *            The arguments used in the log message
735      */
736     public void error(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String targetEntity,
737             String targetServiceName, ErrorCode errorCode, String errorDesc) {
738         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
739         logger.error(msg, normalize(arg0), normalize(arg1), normalize(arg2));
740         MDC.remove(TARGETENTITY);
741         MDC.remove(TARGETSERVICENAME);
742     }
743
744     /**
745      * Record the Error event with 3 arguments
746      *
747      * @param msg
748      *            The log message to put
749      * @param arg0,arg1,arg2
750      *            The arguments used in the log message
751      * @param t
752      *            The exception info
753      */
754     public void error(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String targetEntity,
755             String targetServiceName, ErrorCode errorCode, String errorDesc, Throwable t) {
756         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
757         logger.error(msg, normalize(arg0), normalize(arg1), normalize(arg2));
758         logger.error(exceptionArg, getNormalizedStackTrace(t));
759         logger.debug("Exception raised", t);
760         MDC.remove(TARGETENTITY);
761         MDC.remove(TARGETSERVICENAME);
762     }
763
764     /**
765      * Record the Error event with 4 arguments
766      *
767      * @param msg
768      *            The log message to put
769      * @param arg0,arg1,arg2,arg3
770      *            The arguments used in the log message
771      */
772     public void error(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3,
773             String targetEntity, String targetServiceName, ErrorCode errorCode, String errorDesc) {
774         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
775         logger.error(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3));
776         MDC.remove(TARGETENTITY);
777         MDC.remove(TARGETSERVICENAME);
778     }
779
780     /**
781      * Record the Error event with 4 arguments
782      *
783      * @param msg
784      *            The log message to put
785      * @param arg0,arg1,arg2,arg3
786      *            The arguments used in the log message
787      * @param t
788      *            The exception info
789      */
790     public void error(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3,
791             String targetEntity, String targetServiceName, ErrorCode errorCode, String errorDesc, Throwable t) {
792         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
793         logger.error(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3));
794         logger.error(exceptionArg, getNormalizedStackTrace(t));
795         logger.debug("Exception raised", t);
796         MDC.remove(TARGETENTITY);
797         MDC.remove(TARGETSERVICENAME);
798     }
799
800     /**
801      * Record the Error event with 5 arguments
802      *
803      * @param msg
804      *            The log message to put
805      * @param arg0,arg1,arg2,arg3,arg4
806      *            The arguments used in the log message
807      */
808     public void error(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3, String arg4,
809             String targetEntity, String targetServiceName, ErrorCode errorCode, String errorDesc) {
810         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
811         logger.error(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3), normalize(arg4));
812         MDC.remove(TARGETENTITY);
813         MDC.remove(TARGETSERVICENAME);
814     }
815
816     /**
817      * Record the Error event with 5 arguments
818      *
819      * @param msg
820      *            The log message to put
821      * @param arg0,arg1,arg2,arg3,arg4
822      *            The arguments used in the log message
823      * @param t
824      *            The exception info
825      */
826     public void error(EELFResolvableErrorEnum msg, String arg0, String arg1, String arg2, String arg3, String arg4,
827             String targetEntity, String targetServiceName, ErrorCode errorCode, String errorDesc, Throwable t) {
828         prepareErrorMsg(ERROR_LEVEL, targetEntity, targetServiceName, errorCode, errorDesc);
829         logger.error(msg, normalize(arg0), normalize(arg1), normalize(arg2), normalize(arg3), normalize(arg4));
830         logger.error(exceptionArg, getNormalizedStackTrace(t));
831         logger.debug("Exception raised", t);
832         MDC.remove(TARGETENTITY);
833         MDC.remove(TARGETSERVICENAME);
834     }
835
836     public boolean isDebugEnabled() {
837         return logger.isDebugEnabled();
838     }
839
840     private void prepareMsg(String loggingLevel) {
841         prepareMsg(loggingLevel, null, null);
842     }
843
844     private void prepareMsg(String loggingLevel, String serviceNamep, String timer) {
845         String reqId = MDC.get(REQUEST_ID);
846         String svcId = MDC.get(SERVICE_INSTANCE_ID);
847
848         // Based on the discussion with Adrian,
849         // if these 2 parameters is not available, using dummy value "trace-#"
850         if (reqId == null || reqId.isEmpty()) {
851             MDC.put(REQUEST_ID, DUMMY_VALUE);
852         }
853
854         if (svcId == null || svcId.isEmpty()) {
855             MDC.put(SERVICE_INSTANCE_ID, DUMMY_VALUE);
856         }
857
858         if (timer != null) {
859             MDC.put(TIMER, timer);
860         } else {
861             MDC.remove(TIMER);
862         }
863
864         MDC.put(SERVICE_NAME, getFinalServiceName(serviceNamep));
865         MDC.put(ALERT_SEVERITY, getSeverityLevel(loggingLevel));
866         MDC.put(INSTANCE_UUID, instanceUUID);
867         MDC.put(SERVER_IP, serverIP);
868         MDC.put(FQDN, serverName);
869     }
870
871     private void prepareAuditMsg(long startTime, StatusCode statusCode, int responseCode, String responseDesc) {
872         long endTime = System.currentTimeMillis();
873         prepareMsg(INFO_LEVEL, null, String.valueOf(endTime - startTime));
874         prepareAuditMetricMsg(startTime, endTime, statusCode, responseCode, responseDesc);
875     }
876
877     private void prepareAuditMetricMsg(long startTime, long endTime, StatusCode statusCode, int responseCode,
878             String responseDesc) {
879         Date startDate = new Date(startTime);
880         Date endDate = new Date(endTime);
881         DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
882
883         MDC.put(BEGINTIME, String.valueOf(formatter.format(startDate)));
884         MDC.put(ENDTIME, String.valueOf(formatter.format(endDate)));
885         MDC.put(STATUSCODE, statusCode.name());
886         MDC.put(RESPONSECODE, String.valueOf(responseCode));
887         MDC.put(RESPONSEDESC, responseDesc);
888     }
889
890     private void prepareErrorMsg(String loggingLevel, String targetEntity, String targetServiceName,
891             ErrorCode errorCode, String errorDesc) {
892         MDC.put(ALERT_SEVERITY, getSeverityLevel(loggingLevel));
893         MDC.put(ERRORCODE, String.valueOf(errorCode));
894         MDC.put(ERRORDESC, errorDesc);
895         MDC.put(TARGETENTITY, targetEntity);
896         MDC.put(TARGETSERVICENAME, targetServiceName);
897         MDC.put(SERVICE_NAME, getFinalServiceName(getServiceName()));
898     }
899
900     private void prepareMetricMsg(long startTime, StatusCode statusCode, int responseCode, String responseDesc,
901             String targetEntity, String targetServiceName, String targetVEntity) {
902         long endTime = System.currentTimeMillis();
903         prepareMsg(INFO_LEVEL, null, String.valueOf(endTime - startTime));
904         prepareAuditMetricMsg(startTime, endTime, statusCode, responseCode, responseDesc);
905
906         // Populate Metric log specific parameter
907         MDC.put(TARGETENTITY, targetEntity);
908         MDC.put(TARGETSERVICENAME, targetServiceName);
909
910         if (null != targetVEntity) {
911             MDC.put(TARGETVIRTUALENTITY, targetVEntity);
912         }
913     }
914
915     private String getSeverityLevel(String loggingLevel) {
916         String severity;
917         // According to the Nagios alerting: 0=OK; 1=WARNING; 2=UNKOWN;
918         // 3=CRITICAL
919         switch (loggingLevel) {
920             case ERROR_LEVEL:
921                 severity = "2";
922                 break;
923             case FATAL_LEVEL:
924                 severity = "3";
925                 break;
926             case WARN_LEVEL:
927                 severity = "1";
928                 break;
929             default:
930                 severity = "0";
931                 break;
932         }
933         return severity;
934     }
935
936     private String getFinalServiceName(String serviceNamep) {
937         // This step to set the serviceName should be put after the className is
938         // get,
939         // since the default serviceName is obtained during the method to get
940         // the className.
941         //
942         // There's 3 ways to set the serviceName. The first method has the most
943         // priority to set the value.
944         // a) If the serviceName is set within the log method, this value will
945         // be used first
946         // b) If serviceName is not set within the log method, the value defined
947         // in the MDC will be used
948         // c) If nothing is set specifically, then MsoLogger will assign a
949         // default(MSO.<method_name>) value to it
950         String serName = MDC.get(MsoLogger.SERVICE_NAME);
951
952         // Check if service name was already set as the method name by a
953         // previous call to this method.
954         String isMethodNameStr = MDC.get(MsoLogger.SERVICE_NAME_IS_METHOD_NAME);
955         boolean isMethodName = isMethodNameStr != null && isMethodNameStr.equals(Boolean.TRUE.toString());
956         if (serviceNamep != null) {
957             return serviceNamep;
958         } else if (serName != null && !isMethodName) {
959             return serName;
960         }
961
962         MDC.put(MsoLogger.SERVICE_NAME_IS_METHOD_NAME, Boolean.TRUE.toString());
963         int limit;
964         StackTraceElement[] classArr = new Exception().getStackTrace();
965         if (classArr.length >= 6) {
966             limit = 7;
967         } else {
968             limit = classArr.length;
969         }
970         for (int i = 1; i < limit; i++) {
971             String className = classArr[i].getClassName();
972             if (!className.equals(this.getClass().getName())) {
973                 return classArr[i].getMethodName();
974             }
975         }
976         return classArr[0].getMethodName();
977     }
978
979     // Based on the discussion with Adrian, instanceUUID is used to identifiy
980     // the mso instance,
981     // it is generated during mso instance initialization period
982     // The same mso instnace will use the same instanceUUID value, even after
983     // restart
984     private static String getInstanceUUID() {
985         // Avoid creation during build and tests
986         if (System.getProperty("jboss.server.name") == null) {
987             return "Test UUID as JBoss not found";
988         }
989         File configFile = new File(CONFIG_FILE);
990         String uuid = "";
991         BufferedReader in = null;
992         try{
993             // Verify whether instanceUUID file exist,
994             // If yes, read the content; if not, generate the instanceUUID and
995             // write to the file
996             if (configFile.exists()) {
997                 // read the content of the file
998                 in = new BufferedReader(new FileReader(CONFIG_FILE));
999                 if ((uuid = in.readLine()) == null) {
1000                     // the file is empty, regenerate the file
1001                     uuid = UUID.randomUUID().toString();
1002                     try(BufferedWriter bw = new BufferedWriter(new FileWriter(configFile.getAbsoluteFile()))) {
1003                     bw.write(uuid);
1004                     } catch (IOException e) {
1005                       LOGGER.log(Level.SEVERE, "Error trying to write UUID file", e);
1006                                         }
1007                 }
1008                 in.close();
1009             } else {
1010                 // file doesn't exist yet -> create the file and generate the
1011                 // instanceUUID
1012                 uuid = UUID.randomUUID().toString();
1013                 configFile.getParentFile().mkdirs();
1014                 configFile.createNewFile();
1015                 try(BufferedWriter bw1 = new BufferedWriter(new FileWriter(configFile.getAbsoluteFile()))){
1016                 bw1.write(uuid);
1017                 } catch (IOException e) {
1018                   LOGGER.log(Level.SEVERE, "Error trying to write UUID file", e);
1019                                 }
1020             }
1021         } catch (IOException e) {
1022           LOGGER.log(Level.SEVERE, "Error trying to read UUID file", e);
1023         } finally {
1024             try {
1025                 if (in != null) {
1026                     in.close();
1027                 }
1028             } catch (IOException ex) {
1029                 LOGGER.log(Level.SEVERE, "Error trying to close UUID file", ex);
1030             }
1031         }
1032         return uuid;
1033     }
1034
1035     /**
1036      * Set the requestId and serviceInstanceId
1037      * 
1038      * @param reqId
1039      *            The requestId
1040      * @param svcId
1041      *            The serviceInstanceId
1042      */
1043     public static void setLogContext(String reqId, String svcId) {
1044         if (null != reqId) {
1045             MDC.put(REQUEST_ID, reqId);
1046         }
1047
1048         if (null != svcId) {
1049             MDC.put(SERVICE_INSTANCE_ID, svcId);
1050         }
1051     }
1052
1053     /**
1054      * Set the remoteIp and the basic HTTP Authentication user
1055      * 
1056      * @param remoteIpp
1057      *            The remote ip address
1058      * @param userp
1059      *            The basic http authencitation user
1060      */
1061     public static void setLoggerParameters(String remoteIpp, String userp) {
1062         if (null != remoteIpp) {
1063             MDC.put(REMOTE_HOST, remoteIpp);
1064         }
1065         if (null != userp) {
1066             MDC.put(USER, userp);
1067         }
1068     }
1069
1070     /**
1071      * Set the serviceName
1072      * 
1073      * @param serviceNamep
1074      *            The service name
1075      */
1076     public static void setServiceName(String serviceNamep) {
1077         if (null != serviceNamep) {
1078             MDC.put(SERVICE_NAME, serviceNamep);
1079             MDC.remove(SERVICE_NAME_IS_METHOD_NAME);
1080         }
1081     }
1082
1083     /**
1084      * Get the serviceName
1085      * 
1086      * @return The service name
1087      */
1088     public static String getServiceName() {
1089         return MDC.get(SERVICE_NAME);
1090     }
1091
1092     /**
1093      * Reset the serviceName
1094      */
1095     public static void resetServiceName() {
1096         MDC.remove(SERVICE_NAME);
1097     }
1098
1099     /**
1100      * Set the requestId and serviceInstanceId based on the mso request
1101      * 
1102      * @param msoRequest
1103      *            The mso request
1104      */
1105     public static void setLogContext(MsoRequest msoRequest) {
1106         if (msoRequest != null) {
1107             MDC.put(REQUEST_ID, msoRequest.getRequestId());
1108             MDC.put(SERVICE_INSTANCE_ID, msoRequest.getServiceInstanceId());
1109         } else {
1110             MDC.put(REQUEST_ID, DUMMY_VALUE);
1111             MDC.put(SERVICE_INSTANCE_ID, DUMMY_VALUE);
1112         }
1113     }
1114
1115     private String normalize(String input) {
1116         if (input == null) {
1117             return null;
1118         }
1119         String result = input.replace('|', '!');
1120         result = result.replace("\n", " - ");
1121         return result;
1122     }
1123
1124     private String getNormalizedStackTrace(Throwable t) {
1125         StringWriter sw = new StringWriter();
1126         PrintWriter pw = new PrintWriter(sw);
1127         t.printStackTrace(pw);
1128         return sw.toString().replace('|', '!').replace("\n", " - ");
1129     }
1130
1131     private void setDefaultLogCatalog(MsoLogger.Catalog cat) {
1132         if ("APIH".equals(cat.toString())) {
1133             exceptionArg = MessageEnum.APIH_GENERAL_EXCEPTION_ARG;
1134             defaultException = MessageEnum.APIH_GENERAL_EXCEPTION;
1135             defaultWarning = MessageEnum.APIH_GENERAL_WARNING;
1136             defaultAudit = MessageEnum.APIH_AUDIT_EXEC;
1137             defaultMetrics = MessageEnum.APIH_GENERAL_METRICS;
1138         } else if ("RA".equals(cat.toString())) {
1139             exceptionArg = MessageEnum.RA_GENERAL_EXCEPTION_ARG;
1140             defaultException = MessageEnum.RA_GENERAL_EXCEPTION;
1141             defaultWarning = MessageEnum.RA_GENERAL_WARNING;
1142             defaultAudit = MessageEnum.RA_AUDIT_EXEC;
1143             defaultMetrics = MessageEnum.RA_GENERAL_METRICS;
1144         } else if ("BPEL".equals(cat.toString())) {
1145             exceptionArg = MessageEnum.BPMN_GENERAL_EXCEPTION_ARG;
1146             defaultException = MessageEnum.BPMN_GENERAL_EXCEPTION;
1147             defaultWarning = MessageEnum.BPMN_GENERAL_WARNING;
1148             defaultAudit = MessageEnum.BPMN_AUDIT_EXEC;
1149             defaultMetrics = MessageEnum.BPMN_GENERAL_METRICS;
1150         } else if ("ASDC".equals(cat.toString())) {
1151             exceptionArg = MessageEnum.ASDC_GENERAL_EXCEPTION_ARG;
1152             defaultException = MessageEnum.ASDC_GENERAL_EXCEPTION;
1153             defaultWarning = MessageEnum.ASDC_GENERAL_WARNING;
1154             defaultAudit = MessageEnum.ASDC_AUDIT_EXEC;
1155             defaultMetrics = MessageEnum.ASDC_GENERAL_METRICS;
1156         } else {
1157             exceptionArg = MessageEnum.GENERAL_EXCEPTION_ARG;
1158             defaultException = MessageEnum.GENERAL_EXCEPTION;
1159             defaultWarning = MessageEnum.GENERAL_WARNING;
1160             defaultAudit = MessageEnum.AUDIT_EXEC;
1161             defaultMetrics = MessageEnum.GENERAL_METRICS;
1162         }
1163     }
1164 }