From 025301d08b061482c1f046d562bf017c8cbcfe8d Mon Sep 17 00:00:00 2001 From: ChrisC Date: Tue, 31 Jan 2017 11:40:03 +0100 Subject: Initial OpenECOMP MSO commit Change-Id: Ia6a7574859480717402cc2f22534d9973a78fa6d Signed-off-by: ChrisC --- .../java/org/openecomp/mso/logger/LogFilter.java | 63 ++ .../java/org/openecomp/mso/logger/MessageEnum.java | 229 +++++ .../org/openecomp/mso/logger/MsoAlarmLogger.java | 181 ++++ .../openecomp/mso/logger/MsoLogInitializer.java | 108 +++ .../java/org/openecomp/mso/logger/MsoLogger.java | 973 +++++++++++++++++++++ .../openecomp/mso/logger/MsoLoggingServlet.java | 155 ++++ 6 files changed, 1709 insertions(+) create mode 100644 common/src/main/java/org/openecomp/mso/logger/LogFilter.java create mode 100644 common/src/main/java/org/openecomp/mso/logger/MessageEnum.java create mode 100644 common/src/main/java/org/openecomp/mso/logger/MsoAlarmLogger.java create mode 100644 common/src/main/java/org/openecomp/mso/logger/MsoLogInitializer.java create mode 100644 common/src/main/java/org/openecomp/mso/logger/MsoLogger.java create mode 100644 common/src/main/java/org/openecomp/mso/logger/MsoLoggingServlet.java (limited to 'common/src/main/java/org/openecomp/mso/logger') diff --git a/common/src/main/java/org/openecomp/mso/logger/LogFilter.java b/common/src/main/java/org/openecomp/mso/logger/LogFilter.java new file mode 100644 index 0000000000..ca25ad2e22 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/logger/LogFilter.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.mso.logger; + + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.MDC; + +import java.io.IOException; +import java.security.Principal; + +public class LogFilter implements Filter { + @Override + public void destroy() { + // Nothing to do. + } + + @Override + public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { + final HttpServletRequest httpRequest = (HttpServletRequest) request; + final HttpServletResponse httpResponse = (HttpServletResponse) response; + + MDC.clear (); + MDC.put (MsoLogger.REMOTE_HOST, httpRequest.getRemoteAddr()); + + Principal userPrincipal = httpRequest.getUserPrincipal(); + if (null != userPrincipal) { + MDC.put (MsoLogger.PARTNERNAME, userPrincipal.getName ()); + } + chain.doFilter(httpRequest, httpResponse); + } + + @Override + public void init(final FilterConfig config) throws ServletException { + // Nothing to do + } +} diff --git a/common/src/main/java/org/openecomp/mso/logger/MessageEnum.java b/common/src/main/java/org/openecomp/mso/logger/MessageEnum.java new file mode 100644 index 0000000000..89f6df93b7 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/logger/MessageEnum.java @@ -0,0 +1,229 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.mso.logger; + + +import com.att.eelf.i18n.EELFResolvableErrorEnum; +import com.att.eelf.i18n.EELFResourceManager; + +public enum MessageEnum implements EELFResolvableErrorEnum{ + // Api Handler Messages + APIH_REQUEST_NULL, + APIH_QUERY_FOUND, + APIH_QUERY_NOT_FOUND, + APIH_QUERY_PARAM_WRONG, + APIH_DB_ACCESS_EXC, + APIH_DB_ACCESS_EXC_REASON, + APIH_VALIDATION_ERROR, + APIH_REQUEST_VALIDATION_ERROR, + APIH_SERVICE_VALIDATION_ERROR, + APIH_GENERAL_EXCEPTION_ARG, + APIH_GENERAL_EXCEPTION, + APIH_GENERAL_WARNING, + APIH_AUDIT_EXEC, + APIH_GENERAL_METRICS, + APIH_DUPLICATE_CHECK_EXC, + APIH_DUPLICATE_FOUND, + APIH_BAD_ORDER, + APIH_DB_ATTRIBUTE_NOT_FOUND, + APIH_BPEL_COMMUNICATE_ERROR, + APIH_BPEL_RESPONSE_ERROR, + APIH_WARP_REQUEST, + APIH_ERROR_FROM_BPEL_SERVER, + APIH_DB_INSERT_EXC, + APIH_DB_UPDATE_EXC, + APIH_NO_PROPERTIES, + APIH_PROPERTY_LOAD_SUC, + APIH_LOAD_PROPERTIES_FAIL, + APIH_SDNC_COMMUNICATE_ERROR, + APIH_SDNC_RESPONSE_ERROR, + APIH_CANNOT_READ_SCHEMA, + APIH_HEALTH_CHECK_EXCEPTION, + APIH_REQUEST_VALIDATION_ERROR_REASON, + APIH_JAXB_MARSH_ERROR, + APIH_JAXB_UNMARSH_ERROR, + APIH_VNFREQUEST_VALIDATION_ERROR, + APIH_DOM2STR_ERROR, + APIH_READ_VNFOUTPUT_CLOB_EXCEPTION, + APIH_DUPLICATE_CHECK_EXC_ATT, + APIH_GENERATED_REQUEST_ID, + APIH_GENERATED_SERVICE_INSTANCE_ID, + APIH_REPLACE_REQUEST_ID, + // Resource Adapter Messages + RA_GENERAL_EXCEPTION_ARG, + RA_GENERAL_EXCEPTION, + RA_GENERAL_WARNING, + RA_MISSING_PARAM, + RA_AUDIT_EXEC, + RA_GENERAL_METRICS, + RA_CREATE_STACK_TIMEOUT, + RA_DELETE_STACK_TIMEOUT, + RA_UPDATE_STACK_TIMEOUT, + RA_CONNECTION_EXCEPTION, + RA_PARSING_ERROR, + RA_PROPERTIES_NOT_FOUND, + RA_LOAD_PROPERTIES_SUC, + RA_NETWORK_ALREADY_EXIST, + RA_UPDATE_NETWORK_ERR, + RA_CREATE_STACK_ERR, + RA_UPDATE_STACK_ERR, + RA_CREATE_TENANT_ERR, + RA_NETWORK_NOT_FOUND, + RA_NETWORK_ORCHE_MODE_NOT_SUPPORT, + RA_CREATE_NETWORK_EXC, + RA_PARAM_NOT_FOUND, + RA_CONFIG_EXC, + RA_UNKOWN_PARAM, + RA_VLAN_PARSE, + RA_DELETE_NETWORK_EXC, + RA_ROLLBACK_NULL, + RA_TENANT_NOT_FOUND, + RA_QUERY_NETWORK_EXC, + RA_CREATE_NETWORK_NOTIF_EXC, + RA_ASYNC_ROLLBACK, + RA_WSDL_NOT_FOUND, + RA_WSDL_URL_CONVENTION_EXC, + RA_INIT_NOTIF_EXC, + RA_SET_CALLBACK_AUTH_EXC, + RA_FAULT_INFO_EXC, + RA_MARSHING_ERROR, + RA_PARSING_REQUEST_ERROR, + RA_SEND_REQUEST_SDNC, + RA_RESPONSE_FROM_SDNC, + RA_EXCEPTION_COMMUNICATE_SDNC, + RA_EVALUATE_XPATH_ERROR, + RA_ANALYZE_ERROR_EXC, + RA_ERROR_GET_RESPONSE_SDNC, + RA_CALLBACK_BPEL, + RA_INIT_CALLBACK_WSDL_ERR, + RA_CALLBACK_BPEL_EXC, + RA_CALLBACK_BPEL_COMPLETE, + RA_SDNC_MISS_CONFIG_PARAM, + RA_SDNC_INVALID_CONFIG, + RA_PRINT_URL, + RA_ERROR_CREATE_SDNC_REQUEST, + RA_ERROR_CREATE_SDNC_RESPONSE, + RA_ERROR_CONVERT_XML2STR, + RA_RECEIVE_SDNC_NOTIF, + RA_INIT_SDNC_ADAPTER, + RA_SEND_REQUEST_APPC_ERR, + RA_SEND_REQUEST_SDNC_ERR, + RA_RECEIVE_BPEL_REQUEST, + RA_TENANT_ALREADY_EXIST, + RA_UPDATE_TENANT_ERR, + RA_DELETE_TEMAMT_ERR, + RA_ROLLBACK_TENANT_ERR, + RA_QUERY_VNF_ERR, + RA_VNF_ALREADY_EXIST, + RA_VNF_UNKNOWN_PARAM, + RA_VNF_EXTRA_PARAM, + RA_CREATE_VNF_ERR, + RA_VNF_NOT_EXIST, + RA_UPDATE_VNF_ERR, + RA_DELETE_VNF_ERR, + RA_ASYNC_CREATE_VNF, + RA_SEND_VNF_NOTIF_ERR, + RA_ASYNC_CREATE_VNF_COMPLETE, + RA_ASYNC_UPDATE_VNF, + RA_ASYNC_UPDATE_VNF_COMPLETE, + RA_ASYNC_QUERY_VNF, + RA_ASYNC_QUERY_VNF_COMPLETE, + RA_ASYNC_DELETE_VNF, + RA_ASYNC_DELETE_VNF_COMPLETE, + RA_ASYNC_ROLLBACK_VNF, + RA_ASYNC_ROLLBACK_VNF_COMPLETE, + RA_ROLLBACK_VNF_ERR, + RA_DB_INVALID_STATUS, + RA_CANT_UPDATE_REQUEST, + RA_DB_REQUEST_NOT_EXIST, + RA_CONFIG_NOT_FOUND, + RA_CONFIG_LOAD, + // BPEL engine Messages + BPMN_GENERAL_INFO, + BPMN_GENERAL_EXCEPTION_ARG, + BPMN_GENERAL_EXCEPTION, + BPMN_GENERAL_WARNING, + BPMN_AUDIT_EXEC, + BPMN_GENERAL_METRICS, + BPMN_URN_MAPPING_FAIL, + BPMN_VARIABLE_NULL, + BPMN_SDNC_CALLBACK_EXCEPTION, + // ASDC Messages + ASDC_GENERAL_EXCEPTION_ARG, + ASDC_GENERAL_EXCEPTION, + ASDC_GENERAL_WARNING, + ASDC_AUDIT_EXEC, + ASDC_GENERAL_METRICS, + ASDC_CREATE_SERVICE, + ASDC_ARTIFACT_ALREADY_DEPLOYED, + ASDC_CREATE_ARTIFACT, + ASDC_ARTIFACT_INSTALL_EXC, + ASDC_ARTIFACT_ALREADY_DEPLOYED_DETAIL, + ASDC_ARTIFACT_NOT_DEPLOYED_DETAIL, + ASDC_ARTIFACT_CHECK_EXC, + ASDC_INIT_ASDC_CLIENT_EXC, + ASDC_INIT_ASDC_CLIENT_SUC, + ASDC_LOAD_ASDC_CLIENT_EXC, + ASDC_SINGLETON_CHECKT_EXC, + ASDC_SHUTDOWN_ASDC_CLIENT_EXC, + ASDC_CHECK_HEAT_TEMPLATE, + ASDC_START_INSTALL_ARTIFACT, + ASDC_ARTIFACT_TYPE_NOT_SUPPORT, + ASDC_ARTIFACT_ALREADY_EXIST, + ASDC_ARTIFACT_DOWNLOAD_SUC, + ASDC_ARTIFACT_DOWNLOAD_FAIL, + ASDC_START_DEPLOY_ARTIFACT, + ASDC_SEND_NOTIF_ASDC, + ASDC_SEND_NOTIF_ASDC_EXEC, + ASDC_RECEIVE_CALLBACK_NOTIF, + ASDC_RECEIVE_SERVICE_NOTIF, + ASDC_ARTIFACT_NULL, + ASDC_SERVICE_NOT_SUPPORT, + ASDC_ARTIFACT_DEPLOY_SUC, + ASDC_PROPERTIES_NOT_FOUND, + // Default Messages, in case Log catalog is not defined + GENERAL_EXCEPTION_ARG, + GENERAL_EXCEPTION, + GENERAL_WARNING, + AUDIT_EXEC, + GENERAL_METRICS, + LOGGER_SETUP, + LOGGER_NOT_FOUND, + LOGGER_UPDATE_SUC, + LOGGER_UPDATE_DEBUG, + LOGGER_UPDATE_DEBUG_SUC, + LOAD_PROPERTIES_SUC, + NO_PROPERTIES, + MADATORY_PARAM_MISSING, + LOAD_PROPERTIES_FAIL, + INIT_LOGGER, + INIT_LOGGER_FAIL, + JAXB_EXCEPTION, + IDENTITY_SERVICE_NOT_FOUND; + + static { + EELFResourceManager.loadMessageBundle("GenericMessages"); + EELFResourceManager.loadMessageBundle("ApiHandler"); + EELFResourceManager.loadMessageBundle("BPMN"); + EELFResourceManager.loadMessageBundle("ResourceAdapter"); + EELFResourceManager.loadMessageBundle("ASDC"); + } +} diff --git a/common/src/main/java/org/openecomp/mso/logger/MsoAlarmLogger.java b/common/src/main/java/org/openecomp/mso/logger/MsoAlarmLogger.java new file mode 100644 index 0000000000..147c1ad4f1 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/logger/MsoAlarmLogger.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.mso.logger; + + +import java.io.File; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.encoder.PatternLayoutEncoder; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.rolling.RollingFileAppender; +import ch.qos.logback.core.rolling.TimeBasedRollingPolicy; + +/** + * Wrapper around log4j and Nagios NRDP passive alarming for MSO. + * + * For local alarm logging, this class will look for an alarm log file name + * in the servlet context parameter "mso.alarms.file". If none is found, + * it will look for an MsoProperty of the same name. As a last resort, + * it will use the default path "/var/log/ecomp/MSO/alarms/alarm.log". + * It is expected that all alarms within an application will use the same + * alarm file, so there is no way to dynamically add other alarm files. + * + * Alarms are logged as a simple pipe-delimited string of the format: + * ||| + * + * This class also supports real-time Nagios NRDP alarming. If enabled via + * MsoProperties, all alarms generated and logged to the local alarm file will + * also be transmitted to a Nagios NRDP instance. NRDP requires 4 parameters + * in service alarm events (all Mso Alarms will be Service Alarms): + * hostname, servicename, state, detail + * + * The log file format is also intended to be compatible with Nagios NRDP for + * non-real-time reporting. The command-line tool for sending alarms is + * is "send_nrdp.php", which takes the same 4 parameters as input. + * It will be easy enough to translate entries from an alarm.log file to + * NRDP if real-time NRDP alarming is not enabled. + * + * For Nagios integration, the alarmTypes should all match "service names" + * configured in the receiving Nagios server. Also, the alarm state will + * be limited to the 4 values defined by Nagios: + * 0 = OK, 1 = Warning, 2 = Critical, 3 = Unknown + * + * + */ +public class MsoAlarmLogger implements ServletContextListener { + + private Logger alarmLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(MSO_ALARM_CONTEXT); + private static RollingFileAppender fileAppender = null; + public static final String DEFAULT_MSO_ALARM_FILE = "/var/log/ecomp/MSO/alarms/alarm.log"; + public static final String MSO_ALARM_CONTEXT = "mso.alarms"; + + public static final int OK = 0; + public static final int WARNING = 1; + public static final int CRITICAL = 2; + public static final int UNKNOWN = 3; + + /** + * Get the default MSO Alarm Logger + */ + public MsoAlarmLogger () { + + initializeAlarmLogger(null); + + } + + public MsoAlarmLogger (String alarmFile) { + initializeAlarmLogger(alarmFile); + + } + + /** + * Method to record an alarm. + * + * @param alarm - the alarm identifier (Nagios "service") + * @param state - the alarm state/severity, based on Nagios service + * state values: 0 = OK, 1 = Warning, 2 = Critical, 3 = Unknown + * @param detail - detail message (may contain additional internal + * structure per alarm type) + */ + public void sendAlarm (String alarm, int state, String detail) { + // Write the alarm to Log file + if (alarmLogger != null) { + String output = alarm + "|" + state + "|" + detail; + alarmLogger.info (output); + } + + } + + @Override + public void contextDestroyed (ServletContextEvent event) { + // Nothing to do... + } + + @Override + public void contextInitialized (ServletContextEvent event) { + String msoAlarmFile = event.getServletContext ().getInitParameter ("mso.alarm.file"); + if (msoAlarmFile == null) { + msoAlarmFile = DEFAULT_MSO_ALARM_FILE; + } + + initializeAlarmLogger (msoAlarmFile); + } + + private void initializeAlarmLogger (String alarmFile) { + synchronized (MsoAlarmLogger.class) { + if (fileAppender == null) { + if (alarmFile != null) { + fileAppender = MsoAlarmLogger.getAppender (alarmFile); + } else { + fileAppender = MsoAlarmLogger.getAppender (DEFAULT_MSO_ALARM_FILE); + } + } + } + // The alarmLogger was static originally. + // The initialization of the alarmLogger was fine, but not sure why, it lost its appender info later + // Due to that issue, the alarmLogger is not static any more. + // Instead static attribute fileAppender is added and will be assigned to the alarmLogger every time new MsoAlarmLogger is created. + alarmLogger.setLevel (Level.INFO); + alarmLogger.addAppender (fileAppender); + alarmLogger.setAdditive (false); + } + + + private static RollingFileAppender getAppender (String msoAlarmFile) { + // Create a Logger for alarms. Just use a default Pattern that outputs + // a message. MsoAlarmLogger will handle the formatting. + File alarmFile = new File (msoAlarmFile); + File alarmDir = alarmFile.getParentFile (); + if (!alarmDir.exists ()) { + alarmDir.mkdirs (); + } + + String logPattern = "%d{yyyy-MM-dd HH:mm:ss}|%m%n"; + + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + PatternLayoutEncoder encoder=new PatternLayoutEncoder(); + encoder.setPattern(logPattern); + encoder.setContext(context); + encoder.start(); + RollingFileAppender fileAppender=new RollingFileAppender(); + TimeBasedRollingPolicy rollingPolicy=new TimeBasedRollingPolicy(); + rollingPolicy.setContext(context); + rollingPolicy.setFileNamePattern(msoAlarmFile + ".%d"); + rollingPolicy.setParent(fileAppender); + rollingPolicy.start(); + fileAppender.setFile(msoAlarmFile); + fileAppender.setAppend(true); + fileAppender.setEncoder(encoder); + fileAppender.setRollingPolicy(rollingPolicy); + fileAppender.setContext(context); + fileAppender.start(); + + return fileAppender; + } + +} diff --git a/common/src/main/java/org/openecomp/mso/logger/MsoLogInitializer.java b/common/src/main/java/org/openecomp/mso/logger/MsoLogInitializer.java new file mode 100644 index 0000000000..0c96dabbea --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/logger/MsoLogInitializer.java @@ -0,0 +1,108 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.mso.logger; + + +import java.io.File; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.joran.JoranConfigurator; + + +/** + * This class will attempt to initialize MSO log4j when part of a web application. + * It will look for the logback configuration file logback.xml in the + * following order: + * 1. In an init-param "log.configuration" in web.xml + * 2. TODO: In a property "log.configuration" in an "application.properties" file + * 3. In the default location "/etc/ecomp/mso/config" + * 4. Using the log4j default (check system property log.configuration or + * just look on the classpath for logback.xml) + * + * + */ +@WebListener +public class MsoLogInitializer implements ServletContextListener +{ + private static String DEFAULT_LOG4J_PROPERTIES_FILE = "/etc/ecomp/mso/config/logback.xml"; + private static String prefixMsoPropertiesPath = System.getProperty("mso.config.path"); + static { + if (prefixMsoPropertiesPath == null) { + prefixMsoPropertiesPath = "/"; + } else if (!(prefixMsoPropertiesPath.charAt(prefixMsoPropertiesPath.length() - 1) == '/')) { + prefixMsoPropertiesPath = prefixMsoPropertiesPath + "/"; + } + } + + public MsoLogInitializer () { + } + + + @Override + public void contextDestroyed(ServletContextEvent event) { + // Nothing to do... + } + + @Override + public void contextInitialized(ServletContextEvent event) + { + String logPropertiesFile = null; + try { + // Look first in the init-parameters + String initParam = event.getServletContext().getInitParameter("log.configuration"); + if (initParam != null && fileIsReadable(prefixMsoPropertiesPath + initParam)) { + logPropertiesFile = prefixMsoPropertiesPath + initParam; + } + else if (fileIsReadable(DEFAULT_LOG4J_PROPERTIES_FILE)) { + logPropertiesFile = DEFAULT_LOG4J_PROPERTIES_FILE; + } + + if (logPropertiesFile != null) { + // Initialize loggers with the specified file. If no such file was + // specified, will use the default Log4j resolution. + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + JoranConfigurator jc = new JoranConfigurator(); + jc.setContext(context); + context.reset(); + jc.doConfigure(logPropertiesFile); + // Try it out + MsoLogger initLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.GENERAL); + initLogger.info(MessageEnum.INIT_LOGGER, logPropertiesFile, "", ""); + } + } catch (Exception e) { + MsoLogger initLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.GENERAL); + initLogger.error (MessageEnum.INIT_LOGGER_FAIL, "", "", MsoLogger.ErrorCode.UnknownError, "", e); + } + } + + private boolean fileIsReadable (String filePath) { + File f = new File(filePath); + if (f.exists() && f.canRead()) + return true; + return false; + } +} diff --git a/common/src/main/java/org/openecomp/mso/logger/MsoLogger.java b/common/src/main/java/org/openecomp/mso/logger/MsoLogger.java new file mode 100644 index 0000000000..c53022734f --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/logger/MsoLogger.java @@ -0,0 +1,973 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.mso.logger; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.slf4j.MDC; + +import org.openecomp.mso.entity.MsoRequest; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Simple wrapper around the EELF Logger class for MSO usage. + * This class supports all of the normal logging functions (debug, info, etc.), + * prepending a string of format "[|) value to it + String serName = MDC.get (MsoLogger.SERVICE_NAME); + + // Check if service name was already set as the method name by a previous call to this method. + String isMethodNameStr = MDC.get (MsoLogger.SERVICE_NAME_IS_METHOD_NAME); + boolean isMethodName = isMethodNameStr != null && isMethodNameStr.equals (Boolean.TRUE.toString ()); + if (serviceNamep != null) { + return serviceNamep; + } else if (serName != null && !isMethodName) { + return serName; + } + + MDC.put (MsoLogger.SERVICE_NAME_IS_METHOD_NAME, Boolean.TRUE.toString ()); + int limit; + StackTraceElement[] classArr = new Exception ().getStackTrace (); + if (classArr.length >=6) { + limit = 7; + } else { + limit = classArr.length; + } + for (int i = 1; i < limit; i++) { + String className = classArr[i].getClassName (); + if (!className.equals (this.getClass ().getName ())) { + return classArr[i].getMethodName (); + } + } + return classArr[0].getMethodName (); + } + + // Based on the discussion with Adrian, instanceUUID is used to identifiy the mso instance, + // it is generated during mso instance initialization period + // The same mso instnace will use the same instanceUUID value, even after restart + private static String getInstanceUUID () { + // Avoid creation during build and tests + if (System.getProperty ("jboss.server.name") == null) { + return "Test UUID as JBoss not found"; + } + File configFile = new File (CONFIG_FILE); + String uuid = ""; + BufferedReader in = null; + BufferedWriter bw = null; + try { + // Verify whether instanceUUID file exist, + // If yes, read the content; if not, generate the instanceUUID and write to the file + if (configFile.exists ()) { + // read the content of the file + in = new BufferedReader (new FileReader (CONFIG_FILE)); + if ((uuid = in.readLine ()) == null) { + // the file is empty, regenerate the file + uuid = UUID.randomUUID ().toString (); + FileWriter fw = new FileWriter (configFile.getAbsoluteFile ()); + bw = new BufferedWriter (fw); + bw.write (uuid); + bw.close (); + } + in.close (); + } else { + // file doesn't exist yet -> create the file and generate the instanceUUID + uuid = UUID.randomUUID ().toString (); + configFile.getParentFile ().mkdirs (); + configFile.createNewFile (); + FileWriter fw = new FileWriter (configFile.getAbsoluteFile ()); + bw = new BufferedWriter (fw); + bw.write (uuid); + bw.close (); + } + } catch (IOException e) { + LOGGER.log (Level.SEVERE, "Error trying to read UUID file", e); + } finally { + try { + if (in != null) { + in.close (); + } + if (bw != null) { + bw.close (); + } + } catch (IOException ex) { + LOGGER.log (Level.SEVERE, "Error trying to close UUID file", ex); + } + } + return uuid; + } + + /** + * Set the requestId and serviceInstanceId + * @param reqId The requestId + * @param svcId The serviceInstanceId + */ + public static void setLogContext (String reqId, String svcId) { + if (null != reqId) { + MDC.put (REQUEST_ID, reqId); + } + + if (null != svcId) { + MDC.put (SERVICE_INSTANCE_ID, svcId); + } + } + + /** + * Set the remoteIp and the basic HTTP Authentication user + * @param remoteIpp The remote ip address + * @param userp The basic http authencitation user + */ + public static void setLoggerParameters (String remoteIpp, String userp) { + if (null != remoteIpp) { + MDC.put (REMOTE_HOST, remoteIpp); + } + if (null != userp) { + MDC.put (USER, userp); + } + } + + /** + * Set the serviceName + * @param serviceNamep The service name + */ + public static void setServiceName (String serviceNamep) { + if (null != serviceNamep) { + MDC.put (SERVICE_NAME, serviceNamep); + MDC.remove (SERVICE_NAME_IS_METHOD_NAME); + } + } + + /** + * Get the serviceName + * @return The service name + */ + public static String getServiceName () { + return MDC.get (SERVICE_NAME); + } + + /** + * Reset the serviceName + */ + public static void resetServiceName () { + MDC.remove (SERVICE_NAME); + } + + /** + * Set the requestId and serviceInstanceId based on the mso request + * @param msoRequest The mso request + */ + public static void setLogContext (MsoRequest msoRequest) { + if (msoRequest != null) { + MDC.put (REQUEST_ID, msoRequest.getRequestId()); + MDC.put (SERVICE_INSTANCE_ID, msoRequest.getServiceInstanceId()); + } + else { + MDC.put (REQUEST_ID, DUMMY_VALUE); + MDC.put (SERVICE_INSTANCE_ID, DUMMY_VALUE); + } + } + + private String normalize (String input) { + if (input == null) { + return null; + } + String result = input.replace ('|', '!'); + result = result.replace ("\n", " - "); + return result; + } + + private String getNormalizedStackTrace (Throwable t) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + t.printStackTrace(pw); + return sw.toString().replace ('|', '!').replace ("\n", " - "); + } + + private void setDefaultLogCatalog (MsoLogger.Catalog cat) { + if ("APIH".equals(cat.toString())) { + exceptionArg = MessageEnum.APIH_GENERAL_EXCEPTION_ARG; + defaultException = MessageEnum.APIH_GENERAL_EXCEPTION; + defaultWarning = MessageEnum.APIH_GENERAL_WARNING; + defaultAudit = MessageEnum.APIH_AUDIT_EXEC; + defaultMetrics = MessageEnum.APIH_GENERAL_METRICS; + } else if ("RA".equals(cat.toString())) { + exceptionArg = MessageEnum.RA_GENERAL_EXCEPTION_ARG; + defaultException = MessageEnum.RA_GENERAL_EXCEPTION; + defaultWarning = MessageEnum.RA_GENERAL_WARNING; + defaultAudit = MessageEnum.RA_AUDIT_EXEC; + defaultMetrics = MessageEnum.RA_GENERAL_METRICS; + } else if ("BPEL".equals(cat.toString())) { + exceptionArg = MessageEnum.BPMN_GENERAL_EXCEPTION_ARG; + defaultException = MessageEnum.BPMN_GENERAL_EXCEPTION; + defaultWarning = MessageEnum.BPMN_GENERAL_WARNING; + defaultAudit = MessageEnum.BPMN_AUDIT_EXEC; + defaultMetrics = MessageEnum.BPMN_GENERAL_METRICS; + } else if ("ASDC".equals(cat.toString())) { + exceptionArg = MessageEnum.ASDC_GENERAL_EXCEPTION_ARG; + defaultException = MessageEnum.ASDC_GENERAL_EXCEPTION; + defaultWarning = MessageEnum.ASDC_GENERAL_WARNING; + defaultAudit = MessageEnum.ASDC_AUDIT_EXEC; + defaultMetrics = MessageEnum.ASDC_GENERAL_METRICS; + } else { + exceptionArg = MessageEnum.GENERAL_EXCEPTION_ARG; + defaultException = MessageEnum.GENERAL_EXCEPTION; + defaultWarning = MessageEnum.GENERAL_WARNING; + defaultAudit = MessageEnum.AUDIT_EXEC; + defaultMetrics = MessageEnum.GENERAL_METRICS; + } + } +} diff --git a/common/src/main/java/org/openecomp/mso/logger/MsoLoggingServlet.java b/common/src/main/java/org/openecomp/mso/logger/MsoLoggingServlet.java new file mode 100644 index 0000000000..568ab22447 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/logger/MsoLoggingServlet.java @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.mso.logger; + + +import java.util.List; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.joran.JoranConfigurator; +import ch.qos.logback.core.Appender; + +@Path("/logging") +public class MsoLoggingServlet { + + private static final String DEBUGLOG = "asyncEELFDebug"; + private MsoLogger logger = MsoLogger.getMsoLogger (MsoLogger.Catalog.GENERAL); + private static final String GENERAL_LOGGER = "com.att.eelf.error"; + private static final String AUDIT_LOGGER = "com.att.eelf.audit"; + private static final String METRICS_LOGGER = "com.att.eelf.metrics"; + + @GET + @Path("/setLevel/{logContext}/{level}") + @Produces("text/plain") + public Response setLogLevel (@PathParam("logContext") String logContext, @PathParam("level") String level) { + logger.info (MessageEnum.LOGGER_SETUP, "", ""); + + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + JoranConfigurator jc = new JoranConfigurator(); + jc.setContext(context); + Logger updateLogger = context.getLogger (logContext); + + if (updateLogger == null) { + logger.info (MessageEnum.LOGGER_NOT_FOUND, logContext, "", ""); + String response = "Unknown logger: " + logContext; + return Response.status (200).entity (response).build (); + } + + Level currentLevel = updateLogger.getLevel(); + if (!currentLevel.equals(Level.toLevel(level))) { + Level newLevel = Level.toLevel (level); + updateLogger.setLevel (newLevel); + logger.info (MessageEnum.LOGGER_UPDATE_SUC, updateLogger.getName (), currentLevel.toString(), newLevel.toString()); + } + + String response = "Log level set to: " + level + " for " + updateLogger.getName (); + return Response.status (200).entity (response).build (); + + } + + @GET + @Path("/loggers") + @Produces("text/plain") + @SuppressWarnings("rawtypes") + public Response getLoggers () { + StringBuilder response = new StringBuilder (); + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + JoranConfigurator jc = new JoranConfigurator(); + jc.setContext(context); + List loggerList = context.getLoggerList(); + for (Logger logger:loggerList) { + //if (logger.getLevel() != null) { + response.append (logger.getName () + ":" + logger.getLevel () + " (" + logger.getEffectiveLevel () + ")\n"); + //} + } + return Response.status (200).entity (response).build (); + + } + + @GET + @Path("/debug") + @Produces("text/plain") + @SuppressWarnings("rawtypes") + /* + * Debug log is used as a general log to store all the logs events, including events generated by MSO code or by + * components used by MSO. + * This method will only enable/disable the function to store MSO generated events into debug log, + * since those events will also be generated to error, audit, metrics log. + * The events generated by other components will not be affected by this interface. + */ + public Response updateDebugAppender (@DefaultValue("true") @QueryParam("enable") Boolean enable) { + String response; + + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + JoranConfigurator jc = new JoranConfigurator(); + jc.setContext(context); + List loggerList = context.getLoggerList(); + Logger rootLogger = context.getLogger("ROOT"); + Appender appender = rootLogger.getAppender(DEBUGLOG); + + if (null == appender) { + return Response.status (500).entity ("Not able to found Debug appender. Please verify to make sure the needed logback file is present in the config folder.").build (); + } + + if (enable) { + logger.info (MessageEnum.LOGGER_UPDATE_DEBUG, "", ""); + + for (Logger logger: loggerList) { + if (isMsoLogger (logger.getName ()) && logger.getAppender (DEBUGLOG) == null && logger.getLevel () != null) { + logger.addAppender (appender); + logger.setAdditive(false); + } + } + logger.info (MessageEnum.LOGGER_UPDATE_DEBUG_SUC, "enabled", "", ""); + response = "Debuglog successfully enabled."; + } else { + logger.info (MessageEnum.LOGGER_UPDATE_DEBUG, "", ""); + for (Logger logger: loggerList) { + if (isMsoLogger (logger.getName ())) { + logger.detachAppender (appender); + } + } + logger.info (MessageEnum.LOGGER_UPDATE_DEBUG_SUC, "disabled", "", ""); + response = "Debuglog successfully disabled."; + } + return Response.status (200).entity (response).build (); + + + } + + private boolean isMsoLogger (String loggerName) { + return loggerName.contains (GENERAL_LOGGER) || loggerName.equals (AUDIT_LOGGER) + || loggerName.equals (METRICS_LOGGER); + } + +} -- cgit 1.2.3-korg