[DMAAP-DR] Remove AAF/TLS phase 1
[dmaap/datarouter.git] / datarouter-node / src / main / java / org / onap / dmaap / datarouter / node / log / StatusLog.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 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  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24 package org.onap.dmaap.datarouter.node.log;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28 import java.io.File;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.OutputStream;
32 import java.nio.file.Files;
33 import java.nio.file.Paths;
34 import java.text.SimpleDateFormat;
35 import java.util.Date;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38 import org.onap.dmaap.datarouter.node.NodeConfigManager;
39 import org.onap.dmaap.datarouter.node.utils.NodeUtils;
40
41 /**
42  * Logging for data router delivery events (PUB/DEL/EXP).
43  */
44 public class StatusLog {
45
46     private static final String EXCEPTION = "Exception";
47     private static EELFLogger eelfLogger = EELFManager.getInstance().getLogger(StatusLog.class);
48     private static StatusLog instance = new StatusLog();
49     private SimpleDateFormat filedate = new SimpleDateFormat("-yyyyMMddHHmm");
50
51
52     private String prefix = "logs/events";
53     private String suffix = ".log";
54     private String plainfile;
55     private String curfile;
56     private long nexttime;
57     private OutputStream os;
58     private long intvl;
59     private static NodeConfigManager config = NodeConfigManager.getInstance();
60
61     private StatusLog() {
62     }
63
64     /**
65      * Parse an interval of the form xxhyymzzs and round it to the nearest whole fraction of 24 hours.If no units are
66      * specified, assume seconds.
67      */
68     public static long parseInterval(String interval, int def) {
69         try {
70             Matcher matcher = Pattern.compile("(?:(\\d+)[Hh])?(?:(\\d+)[Mm])?(?:(\\d+)[Ss]?)?").matcher(interval);
71             if (matcher.matches()) {
72                 int dur = getDur(matcher);
73                 int best = 86400;
74                 int dist = best - dur;
75                 if (dur > best) {
76                     dist = dur - best;
77                 }
78                 best = getBest(dur, best, dist);
79                 def = best * 1000;
80             }
81         } catch (Exception e) {
82             eelfLogger.error(EXCEPTION, e);
83         }
84         return (def);
85     }
86
87     private static int getBest(int dur, int best, int dist) {
88         int base = 1;
89         for (int i = 0; i < 8; i++) {
90             int base2 = base;
91             base *= 2;
92             for (int j = 0; j < 4; j++) {
93                 int base3 = base2;
94                 base2 *= 3;
95                 for (int k = 0; k < 3; k++) {
96                     int cur = base3;
97                     base3 *= 5;
98                     int ndist = cur - dur;
99                     if (dur > cur) {
100                         ndist = dur - cur;
101                     }
102                     if (ndist < dist) {
103                         best = cur;
104                         dist = ndist;
105                     }
106                 }
107             }
108         }
109         return best;
110     }
111
112     private static int getDur(Matcher matcher) {
113         int dur = 0;
114         String match = matcher.group(1);
115         if (match != null) {
116             dur += 3600 * Integer.parseInt(match);
117         }
118         match = matcher.group(2);
119         if (match != null) {
120             dur += 60 * Integer.parseInt(match);
121         }
122         match = matcher.group(3);
123         if (match != null) {
124             dur += Integer.parseInt(match);
125         }
126         if (dur < 60) {
127             dur = 60;
128         }
129         return dur;
130     }
131
132     /**
133      * Get the name of the current log file.
134      *
135      * @return The full path name of the current event log file
136      */
137     public static synchronized String getCurLogFile() {
138         try {
139             instance.checkRoll(System.currentTimeMillis());
140         } catch (Exception e) {
141             eelfLogger.error(EXCEPTION, e);
142         }
143         return (instance.curfile);
144     }
145
146     /**
147      * Log a received publication attempt.
148      *
149      * @param pubid The publish ID assigned by the node
150      * @param feedid The feed id given by the publisher
151      * @param requrl The URL of the received request
152      * @param method The method (DELETE or PUT) in the received request
153      * @param ctype The content type (if method is PUT and clen > 0)
154      * @param clen The content length (if method is PUT)
155      * @param srcip The IP address of the publisher
156      * @param user The identity of the publisher
157      * @param status The status returned to the publisher
158      */
159     public static void logPub(String pubid, String feedid, String requrl, String method, String ctype, long clen,
160             String srcip, String user, int status) {
161         instance.log(
162                 "PUB|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + srcip
163                         + "|" + user + "|" + status);
164         eelfLogger.info("PUB|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|"
165                                 + clen + "|" + srcip + "|" + user + "|" + status);
166     }
167
168     /**
169      * Log a data transfer error receiving a publication attempt.
170      *
171      * @param pubid The publish ID assigned by the node
172      * @param feedid The feed id given by the publisher
173      * @param requrl The URL of the received request
174      * @param method The method (DELETE or PUT) in the received request
175      * @param ctype The content type (if method is PUT and clen > 0)
176      * @param clen The expected content length (if method is PUT)
177      * @param rcvd The content length received
178      * @param srcip The IP address of the publisher
179      * @param user The identity of the publisher
180      * @param error The error message from the IO exception
181      */
182     public static void logPubFail(String pubid, String feedid, String requrl, String method, String ctype, long clen,
183             long rcvd, String srcip, String user, String error) {
184         instance.log("PBF|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + rcvd
185                 + "|" + srcip + "|" + user + "|" + error);
186         eelfLogger.info("PBF|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen
187                                 + "|" + rcvd + "|" + srcip + "|" + user + "|" + error);
188     }
189
190     /**
191      * Log a delivery attempt.
192      *
193      * @param pubid The publish ID assigned by the node
194      * @param feedid The feed ID
195      * @param subid The (space delimited list of) subscription ID
196      * @param requrl The URL used in the attempt
197      * @param method The method (DELETE or PUT) in the attempt
198      * @param ctype The content type (if method is PUT, not metaonly, and clen > 0)
199      * @param clen The content length (if PUT and not metaonly)
200      * @param user The identity given to the subscriber
201      * @param status The status returned by the subscriber or -1 if an exeception occured trying to connect
202      * @param xpubid The publish ID returned by the subscriber
203      */
204     public static void logDel(String pubid, String feedid, String subid, String requrl, String method, String ctype,
205             long clen, String user, int status, String xpubid) {
206         if (feedid == null) {
207             return;
208         }
209         instance.log(
210                 "DEL|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen
211                         + "|" + user + "|" + status + "|" + xpubid);
212         eelfLogger.info("DEL|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|"
213                                 + ctype + "|" + clen + "|" + user + "|" + status + "|" + xpubid);
214     }
215
216     /**
217      * Log delivery attempts expired.
218      *
219      * @param pubid The publish ID assigned by the node
220      * @param feedid The feed ID
221      * @param subid The (space delimited list of) subscription ID
222      * @param requrl The URL that would be delivered to
223      * @param method The method (DELETE or PUT) in the request
224      * @param ctype The content type (if method is PUT, not metaonly, and clen > 0)
225      * @param clen The content length (if PUT and not metaonly)
226      * @param reason The reason the attempts were discontinued
227      * @param attempts The number of attempts made
228      */
229     public static void logExp(String pubid, String feedid, String subid, String requrl, String method, String ctype,
230             long clen, String reason, int attempts) {
231         if (feedid == null) {
232             return;
233         }
234         instance.log(
235                 "EXP|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen
236                         + "|" + reason + "|" + attempts);
237         eelfLogger.info("EXP|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|"
238                                 + ctype + "|" + clen + "|" + reason + "|" + attempts);
239     }
240
241     /**
242      * Log extra statistics about unsuccessful delivery attempts.
243      *
244      * @param pubid The publish ID assigned by the node
245      * @param feedid The feed ID
246      * @param subid The (space delimited list of) subscription ID
247      * @param clen The content length
248      * @param sent The # of bytes sent or -1 if subscriber returned an error instead of 100 Continue, otherwise, the
249      *      number of bytes sent before an error occurred.
250      */
251     public static void logDelExtra(String pubid, String feedid, String subid, long clen, long sent) {
252         if (feedid == null) {
253             return;
254         }
255         instance.log("DLX|" + pubid + "|" + feedid + "|" + subid + "|" + clen + "|" + sent);
256         eelfLogger.info("DLX|" + pubid + "|" + feedid + "|" + subid + "|" + clen + "|" + sent);
257     }
258
259     private synchronized void checkRoll(long now) throws IOException {
260         if (now >= nexttime) {
261             if (os != null) {
262                 os.close();
263                 os = null;
264             }
265             intvl = parseInterval(config.getEventLogInterval(), 300000);
266             prefix = config.getEventLogPrefix();
267             suffix = config.getEventLogSuffix();
268             nexttime = now - now % intvl + intvl;
269             curfile = prefix + filedate.format(new Date(nexttime - intvl)) + suffix;
270             plainfile = prefix + suffix;
271             notifyAll();
272         }
273     }
274
275     private synchronized void log(String string) {
276         try {
277             long now = System.currentTimeMillis();
278             checkRoll(now);
279             if (os == null) {
280                 os = new FileOutputStream(curfile, true);
281                 Files.deleteIfExists(new File(plainfile).toPath());
282                 Files.createLink(Paths.get(plainfile), Paths.get(curfile));
283             }
284             os.write((NodeUtils.logts(new Date(now)) + '|' + string + '\n').getBytes());
285             os.flush();
286         } catch (IOException ioe) {
287             eelfLogger.error("IOException", ioe);
288         }
289     }
290 }