1 /*******************************************************************************
2 * ============LICENSE_START==================================================
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
11 * * http://www.apache.org/licenses/LICENSE-2.0
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====================================================
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 ******************************************************************************/
24 package org.onap.dmaap.datarouter.node;
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
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;
40 * Logging for data router delivery events (PUB/DEL/EXP).
42 public class StatusLog {
44 private static final String EXCEPTION = "Exception";
45 private static EELFLogger eelfLogger = EELFManager.getInstance().getLogger(StatusLog.class);
46 private static StatusLog instance = new StatusLog();
47 private SimpleDateFormat filedate = new SimpleDateFormat("-yyyyMMddHHmm");
50 private String prefix = "logs/events";
51 private String suffix = ".log";
52 private String plainfile;
53 private String curfile;
54 private long nexttime;
55 private OutputStream os;
57 private static NodeConfigManager config = NodeConfigManager.getInstance();
63 * Parse an interval of the form xxhyymzzs and round it to the nearest whole fraction of 24 hours.If no units are
64 * specified, assume seconds.
66 public static long parseInterval(String interval, int def) {
68 Matcher matcher = Pattern.compile("(?:(\\d+)[Hh])?(?:(\\d+)[Mm])?(?:(\\d+)[Ss]?)?").matcher(interval);
69 if (matcher.matches()) {
70 int dur = getDur(matcher);
72 int dist = best - dur;
76 best = getBest(dur, best, dist);
79 } catch (Exception e) {
80 eelfLogger.error(EXCEPTION, e);
85 private static int getBest(int dur, int best, int dist) {
87 for (int i = 0; i < 8; i++) {
90 for (int j = 0; j < 4; j++) {
93 for (int k = 0; k < 3; k++) {
96 int ndist = cur - dur;
110 private static int getDur(Matcher matcher) {
112 String match = matcher.group(1);
114 dur += 3600 * Integer.parseInt(match);
116 match = matcher.group(2);
118 dur += 60 * Integer.parseInt(match);
120 match = matcher.group(3);
122 dur += Integer.parseInt(match);
131 * Get the name of the current log file.
133 * @return The full path name of the current event log file
135 public static synchronized String getCurLogFile() {
137 instance.checkRoll(System.currentTimeMillis());
138 } catch (Exception e) {
139 eelfLogger.error(EXCEPTION, e);
141 return (instance.curfile);
145 * Log a received publication attempt.
147 * @param pubid The publish ID assigned by the node
148 * @param feedid The feed id given by the publisher
149 * @param requrl The URL of the received request
150 * @param method The method (DELETE or PUT) in the received request
151 * @param ctype The content type (if method is PUT and clen > 0)
152 * @param clen The content length (if method is PUT)
153 * @param srcip The IP address of the publisher
154 * @param user The identity of the publisher
155 * @param status The status returned to the publisher
157 public static void logPub(String pubid, String feedid, String requrl, String method, String ctype, long clen,
158 String srcip, String user, int status) {
160 "PUB|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + srcip
161 + "|" + user + "|" + status);
162 eelfLogger.info("PUB|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|"
163 + clen + "|" + srcip + "|" + user + "|" + status);
167 * Log a data transfer error receiving a publication attempt.
169 * @param pubid The publish ID assigned by the node
170 * @param feedid The feed id given by the publisher
171 * @param requrl The URL of the received request
172 * @param method The method (DELETE or PUT) in the received request
173 * @param ctype The content type (if method is PUT and clen > 0)
174 * @param clen The expected content length (if method is PUT)
175 * @param rcvd The content length received
176 * @param srcip The IP address of the publisher
177 * @param user The identity of the publisher
178 * @param error The error message from the IO exception
180 public static void logPubFail(String pubid, String feedid, String requrl, String method, String ctype, long clen,
181 long rcvd, String srcip, String user, String error) {
182 instance.log("PBF|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + rcvd
183 + "|" + srcip + "|" + user + "|" + error);
184 eelfLogger.info("PBF|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen
185 + "|" + rcvd + "|" + srcip + "|" + user + "|" + error);
189 * Log a delivery attempt.
191 * @param pubid The publish ID assigned by the node
192 * @param feedid The feed ID
193 * @param subid The (space delimited list of) subscription ID
194 * @param requrl The URL used in the attempt
195 * @param method The method (DELETE or PUT) in the attempt
196 * @param ctype The content type (if method is PUT, not metaonly, and clen > 0)
197 * @param clen The content length (if PUT and not metaonly)
198 * @param user The identity given to the subscriber
199 * @param status The status returned by the subscriber or -1 if an exeception occured trying to connect
200 * @param xpubid The publish ID returned by the subscriber
202 public static void logDel(String pubid, String feedid, String subid, String requrl, String method, String ctype,
203 long clen, String user, int status, String xpubid) {
204 if (feedid == null) {
208 "DEL|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen
209 + "|" + user + "|" + status + "|" + xpubid);
210 eelfLogger.info("DEL|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|"
211 + ctype + "|" + clen + "|" + user + "|" + status + "|" + xpubid);
215 * Log delivery attempts expired.
217 * @param pubid The publish ID assigned by the node
218 * @param feedid The feed ID
219 * @param subid The (space delimited list of) subscription ID
220 * @param requrl The URL that would be delivered to
221 * @param method The method (DELETE or PUT) in the request
222 * @param ctype The content type (if method is PUT, not metaonly, and clen > 0)
223 * @param clen The content length (if PUT and not metaonly)
224 * @param reason The reason the attempts were discontinued
225 * @param attempts The number of attempts made
227 public static void logExp(String pubid, String feedid, String subid, String requrl, String method, String ctype,
228 long clen, String reason, int attempts) {
229 if (feedid == null) {
233 "EXP|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen
234 + "|" + reason + "|" + attempts);
235 eelfLogger.info("EXP|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|"
236 + ctype + "|" + clen + "|" + reason + "|" + attempts);
240 * Log extra statistics about unsuccessful delivery attempts.
242 * @param pubid The publish ID assigned by the node
243 * @param feedid The feed ID
244 * @param subid The (space delimited list of) subscription ID
245 * @param clen The content length
246 * @param sent The # of bytes sent or -1 if subscriber returned an error instead of 100 Continue, otherwise, the
247 * number of bytes sent before an error occurred.
249 public static void logDelExtra(String pubid, String feedid, String subid, long clen, long sent) {
250 if (feedid == null) {
253 instance.log("DLX|" + pubid + "|" + feedid + "|" + subid + "|" + clen + "|" + sent);
254 eelfLogger.info("DLX|" + pubid + "|" + feedid + "|" + subid + "|" + clen + "|" + sent);
257 private synchronized void checkRoll(long now) throws IOException {
258 if (now >= nexttime) {
263 intvl = parseInterval(config.getEventLogInterval(), 300000);
264 prefix = config.getEventLogPrefix();
265 suffix = config.getEventLogSuffix();
266 nexttime = now - now % intvl + intvl;
267 curfile = prefix + filedate.format(new Date(nexttime - intvl)) + suffix;
268 plainfile = prefix + suffix;
273 private synchronized void log(String string) {
275 long now = System.currentTimeMillis();
278 os = new FileOutputStream(curfile, true);
279 Files.deleteIfExists(new File(plainfile).toPath());
280 Files.createLink(Paths.get(plainfile), Paths.get(curfile));
282 os.write((NodeUtils.logts(new Date(now)) + '|' + string + '\n').getBytes());
284 } catch (IOException ioe) {
285 eelfLogger.error("IOException", ioe);