Skip to content

Instantly share code, notes, and snippets.

@vongosling vongosling/gist:9661145
Last active Aug 29, 2015

Embed
What would you like to do?
Performance analyzer v1.1.0
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.perf4j.LogParser;
import org.perf4j.StopWatch;
import org.perf4j.slf4j.Slf4JStopWatch;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import com.google.common.collect.Lists;
/**
* Performance analyzer v1.1.0
*
* @author vongosling 2013-5-8
* @param <T> Concrete business Class
*/
public class LoadExecutor<T> {
private static String LOG_TIME = "time.log";
private static String LOG_RESULT = "result.log";
private static String LOG_PATTERN = "%-5level [%thread]: %message%n";
private int threads;
private long requests;
private ExecutorService executor;
private T target;
public LoadExecutor(int threads, long requests, T target) {
this.threads = threads;
this.requests = requests;
this.target = target;
}
public void exec(String method, Object... args) throws InterruptedException, SecurityException,
NoSuchMethodException, ExecutionException, TimeoutException, IOException {
String targetMethod = target.getClass().getSimpleName() + "-" + method;
String prefix = getFmtDate();
String threadCount = String.valueOf(threads);
String reqCount = String.valueOf(requests);
String timeFile = fileNameGenerator(prefix, targetMethod, threadCount, reqCount, LOG_TIME);
String resultFile = fileNameGenerator(prefix, targetMethod, threadCount, reqCount,
LOG_RESULT);
// Layout layout = new EnhancedPatternLayout();
// Appender timeFileAppender = new FileAppender(layout, timeFile, false);
// Appender resultFileAppender = new FileAppender(layout, resultFile, false);
// Logger loggerTime = Logger.getLogger(LOG_TIME);
// Logger loggerResult = Logger.getLogger(LOG_RESULT);
// loggerTime.setAdditivity(false);
// loggerTime.addAppender(timeFileAppender);
// loggerResult.setAdditivity(false);
// loggerResult.addAppender(resultFileAppender);
// doProbe(loggerTime, loggerResult, method, args);
LoggerContext resultFileContext = (LoggerContext) LoggerFactory.getILoggerFactory();
LoggerContext timeFileContext = (LoggerContext) LoggerFactory.getILoggerFactory();
PatternLayoutEncoder resultFileEncoder = new PatternLayoutEncoder();
resultFileEncoder.setContext(resultFileContext);
resultFileEncoder.setPattern(LOG_PATTERN);
resultFileEncoder.start();
PatternLayoutEncoder timeFileEncoder = new PatternLayoutEncoder();
timeFileEncoder.setContext(timeFileContext);
timeFileEncoder.setPattern(LOG_PATTERN);
timeFileEncoder.start();
FileAppender<ILoggingEvent> resultFileAppender = new FileAppender<ILoggingEvent>();
resultFileAppender.setFile(resultFile);
resultFileAppender.setContext(resultFileContext);
resultFileAppender.setEncoder(resultFileEncoder);
resultFileAppender.setPrudent(true);
resultFileAppender.start();
FileAppender<ILoggingEvent> timeFileAppender = new FileAppender<ILoggingEvent>();
timeFileAppender.setFile(timeFile);
timeFileAppender.setContext(timeFileContext);
timeFileAppender.setEncoder(timeFileEncoder);
timeFileAppender.setPrudent(true);
timeFileAppender.start();
Logger loggerTime = (Logger) LoggerFactory.getLogger(LOG_TIME);
Logger loggerResult = (Logger) LoggerFactory.getLogger(LOG_RESULT);
loggerTime.setAdditive(false);
loggerTime.setLevel(Level.INFO);
loggerTime.addAppender(timeFileAppender);
loggerResult.setAdditive(false);
loggerResult.setLevel(Level.INFO);
loggerResult.addAppender(resultFileAppender);
doProbe(loggerTime, loggerResult, method, args);
doCollect(targetMethod, prefix, threadCount, reqCount, timeFile);
}
private void doCollect(String targetMethod, String prefix, String threadCount, String reqCount,
String timeFile) {
String tpsFile = fileNameGenerator(prefix, targetMethod, threadCount, reqCount, "tps.html");
String statFile = fileNameGenerator(prefix, targetMethod, threadCount, reqCount, "stat.log");
String[] args = { "-o", statFile, "-g", tpsFile, timeFile };
LogParser.runMain(args);
}
private void doProbe(Logger loggerTime, Logger loggerResult, String method, Object... args)
throws NoSuchMethodException, InterruptedException, ExecutionException,
TimeoutException {
List<Class<?>> clazs = Lists.newArrayList();
executor = Executors.newFixedThreadPool(threads);
CompletionService<Boolean> cService = new ExecutorCompletionService<Boolean>(executor);
for (Object obj : args) {
clazs.add(obj.getClass());
}
Method m = target.getClass().getDeclaredMethod(method, clazs.toArray(new Class<?>[] {}));
warmUp(m, args);
for (long i = 1; i < requests + 1; i++) {
cService.submit(new Caller(loggerTime, m, args));
}
for (long i = 1; i < requests + 1; i++) {
Future<Boolean> future = cService.take();
boolean result = future.get(50, TimeUnit.SECONDS);
loggerResult.info("request " + i + " result is " + result);
}
}
private String fileNameGenerator(String name, String... args) {
StringBuilder sb = new StringBuilder(name);
for (String arg : args) {
sb.append("-");
sb.append(arg);
}
return sb.toString();
}
private String getFmtDate() {
Date date = new Date();
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
String prefix = fmt.format(date);
return prefix;
}
private void warmUp(Method method, Object... args) throws InterruptedException {
for (int i = 0; i < threads; i++) {
executor.execute(new WarmUp(method, args));
Thread.sleep(50);
}
}
private class WarmUp implements Runnable {
private Method method;
private Object[] args;
public WarmUp(Method method, Object... args) {
this.method = method;
this.args = args;
}
public void run() {
try {
method.invoke(target, args);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class Caller implements Callable<Boolean> {
private Method method;
private Logger log;
private Object[] args;
public Caller(Logger logger, Method method, Object... args) {
this.log = logger;
this.method = method;
this.args = args;
}
public Boolean call() throws Exception {
StopWatch stopWatch = new Slf4JStopWatch(log);
method.invoke(target, args);
stopWatch.stop(method.getName());
return true;
}
}
}
@vongosling

This comment has been minimized.

Copy link
Owner Author

vongosling commented Mar 20, 2014

public class LoadExecutorTest {

@Test
public void testExec() throws Exception {
    Calendar instance = Calendar.getInstance();
    //instance.add(Calendar.DAY_OF_WEEK, 5);
    //System.out.println(Arrays.asList(instance.getClass().getDeclaredMethods()));
    LoadExecutor<Calendar> loadExecutor = new LoadExecutor<Calendar>(20, 100, instance);
    loadExecutor.exec("getTimeZone");
}

}

@vongosling

This comment has been minimized.

Copy link
Owner Author

vongosling commented Mar 21, 2014

2013-5-08 - version 1.0.0 released
2014-3-21 - version 1.1.0 released
Fixed - log4j thread safe problem
Feature - support logback

@inter12

This comment has been minimized.

Copy link

inter12 commented Aug 6, 2014

查看某一个方法的执行时间?
感觉还可以写的更好点!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.