Skip to content

Commit

Permalink
Merge pull request #30274 from mkouba/build-metrics-items
Browse files Browse the repository at this point in the history
Build metrics - collect information about produced build items
  • Loading branch information
gsmet committed Jan 30, 2023
2 parents 5df1f9a + 4511f2e commit 0e301b0
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 4 deletions.
Expand Up @@ -254,6 +254,7 @@ private void doProduce(ItemId id, BuildItem value) {
throw Messages.msg.cannotMulti(id);
}
}
execution.getMetrics().buildItemProduced(value);
}

void depFinished() {
Expand Down
41 changes: 38 additions & 3 deletions core/builder/src/main/java/io/quarkus/builder/BuildMetrics.java
Expand Up @@ -13,6 +13,7 @@
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
Expand All @@ -21,6 +22,7 @@

import io.quarkus.builder.Json.JsonArrayBuilder;
import io.quarkus.builder.Json.JsonObjectBuilder;
import io.quarkus.builder.item.BuildItem;

public class BuildMetrics {

Expand All @@ -30,6 +32,7 @@ public class BuildMetrics {
private volatile long duration;
private final String buildTargetName;
private final ConcurrentMap<String, BuildStepRecord> records = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Integer> buildItems = new ConcurrentHashMap<>();
private final AtomicInteger idGenerator;

public BuildMetrics(String buildTargetName) {
Expand All @@ -54,11 +57,22 @@ public void buildStepFinished(StepInfo stepInfo, String thread, LocalTime starte
new BuildStepRecord(idGenerator.incrementAndGet(), stepInfo, thread, started, duration));
}

public void buildItemProduced(BuildItem buildItem) {
buildItems.compute(buildItem.getClass().getName(), this::itemProduced);
}

private Integer itemProduced(String key, Integer val) {
if (val == null) {
return 1;
}
return val + 1;
}

public void dumpTo(Path file) throws IOException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");

List<BuildStepRecord> sorted = new ArrayList<>(records.values());
sorted.sort(new Comparator<BuildStepRecord>() {
List<BuildStepRecord> sortedSteps = new ArrayList<>(records.values());
sortedSteps.sort(new Comparator<BuildStepRecord>() {
@Override
public int compare(BuildStepRecord o1, BuildStepRecord o2) {
return Long.compare(o2.duration, o1.duration);
Expand All @@ -72,7 +86,7 @@ public int compare(BuildStepRecord o1, BuildStepRecord o2) {

JsonArrayBuilder steps = Json.array();
json.put("records", steps);
for (BuildStepRecord rec : sorted) {
for (BuildStepRecord rec : sortedSteps) {
JsonObjectBuilder recObject = Json.object();
recObject.put("id", rec.id);
recObject.put("stepId", rec.stepInfo.getBuildStep().getId());
Expand All @@ -91,6 +105,27 @@ public int compare(BuildStepRecord o1, BuildStepRecord o2) {
recObject.put("dependents", dependentsArray);
steps.add(recObject);
}

List<Entry<String, Integer>> sortedItems = new ArrayList<>(buildItems.size());
buildItems.entrySet().forEach(sortedItems::add);
sortedItems.sort(new Comparator<Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return Integer.compare(o2.getValue(), o1.getValue());
}
});
JsonArrayBuilder items = Json.array();
json.put("items", items);
Integer itemsCount = 0;
for (Entry<String, Integer> e : sortedItems) {
JsonObjectBuilder itemObject = Json.object();
itemObject.put("class", e.getKey());
itemObject.put("count", e.getValue());
items.add(itemObject);
itemsCount += e.getValue();
}
json.put("itemsCount", itemsCount);

try (BufferedWriter writer = new BufferedWriter(new FileWriter(file.toFile(), StandardCharsets.UTF_8))) {
json.appendTo(writer);
}
Expand Down
Expand Up @@ -57,8 +57,8 @@ public Map<String, Object> get() {
buildDuration = data.getLong("duration");
buildStarted = LocalDateTime
.parse(data.getString("started"), DateTimeFormatter.ISO_LOCAL_DATE_TIME).toLocalTime();
JsonArray records = data.getJsonArray("records");

JsonArray records = data.getJsonArray("records");
for (Object record : records) {
JsonObject recordObj = (JsonObject) record;
recordObj.put("encodedStepId", URLEncoder.encode(recordObj.getString("stepId"),
Expand All @@ -73,7 +73,10 @@ public Map<String, Object> get() {
}
steps.add(recordObj);
}

metrics.put("records", records);
metrics.put("items", data.getJsonArray("items"));
metrics.put("itemsCount", data.getInteger("itemsCount"));
metrics.put("duration", buildDuration);
} catch (IOException e) {
LOG.error(e);
Expand Down
Expand Up @@ -15,6 +15,12 @@
Build Steps
</a>
</p>
<p class="card-text">
<a href="io.quarkus.quarkus-vertx-http/build-items" class="badge badge-light">
<i class="fas fa-hard-hat"></i>
Build Items
</a>
</p>
</div>
</div>
</div>
Expand Down
@@ -0,0 +1,34 @@
{#let metrics=info:buildMetrics.get}

{#include main fluid=true}
{#title}Build Items{/title}
{#body}
<p class="lead mt-4 mb-4">
Produced <strong>{metrics.itemsCount}</strong> build items.
</p>

<table class="table table-striped mb-4">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Build Item</th>
<th scope="col">Count</th>
</tr>
</thead>
<tbody>
{#for item in metrics.items}
<tr>
<td>{item_count}</td>
<td>
{item.class}
</td>
<td>
{item.count}
</td>
{/for}
</tbody>
</table>

{/include}

{/let}

0 comments on commit 0e301b0

Please sign in to comment.