Skip to content

Commit

Permalink
ArC new Dev UI - monitoring - invocation trees
Browse files Browse the repository at this point in the history
- add basic implementation (no streaming, no clickable trees, etc.)
  • Loading branch information
mkouba committed Apr 21, 2023
1 parent d0993ef commit eaf40b6
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
</tr>
</thead>
<tbody>
{#each info:invocationsMonitor.lastInvocations.orEmpty}
{#each info:invocationsMonitor.filteredLastInvocations.orEmpty}
<tr>
<td>{it.startFormatted}</td>
<td><ul id="tree">{#tree it root=true /}</ul></td>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { LitElement, html, css} from 'lit';
import { until } from 'lit/directives/until.js';
import { JsonRpc } from 'jsonrpc';
import { columnBodyRenderer } from '@vaadin/grid/lit.js';
import '@vaadin/grid';
import '@vaadin/grid/vaadin-grid-tree-column.js';
import '@vaadin/button';
import '@vaadin/checkbox';

Expand All @@ -26,14 +26,26 @@ export class QwcArcInvocationTrees extends LitElement {
.arctable {
height: 100%;
padding-bottom: 10px;
}`;
}
ul li::before {
content: "└─ ";
}
ul {
list-style: none;
}
code {
font-size: 90%;
}
`;

static properties = {
_invocations: {state: true}
_invocations: {state: true},
_filterOutQuarkusBeans: {state: true}
};

connectedCallback() {
super.connectedCallback();
this._filterOutQuarkusBeans = true;
this._refresh();
}

Expand All @@ -44,28 +56,59 @@ export class QwcArcInvocationTrees extends LitElement {
_renderInvocations(){
if(this._invocations){
return html`<div class="menubar">
<vaadin-button theme="small" @click=${()=>this._refresh} class="button">
<vaadin-button theme="small" @click=${() => this._refresh()} class="button">
<vaadin-icon icon="font-awesome-solid:rotate"></vaadin-icon> Refresh
</vaadin-button>
<vaadin-button theme="small" @click=${()=>this._clear} class="button">
<vaadin-button theme="small" @click=${() => this._clear()} class="button">
<vaadin-icon icon="font-awesome-solid:trash-can"></vaadin-icon> Clear
</vaadin-button>
<vaadin-checkbox theme="small" label="Filter out Quarkus beans" @click=${()=>this._toggleFilter}></vaadin-checkbox>
<vaadin-checkbox theme="small" .checked="${this._filterOutQuarkusBeans}" label="Filter out Quarkus beans" @change=${() => this._toggleFilter()}></vaadin-checkbox>
</div>
<vaadin-grid .items="${this._invocations}" class="arctable" theme="no-border">
<vaadin-grid-column auto-width
header="Start"
path="startTime"
resizable>
</vaadin-grid-column>
<vaadin-grid-column width="70%"
header="Invocations"
${columnBodyRenderer(this._invocationsRenderer, [])}
resizable>
</vaadin-grid-column>
</vaadin-grid>`;
}
}

_invocationsRenderer(invocation) {
return html`
<ul>
${this._invocationRenderer(invocation)}
</ul>
`;
}

_invocationRenderer(invocation) {
return html`
<li>
<qui-badge small><span>${invocation.kind.toLowerCase()}</span></qui-badge>
<code>${invocation.methodName}</code>
<qui-badge small primary><span>${invocation.duration == 0 ? '< 1' : invocation.duration} ms</span></qui-badge>
<ul>
${invocation.children.map(child =>
html`${this._invocationRenderer(child)}`
)}
</ul>
</li>
`;
}

_refresh(){
this.jsonRpc.getLastInvocations().then(invocations => {
this._invocations = invocations.result;
if (this._filterOutQuarkusBeans) {
this._invocations = invocations.result.filter(i => !i.quarkusBean);
} else {
this._invocations = invocations.result;
}
});
}

Expand All @@ -76,7 +119,8 @@ export class QwcArcInvocationTrees extends LitElement {
}

_toggleFilter(){
// TODO:
this._filterOutQuarkusBeans = !this._filterOutQuarkusBeans;
this._refresh();
}
}
customElements.define('qwc-arc-invocation-trees', QwcArcInvocationTrees);
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ public String getPackageName(String name) {
return "";
}

public boolean isQuarkusBean() {
if (interceptedBean == null) {
return false;
}
return interceptedBean.getBeanClass().getName().startsWith("io.quarkus");
}

public enum Kind {

BUSINESS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,22 @@ void addInvocation(Invocation invocation) {
invocations.add(invocation);
}

public List<Invocation> getLastInvocations() {
List<Invocation> result = new ArrayList<>(invocations);
// this method should be removed when the Dev UI 1 components are removed
public List<Invocation> getFilteredLastInvocations() {
List<Invocation> result = getLastInvocations();
if (filterOutQuarkusBeans) {
for (Iterator<Invocation> it = result.iterator(); it.hasNext();) {
Invocation invocation = it.next();
if (invocation.getInterceptedBean().getBeanClass().getName().startsWith("io.quarkus")) {
if (invocation.isQuarkusBean()) {
it.remove();
}
}
}
return result;
}

public List<Invocation> getLastInvocations() {
List<Invocation> result = new ArrayList<>(invocations);
Collections.reverse(result);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
package io.quarkus.arc.runtime.devmode;

import java.util.List;

public class InvocationInfo {

private String startTime;

private String methodName;

// in milliseconds
private long duration;

// business method, producer, observer, etc.
private String kind;

private List<InvocationInfo> children;

private boolean quarkusBean;

public String getStartTime() {
return startTime;
}
Expand All @@ -12,4 +26,44 @@ public void setStartTime(String startTime) {
this.startTime = startTime;
}

public String getMethodName() {
return methodName;
}

public void setMethodName(String methodName) {
this.methodName = methodName;
}

public long getDuration() {
return duration;
}

public void setDuration(long duration) {
this.duration = duration;
}

public String getKind() {
return kind;
}

public void setKind(String kind) {
this.kind = kind;
}

public List<InvocationInfo> getChildren() {
return children;
}

public void setChildren(List<InvocationInfo> children) {
this.children = children;
}

public boolean isQuarkusBean() {
return quarkusBean;
}

public void setQuarkusBean(boolean quarkusBean) {
this.quarkusBean = quarkusBean;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,13 @@ private List<InvocationInfo> toInvocationInfos(List<Invocation> invocations) {

private InvocationInfo toInvocationInfo(Invocation invocation) {
InvocationInfo info = new InvocationInfo();
LocalDateTime starttime = LocalDateTime.ofInstant(Instant.ofEpochMilli(invocation.getStart()), ZoneId.systemDefault());
info.setStartTime(timeString(starttime));
info.setStartTime(
timeString(LocalDateTime.ofInstant(Instant.ofEpochMilli(invocation.getStart()), ZoneId.systemDefault())));
info.setMethodName(invocation.getDeclaringClassName() + "#" + invocation.getMethod().getName());
info.setDuration(invocation.getDurationMillis());
info.setKind(invocation.getKind().toString());
info.setChildren(toInvocationInfos(invocation.getChildren()));
info.setQuarkusBean(invocation.isQuarkusBean());
return info;
}

Expand Down

0 comments on commit eaf40b6

Please sign in to comment.