Skip to content

Commit

Permalink
Add Recent Traces button in TraceInputDialog
Browse files Browse the repository at this point in the history
  • Loading branch information
patschuh committed Nov 25, 2021
1 parent 41a90cf commit a48a7b0
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 12 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Expand Up @@ -61,6 +61,7 @@ dependencies {
compile 'net.thisptr:jackson-jq:1.0.0-preview.20191208'
compile 'com.dlsc.formsfx:formsfx-core:8.4.0'
compile group: 'org.sourcelab', name: 'kafka-connect-client', version: '3.1.0'
compile 'org.controlsfx:controlsfx:8.40.18'

testCompile 'junit:junit:4.12'
testCompile 'org.springframework.kafka:spring-kafka-test:2.2.0.RELEASE'
Expand All @@ -69,7 +70,7 @@ dependencies {
}

group = 'at.esque.kafka'
version = '1.5.0-SNAPSHOT'
version = '1.6.0-SNAPSHOT'
sourceCompatibility = '1.8'

publishing {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/at/esque/kafka/Controller.java
Expand Up @@ -406,7 +406,7 @@ private ListCell<String> topicListCellFactory() {
Map<String, TopicMessageTypeConfig> configs = configHandler.getTopicConfigForClusterIdentifier(selectedCluster().getIdentifier());
TopicMessageTypeConfig topicMessageTypeConfig = getTopicMessageTypeConfig(configs);
Map<String, String> consumerConfig = configHandler.readConsumerConfigs(selectedCluster().getIdentifier());
TraceInputDialog.show(true, topicMessageTypeConfig.getKeyType() == MessageType.AVRO, Settings.isTraceQuickSelectEnabled(configHandler.getSettingsProperties()), Settings.readDurationSetting(configHandler.getSettingsProperties()))
TraceInputDialog.show(true, topicMessageTypeConfig.getKeyType() == MessageType.AVRO, Settings.isTraceQuickSelectEnabled(configHandler.getSettingsProperties()), Settings.readDurationSetting(configHandler.getSettingsProperties()), Integer.parseInt(configHandler.getSettingsProperties().get(Settings.RECENT_TRACE_MAX_ENTRIES)))
.ifPresent(traceKeyInput -> {
backGroundTaskHolder.setBackGroundTaskDescription("tracing key: " + traceKeyInput.getSearch());
Integer partition = null;
Expand All @@ -428,7 +428,7 @@ private ListCell<String> topicListCellFactory() {
Map<String, TopicMessageTypeConfig> configs = configHandler.getTopicConfigForClusterIdentifier(selectedCluster().getIdentifier());
TopicMessageTypeConfig topicMessageTypeConfig = getTopicMessageTypeConfig(configs);
Map<String, String> consumerConfig = configHandler.readConsumerConfigs(selectedCluster().getIdentifier());
TraceInputDialog.show(false, false, Settings.isTraceQuickSelectEnabled(configHandler.getSettingsProperties()), Settings.readDurationSetting(configHandler.getSettingsProperties()))
TraceInputDialog.show(false, false, Settings.isTraceQuickSelectEnabled(configHandler.getSettingsProperties()), Settings.readDurationSetting(configHandler.getSettingsProperties()),Integer.parseInt(configHandler.getSettingsProperties().get(Settings.RECENT_TRACE_MAX_ENTRIES)))
.ifPresent(traceInput -> {
backGroundTaskHolder.setBackGroundTaskDescription("tracing in Value: " + traceInput.getSearch());
Pattern pattern = Pattern.compile(traceInput.getSearch());
Expand Down
109 changes: 102 additions & 7 deletions src/main/java/at/esque/kafka/dialogs/TraceInputDialog.java
Expand Up @@ -3,22 +3,47 @@
import at.esque.kafka.Main;
import at.esque.kafka.alerts.ErrorAlert;
import at.esque.kafka.controls.InstantPicker;
import at.esque.kafka.handlers.Settings;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.Background;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import org.controlsfx.control.PopOver;
import org.jetbrains.annotations.NotNull;
import org.kordamp.ikonli.fontawesome.FontAwesome;
import org.kordamp.ikonli.javafx.FontIcon;

import java.time.*;
import java.util.*;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

public class TraceInputDialog {
public static Optional<TraceInput> show(boolean isKeyTrace, boolean isAvroKeyType, boolean traceQuickSelectEnabled, List<Duration> durations) {

public static final LinkedList<String> recentTrace = new LinkedList<>();

public static Optional<TraceInput> show(boolean isKeyTrace, boolean isAvroKeyType, boolean traceQuickSelectEnabled, List<Duration> durations, int recentTraceMaxEntries) {
Dialog<TraceInput> dialog = new Dialog<>();
Main.applyIcon(dialog);
Main.applyStylesheet(dialog.getDialogPane().getScene());
Expand All @@ -37,7 +62,11 @@ public static Optional<TraceInput> show(boolean isKeyTrace, boolean isAvroKeyTyp
grid.setVgap(10);
grid.setPadding(new Insets(20, 20, 20, 20));


TextField key = new TextField();
key.getStyleClass().add("first");
HBox.setHgrow(key, Priority.ALWAYS);
HBox keyBox = buildKeyHBox(key);
key.setPrefWidth(500);
CheckBox fastTraceFlag = new CheckBox();
CheckBox searchNullFlag = new CheckBox();
Expand All @@ -59,6 +88,7 @@ public static Optional<TraceInput> show(boolean isKeyTrace, boolean isAvroKeyTyp
fastTraceLabel.setTooltip(new Tooltip("Fast Trace traces in one partition determined by the default partitioning"));
grid.add(fastTraceLabel, 0, 1);
grid.add(fastTraceFlag, 1, 1);
fastTraceFlag.setSelected(true);
}
key.setPromptText("search");
grid.add(new Label("Key:"), 0, 0);
Expand All @@ -70,11 +100,11 @@ public static Optional<TraceInput> show(boolean isKeyTrace, boolean isAvroKeyTyp
key.disableProperty().bind(searchNullFlag.selectedProperty());
grid.add(new Label("regex:"), 0, 0);
}
grid.add(key, 1, 0);
grid.add(keyBox, 1, 0);
grid.add(startTimeLabel, 0, 2);
grid.add(hBox, 1, 2);

if(traceQuickSelectEnabled) {
if (traceQuickSelectEnabled) {
HBox buttonBar = new HBox();
fillButtonBar(buttonBar, instantPicker, durations);
buttonBar.setMaxWidth(Double.MAX_VALUE);
Expand All @@ -92,6 +122,7 @@ public static Optional<TraceInput> show(boolean isKeyTrace, boolean isAvroKeyTyp

dialog.setResultConverter(dialogButton -> {
if (dialogButton == ButtonType.OK) {
updateRecentTrace(key.getText(), recentTraceMaxEntries);
return new TraceInput(key.getText(), fastTraceFlag.isSelected(), searchNullFlag.isSelected(), instantPicker.getInstantValue() == null ? null : instantPicker.getInstantValue().toEpochMilli());
}
return null;
Expand All @@ -100,6 +131,70 @@ public static Optional<TraceInput> show(boolean isKeyTrace, boolean isAvroKeyTyp
return dialog.showAndWait();
}

@NotNull
private static HBox buildKeyHBox(TextField key) {
HBox keyBox = new HBox();
keyBox.getChildren().add(key);
FontIcon icon = new FontIcon();
icon.setIconCode(FontAwesome.HISTORY);
ListView<String> recentTraces = buildRecentTracesView(key);
PopOver popOver = buildPopover(recentTraces);
Button traceHistoryButton = new Button();
traceHistoryButton.setGraphic(icon);
traceHistoryButton.getStyleClass().add("last");
keyBox.getChildren().add(traceHistoryButton);
traceHistoryButton.setOnAction(event -> {
popOver.show(traceHistoryButton);
});
return keyBox;
}

@NotNull
private static PopOver buildPopover(ListView<String> recentTraces) {
PopOver popOver = new PopOver();
popOver.setContentNode(recentTraces);
popOver.setTitle("Recent Traces");
popOver.setCloseButtonEnabled(true);
popOver.setHeaderAlwaysVisible(true);
return popOver;
}

@NotNull
private static ListView<String> buildRecentTracesView(TextField key) {
ListView<String> recentTraces = new ListView<>();
recentTraces.setFocusTraversable(false);
recentTraces.setMaxHeight(200);
recentTraces.setBackground(Background.EMPTY);
recentTraces.setCellFactory(param -> {
ListCell<String> cell = new ListCell<>();

cell.textProperty().bind(cell.itemProperty());

cell.emptyProperty().addListener((obs, wasEmpty, isNowEmpty) -> {
if (isNowEmpty) {
cell.setOnMouseClicked(null);
} else {
cell.setOnMouseClicked(event -> key.setText(cell.getText()));
}
});

return cell;
});
ArrayList<String> sortable = new ArrayList<>(recentTrace);
Collections.reverse(sortable);
recentTraces.setItems(FXCollections.observableArrayList(sortable));
return recentTraces;
}

private static void updateRecentTrace(String text, int recentTraceMaxEntries) {
//resets element as the most recent entry if it already exists
recentTrace.remove(text);
recentTrace.add(text);
while (recentTrace.size() > recentTraceMaxEntries) {
recentTrace.removeFirst();
}
}

private static void fillButtonBar(HBox buttonBar, InstantPicker instantPicker, List<Duration> durations) {
Button todayButton = new Button("Today");
todayButton.setOnAction(event -> {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/at/esque/kafka/handlers/ConfigHandler.java
Expand Up @@ -144,6 +144,10 @@ private boolean setDefaultsIfMissing() {
settings.put(Settings.SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS, Settings.SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS_DEFAULT);
changed = true;
}
if (!settings.containsKey(Settings.RECENT_TRACE_MAX_ENTRIES)) {
settings.put(Settings.RECENT_TRACE_MAX_ENTRIES, Settings.RECENT_TRACE_MAX_ENTRIES_DEFAULT);
changed = true;
}
return changed;
}

Expand Down
8 changes: 7 additions & 1 deletion src/main/java/at/esque/kafka/handlers/Settings.java
Expand Up @@ -5,7 +5,11 @@
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

public class Settings {
Expand All @@ -24,6 +28,8 @@ private Settings() {
public static final String SYNTAX_HIGHLIGHT_THRESHOLD_ENABLED_DEFAULT = "true";
public static final String SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS = "syntax.highlight.threshold.characters";
public static final String SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS_DEFAULT = "50000";
public static final String RECENT_TRACE_MAX_ENTRIES = "recent.trace.max.entries";
public static final String RECENT_TRACE_MAX_ENTRIES_DEFAULT = "10";

public static List<Duration> readDurationSetting(Map<String, String> settings) {
return readDurationSetting(settings.get(TRACE_QUICK_SELECT_DURATION_LIST));
Expand Down
Expand Up @@ -22,7 +22,7 @@ public void setup() throws TimeoutException {
Button openDialogButton = new Button("Open Dialog");
openDialogButton.setId("openDialog");
openDialogButton.setOnAction(event -> {
TraceInputDialog.show(true, false, false, new ArrayList<>());
TraceInputDialog.show(true, false, false, new ArrayList<>(), 0);
});
StackPane root = new StackPane(openDialogButton);
root.setPrefSize(800, 500);
Expand Down

0 comments on commit a48a7b0

Please sign in to comment.