001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.jbi.monitoring;
018
019 import java.io.File;
020 import java.io.FileOutputStream;
021 import java.io.IOException;
022 import java.io.PrintWriter;
023
024 import javax.management.JMException;
025 import javax.management.MBeanAttributeInfo;
026 import javax.management.MBeanOperationInfo;
027
028 import org.apache.commons.logging.Log;
029 import org.apache.commons.logging.LogFactory;
030 import org.apache.servicemix.jbi.framework.ComponentMBeanImpl;
031 import org.apache.servicemix.jbi.management.AttributeInfoHelper;
032 import org.apache.servicemix.jbi.management.BaseLifeCycle;
033 import org.apache.servicemix.jbi.management.OperationInfoHelper;
034
035 /**
036 * Defines basic statistics on the Component
037 */
038 public class ComponentStats extends BaseLifeCycle implements ComponentStatsMBean {
039
040 public static final String STATS_FILE = "stats.csv";
041
042 private static final Log LOG = LogFactory.getLog(ComponentStats.class);
043
044 private ComponentMBeanImpl component;
045 private MessagingStats stats;
046 private File statsFile;
047 private PrintWriter statsWriter;
048
049 /**
050 * Constructor
051 *
052 * @param lcc
053 */
054 public ComponentStats(ComponentMBeanImpl component) {
055 this.component = component;
056 this.stats = new MessagingStats(component.getName());
057 if (component.getContext() != null && component.getContext().getEnvironment() != null) {
058 File componentRoot = component.getContext().getEnvironment().getComponentRoot();
059 if (componentRoot != null && componentRoot.exists()) {
060 this.statsFile = new File(componentRoot, STATS_FILE);
061 }
062 }
063 }
064
065 MessagingStats getMessagingStats() {
066 return stats;
067 }
068
069 void dumpStats() {
070 if (statsFile != null) {
071 try {
072 if (statsWriter == null) {
073 FileOutputStream fileOut = new FileOutputStream(statsFile);
074 statsWriter = new PrintWriter(fileOut, true);
075 statsWriter.println(component.getComponentNameSpace().getName() + ":");
076 statsWriter.println("inboundExchanges,inboundExchangeRate,outboundExchanges,outboundExchangeRate");
077 }
078 long inbound = stats.getInboundExchanges().getCount();
079 double inboundRate = stats.getInboundExchangeRate().getAveragePerSecond();
080 long outbound = stats.getOutboundExchanges().getCount();
081 double outboundRate = stats.getOutboundExchangeRate().getAveragePerSecond();
082 statsWriter.println(inbound + "," + inboundRate + "," + outbound + "," + outboundRate);
083 } catch (IOException e) {
084 LOG.warn("Failed to dump stats", e);
085 }
086 }
087 }
088
089 void close() {
090 if (statsWriter != null) {
091 statsWriter.close();
092 statsWriter = null;
093 }
094 }
095
096 void incrementInbound() {
097 /*
098 if (component.getContainer().isNotifyStatistics()) {
099 long oldCount = stats.getInboundExchanges().getCount();
100 stats.getInboundExchanges().increment();
101 component.firePropertyChanged(
102 "inboundExchangeCount",
103 new Long(oldCount),
104 new Long(stats.getInboundExchanges().getCount()));
105 double oldRate = stats.getInboundExchangeRate().getAverageTime();
106 stats.getInboundExchangeRate().addTime();
107 component.firePropertyChanged("inboundExchangeRate",
108 new Double(oldRate),
109 new Double(stats.getInboundExchangeRate().getAverageTime()));
110 } else {
111 stats.getInboundExchanges().increment();
112 stats.getInboundExchangeRate().addTime();
113 }
114 */
115 stats.getInboundExchanges().increment();
116 stats.getInboundExchangeRate().addTime();
117 }
118
119 void incrementOutbound() {
120 /*
121 if (component.getContainer().isNotifyStatistics()) {
122 long oldCount = stats.getInboundExchanges().getCount();
123 stats.getOutboundExchanges().increment();
124 component.firePropertyChanged(
125 "outboundExchangeCount",
126 new Long(oldCount),
127 new Long(stats.getInboundExchanges().getCount()));
128 double oldRate = stats.getInboundExchangeRate().getAverageTime();
129 stats.getOutboundExchangeRate().addTime();
130 component.firePropertyChanged("outboundExchangeRate",
131 new Double(oldRate),
132 new Double(stats.getInboundExchangeRate().getAverageTime()));
133 } else {
134 stats.getOutboundExchanges().increment();
135 stats.getOutboundExchangeRate().addTime();
136 }
137 */
138 stats.getOutboundExchanges().increment();
139 stats.getOutboundExchangeRate().addTime();
140 }
141
142 /**
143 * Get the type of the item
144 * @return the type
145 */
146 public String getType() {
147 return "Statistics";
148 }
149
150 public String getSubType() {
151 return "Component";
152 }
153
154 /**
155 * Get the name of the item
156 * @return the name
157 */
158 public String getName() {
159 return component.getName();
160 }
161
162 /**
163 * Get the Description of the item
164 * @return the description
165 */
166 public String getDescription() {
167 return "Statistics for component " + component.getDescription();
168 }
169
170 /**
171 * Get the Inbound MessageExchange count
172 *
173 * @return inbound count
174 */
175 public long getInboundExchangeCount() {
176 return stats.getInboundExchanges().getCount();
177 }
178
179 /**
180 * Get the Inbound MessageExchange rate (number/sec)
181 *
182 * @return the inbound exchange rate
183 */
184 public double getInboundExchangeRate() {
185 return stats.getInboundExchangeRate().getAveragePerSecond();
186 }
187
188 /**
189 * Get the Outbound MessageExchange count
190 *
191 * @return outbound count
192 */
193 public long getOutboundExchangeCount() {
194 return stats.getOutboundExchanges().getCount();
195 }
196
197 /**
198 * Get the Outbound MessageExchange rate (number/sec)
199 *
200 * @return the outbound exchange rate
201 */
202 public double getOutboundExchangeRate() {
203 return stats.getOutboundExchangeRate().getAveragePerSecond();
204 }
205
206 /**
207 * @return size of the inbound Queue
208 */
209 public int getInboundQueueSize() {
210 if (component.getDeliveryChannel() != null) {
211 return component.getDeliveryChannel().getQueueSize();
212 } else {
213 return 0;
214 }
215 }
216
217 /**
218 * Reset all stats counters
219 */
220 public void reset() {
221 stats.reset();
222 }
223
224 /**
225 * Get an array of MBeanAttributeInfo
226 *
227 * @return array of AttributeInfos
228 * @throws JMException
229 */
230 public MBeanAttributeInfo[] getAttributeInfos() throws JMException {
231 AttributeInfoHelper helper = new AttributeInfoHelper();
232 helper.addAttribute(getObjectToManage(), "inboundQueueSize", "size of the inbound queue");
233 helper.addAttribute(getObjectToManage(), "inboundExchangeCount", "count of inbound exchanges");
234 helper.addAttribute(getObjectToManage(), "outboundExchangeCount", "count of outbound exchanges");
235 helper.addAttribute(getObjectToManage(), "inboundExchangeRate", "rate of inbound exchanges/sec");
236 helper.addAttribute(getObjectToManage(), "outboundExchangeRate", "rate of outbound exchanges/sec");
237 return helper.getAttributeInfos();
238 }
239
240 /**
241 * Get an array of MBeanOperationInfo
242 *
243 * @return array of OperationInfos
244 */
245 public MBeanOperationInfo[] getOperationInfos() {
246 OperationInfoHelper helper = new OperationInfoHelper();
247 helper.addOperation(getObjectToManage(), "reset", "reset statistic counters");
248 return helper.getOperationInfos();
249 }
250
251 }