5

codahale Metrics API for Java を使用しています。

レイテンシを収集するために、システム全体でタイマーを使用しています。

パフォーマンス テスト中、JMX 経由でシステムに接続して、平均レイテンシ、75 パーセンタイル レイテンシなどの統計を収集します。

問題は、すべての Metrics オブジェクトを削除して再作成する以外に (多くのリファクタリングが必要になるように見えます)、新しいテストを開始するときに再起動する必要がないように、履歴データをクリアする方法があるかどうかです。アウトシステム?

どんな助けでも大歓迎です。

4

1 に答える 1

2

既存の方法はわかりませんが、resetTimers() 機能を拡張してMetricRegistryに追加できます。codahale メトリクス リポジトリから独自のリザーバーまたはブランチを実装する必要があります。ResettableUniformReservoirはUniformReservoirからコピーされます。デフォルトの Reservoir 実装はExponentiallyDecayingReservoirですが、コピーするコードが増えます :)

public class MyRegistry extends MetricRegistry {

    private final ConcurrentMap<String, ResettableUniformReservoir> reservoirs = new ConcurrentHashMap<>();

    @Override
    public Timer timer(String name) {
         ResettableUniformReservoir reservoir = new ResettableUniformReservoir();
         reservoirs.put(name, reservoir);
         return super.register(name, new Timer(reservoir));
    }

    public void resetTimers() {
        for (ResettableUniformReservoir reservoir : reservoirs.values()) {
            reservoir.reset();
        }
    }


    static class ResettableUniformReservoir implements Reservoir {

        private static final int DEFAULT_SIZE = 1028;
        private static final int BITS_PER_LONG = 63;

        private final AtomicLong count = new AtomicLong();
        private volatile AtomicLongArray values = new AtomicLongArray(DEFAULT_SIZE);

        @Override
        public int size() {
            final long c = count.get();
            if (c > values.length()) {
                return values.length();
            }
            return (int) c;
        }

        @Override
        public void update(long value) {
            final long c = count.incrementAndGet();
            if (c <= values.length()) {
                values.set((int) c - 1, value);
            } else {
                final long r = nextLong(c);
                if (r < values.length()) {
                    values.set((int) r, value);
                }
            }
        }

        private static long nextLong(long n) {
            long bits, val;
            do {
                bits = ThreadLocalRandom.current().nextLong() & (~(1L << BITS_PER_LONG));
                val = bits % n;
            } while (bits - val + (n - 1) < 0L);
            return val;
        }

        @Override
        public Snapshot getSnapshot() {
            final int s = size();
            final List<Long> copy = new ArrayList<Long>(s);
            for (int i = 0; i < s; i++) {
                copy.add(values.get(i));
            }
            return new UniformSnapshot(copy);
        }

        public void reset() {
            count.set(0);
            values = new AtomicLongArray(DEFAULT_SIZE);
        }
    }
}
于 2015-05-06T13:04:09.457 に答える