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

com.gs.api.accelrx.context.SimplePerformanceLog Maven / Gradle / Ivy

The newest version!
package com.gs.api.accelrx.context;

import com.gs.api.accelrx.PerformanceLog;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

public class SimplePerformanceLog implements PerformanceLog {
    private static final Logger log = LoggerFactory.getLogger(SimplePerformanceLog.class);

    private final Map timepoints = new TreeMap<>();
    private final Map timeline = new TreeMap<>();

    @Override
    public void markStartTime(String timepointId) {
        markTime(timepointId + ":start");
    }

    @Override
    public void markEndTime(String timepointId) {
        markTime(timepointId + ":end");
    }

    @Override
    public void logRequestPerformance() {
        log.info("Request Performance: {} [{},{}]",
                requestTotal(),
                requestHandlers(),
                function());
    }

    @Override
    public void logClientPerformance(String serviceName) {
        log.info("Client Performance: {} [{}], Timeline [{}]",
                clientTotal(serviceName),
                clientBreakdown(serviceName),
                timeline());
    }

    String requestTotal() {
        return perfLog("request");
    }

    String function() {
        return perfLog("function");
    }

    String requestHandlers() {
        return filterKeys("handler").stream()
                .map(this::perfLog)
                .filter(Objects::nonNull)
                .collect(Collectors.joining(","));
    }

    String clientTotal(String serviceName) {
        return perfLog("client:" + serviceName);
    }

    String clientBreakdown(String serviceName) {
        String client = perfLog("client:" + serviceName + ":create-request") + ",";

        if (timepoints.containsKey("client:" + serviceName + ":body-serialization:start")) {
            client = client + perfLog("client:" + serviceName + ":body-serialization") + ",";
        }
        if (timepoints.containsKey("client:" + serviceName + ":sign-request:start")) {
            client = client + perfLog("client:" + serviceName + ":sign-request") + ",";
        }

        client = client + perfLog("client:" + serviceName + ":request") + "," +
                perfLog("client:" + serviceName + ":process-response");
        return client;
    }

    String timeline() {
        final AtomicLong baseline = new AtomicLong(-1);
        final AtomicLong previousTime = new AtomicLong(-1);
        return timeline.entrySet().stream()
                .map(entry -> {
                    long time = entry.getKey();
                    if (baseline.get() < 0) {
                        baseline.set(time);
                        previousTime.set(time);
                    }
                    String timepoint = "[" +
                            TimeUnit.NANOSECONDS.toMillis(time - baseline.get()) + ":" +
                            TimeUnit.NANOSECONDS.toMillis(time - previousTime.get()) + "]->" +
                            entry.getValue();
                    previousTime.set(time);
                    return timepoint;
                })
                .collect(Collectors.joining(","));
    }

    private Set filterKeys(String filter) {
        return timepoints.keySet().stream()
                .filter(key -> key.startsWith(filter + ":"))
                .map(key -> StringUtils.substringBeforeLast(key, ":"))
                .collect(Collectors.toSet());
    }

    private void markTime(String timepoint) {
        long time = System.nanoTime();
        timepoints.put(timepoint, time);
        timeline.put(time, timepoint);
    }

    private String perfLog(String timepointId) {
        if (timepoints.containsKey(timepointId + ":start") && timepoints.containsKey(timepointId + ":end")) {
            long duration = timepoints.get(timepointId + ":end") - timepoints.get(timepointId + ":start");
            return timepointId + "=" + TimeUnit.NANOSECONDS.toMillis(duration) + "ms";
        } else {
            return null;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy