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    }