diff --git a/celements-performance/pom.xml b/celements-performance/pom.xml new file mode 100644 index 000000000..e7a83c19a --- /dev/null +++ b/celements-performance/pom.xml @@ -0,0 +1,47 @@ + + + + + com.celements + celements + 5.5 + + 4.0.0 + celements-performance + 5.0-SNAPSHOT + Celements Performance metrics + + + com.celements + celements-model + 5.4 + provided + + + + scm:git:git@github.com:celements/celements-xwiki.git + scm:git:git@github.com:celements/celements-xwiki.git + https://github.com/celements/celements-xwiki + HEAD + + diff --git a/celements-performance/src/main/java/com/celements/performance/BenchmarkRole.java b/celements-performance/src/main/java/com/celements/performance/BenchmarkRole.java new file mode 100644 index 000000000..9b55bb9f5 --- /dev/null +++ b/celements-performance/src/main/java/com/celements/performance/BenchmarkRole.java @@ -0,0 +1,18 @@ +package com.celements.performance; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +import org.xwiki.component.annotation.ComponentRole; + +@ComponentRole +public interface BenchmarkRole { + + void bench(@NotEmpty String label); + + void startBench(); + + @NotNull + String println(boolean visible); + +} diff --git a/celements-performance/src/main/java/com/celements/performance/BenchmarkScriptService.java b/celements-performance/src/main/java/com/celements/performance/BenchmarkScriptService.java new file mode 100644 index 000000000..02ae83724 --- /dev/null +++ b/celements-performance/src/main/java/com/celements/performance/BenchmarkScriptService.java @@ -0,0 +1,38 @@ +package com.celements.performance; + +import org.xwiki.component.annotation.Component; +import org.xwiki.component.annotation.Requirement; +import org.xwiki.script.service.ScriptService; + +import com.celements.model.context.ModelContext; + +@Component("bench") +public class BenchmarkScriptService implements ScriptService { + + @Requirement + private ModelContext context; + + @Requirement + private BenchmarkRole benchSrv; + + public String benchAndPrint(String label) { + return benchAndPrint(label, false); + } + + public void bench(String label) { + benchSrv.bench(label); + } + + public String benchAndPrint(String label, boolean visible) { + benchSrv.bench(label); + boolean requestVisible = context.getRequest().toJavaUtil() + .map(request -> "true".equals(request.getParameter("showBenchmark"))) + .orElse(false); + return benchSrv.println(visible || requestVisible); + } + + public void startBench() { + benchSrv.startBench(); + } + +} diff --git a/celements-performance/src/main/java/com/celements/performance/BenchmarkService.java b/celements-performance/src/main/java/com/celements/performance/BenchmarkService.java new file mode 100644 index 000000000..49905ae80 --- /dev/null +++ b/celements-performance/src/main/java/com/celements/performance/BenchmarkService.java @@ -0,0 +1,93 @@ +package com.celements.performance; + +import static com.google.common.base.Preconditions.*; + +import java.util.ArrayList; +import java.util.Date; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xwiki.component.annotation.Component; +import org.xwiki.component.annotation.Requirement; +import org.xwiki.context.Execution; + +import com.google.common.base.Strings; + +@Component +public class BenchmarkService implements BenchmarkRole { + + private static final Logger LOGGER = LoggerFactory.getLogger(BenchmarkService.class); + + private static final String BENCH_LAST_TIME = "bench_lastTime"; + + private static final String BENCH_START_TIME = "bench_startTime"; + + private static final String CEL_BENCHMARK_VAL_PREFIX = "CEL_BENCHMARK_"; + + private static final String CEL_BENCHMARK_OUT_STRINGS = CEL_BENCHMARK_VAL_PREFIX + + "benchOutStrings"; + + @Requirement + Execution execution; + + private boolean isBenchStarted() { + return getContextLongValue(BENCH_START_TIME) != null; + } + + private Long getContextLongValue(String name) { + return (Long) execution.getContext().getProperty(CEL_BENCHMARK_VAL_PREFIX + name); + } + + private void setContextLongValue(String name, long value) { + execution.getContext().setProperty(CEL_BENCHMARK_VAL_PREFIX + name, value); + } + + @SuppressWarnings("unchecked") + private ArrayList getBenchOutStringArray() { + ArrayList benchOutStringArray; + if (execution.getContext().getProperty(CEL_BENCHMARK_OUT_STRINGS) == null) { + benchOutStringArray = new ArrayList<>(); + execution.getContext().setProperty(CEL_BENCHMARK_OUT_STRINGS, benchOutStringArray); + } else { + benchOutStringArray = (ArrayList) execution.getContext() + .getProperty(CEL_BENCHMARK_OUT_STRINGS); + } + return benchOutStringArray; + } + + @Override + public void bench(String label) { + checkArgument(!Strings.isNullOrEmpty(label)); + if (isBenchStarted()) { + long currTime = new Date().getTime(); + double totalTime = (currTime - getContextLongValue(BENCH_START_TIME)) / 1000.0; + double time = (currTime - getContextLongValue(BENCH_LAST_TIME)) / 1000.0; + setContextLongValue(BENCH_LAST_TIME, currTime); + getBenchOutStringArray() + .add("bench '" + label + "' — in " + time + "s — total " + totalTime + + "s"); + } else { + LOGGER.info("bench called without startBench. Skipping."); + } + } + + @Override + public void startBench() { + long benchStartTime = new Date().getTime(); + setContextLongValue(BENCH_START_TIME, benchStartTime); + setContextLongValue(BENCH_LAST_TIME, benchStartTime); + } + + @Override + public String println(boolean visible) { + String outStr = getBenchOutStringArray().stream() + .collect(Collectors.joining("\n")); + getBenchOutStringArray().clear(); + if (!visible) { + outStr = "\n"; + } + return outStr; + } + +} diff --git a/celements-performance/src/main/resources/META-INF/MANIFEST.MF b/celements-performance/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 000000000..5e9495128 --- /dev/null +++ b/celements-performance/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/celements-performance/src/main/resources/META-INF/components.txt b/celements-performance/src/main/resources/META-INF/components.txt new file mode 100644 index 000000000..1a12d83ca --- /dev/null +++ b/celements-performance/src/main/resources/META-INF/components.txt @@ -0,0 +1,2 @@ +com.celements.performance.BenchmarkService +com.celements.performance.BenchmarkScriptService