diff --git a/lib/kieker-teetime-stages-1.0-SNAPSHOT.jar b/lib/kieker-teetime-stages-1.0-SNAPSHOT.jar index 491905cc1da4c6d3a12dfa673420ef0abea8a7e3..75cbe272d185eb1a7e285c9c48d4437b2c7e5430 100644 Binary files a/lib/kieker-teetime-stages-1.0-SNAPSHOT.jar and b/lib/kieker-teetime-stages-1.0-SNAPSHOT.jar differ diff --git a/src/main/java/kieker/gui/model/AggregatedExecutionEntry.java b/src/main/java/kieker/gui/model/AggregatedExecutionEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..f366ffad31e0bdf88f3ea012c17f028bb5a625ec --- /dev/null +++ b/src/main/java/kieker/gui/model/AggregatedExecutionEntry.java @@ -0,0 +1,36 @@ +package kieker.gui.model; + +public final class AggregatedExecutionEntry { + + private final String container; + private final String component; + private final String operation; + private int calls; + + public AggregatedExecutionEntry(final String container, final String component, final String operation) { + this.container = container; + this.component = component; + this.operation = operation; + } + + public String getContainer() { + return this.container; + } + + public String getComponent() { + return this.component; + } + + public String getOperation() { + return this.operation; + } + + public void incrementCalls() { + this.calls++; + } + + public int getCalls() { + return this.calls; + } + +} diff --git a/src/main/java/kieker/gui/model/DataSource.java b/src/main/java/kieker/gui/model/DataSource.java index a9b718ae6186e92741be49efc4c246f5e7dc5046..514215aaf2d57ea72629fbd3233069640a54abbe 100644 --- a/src/main/java/kieker/gui/model/DataSource.java +++ b/src/main/java/kieker/gui/model/DataSource.java @@ -25,13 +25,14 @@ import teetime.framework.Analysis; /** * A container for data used within this application. - * + * * @author Nils Christian Ehmke */ public final class DataSource { private List<RecordEntry> records = Collections.emptyList(); private List<ExecutionEntry> traces = Collections.emptyList(); + private List<AggregatedExecutionEntry> aggregatedTraces; public void loadMonitoringLogFromFS(final String directory) { // Load and analyze the monitoring logs from the given directory @@ -44,6 +45,7 @@ public final class DataSource { // Store the results from the analysis this.records = analysisConfiguration.getRecordsList(); this.traces = analysisConfiguration.getTracesList(); + this.aggregatedTraces = analysisConfiguration.getAggregatedTraces(); } public List<RecordEntry> getRecords() { @@ -54,4 +56,8 @@ public final class DataSource { return this.traces; } + public List<AggregatedExecutionEntry> getAggregatedTrace() { + return this.aggregatedTraces; + } + } diff --git a/src/main/java/kieker/gui/model/ExecutionEntry.java b/src/main/java/kieker/gui/model/ExecutionEntry.java index 4b14b0520d4de6f63275b60d9ccc840976ed2b47..598e7d6844b6891d0d21428f47365869fb2c4a86 100644 --- a/src/main/java/kieker/gui/model/ExecutionEntry.java +++ b/src/main/java/kieker/gui/model/ExecutionEntry.java @@ -17,6 +17,7 @@ package kieker.gui.model; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; /** @@ -124,4 +125,65 @@ public final class ExecutionEntry { } } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + ((this.children == null) ? 0 : this.children.hashCode()); + result = (prime * result) + ((this.component == null) ? 0 : this.component.hashCode()); + result = (prime * result) + ((this.container == null) ? 0 : this.container.hashCode()); + result = (prime * result) + ((this.failedCause == null) ? 0 : this.failedCause.hashCode()); + result = (prime * result) + ((this.operation == null) ? 0 : this.operation.hashCode()); + return result; + } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (other == null) { + return false; + } + if (!(other instanceof ExecutionEntry)) { + return false; + } + final ExecutionEntry otherEntry = (ExecutionEntry) other; + if (!this.container.equals(otherEntry.container)) { + return false; + } + if (!this.component.equals(otherEntry.component)) { + return false; + } + if (!this.operation.equals(otherEntry.operation)) { + return false; + } + if (this.failedCause == null) { + if (otherEntry.failedCause != null) { + return false; + } + } else { + if (!this.failedCause.equals(otherEntry.failedCause)) { + return false; + } + } + if (this.children.size() != otherEntry.children.size()) { + return false; + } + + final Iterator<ExecutionEntry> ownChildrenIterator = this.children.iterator(); + final Iterator<ExecutionEntry> otherChildrenIterator = otherEntry.children.iterator(); + + while (ownChildrenIterator.hasNext()) { + final ExecutionEntry ownChild = ownChildrenIterator.next(); + final ExecutionEntry otherChild = otherChildrenIterator.next(); + + if (!ownChild.equals(otherChild)) { + return false; + } + } + + return true; + } + } diff --git a/src/main/java/kieker/gui/model/importer/ImportAnalysisConfiguration.java b/src/main/java/kieker/gui/model/importer/ImportAnalysisConfiguration.java index e6286894e0b72a5a4b8b05f2a88b7be07a307018..cf73b0e7d9c3bcff36bba77ec558837cadd6cf2a 100644 --- a/src/main/java/kieker/gui/model/importer/ImportAnalysisConfiguration.java +++ b/src/main/java/kieker/gui/model/importer/ImportAnalysisConfiguration.java @@ -22,10 +22,12 @@ import java.util.Vector; import kieker.common.record.IMonitoringRecord; import kieker.common.record.flow.IFlowRecord; +import kieker.gui.model.AggregatedExecutionEntry; import kieker.gui.model.ExecutionEntry; import kieker.gui.model.RecordEntry; import kieker.gui.model.importer.filter.Cloner; import kieker.gui.model.importer.filter.RecordSimplificator; +import kieker.gui.model.importer.filter.TraceAggregator; import kieker.gui.model.importer.filter.TraceReconstructor; import teetime.framework.AnalysisConfiguration; import teetime.framework.pipe.IPipeFactory; @@ -38,35 +40,42 @@ import teetime.stage.className.ClassNameRegistryRepository; import teetime.stage.io.filesystem.Dir2RecordsFilter; /** - * A configuration for the import and analysis of monitoring logs. - * + * A configuration for the import and analysis of monitoring logs. + * * @author Nils Christian Ehmke */ public final class ImportAnalysisConfiguration extends AnalysisConfiguration { private final List<RecordEntry> recordsList = new Vector<>(100000); private final List<ExecutionEntry> tracesList = new Vector<>(100000); + private final List<AggregatedExecutionEntry> aggregatedTraces = new Vector<>(100000); public ImportAnalysisConfiguration(final File importDirectory) { // Create the stages final InitialElementProducer<File> producer = new InitialElementProducer<>(importDirectory); final Dir2RecordsFilter reader = new Dir2RecordsFilter(new ClassNameRegistryRepository()); final InstanceOfFilter<IMonitoringRecord, IFlowRecord> typeFilter = new InstanceOfFilter<>(IFlowRecord.class); - final Cloner<IFlowRecord> distributor = new Cloner<>(); + final Cloner<IFlowRecord> fstDistributor = new Cloner<>(); final RecordSimplificator recordSimplificator = new RecordSimplificator(); final CollectorSink<RecordEntry> recordCollector = new CollectorSink<>(this.recordsList); final TraceReconstructor traceReconstructor = new TraceReconstructor(); + final Cloner<ExecutionEntry> sndDistributor = new Cloner<>(); final CollectorSink<ExecutionEntry> traceCollector = new CollectorSink<>(this.tracesList); + final TraceAggregator traceAggregator = new TraceAggregator(); + final CollectorSink<AggregatedExecutionEntry> aggregatedTraceCollector = new CollectorSink<>(this.aggregatedTraces); // Connect the stages final IPipeFactory pipeFactory = AnalysisConfiguration.PIPE_FACTORY_REGISTRY.getPipeFactory(ThreadCommunication.INTRA, PipeOrdering.ARBITRARY, false); pipeFactory.create(producer.getOutputPort(), reader.getInputPort()); pipeFactory.create(reader.getOutputPort(), typeFilter.getInputPort()); - pipeFactory.create(typeFilter.getOutputPort(), distributor.getInputPort()); - pipeFactory.create(distributor.getFirstOutputPort(), recordSimplificator.getInputPort()); + pipeFactory.create(typeFilter.getOutputPort(), fstDistributor.getInputPort()); + pipeFactory.create(fstDistributor.getFirstOutputPort(), recordSimplificator.getInputPort()); pipeFactory.create(recordSimplificator.getOutputPort(), recordCollector.getInputPort()); - pipeFactory.create(distributor.getSecondOutputPort(), traceReconstructor.getInputPort()); - pipeFactory.create(traceReconstructor.getOutputPort(), traceCollector.getInputPort()); + pipeFactory.create(fstDistributor.getSecondOutputPort(), traceReconstructor.getInputPort()); + pipeFactory.create(traceReconstructor.getOutputPort(), sndDistributor.getInputPort()); + pipeFactory.create(sndDistributor.getFirstOutputPort(), traceCollector.getInputPort()); + pipeFactory.create(sndDistributor.getSecondOutputPort(), traceAggregator.getInputPort()); + pipeFactory.create(traceAggregator.getOutputPort(), aggregatedTraceCollector.getInputPort()); // Make sure that the producer is executed by the analysis super.addThreadableStage(producer); @@ -80,4 +89,8 @@ public final class ImportAnalysisConfiguration extends AnalysisConfiguration { return this.tracesList; } + public List<AggregatedExecutionEntry> getAggregatedTraces() { + return this.aggregatedTraces; + } + } diff --git a/src/main/java/kieker/gui/model/importer/filter/TraceAggregator.java b/src/main/java/kieker/gui/model/importer/filter/TraceAggregator.java new file mode 100644 index 0000000000000000000000000000000000000000..a0ec2f106fd8a050651d9ae164c89db49c34bc06 --- /dev/null +++ b/src/main/java/kieker/gui/model/importer/filter/TraceAggregator.java @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * 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 kieker.gui.model.importer.filter; + +import java.util.HashMap; +import java.util.Map; + +import kieker.gui.model.AggregatedExecutionEntry; +import kieker.gui.model.ExecutionEntry; +import teetime.framework.AbstractConsumerStage; +import teetime.framework.OutputPort; + +/** + * @author Nils Christian Ehmke + */ +public final class TraceAggregator extends AbstractConsumerStage<ExecutionEntry> { + + private final OutputPort<AggregatedExecutionEntry> outputPort = super.createOutputPort(); + private final Map<ExecutionEntry, AggregatedExecutionEntry> aggregationMap = new HashMap<>(); + + @Override + protected void execute(final ExecutionEntry execEntry) { + if (!this.aggregationMap.containsKey(execEntry)) { + final AggregatedExecutionEntry aggregatedExecutionEntry = new AggregatedExecutionEntry(execEntry.getContainer(), execEntry.getComponent(), execEntry.getOperation()); + this.aggregationMap.put(execEntry, aggregatedExecutionEntry); + } + this.aggregationMap.get(execEntry).incrementCalls(); + } + + @Override + public void onTerminating() throws Exception { + System.out.println("onTerminating"); + for (final AggregatedExecutionEntry aggregatedExecutionEntry : this.aggregationMap.values()) { + this.outputPort.send(aggregatedExecutionEntry); + } + super.onTerminating(); + } + + public OutputPort<AggregatedExecutionEntry> getOutputPort() { + return this.outputPort; + } + +} diff --git a/src/main/java/kieker/gui/view/MainWindow.java b/src/main/java/kieker/gui/view/MainWindow.java index e3661f114b1d51d83ca4034ef2bda7883f24a70f..04c391829e7a3da8b42eeeddd05bf039a1a204a8 100644 --- a/src/main/java/kieker/gui/view/MainWindow.java +++ b/src/main/java/kieker/gui/view/MainWindow.java @@ -16,8 +16,6 @@ package kieker.gui.view; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -25,12 +23,11 @@ import java.util.Observable; import java.util.Observer; import kieker.common.record.IMonitoringRecord; +import kieker.gui.model.AggregatedExecutionEntry; import kieker.gui.model.DataSource; import kieker.gui.model.ExecutionEntry; import kieker.gui.model.Properties; import kieker.gui.model.RecordEntry; -import kieker.tools.traceAnalysis.systemModel.ComponentType; -import kieker.tools.traceAnalysis.systemModel.Operation; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TreeViewer; @@ -64,7 +61,7 @@ import org.eclipse.wb.swt.SWTResourceManager; /** * The main window of this application. This file should probably be maintained with the Eclipse GUI builder. - * + * * @author Nils Christian Ehmke */ public class MainWindow { @@ -72,15 +69,14 @@ public class MainWindow { protected Shell shell; private Composite mainComposite; private Table recordsTable; - private TreeViewer treeViewer_4; - private SashForm sashForm; + private SashForm outerForm; private TreeViewer explorerTreeViewer; private TreeItem explorerTreeItem; private TreeItem recordsTreeItem; private TreeItem executionTracesTreeItem; private TableViewer recordsTableViewer; private TableColumn recordsTableTimestampColumn; - private TableColumn recordsTableRecordsColumn; + private TableColumn recordsTableRecordColumn; private Menu menuBar; private MenuItem fileMenuItem; private Menu fileMenu; @@ -91,7 +87,7 @@ public class MainWindow { private MenuItem aboutMenuItem; private Tree explorerTree; private Tree executionTracesTree; - private TreeColumn treeColumn_7; + private TreeColumn tracesTreeContainerColumn; private TreeColumn treeColumn_8; private TreeColumn treeColumn_10; private TreeColumn treeColumn_11; @@ -102,13 +98,13 @@ public class MainWindow { private MenuItem mntmLongComponentNames; private MenuItem mntmShortOperationParameters; private MenuItem mntmLongOperationParameters; - private TableColumn tblclmnType; - private SashForm sashForm_1; + private TableColumn recordsTableTypeColumn; + private SashForm explorerForm; private final DataSource model = new DataSource(); private TreeColumn trclmnPercent; private Label lblNa; - private SashForm sashForm_2; - private Composite composite; + private SashForm executionTracesForm; + private Composite executionTracesDetailComposite; private Label lblTraceId; private Label lblNa_1; private Label lblFailed; @@ -123,6 +119,24 @@ public class MainWindow { private Label lblNa_6; private Label lblStackDepth; private Label lblNa_7; + private SashForm sashForm; + private Tree tree_1; + private TreeColumn treeColumn; + private TreeColumn treeColumn_1; + private TreeColumn treeColumn_2; + private TreeColumn trclmnCalls; + private Composite composite; + private Label label; + private Label label_1; + private Label label_2; + private Label label_3; + private Label label_4; + private Label label_5; + private Label label_10; + private Label label_11; + private Label label_12; + private Label label_13; + private TreeItem trtmAggregatedExecutionTraces; public static void main(final String[] args) { final MainWindow window = new MainWindow(); @@ -132,7 +146,7 @@ public class MainWindow { public void open() { final Display display = Display.getDefault(); this.createContents(); - + this.model.loadMonitoringLogFromFS("testdata"); this.shell.open(); this.shell.layout(); while (!this.shell.isDisposed()) { @@ -149,12 +163,12 @@ public class MainWindow { this.shell.setText("Kieker's GUI"); this.shell.setLayout(new GridLayout(1, false)); - this.sashForm = new SashForm(this.shell, SWT.NONE); - this.sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + this.outerForm = new SashForm(this.shell, SWT.NONE); + this.outerForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); - this.sashForm_1 = new SashForm(this.sashForm, SWT.VERTICAL); + this.explorerForm = new SashForm(this.outerForm, SWT.VERTICAL); - this.explorerTreeViewer = new TreeViewer(this.sashForm_1, SWT.BORDER); + this.explorerTreeViewer = new TreeViewer(this.explorerForm, SWT.BORDER); this.explorerTree = this.explorerTreeViewer.getTree(); this.explorerTreeItem = new TreeItem(this.explorerTree, SWT.NONE); @@ -166,13 +180,16 @@ public class MainWindow { this.executionTracesTreeItem = new TreeItem(this.explorerTreeItem, SWT.NONE); this.executionTracesTreeItem.setText("Execution Traces"); + this.trtmAggregatedExecutionTraces = new TreeItem(this.executionTracesTreeItem, SWT.NONE); + this.trtmAggregatedExecutionTraces.setText("Aggregated Execution Traces"); + this.executionTracesTreeItem.setExpanded(true); this.explorerTreeItem.setExpanded(true); this.explorerTree.addSelectionListener(new ExplorerTreeSelectionAdapter()); - this.sashForm_1.setWeights(new int[] { 3 }); + this.explorerForm.setWeights(new int[] { 3 }); - this.mainComposite = new Composite(this.sashForm, SWT.NONE); + this.mainComposite = new Composite(this.outerForm, SWT.NONE); this.mainComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.mainComposite.setLayout(new StackLayout()); @@ -186,27 +203,27 @@ public class MainWindow { this.recordsTableTimestampColumn.setText("Timestamp"); this.recordsTableTimestampColumn.addListener(SWT.Selection, new RecordsTableTimestampSortListener()); - this.tblclmnType = new TableColumn(this.recordsTable, SWT.NONE); - this.tblclmnType.setWidth(100); - this.tblclmnType.setText("Type"); - this.tblclmnType.addListener(SWT.Selection, new RecordsTableTypeSortListener()); + this.recordsTableTypeColumn = new TableColumn(this.recordsTable, SWT.NONE); + this.recordsTableTypeColumn.setWidth(100); + this.recordsTableTypeColumn.setText("Type"); + this.recordsTableTypeColumn.addListener(SWT.Selection, new RecordsTableTypeSortListener()); - this.recordsTableRecordsColumn = new TableColumn(this.recordsTable, SWT.NONE); - this.recordsTableRecordsColumn.setWidth(100); - this.recordsTableRecordsColumn.setText("Record"); - this.recordsTableRecordsColumn.addListener(SWT.Selection, new RecordsTableTimestampSortListener()); + this.recordsTableRecordColumn = new TableColumn(this.recordsTable, SWT.NONE); + this.recordsTableRecordColumn.setWidth(100); + this.recordsTableRecordColumn.setText("Record"); + this.recordsTableRecordColumn.addListener(SWT.Selection, new RecordsTableTimestampSortListener()); - this.sashForm_2 = new SashForm(this.mainComposite, SWT.VERTICAL); + this.executionTracesForm = new SashForm(this.mainComposite, SWT.VERTICAL); - this.executionTracesTree = new Tree(this.sashForm_2, SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL); + this.executionTracesTree = new Tree(this.executionTracesForm, SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL); this.executionTracesTree.setHeaderVisible(true); this.executionTracesTree.addListener(SWT.SetData, new ExecutionTracesTreeSetDataListener()); this.executionTracesTree.addSelectionListener(new ExecutionTraceTreeSelectionListener()); Properties.getInstance().addObserver(new TreeUpdateObserver(this.executionTracesTree)); - this.treeColumn_7 = new TreeColumn(this.executionTracesTree, SWT.NONE); - this.treeColumn_7.setWidth(100); - this.treeColumn_7.setText("Execution Container"); + this.tracesTreeContainerColumn = new TreeColumn(this.executionTracesTree, SWT.NONE); + this.tracesTreeContainerColumn.setWidth(100); + this.tracesTreeContainerColumn.setText("Execution Container"); this.treeColumn_8 = new TreeColumn(this.executionTracesTree, SWT.NONE); this.treeColumn_8.setWidth(100); @@ -228,69 +245,137 @@ public class MainWindow { this.treeColumn_16.setWidth(100); this.treeColumn_16.setText("Trace ID"); - this.composite = new Composite(this.sashForm_2, SWT.BORDER); - this.composite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); - this.composite.setLayout(new GridLayout(2, false)); + this.executionTracesDetailComposite = new Composite(this.executionTracesForm, SWT.BORDER); + this.executionTracesDetailComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + this.executionTracesDetailComposite.setLayout(new GridLayout(2, false)); - this.lblExecutionContainer = new Label(this.composite, SWT.NONE); + this.lblExecutionContainer = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblExecutionContainer.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblExecutionContainer.setText("Execution Container:"); - this.lblNa_4 = new Label(this.composite, SWT.NONE); + this.lblNa_4 = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblNa_4.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); this.lblNa_4.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblNa_4.setText("N/A"); - this.lblComponent = new Label(this.composite, SWT.NONE); + this.lblComponent = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblComponent.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblComponent.setText("Component:"); - this.lblNa_5 = new Label(this.composite, SWT.NONE); + this.lblNa_5 = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblNa_5.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblNa_5.setText("N/A"); - this.lblOperation = new Label(this.composite, SWT.NONE); + this.lblOperation = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblOperation.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblOperation.setText("Operation:"); - this.lblNa_6 = new Label(this.composite, SWT.NONE); + this.lblNa_6 = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblNa_6.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblNa_6.setText("N/A"); - this.lblTraceId = new Label(this.composite, SWT.NONE); + this.lblTraceId = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblTraceId.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblTraceId.setText("Trace ID:"); - this.lblNa_1 = new Label(this.composite, SWT.NONE); + this.lblNa_1 = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblNa_1.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblNa_1.setText("N/A"); - this.lblDuration = new Label(this.composite, SWT.NONE); + this.lblDuration = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblDuration.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblDuration.setText("Duration:"); - this.lblNa_3 = new Label(this.composite, SWT.NONE); + this.lblNa_3 = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblNa_3.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblNa_3.setText("N/A"); - this.lblStackDepth = new Label(this.composite, SWT.NONE); + this.lblStackDepth = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblStackDepth.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblStackDepth.setText("Stack Depth:"); - this.lblNa_7 = new Label(this.composite, SWT.NONE); + this.lblNa_7 = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblNa_7.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblNa_7.setText("N/A"); - this.lblFailed = new Label(this.composite, SWT.NONE); + this.lblFailed = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblFailed.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblFailed.setText("Failed:"); - this.lblNa_2 = new Label(this.composite, SWT.NONE); + this.lblNa_2 = new Label(this.executionTracesDetailComposite, SWT.NONE); this.lblNa_2.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); this.lblNa_2.setText("N/A"); - this.sashForm_2.setWeights(new int[] { 2, 1 }); + this.executionTracesForm.setWeights(new int[] { 2, 1 }); + + this.sashForm = new SashForm(this.mainComposite, SWT.VERTICAL); + + this.tree_1 = new Tree(this.sashForm, SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL); + this.tree_1.setHeaderVisible(true); + this.tree_1.addListener(SWT.SetData, new AggregatedExecutionTracesTreeSetDataListener()); + + this.treeColumn = new TreeColumn(this.tree_1, SWT.NONE); + this.treeColumn.setWidth(100); + this.treeColumn.setText("Execution Container"); + + this.treeColumn_1 = new TreeColumn(this.tree_1, SWT.NONE); + this.treeColumn_1.setWidth(100); + this.treeColumn_1.setText("Component"); + + this.treeColumn_2 = new TreeColumn(this.tree_1, SWT.NONE); + this.treeColumn_2.setWidth(100); + this.treeColumn_2.setText("Operation"); + + this.trclmnCalls = new TreeColumn(this.tree_1, SWT.NONE); + this.trclmnCalls.setWidth(100); + this.trclmnCalls.setText("# Calls"); + + this.composite = new Composite(this.sashForm, SWT.BORDER); + this.composite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + this.composite.setLayout(new GridLayout(2, false)); + + this.label = new Label(this.composite, SWT.NONE); + this.label.setText("Execution Container:"); + this.label.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + + this.label_1 = new Label(this.composite, SWT.NONE); + this.label_1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); + this.label_1.setText("N/A"); + this.label_1.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + + this.label_2 = new Label(this.composite, SWT.NONE); + this.label_2.setText("Component:"); + this.label_2.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + + this.label_3 = new Label(this.composite, SWT.NONE); + this.label_3.setText("N/A"); + this.label_3.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + + this.label_4 = new Label(this.composite, SWT.NONE); + this.label_4.setText("Operation:"); + this.label_4.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + + this.label_5 = new Label(this.composite, SWT.NONE); + this.label_5.setText("N/A"); + this.label_5.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + + this.label_10 = new Label(this.composite, SWT.NONE); + this.label_10.setText("Stack Depth:"); + this.label_10.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + + this.label_11 = new Label(this.composite, SWT.NONE); + this.label_11.setText("N/A"); + this.label_11.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); - this.sashForm.setWeights(new int[] { 2, 4 }); + this.label_12 = new Label(this.composite, SWT.NONE); + this.label_12.setText("Failed:"); + this.label_12.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + + this.label_13 = new Label(this.composite, SWT.NONE); + this.label_13.setText("N/A"); + this.label_13.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); + this.sashForm.setWeights(new int[] { 2, 1 }); + + this.outerForm.setWeights(new int[] { 2, 4 }); this.menuBar = new Menu(this.shell, SWT.BAR); this.shell.setMenuBar(this.menuBar); @@ -381,7 +466,21 @@ public class MainWindow { protected void showAggregatedExecutionTraces() { // Show the tree + this.setVisibleMainComponent(this.sashForm); + + // Reload the data from the model... + final List<AggregatedExecutionEntry> traces = this.model.getAggregatedTrace(); + + // ...and write it into the tree + this.tree_1.setItemCount(traces.size()); + this.tree_1.setData(traces); + this.lblNa.setText(Integer.toString(traces.size()) + " Aggregated Traces"); + this.lblNa.pack(); + // Resize the columns + for (final TreeColumn column : this.tree_1.getColumns()) { + column.pack(); + } } protected void showAggregatedExecutionTracesByContainer() { @@ -394,7 +493,7 @@ public class MainWindow { protected void showExecutionTraces() { // Show the tree - this.setVisibleMainComponent(this.sashForm_2); + this.setVisibleMainComponent(this.executionTracesForm); // Reload the data from the model... final List<ExecutionEntry> traces = this.model.getTraces(); @@ -456,6 +555,8 @@ public class MainWindow { MainWindow.this.showRecords(); } else if (MainWindow.this.executionTracesTreeItem == selectedWidget) { MainWindow.this.showExecutionTraces(); + } else if (MainWindow.this.trtmAggregatedExecutionTraces == selectedWidget) { + MainWindow.this.showAggregatedExecutionTraces(); } else { MainWindow.this.setVisibleMainComponent(null); MainWindow.this.lblNa.setText(""); @@ -464,7 +565,7 @@ public class MainWindow { } - private class SystemModelTreeSetDataListener implements Listener { + private class AggregatedExecutionTracesTreeSetDataListener implements Listener { @Override public void handleEvent(final Event event) { @@ -475,19 +576,36 @@ public class MainWindow { final TreeItem parent = item.getParentItem(); // Decide whether the current item is a root or not + final AggregatedExecutionEntry executionEntry; if (parent == null) { - final List<ComponentType> components = new ArrayList<>((Collection<ComponentType>) tree.getData()); - final ComponentType component = components.get(tableIndex); + executionEntry = ((List<AggregatedExecutionEntry>) tree.getData()).get(tableIndex); + } else { + // executionEntry = ((AggregatedExecutionEntry) parent.getData()).getChildren().get(tableIndex); + executionEntry = null; + } - item.setText(component.getFullQualifiedName()); + String componentName = executionEntry.getComponent(); + if (Properties.getInstance().isShortComponentNames()) { + final int lastPointPos = componentName.lastIndexOf('.'); + componentName = componentName.substring(lastPointPos + 1); + } + String operationString = executionEntry.getOperation(); + if (Properties.getInstance().isShortOperationParameters()) { + operationString = operationString.replaceAll("\\(..*\\)", "(...)"); - item.setData(component.getOperations()); - item.setItemCount(component.getOperations().size()); - } else { - final List<Operation> operations = new ArrayList<>((Collection<Operation>) parent.getData()); - final Operation operation = operations.get(tableIndex); - item.setText(operation.getSignature().toString()); + final int lastPointPos = operationString.lastIndexOf('.', operationString.length() - 5); + operationString = operationString.substring(lastPointPos + 1); } + item.setText(new String[] { executionEntry.getContainer(), componentName, operationString, Integer.toString(executionEntry.getCalls()) }); + + // if (executionEntry.isFailed()) { + // final Color colorRed = Display.getCurrent().getSystemColor(SWT.COLOR_RED); + // item.setForeground(colorRed); + // } + + item.setData(executionEntry); + item.setItemCount(0); + // item.setItemCount(executionEntry.getChildren().size()); } } @@ -503,7 +621,6 @@ public class MainWindow { // Decide whether the current item is a root or not final ExecutionEntry executionEntry; - final List<ExecutionEntry> executions; final String traceID; if (parent == null) {