All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.taobao.metamorphosis.utils.MetaStatLog Maven / Gradle / Ivy

/*
 * (C) 2007-2012 Alibaba Group Holding Limited.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * Authors:
 *   wuhua  , boyan 
 */
package com.taobao.metamorphosis.utils;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import com.taobao.metamorphosis.utils.monitor.MonitorLog;


/**
 * 
 * 
 * StatLog?İ?װ??
 * 
 * @author boyan
 * 
 * @since 1.0, 2009-6-2 ????03:15:37
 */

public final class MetaStatLog {

    public static boolean startRealTimeStat = false;


    private MetaStatLog() {

    }

    // û???κ????ã?????Ϊ??ע???????
    static MetaStatLog ME = new MetaStatLog();

    static ConcurrentHashMap>> realTimeStatMap =
            new ConcurrentHashMap>>();

    public static volatile long lastResetTime = System.currentTimeMillis();

    static class StatCounter {
        private final AtomicLong count = new AtomicLong(0L);
        private final AtomicLong value = new AtomicLong(0L);


        public void incrementCount() {
            this.count.incrementAndGet();
        }


        public void addValue(final long value) {
            this.value.addAndGet(value);
        }


        public synchronized void reset() {
            this.count.set(0L);
            this.value.set(0L);
        }
    }


    public static void clearRealTimeStat() {
        realTimeStatMap =
                new ConcurrentHashMap>>();
    }

    public static class RealTimeStatRestTask implements Runnable {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(30 * 60 * 1000);

                }
                catch (final InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                resetRealTimeStat();

            }
        }
    }


    public synchronized static final void resetRealTimeStat() {
        for (final Map.Entry>> entry1 : realTimeStatMap
            .entrySet()) {
            for (final Map.Entry> entry2 : entry1.getValue().entrySet()) {
                for (final Map.Entry entry3 : entry2.getValue().entrySet()) {
                    entry3.getValue().reset();
                }
            }
        }
        lastResetTime = System.currentTimeMillis();
    }


    public static List getRealTimeStatItemNames() {
        final List result = new ArrayList();
        for (final Map.Entry>> entry1 : realTimeStatMap
            .entrySet()) {
            for (final Map.Entry> entry2 : entry1.getValue().entrySet()) {
                for (final Map.Entry entry3 : entry2.getValue().entrySet()) {
                    final StringBuilder sb = new StringBuilder("[");
                    sb.append(entry1.getKey()).append(",");
                    sb.append(entry2.getKey()).append(",");
                    sb.append(entry3.getKey()).append("]");
                    result.add(sb.toString());
                }
            }
        }
        return result;
    }


    public static final String getRealTimeStatResult(final String key1, final String key2, final String key3) {
        final ConcurrentHashMap> map1 = realTimeStatMap.get(key1);
        if (map1 == null) {
            return "Invalid keyOne:" + key1;
        }
        final ConcurrentHashMap map2 = map1.get(key2);
        if (map2 == null) {
            return "Invalid keyTwo:" + key2;
        }
        final StatCounter counter = map2.get(key3);
        if (counter == null) {
            return "Invalid keyThree:" + key3;
        }
        return formatOutput(counter);
    }


    private static String formatOutput(final StatCounter counter) {
        final double count = counter.count.get();
        final double values = counter.value.get();
        final long duration = (System.currentTimeMillis() - lastResetTime) / 1000;
        String averageValueStr = "invalid";
        String averageCountStr = "invalid";
        final DecimalFormat numberFormat = new DecimalFormat("#.##");
        if (count != 0) {
            final double averageValue = values / count;
            averageValueStr = numberFormat.format(averageValue);
        }
        if (duration != 0) {
            final double averageCount = count / duration;
            averageCountStr = numberFormat.format(averageCount);
        }
        return String.format(OUTPUT_FORMAT, numberFormat.format(count), numberFormat.format(values), averageValueStr,
            averageCountStr, duration);
    }


    public static final String getGroupedRealTimeStatResult(final String key1) {
        final ConcurrentHashMap> map1 = realTimeStatMap.get(key1);
        if (null == map1) {
            return null;
        }
        final StatCounter statCounter = new StatCounter();
        for (final Map.Entry> entry1 : map1
            .entrySet()) {
            final ConcurrentHashMap map2 = entry1.getValue();
            if (null == map2) {
                continue;
            }
            for (final Map.Entry entry2 : map2.entrySet()) {
                statCounter.count.addAndGet(entry2.getValue().count.longValue());
                statCounter.value.addAndGet(entry2.getValue().value.longValue());
            }
        }

        return formatOutput(statCounter);
    }


    public static final String getGroupedRealTimeStatResult(final String key1, final String key2) {
        final ConcurrentHashMap> map1 = realTimeStatMap.get(key1);
        if (null == map1) {
            return null;
        }
        final ConcurrentHashMap map2 = map1.get(key2);
        if (map2 == null) {
            return "Invalid keyTwo:" + key2;
        }

        final StatCounter statCounter = new StatCounter();
        for (final Map.Entry entry2 : map2.entrySet()) {
            statCounter.count.addAndGet(entry2.getValue().count.longValue());
            statCounter.value.addAndGet(entry2.getValue().value.longValue());
        }

        return formatOutput(statCounter);
    }


    public static long getDuration() {
        return (System.currentTimeMillis() - lastResetTime) / 1000;
    }

    public static String OUTPUT_FORMAT = "Count=%s,Value=%s,Value/Count=%s,Count/Duration=%s,Duration=%d";


    public static final void addStat(final String appName, final String keyOne, final String keyTwo,
            final String keyThree) {
        realTimeStat(keyOne, keyTwo, keyThree, 0);
        MonitorLog.addStat(keyOne, keyTwo, keyThree, 0L, 1L);
    }

    @SuppressWarnings("unused")
    private static class RealTimeStaticKey {

        private String key1;
        private String key2;
        private String key3;


        public RealTimeStaticKey(final String key1, final String key2, final String key3) {
            this.key1 = key1;
            this.key2 = key2;
            this.key3 = key3;
        }


        public String getKey1() {
            return this.key1;
        }


        public void setKey1(final String key1) {
            this.key1 = key1;
        }


        public String getKey2() {
            return this.key2;
        }


        public void setKey2(final String key2) {
            this.key2 = key2;
        }


        public String getKey3() {
            return this.key3;
        }


        public void setKey3(final String key3) {
            this.key3 = key3;
        }

    }


    public static final void realTimeStat(final String key1, final String key2, final String key3, final long value) {
        if (startRealTimeStat) {
            processMap2(key1, key2, key3, value);
        }
    }


    private static void processMap2(final String key1, final String key2, final String key3, final long value) {
        ConcurrentHashMap> statMap1 = realTimeStatMap.get(key1);
        if (statMap1 == null) {
            statMap1 = new ConcurrentHashMap>();
            final ConcurrentHashMap> oldStatMap1 =
                    realTimeStatMap.putIfAbsent(key1, statMap1);
            if (oldStatMap1 != null) {
                statMap1 = oldStatMap1;
            }
        }
        ConcurrentHashMap statMap2 = statMap1.get(key2);
        if (statMap2 == null) {
            statMap2 = new ConcurrentHashMap();
            final ConcurrentHashMap oldStatMap2 = statMap1.putIfAbsent(key2, statMap2);
            if (oldStatMap2 != null) {
                statMap2 = oldStatMap2;
            }
        }

        StatCounter statCounter = statMap2.get(key3);
        if (statCounter == null) {
            statCounter = new StatCounter();
            final StatCounter oldCounter = statMap2.putIfAbsent(key3, statCounter);
            if (oldCounter != null) {
                statCounter = oldCounter;
            }
        }
        statCounter.incrementCount();
        statCounter.addValue(value);
    }


    public static final void addStat(final String appName, final String keyOne, final String keyTwo) {
        realTimeStat(keyOne, keyTwo, "*", 0);

        MonitorLog.addStat(keyOne, keyTwo, null, 0L, 1L);
    }


    public static final void addStat(final String appName, final String keyOne) {

        realTimeStat(keyOne, "*", "*", 0);
        MonitorLog.addStat(keyOne, null, null, 0L, 1L);
    }


    public static final void addStatValue2(final String appName, final String keyOne, final long value) {
        realTimeStat(keyOne, "*", "*", value);

        MonitorLog.addStat(keyOne, null, null, value, 1L);
    }


    public static final void addStatValue2(final String appName, final String keyOne, final String keyTwo,
            final long value) {
        realTimeStat(keyOne, keyTwo, "*", value);

        MonitorLog.addStatValue2(keyOne, keyTwo, null, value);
    }


    public static final void addStatValue2(final String appName, final String keyOne, final String keyTwo,
            final String keyThree, final long value) {
        realTimeStat(keyOne, keyTwo, keyThree, value);

        MonitorLog.addStat(keyOne, keyTwo, keyThree, value, 1L);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy