-/*******************************************************************************\r
- * ============LICENSE_START==================================================\r
- * * org.onap.dmaap\r
- * * ===========================================================================\r
- * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
- * * ===========================================================================\r
- * * Licensed under the Apache License, Version 2.0 (the "License");\r
- * * you may not use this file except in compliance with the License.\r
- * * You may obtain a copy of the License at\r
- * * \r
- * * http://www.apache.org/licenses/LICENSE-2.0\r
- * * \r
- * * Unless required by applicable law or agreed to in writing, software\r
- * * distributed under the License is distributed on an "AS IS" BASIS,\r
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * * See the License for the specific language governing permissions and\r
- * * limitations under the License.\r
- * * ============LICENSE_END====================================================\r
- * *\r
- * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
- * *\r
- ******************************************************************************/\r
-\r
-package org.onap.dmaap.datarouter.node;\r
-\r
-import java.util.regex.*;\r
-import java.util.*;\r
-import java.io.*;\r
-import java.nio.file.*;\r
-import java.text.*;\r
-\r
-/**\r
- * Logging for data router delivery events (PUB/DEL/EXP)\r
- */\r
-public class StatusLog {\r
- private static StatusLog instance = new StatusLog();\r
- private HashSet<String> toship = new HashSet<String>();\r
- private SimpleDateFormat filedate;\r
- private String prefix = "logs/events";\r
- private String suffix = ".log";\r
- private String plainfile;\r
- private String curfile;\r
- private long nexttime;\r
- private OutputStream os;\r
- private long intvl;\r
- private NodeConfigManager config = NodeConfigManager.getInstance();\r
- {\r
- try { filedate = new SimpleDateFormat("-yyyyMMddHHmm"); } catch (Exception e) {}\r
- }\r
- /**\r
- * Parse an interval of the form xxhyymzzs and round it to the nearest whole fraction of 24 hours. If no units are specified, assume seconds.\r
- */\r
- public static long parseInterval(String interval, int def) {\r
- try {\r
- Matcher m = Pattern.compile("(?:(\\d+)[Hh])?(?:(\\d+)[Mm])?(?:(\\d+)[Ss]?)?").matcher(interval);\r
- if (m.matches()) {\r
- int dur = 0;\r
- String x = m.group(1);\r
- if (x != null) {\r
- dur += 3600 * Integer.parseInt(x);\r
- }\r
- x = m.group(2);\r
- if (x != null) {\r
- dur += 60 * Integer.parseInt(x);\r
- }\r
- x = m.group(3);\r
- if (x != null) {\r
- dur += Integer.parseInt(x);\r
- }\r
- if (dur < 60) {\r
- dur = 60;\r
- }\r
- int best = 86400;\r
- int dist = best - dur;\r
- if (dur > best) {\r
- dist = dur - best;\r
- }\r
- int base = 1;\r
- for (int i = 0; i < 8; i++) {\r
- int base2 = base;\r
- base *= 2;\r
- for (int j = 0; j < 4; j++) {\r
- int base3 = base2;\r
- base2 *= 3;\r
- for (int k = 0; k < 3; k++) {\r
- int cur = base3;\r
- base3 *= 5;\r
- int ndist = cur - dur;\r
- if (dur > cur) {\r
- ndist = dur - cur;\r
- }\r
- if (ndist < dist) {\r
- best = cur;\r
- dist = ndist;\r
- }\r
- }\r
- }\r
- }\r
- def = best * 1000;\r
- }\r
- } catch (Exception e) {\r
- }\r
- return(def);\r
- }\r
- private synchronized void checkRoll(long now) throws IOException {\r
- if (now >= nexttime) {\r
- if (os != null) {\r
- os.close();\r
- os = null;\r
- }\r
- intvl = parseInterval(config.getEventLogInterval(), 300000);\r
- prefix = config.getEventLogPrefix();\r
- suffix = config.getEventLogSuffix();\r
- nexttime = now - now % intvl + intvl;\r
- curfile = prefix + filedate.format(new Date(nexttime - intvl)) + suffix;\r
- plainfile = prefix + suffix;\r
- notify();\r
- }\r
- }\r
- /**\r
- * Get the name of the current log file\r
- * @return The full path name of the current event log file\r
- */\r
- public static synchronized String getCurLogFile() {\r
- try {\r
- instance.checkRoll(System.currentTimeMillis());\r
- } catch (Exception e) {\r
- }\r
- return(instance.curfile);\r
- }\r
- private synchronized void log(String s) {\r
- try {\r
- long now = System.currentTimeMillis();\r
- checkRoll(now);\r
- if (os == null) {\r
- os = new FileOutputStream(curfile, true);\r
- (new File(plainfile)).delete();\r
- Files.createLink(Paths.get(plainfile), Paths.get(curfile));\r
- }\r
- os.write((NodeUtils.logts(new Date(now)) + '|' + s + '\n').getBytes());\r
- os.flush();\r
- } catch (IOException ioe) {\r
- }\r
- }\r
- /**\r
- * Log a received publication attempt.\r
- * @param pubid The publish ID assigned by the node\r
- * @param feedid The feed id given by the publisher\r
- * @param requrl The URL of the received request\r
- * @param method The method (DELETE or PUT) in the received request\r
- * @param ctype The content type (if method is PUT and clen > 0)\r
- * @param clen The content length (if method is PUT)\r
- * @param srcip The IP address of the publisher\r
- * @param user The identity of the publisher\r
- * @param status The status returned to the publisher\r
- */\r
- public static void logPub(String pubid, String feedid, String requrl, String method, String ctype, long clen, String srcip, String user, int status) {\r
- instance.log("PUB|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + srcip + "|" + user + "|" + status);\r
- }\r
- /**\r
- * Log a data transfer error receiving a publication attempt\r
- * @param pubid The publish ID assigned by the node\r
- * @param feedid The feed id given by the publisher\r
- * @param requrl The URL of the received request\r
- * @param method The method (DELETE or PUT) in the received request\r
- * @param ctype The content type (if method is PUT and clen > 0)\r
- * @param clen The expected content length (if method is PUT)\r
- * @param rcvd The content length received\r
- * @param srcip The IP address of the publisher\r
- * @param user The identity of the publisher\r
- * @param error The error message from the IO exception\r
- */\r
- public static void logPubFail(String pubid, String feedid, String requrl, String method, String ctype, long clen, long rcvd, String srcip, String user, String error) {\r
- instance.log("PBF|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + rcvd + "|" + srcip + "|" + user + "|" + error);\r
- }\r
- /**\r
- * Log a delivery attempt.\r
- * @param pubid The publish ID assigned by the node\r
- * @param feedid The feed ID\r
- * @param subid The (space delimited list of) subscription ID\r
- * @param requrl The URL used in the attempt\r
- * @param method The method (DELETE or PUT) in the attempt\r
- * @param ctype The content type (if method is PUT, not metaonly, and clen > 0)\r
- * @param clen The content length (if PUT and not metaonly)\r
- * @param user The identity given to the subscriber\r
- * @param status The status returned by the subscriber or -1 if an exeception occured trying to connect\r
- * @param xpubid The publish ID returned by the subscriber\r
- */\r
- public static void logDel(String pubid, String feedid, String subid, String requrl, String method, String ctype, long clen, String user, int status, String xpubid) {\r
- if (feedid == null) {\r
- return;\r
- }\r
- instance.log("DEL|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + user + "|" + status + "|" + xpubid);\r
- }\r
- /**\r
- * Log delivery attempts expired\r
- * @param pubid The publish ID assigned by the node\r
- * @param feedid The feed ID\r
- * @param subid The (space delimited list of) subscription ID\r
- * @param requrl The URL that would be delivered to\r
- * @param method The method (DELETE or PUT) in the request\r
- * @param ctype The content type (if method is PUT, not metaonly, and clen > 0)\r
- * @param clen The content length (if PUT and not metaonly)\r
- * @param reason The reason the attempts were discontinued\r
- * @param attempts The number of attempts made\r
- */\r
- public static void logExp(String pubid, String feedid, String subid, String requrl, String method, String ctype, long clen, String reason, int attempts) {\r
- if (feedid == null) {\r
- return;\r
- }\r
- instance.log("EXP|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + reason + "|" + attempts);\r
- }\r
- /**\r
- * Log extra statistics about unsuccessful delivery attempts.\r
- * @param pubid The publish ID assigned by the node\r
- * @param feedid The feed ID\r
- * @param subid The (space delimited list of) subscription ID\r
- * @param clen The content length\r
- * @param sent The # of bytes sent or -1 if subscriber returned an error instead of 100 Continue, otherwise, the number of bytes sent before an error occurred.\r
- */\r
- public static void logDelExtra(String pubid, String feedid, String subid, long clen, long sent) {\r
- if (feedid == null) {\r
- return;\r
- }\r
- instance.log("DLX|" + pubid + "|" + feedid + "|" + subid + "|" + clen + "|" + sent);\r
- }\r
- private StatusLog() {\r
- }\r
-}\r
+/*******************************************************************************
+ * ============LICENSE_START==================================================
+ * * org.onap.dmaap
+ * * ===========================================================================
+ * * Copyright © 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+
+package org.onap.dmaap.datarouter.node;
+
+import java.util.regex.*;
+import java.util.*;
+import java.io.*;
+import java.nio.file.*;
+import java.text.*;
+
+/**
+ * Logging for data router delivery events (PUB/DEL/EXP)
+ */
+public class StatusLog {
+ private static StatusLog instance = new StatusLog();
+ private HashSet<String> toship = new HashSet<String>();
+ private SimpleDateFormat filedate;
+ private String prefix = "logs/events";
+ private String suffix = ".log";
+ private String plainfile;
+ private String curfile;
+ private long nexttime;
+ private OutputStream os;
+ private long intvl;
+ private NodeConfigManager config = NodeConfigManager.getInstance();
+
+ {
+ try {
+ filedate = new SimpleDateFormat("-yyyyMMddHHmm");
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Parse an interval of the form xxhyymzzs and round it to the nearest whole fraction of 24 hours. If no units are specified, assume seconds.
+ */
+ public static long parseInterval(String interval, int def) {
+ try {
+ Matcher m = Pattern.compile("(?:(\\d+)[Hh])?(?:(\\d+)[Mm])?(?:(\\d+)[Ss]?)?").matcher(interval);
+ if (m.matches()) {
+ int dur = 0;
+ String x = m.group(1);
+ if (x != null) {
+ dur += 3600 * Integer.parseInt(x);
+ }
+ x = m.group(2);
+ if (x != null) {
+ dur += 60 * Integer.parseInt(x);
+ }
+ x = m.group(3);
+ if (x != null) {
+ dur += Integer.parseInt(x);
+ }
+ if (dur < 60) {
+ dur = 60;
+ }
+ int best = 86400;
+ int dist = best - dur;
+ if (dur > best) {
+ dist = dur - best;
+ }
+ int base = 1;
+ for (int i = 0; i < 8; i++) {
+ int base2 = base;
+ base *= 2;
+ for (int j = 0; j < 4; j++) {
+ int base3 = base2;
+ base2 *= 3;
+ for (int k = 0; k < 3; k++) {
+ int cur = base3;
+ base3 *= 5;
+ int ndist = cur - dur;
+ if (dur > cur) {
+ ndist = dur - cur;
+ }
+ if (ndist < dist) {
+ best = cur;
+ dist = ndist;
+ }
+ }
+ }
+ }
+ def = best * 1000;
+ }
+ } catch (Exception e) {
+ }
+ return (def);
+ }
+
+ private synchronized void checkRoll(long now) throws IOException {
+ if (now >= nexttime) {
+ if (os != null) {
+ os.close();
+ os = null;
+ }
+ intvl = parseInterval(config.getEventLogInterval(), 300000);
+ prefix = config.getEventLogPrefix();
+ suffix = config.getEventLogSuffix();
+ nexttime = now - now % intvl + intvl;
+ curfile = prefix + filedate.format(new Date(nexttime - intvl)) + suffix;
+ plainfile = prefix + suffix;
+ notify();
+ }
+ }
+
+ /**
+ * Get the name of the current log file
+ *
+ * @return The full path name of the current event log file
+ */
+ public static synchronized String getCurLogFile() {
+ try {
+ instance.checkRoll(System.currentTimeMillis());
+ } catch (Exception e) {
+ }
+ return (instance.curfile);
+ }
+
+ private synchronized void log(String s) {
+ try {
+ long now = System.currentTimeMillis();
+ checkRoll(now);
+ if (os == null) {
+ os = new FileOutputStream(curfile, true);
+ (new File(plainfile)).delete();
+ Files.createLink(Paths.get(plainfile), Paths.get(curfile));
+ }
+ os.write((NodeUtils.logts(new Date(now)) + '|' + s + '\n').getBytes());
+ os.flush();
+ } catch (IOException ioe) {
+ }
+ }
+
+ /**
+ * Log a received publication attempt.
+ *
+ * @param pubid The publish ID assigned by the node
+ * @param feedid The feed id given by the publisher
+ * @param requrl The URL of the received request
+ * @param method The method (DELETE or PUT) in the received request
+ * @param ctype The content type (if method is PUT and clen > 0)
+ * @param clen The content length (if method is PUT)
+ * @param srcip The IP address of the publisher
+ * @param user The identity of the publisher
+ * @param status The status returned to the publisher
+ */
+ public static void logPub(String pubid, String feedid, String requrl, String method, String ctype, long clen, String srcip, String user, int status) {
+ instance.log("PUB|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + srcip + "|" + user + "|" + status);
+ }
+
+ /**
+ * Log a data transfer error receiving a publication attempt
+ *
+ * @param pubid The publish ID assigned by the node
+ * @param feedid The feed id given by the publisher
+ * @param requrl The URL of the received request
+ * @param method The method (DELETE or PUT) in the received request
+ * @param ctype The content type (if method is PUT and clen > 0)
+ * @param clen The expected content length (if method is PUT)
+ * @param rcvd The content length received
+ * @param srcip The IP address of the publisher
+ * @param user The identity of the publisher
+ * @param error The error message from the IO exception
+ */
+ public static void logPubFail(String pubid, String feedid, String requrl, String method, String ctype, long clen, long rcvd, String srcip, String user, String error) {
+ instance.log("PBF|" + pubid + "|" + feedid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + rcvd + "|" + srcip + "|" + user + "|" + error);
+ }
+
+ /**
+ * Log a delivery attempt.
+ *
+ * @param pubid The publish ID assigned by the node
+ * @param feedid The feed ID
+ * @param subid The (space delimited list of) subscription ID
+ * @param requrl The URL used in the attempt
+ * @param method The method (DELETE or PUT) in the attempt
+ * @param ctype The content type (if method is PUT, not metaonly, and clen > 0)
+ * @param clen The content length (if PUT and not metaonly)
+ * @param user The identity given to the subscriber
+ * @param status The status returned by the subscriber or -1 if an exeception occured trying to connect
+ * @param xpubid The publish ID returned by the subscriber
+ */
+ public static void logDel(String pubid, String feedid, String subid, String requrl, String method, String ctype, long clen, String user, int status, String xpubid) {
+ if (feedid == null) {
+ return;
+ }
+ instance.log("DEL|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + user + "|" + status + "|" + xpubid);
+ }
+
+ /**
+ * Log delivery attempts expired
+ *
+ * @param pubid The publish ID assigned by the node
+ * @param feedid The feed ID
+ * @param subid The (space delimited list of) subscription ID
+ * @param requrl The URL that would be delivered to
+ * @param method The method (DELETE or PUT) in the request
+ * @param ctype The content type (if method is PUT, not metaonly, and clen > 0)
+ * @param clen The content length (if PUT and not metaonly)
+ * @param reason The reason the attempts were discontinued
+ * @param attempts The number of attempts made
+ */
+ public static void logExp(String pubid, String feedid, String subid, String requrl, String method, String ctype, long clen, String reason, int attempts) {
+ if (feedid == null) {
+ return;
+ }
+ instance.log("EXP|" + pubid + "|" + feedid + "|" + subid + "|" + requrl + "|" + method + "|" + ctype + "|" + clen + "|" + reason + "|" + attempts);
+ }
+
+ /**
+ * Log extra statistics about unsuccessful delivery attempts.
+ *
+ * @param pubid The publish ID assigned by the node
+ * @param feedid The feed ID
+ * @param subid The (space delimited list of) subscription ID
+ * @param clen The content length
+ * @param sent The # of bytes sent or -1 if subscriber returned an error instead of 100 Continue, otherwise, the number of bytes sent before an error occurred.
+ */
+ public static void logDelExtra(String pubid, String feedid, String subid, long clen, long sent) {
+ if (feedid == null) {
+ return;
+ }
+ instance.log("DLX|" + pubid + "|" + feedid + "|" + subid + "|" + clen + "|" + sent);
+ }
+
+ private StatusLog() {
+ }
+}