View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2009 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.util.socketstatistics;
18  
19  import java.net.InetAddress;
20  import java.util.Date;
21  
22  import ch.elca.el4j.util.socketstatistics.genericlogger.GenericLogFactory;
23  import ch.elca.el4j.util.socketstatistics.genericlogger.GenericLogger;
24  
25  
26  /**
27   * Keeps statistics of one (open / closed) socket connection.
28   *
29   * @svnLink $Revision: 3990 $;$Date: 2009-11-13 16:36:10 +0100 (Fr, 13. Nov 2009) $;$Author: jonasha $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/socketstatistics/src/main/java/ch/elca/el4j/util/socketstatistics/ConnectionStatistics.java $
30   *
31   * @author Jonas Hauenstein (JHN)
32   */
33  public class ConnectionStatistics implements Comparable<ConnectionStatistics> {
34  
35  	/**
36  	 * Generic m_logger.
37  	 */
38  	private final GenericLogger m_logger = GenericLogFactory.getLogger(SocketStatistics.class);
39  
40  	/**
41  	 * Date when socket was created.
42  	 */
43  	private Date m_created;
44  
45  	/**
46  	 * Date when socket was destroyed / closed.
47  	 */
48  	private Date m_destroyed;
49  
50  	/**
51  	 * The total number of bytes sent on socket.
52  	 */
53  	private long m_totalBytesSent;
54  
55  	/**
56  	 * The total number of bytes received on socket.
57  	 */
58  	private long m_totalBytesRecveived;
59  
60  	/**
61  	 * The unique id of the socket.
62  	 */
63  	private long m_socketId;
64  
65  	/**
66  	 * The remote address of the socket.
67  	 */
68  	private InetAddress m_remoteAddress;
69  
70  	/**
71  	 * The remoteport of the socket.
72  	 */
73  	private int m_remotePort;
74  
75  	/**
76  	 * The local port of the socket.
77  	 */
78  	private int m_localPort;
79  
80  	/**
81  	 * Constructor.
82  	 * 
83  	 * @param socketID
84  	 *            (unique) id to be assigned to socket
85  	 */
86  	public ConnectionStatistics(long socketID) {
87  		this.m_socketId = socketID;
88  		this.m_created = new Date();
89  		this.m_destroyed = null;
90  		this.m_totalBytesSent = 0;
91  		this.m_totalBytesRecveived = 0;
92  		this.m_remoteAddress = null;
93  		this.m_remotePort = 0;
94  		this.m_localPort = 0;
95  		m_logger.log("info", "Socket opened with Socket-ID " + m_socketId);
96  	}
97  
98  	/**
99  	 * Add a certain amounts of sent bytes to socket stats.
100 	 * 
101 	 * @param nrofbytes
102 	 *            number of sent bytes
103 	 */
104 	public synchronized void addbytessent(int nrofbytes) {
105 		m_totalBytesSent += nrofbytes;
106 	}
107 
108 	/**
109 	 * Add a certain amounts of received bytes to socket stats.
110 	 * 
111 	 * @param nrofbytes
112 	 *            number of received bytes
113 	 */
114 	public synchronized void addbytesrecv(int nrofbytes) {
115 		m_totalBytesRecveived += nrofbytes;
116 	}
117 
118 	/**
119 	 * Getter for number of received bytes.
120 	 * 
121 	 * @return total number of bytes received on socket
122 	 */
123 	public long getBytesReceived() {
124 		return m_totalBytesRecveived;
125 	}
126 
127 	/**
128 	 * Getter for number of sent bytes.
129 	 * 
130 	 * @return total number of bytes sent on socket
131 	 */
132 	public long getBytesSent() {
133 		return m_totalBytesSent;
134 	}
135 
136 	/**
137 	 * Setter for sockets remote address.
138 	 * 
139 	 * @param ra
140 	 *            sockets remote address
141 	 */
142 	public synchronized void setRemoteAdress(InetAddress ra) {
143 		this.m_remoteAddress = ra;
144 	}
145 
146 	/**
147 	 * Getter for sockets remote address. Using string to guarantee compatibility to MXBeans
148 	 * 
149 	 * @return sockets remote address
150 	 */
151 	public synchronized String getRemoteAdress() {
152 		return this.m_remoteAddress == null ? "" : this.m_remoteAddress.toString();
153 	}
154 
155 	/**
156 	 * Setter for sockets remote port.
157 	 * 
158 	 * @param rp
159 	 *            sockets remote port
160 	 */
161 	public synchronized void setRemotePort(int rp) {
162 		this.m_remotePort = rp;
163 	}
164 
165 	/**
166 	 * Getter for sockets remote port.
167 	 * 
168 	 * @return sockets remote port
169 	 */
170 	public synchronized int getRemotePort() {
171 		return this.m_remotePort;
172 	}
173 
174 	/**
175 	 * Setter for sockets local port.
176 	 * 
177 	 * @param lp
178 	 *            sockets local port
179 	 */
180 	public synchronized void setLocalPort(int lp) {
181 		this.m_localPort = lp;
182 	}
183 
184 	/**
185 	 * Getter for sockets local port.
186 	 * 
187 	 * @return sockets local port
188 	 */
189 	public synchronized int getLocalPort() {
190 		return this.m_localPort;
191 	}
192 
193 	/**
194 	 * Mark monitored socket as closed / destroyed.
195 	 */
196 	public synchronized void setDestroyed() {
197 		m_logger.log("info", "Socket closed with Socket-ID " + m_socketId);
198 		SocketStatistics.setConnectionDestroyed(this);
199 	}
200 
201 	/**
202 	 * External getter for sockets destroyed / close date. Using string to guarantee compatibility to MXBeans
203 	 * 
204 	 * @return string of date when socket was destroyed / closed
205 	 */
206 	public String getDestroyedDate() {
207 		return m_destroyed == null ? "" : m_destroyed.toString();
208 	}
209 
210 	/**
211 	 * Internal getter for sockets destroyed / close date. Returns date object
212 	 * 
213 	 * @return date when socket was destroyed / closed
214 	 */
215 	protected synchronized Date getDestroyedDateInt() {
216 		return m_destroyed;
217 	}
218 
219 	/**
220 	 * Sets socket as destroyed / closed with date = now.
221 	 */
222 	protected synchronized void setDestroyedDateInt() {
223 		m_destroyed = new Date();
224 	}
225 
226 	/**
227 	 * External getter for sockets creation date. Using string to guarantee compatibility to MXBeans
228 	 * 
229 	 * @return string of date when socket was created
230 	 */
231 	public String getCreatedDate() {
232 		return m_created == null ? "" : m_created.toString();
233 	}
234 
235 	/**
236 	 * Internal getter for sockets creation date. Returns date object
237 	 * 
238 	 * @return date when socket was created
239 	 */
240 	protected Date getCreatedDateInt() {
241 		return m_created;
242 	}
243 
244 	/**
245 	 * Getter for sockets id.
246 	 * 
247 	 * @return sockets unique id
248 	 */
249 	public long getSocketID() {
250 		return m_socketId;
251 	}
252 
253 	/**
254 	 * Return stats of socket as string.
255 	 * 
256 	 * @return stats of socket
257 	 */
258 	protected String getStatistics() {
259 		StringBuilder sb = new StringBuilder("Socket ID: " + m_socketId);
260 		sb.append("\n  [ created on " + getCreatedDate() + " ]");
261 		if (m_destroyed != null) { sb.append("\n  [ closed on " + getDestroyedDate() + " ]"); }
262 		sb.append("\n  [ Remote address / port: " + getRemoteAdress() + " / " + getRemotePort() + " ]");
263 		sb.append("\n  [ Local port: " + getLocalPort() + " ]");
264 		sb.append("\n  [ Total bytes received on socket: " + m_totalBytesRecveived + " ]");
265 		sb.append("\n  [ Total bytes sent on socket: " + m_totalBytesSent + " ]");
266 		return sb.toString();
267 	}
268 
269 	/**
270 	 * Return stats of socket as string in csv format.
271 	 * 
272 	 * @return stats of socket
273 	 */
274 	protected String getStatisticsCSV() {
275 		StringBuilder sb = new StringBuilder();
276 		sb.append(m_socketId);
277 		sb.append(";");
278 		sb.append(getCreatedDate());
279 		sb.append(";");
280 		sb.append(getDestroyedDate());
281 		sb.append(";");
282 		sb.append(getRemoteAdress());
283 		sb.append(";");
284 		sb.append(getRemotePort());
285 		sb.append(";");
286 		sb.append(getRemoteAdress());
287 		sb.append(";");
288 		sb.append(m_totalBytesRecveived);
289 		sb.append(";");
290 		sb.append(m_totalBytesSent);
291 		sb.append("\n");
292 		return sb.toString();
293 	}
294 
295 	/**
296 	 * Compare using destroyed / closed date of socket / ConnectionStatics. First hand sort order is destruction
297 	 * ascending date. Open sockets are sorted among each other by creation date. {@inheritDoc}
298 	 */
299 	@Override
300 	public int compareTo(ConnectionStatistics o) {
301 		// check if they are the same
302 		if (this.m_socketId == o.getSocketID()) {
303 			return 0;
304 		}
305 		// sort by destroyed date asc
306 		// put open / not yet closed sockets on bottom of list ordered by creation date
307 		if (this.m_destroyed == null && o.getDestroyedDateInt() != null) {
308 			return 1;
309 		}
310 		if (this.m_destroyed != null && o.getDestroyedDateInt() == null) {
311 			return -1;
312 		}
313 		if (this.m_destroyed == null && o.getDestroyedDateInt() == null) {
314 			if (this.m_created.getTime() < o.getCreatedDateInt().getTime()) {
315 				return -1;
316 			} else if (this.m_created.getTime() == o.getCreatedDateInt().getTime()) {
317 				return this.m_socketId < o.getSocketID() ? -1 : 1;
318 			} else {
319 				return 1;
320 			}
321 		}
322 		if (getDestroyedDateInt().getTime() < o.getDestroyedDateInt().getTime()) {
323 			return -1;
324 		} else if (this.m_destroyed.getTime() == o.getDestroyedDateInt().getTime()) {
325 			return this.m_socketId < o.getSocketID() ? -1 : 1;
326 		} else {
327 			return 1;
328 		}
329 	}
330 
331 	@Override
332 	public int hashCode() {
333 		return (int) m_socketId;
334 	}
335 
336 	@Override
337 	public boolean equals(Object o) {
338 		if (o != null && o instanceof ConnectionStatistics) {
339 			return ((ConnectionStatistics) o).getSocketID() == getSocketID();
340 		} else {
341 			return false;
342 		}
343 		
344 	}
345 }