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 */ 017package org.apache.camel.management.mbean; 018 019import java.util.concurrent.locks.Lock; 020import java.util.concurrent.locks.ReentrantLock; 021 022/** 023 * Holds the loads (inflight messages, not cpu) averaged over 1min, 5min, and 15min. 024 */ 025public final class LoadTriplet { 026 027 // Exponents for EWMA: exp(-INTERVAL / WINDOW) (in seconds) 028 private static final double EXP_1 = Math.exp(-1 / (60.0)); 029 private static final double EXP_5 = Math.exp(-1 / (60.0 * 5.0)); 030 private static final double EXP_15 = Math.exp(-1 / (60.0 * 15.0)); 031 032 private static final Lock LOCK = new ReentrantLock(); 033 private double load01 = Double.NaN; 034 private double load05 = Double.NaN; 035 private double load15 = Double.NaN; 036 037 /** 038 * Update the load statistics 039 * 040 * @param currentReading the current reading 041 */ 042 public void update(int currentReading) { 043 LOCK.lock(); 044 try { 045 load01 = updateLoad(currentReading, EXP_1, load01); 046 load05 = updateLoad(currentReading, EXP_5, load05); 047 load15 = updateLoad(currentReading, EXP_15, load15); 048 } finally { 049 LOCK.unlock(); 050 } 051 } 052 053 private double updateLoad(int reading, double exp, double recentLoad) { 054 return Double.isNaN(recentLoad) ? reading : reading + exp * (recentLoad - reading); 055 } 056 057 public double getLoad1() { 058 LOCK.lock(); 059 try { 060 return load01; 061 } finally { 062 LOCK.unlock(); 063 } 064 } 065 066 public double getLoad5() { 067 LOCK.lock(); 068 try { 069 return load05; 070 } finally { 071 LOCK.unlock(); 072 } 073 } 074 075 public double getLoad15() { 076 LOCK.lock(); 077 try { 078 return load15; 079 } finally { 080 LOCK.unlock(); 081 } 082 } 083 084 public void reset() { 085 LOCK.lock(); 086 try { 087 load01 = Double.NaN; 088 load05 = Double.NaN; 089 load15 = Double.NaN; 090 } finally { 091 LOCK.unlock(); 092 } 093 } 094 095 @Override 096 public String toString() { 097 return String.format("%.2f, %.2f, %.2f", getLoad1(), getLoad5(), getLoad15()); 098 } 099 100}