com.mgmtp.perfload.perfalyzer.binning.PerfMonBinningStrategy.java Source code

Java tutorial

Introduction

Here is the source code for com.mgmtp.perfload.perfalyzer.binning.PerfMonBinningStrategy.java

Source

/*
 * Copyright (c) 2013-2014 mgm technology partners GmbH
 *
 * 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.
 */
package com.mgmtp.perfload.perfalyzer.binning;

import com.google.common.base.Charsets;
import com.google.common.primitives.Doubles;
import com.mgmtp.perfload.perfalyzer.constants.PerfAlyzerConstants;
import com.mgmtp.perfload.perfalyzer.util.ChannelManager;
import com.mgmtp.perfload.perfalyzer.util.PerfAlyzerFile;
import com.mgmtp.perfload.perfalyzer.util.PerfMonTypeConfig;
import org.apache.commons.lang3.text.StrBuilder;
import org.apache.commons.math3.stat.StatUtils;
import org.apache.commons.math3.stat.descriptive.rank.Percentile;

import java.io.IOException;
import java.nio.channels.WritableByteChannel;
import java.text.NumberFormat;
import java.util.List;
import java.util.Scanner;

import static com.mgmtp.perfload.perfalyzer.constants.PerfAlyzerConstants.DELIMITER;
import static com.mgmtp.perfload.perfalyzer.util.IoUtilities.writeLineToChannel;
import static com.mgmtp.perfload.perfalyzer.util.StrBuilderUtils.appendEscapedAndQuoted;

/**
 * Binning implementation for perfMon logs.
 *
 * @author rnaegele
 */
public class PerfMonBinningStrategy extends AbstractBinningStrategy {

    private final BinManager binManager;
    private PerfMonTypeConfig typeConfig;

    public PerfMonBinningStrategy(final long startOfFirstBin, final NumberFormat intNumberFormat,
            final NumberFormat floatNumberFormat) {
        super(startOfFirstBin, intNumberFormat, floatNumberFormat);
        binManager = new BinManager(startOfFirstBin, PerfAlyzerConstants.BIN_SIZE_MILLIS_30_SECONDS);
    }

    @Override
    public void binData(final Scanner scanner, final WritableByteChannel destChannel) throws IOException {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            tokenizer.reset(line);
            List<String> tokenList = tokenizer.getTokenList();

            if (typeConfig == null) {
                String type = tokenList.get(1);
                typeConfig = PerfMonTypeConfig.fromString(type);
            }

            try {
                long timestampMillis = Long.parseLong(tokenList.get(0));
                Double value = Double.valueOf(tokenList.get(2));
                binManager.addValue(timestampMillis, value);
            } catch (NumberFormatException ex) {
                log.error("Could not parse value {}. Line in perfMon file might be incomplete. Ignoring it.", ex);
            }
        }

        binManager.toCsv(destChannel, "seconds", typeConfig.getHeader(), intNumberFormat,
                typeConfig.getAggregationType());
    }

    @Override
    public void aggregateData(final ChannelManager channelManager) throws IOException {
        WritableByteChannel channel = channelManager.getChannel("aggregated");
        writeAggregatedHeader(channel);
        writeAggregatedLine(channel);
    }

    @Override
    public boolean needsBinning() {
        return true;
    }

    @Override
    public String transformDefautBinnedFilePath(final PerfAlyzerFile file) {
        return file.getFile().getPath();
    }

    private void writeAggregatedHeader(final WritableByteChannel destChannel) throws IOException {
        StrBuilder sb = new StrBuilder();
        typeConfig.getAggregatedHeaders().forEach(header -> appendEscapedAndQuoted(sb, DELIMITER, header));
        writeLineToChannel(destChannel, sb.toString(), Charsets.UTF_8);
    }

    private void writeAggregatedLine(final WritableByteChannel destChannel) throws IOException {
        double[] allValues = binManager.flatValuesStream().toArray();

        StrBuilder sb = new StrBuilder();

        String min = intNumberFormat.format(Doubles.min(allValues));
        String max = intNumberFormat.format(Doubles.max(allValues));

        switch (typeConfig) {
        case CPU:
        case IO:
        case JAVA:
            String mean = intNumberFormat.format(StatUtils.mean(allValues));
            appendEscapedAndQuoted(sb, DELIMITER, min, mean, max);
            break;
        case MEM:
        case SWAP:
            Percentile percentile = new Percentile();
            percentile.setData(allValues);
            String q10 = intNumberFormat.format(percentile.evaluate(10d));
            String q50 = intNumberFormat.format(percentile.evaluate(50d));
            String q90 = intNumberFormat.format(percentile.evaluate(90d));
            appendEscapedAndQuoted(sb, DELIMITER, min, q10, q50, q90, max);
            break;
        default:
            throw new IllegalStateException("Invalid perfMon data type");
        }

        writeLineToChannel(destChannel, sb.toString(), Charsets.UTF_8);
    }
}