Change the header to SO
[so.git] / common / src / main / java / org / openecomp / mso / logger / MsoAlarmLogger.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
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  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.mso.logger;
22
23
24 import java.io.File;
25 import javax.servlet.ServletContextEvent;
26 import javax.servlet.ServletContextListener;
27
28 import org.slf4j.LoggerFactory;
29
30 import ch.qos.logback.classic.Level;
31 import ch.qos.logback.classic.Logger;
32 import ch.qos.logback.classic.LoggerContext;
33 import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
34 import ch.qos.logback.classic.spi.ILoggingEvent;
35 import ch.qos.logback.core.rolling.RollingFileAppender;
36 import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
37
38 /**
39  * Wrapper around log4j and Nagios NRDP passive alarming for MSO.
40  *
41  * For local alarm logging, this class will look for an alarm log file name
42  * in the servlet context parameter "mso.alarms.file". If none is found,
43  * it will look for an MsoProperty of the same name. As a last resort,
44  * it will use the default path "/var/log/ecomp/MSO/alarms/alarm.log".
45  * It is expected that all alarms within an application will use the same
46  * alarm file, so there is no way to dynamically add other alarm files.
47  *
48  * Alarms are logged as a simple pipe-delimited string of the format:
49  * <dateTime>|<alarmType>|<state>|<detailMessage>
50  *
51  * This class also supports real-time Nagios NRDP alarming. If enabled via
52  * MsoProperties, all alarms generated and logged to the local alarm file will
53  * also be transmitted to a Nagios NRDP instance. NRDP requires 4 parameters
54  * in service alarm events (all Mso Alarms will be Service Alarms):
55  * hostname, servicename, state, detail
56  *
57  * The log file format is also intended to be compatible with Nagios NRDP for
58  * non-real-time reporting. The command-line tool for sending alarms is
59  * is "send_nrdp.php", which takes the same 4 parameters as input.
60  * It will be easy enough to translate entries from an alarm.log file to
61  * NRDP if real-time NRDP alarming is not enabled.
62  *
63  * For Nagios integration, the alarmTypes should all match "service names"
64  * configured in the receiving Nagios server. Also, the alarm state will
65  * be limited to the 4 values defined by Nagios:
66  * 0 = OK, 1 = Warning, 2 = Critical, 3 = Unknown
67  *
68  *
69  */
70 public class MsoAlarmLogger implements ServletContextListener {
71
72         private Logger alarmLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(MSO_ALARM_CONTEXT);
73     private static RollingFileAppender<ILoggingEvent> fileAppender = null;
74     public static final String DEFAULT_MSO_ALARM_FILE = "/var/log/ecomp/MSO/alarms/alarm.log";
75     public static final String MSO_ALARM_CONTEXT = "mso.alarms";
76     
77     public static final int OK = 0;
78     public static final int WARNING = 1;
79     public static final int CRITICAL = 2;
80     public static final int UNKNOWN = 3;
81
82     /**
83      * Get the default MSO Alarm Logger
84      */
85     public MsoAlarmLogger () {
86                 
87         initializeAlarmLogger(null);
88
89     }
90
91     public MsoAlarmLogger (String alarmFile) {
92         initializeAlarmLogger(alarmFile);
93
94     }
95
96      /**
97      * Method to record an alarm.
98      *
99      * @param alarm - the alarm identifier (Nagios "service")
100      * @param state - the alarm state/severity, based on Nagios service
101      *        state values: 0 = OK, 1 = Warning, 2 = Critical, 3 = Unknown
102      * @param detail - detail message (may contain additional internal
103      *        structure per alarm type)
104      */
105     public void sendAlarm (String alarm, int state, String detail) {
106         // Write the alarm to Log file
107         if (alarmLogger != null) {
108             String output = alarm + "|" + state + "|" + detail;
109             alarmLogger.info (output);
110         }
111
112     }
113
114     @Override
115     public void contextDestroyed (ServletContextEvent event) {
116         // Nothing to do...
117     }
118
119     @Override
120     public void contextInitialized (ServletContextEvent event) {
121         String msoAlarmFile = event.getServletContext ().getInitParameter ("mso.alarm.file");
122         if (msoAlarmFile == null) {
123             msoAlarmFile = DEFAULT_MSO_ALARM_FILE;
124         }
125
126         initializeAlarmLogger (msoAlarmFile);
127     }
128
129     private void initializeAlarmLogger (String alarmFile) {
130         synchronized (MsoAlarmLogger.class) {
131             if (fileAppender == null) {
132                 if (alarmFile != null) {
133                         fileAppender = MsoAlarmLogger.getAppender (alarmFile);
134                 } else {
135                         fileAppender = MsoAlarmLogger.getAppender (DEFAULT_MSO_ALARM_FILE);
136                 }
137             }
138         }
139         // The alarmLogger was static originally.
140         // The initialization of the alarmLogger was fine, but not sure why, it lost its appender info later
141         // Due to that issue, the alarmLogger is not static any more.
142         // Instead static attribute fileAppender is added and will be assigned to the alarmLogger every time new MsoAlarmLogger is created.
143         alarmLogger.setLevel (Level.INFO);
144         alarmLogger.addAppender (fileAppender);
145         alarmLogger.setAdditive (false);
146     }
147
148
149     private static RollingFileAppender<ILoggingEvent> getAppender (String msoAlarmFile) {
150         // Create a Logger for alarms. Just use a default Pattern that outputs
151         // a message. MsoAlarmLogger will handle the formatting.
152         File alarmFile = new File (msoAlarmFile);
153         File alarmDir = alarmFile.getParentFile ();
154         if (!alarmDir.exists ()) {
155             alarmDir.mkdirs ();
156         }
157
158         String logPattern = "%d{yyyy-MM-dd HH:mm:ss}|%m%n";
159
160         LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
161         PatternLayoutEncoder encoder=new PatternLayoutEncoder();
162         encoder.setPattern(logPattern);
163         encoder.setContext(context);
164         encoder.start();
165         RollingFileAppender<ILoggingEvent> fileAppender=new RollingFileAppender<ILoggingEvent>();
166         TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy=new TimeBasedRollingPolicy<ILoggingEvent>();
167         rollingPolicy.setContext(context);
168         rollingPolicy.setFileNamePattern(msoAlarmFile + ".%d");
169         rollingPolicy.setParent(fileAppender);
170         rollingPolicy.start();
171         fileAppender.setFile(msoAlarmFile);
172         fileAppender.setAppend(true);
173         fileAppender.setEncoder(encoder);
174         fileAppender.setRollingPolicy(rollingPolicy);
175         fileAppender.setContext(context);
176         fileAppender.start();
177
178         return fileAppender;
179     }
180
181 }