1 /*******************************************************************************
\r
2 * ============LICENSE_START==================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
25 package org.onap.dmaap.datarouter.reports;
\r
27 import java.io.FileNotFoundException;
\r
28 import java.io.PrintWriter;
\r
29 import java.sql.Connection;
\r
30 import java.sql.PreparedStatement;
\r
31 import java.sql.ResultSet;
\r
32 import java.sql.SQLException;
\r
33 import java.util.ArrayList;
\r
34 import java.util.List;
\r
36 import org.onap.dmaap.datarouter.provisioning.utils.DB;
\r
39 * Generate a per-file latency report. It reports on the details related to one file published
\r
40 * on one feed. This report can be further reduced in order to generate more specific reports
\r
41 * based on feed ID or node name. The report is a .csv file containing the following columns:
\r
43 * <tr><td>recordid</td><td>the unique record ID assigned to a particular incoming feed</td></tr>
\r
44 * <tr><td>feedid</td><td>the Feed ID for this record</td></tr>
\r
45 * <tr><td>uri</td><td>the URI of the file delivered</td></tr>
\r
46 * <tr><td>size</td><td>the size of the file delivered</td></tr>
\r
47 * <tr><td>min</td><td>the minimum latency in delivering this feed to a subscriber (in ms)</td></tr>
\r
48 * <tr><td>max</td><td>the maximum latency in delivering this feed to a subscriber (in ms)</td></tr>
\r
49 * <tr><td>avg</td><td>the average latency in delivering this feed to all subscribers (in ms)</td></tr>
\r
50 * <tr><td>fanout</td><td>the number of subscribers this feed was delivered to</td></tr>
\r
53 * @author Robert P. Eby
\r
54 * @version $Id: LatencyReport.java,v 1.1 2013/10/28 18:06:53 eby Exp $
\r
56 public class LatencyReport extends ReportBase {
\r
57 private static final String SELECT_SQL =
\r
58 "select EVENT_TIME, TYPE, PUBLISH_ID, FEED_FILEID, FEEDID, CONTENT_LENGTH from LOG_RECORDS" +
\r
59 " where EVENT_TIME >= ? and EVENT_TIME <= ? order by PUBLISH_ID, EVENT_TIME";
\r
61 private class Event {
\r
62 public final String type;
\r
63 public final long time;
\r
65 public Event(String t, long tm) {
\r
71 private class Counters {
\r
72 public final String id;
\r
73 public final int feedid;
\r
74 public final long clen;
\r
75 public final String fileid;
\r
76 public final List<Event> events;
\r
78 public Counters(String i, int fid, long c, String s) {
\r
83 events = new ArrayList<Event>();
\r
86 private long pubtime;
\r
88 public void addEvent(String t, long tm) {
\r
89 events.add(new Event(t, tm));
\r
90 if (t.equals("pub"))
\r
95 long min = Long.MAX_VALUE;
\r
96 for (Event e : events) {
\r
97 if (e.type.equals("del")) {
\r
98 min = Math.min(min, e.time - pubtime);
\r
104 public long max() {
\r
106 for (Event e : events) {
\r
107 if (e.type.equals("del")) {
\r
108 max = Math.max(max, e.time - pubtime);
\r
114 public long avg() {
\r
115 long total = 0, c = 0;
\r
116 for (Event e : events) {
\r
117 if (e.type.equals("del")) {
\r
118 total += e.time - pubtime;
\r
122 return (c == 0) ? 0 : total / c;
\r
125 public int fanout() {
\r
127 for (Event e : events) {
\r
128 if (e.type.equals("del")) {
\r
136 public String toString() {
\r
137 return feedid + "," + fileid + "," + clen + "," + min() + "," + max() + "," + avg() + "," + fanout();
\r
142 public void run() {
\r
143 long start = System.currentTimeMillis();
\r
146 @SuppressWarnings("resource")
\r
147 Connection conn = db.getConnection();
\r
148 try(PreparedStatement ps = conn.prepareStatement(SELECT_SQL)){
\r
149 ps.setLong(1, from);
\r
151 try(ResultSet rs = ps.executeQuery()) {
\r
152 try(PrintWriter os = new PrintWriter(outfile)) {
\r
153 os.println("recordid,feedid,uri,size,min,max,avg,fanout");
\r
155 while (rs.next()) {
\r
156 long etime = rs.getLong("EVENT_TIME");
\r
157 String type = rs.getString("TYPE");
\r
158 String id = rs.getString("PUBLISH_ID");
\r
159 String fid = rs.getString("FEED_FILEID");
\r
160 int feed = rs.getInt("FEEDID");
\r
161 long clen = rs.getLong("CONTENT_LENGTH");
\r
162 if (c != null && !id.equals(c.id)) {
\r
163 String line = id + "," + c.toString();
\r
168 c = new Counters(id, feed, clen, fid);
\r
170 if (feed != c.feedid)
\r
171 System.err.println("Feed ID mismatch, " + feed + " <=> " + c.feedid);
\r
172 if (clen != c.clen)
\r
173 System.err.println("Cont Len mismatch, " + clen + " <=> " + c.clen);
\r
174 c.addEvent(type, etime);
\r
180 } catch (FileNotFoundException e) {
\r
181 System.err.println("File cannot be written: " + outfile);
\r
182 } catch (SQLException e) {
\r
183 logger.error("SQLException: " + e.getMessage());
\r
185 logger.debug("Query time: " + (System.currentTimeMillis() - start) + " ms");
\r