Skip to content

Commit

Permalink
Add HTTP Access Log to Dev UI
Browse files Browse the repository at this point in the history
Signed-off-by: Phillip Kruger <phillip.kruger@gmail.com>
  • Loading branch information
phillip-kruger committed Sep 23, 2024
1 parent ffd0c78 commit cf4cd34
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import io.quarkus.devui.spi.page.Page;
import io.quarkus.devui.spi.page.PageBuilder;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
import io.vertx.core.json.jackson.DatabindCodec;

Expand Down Expand Up @@ -209,21 +210,30 @@ DeploymentMethodBuildItem mapDeploymentMethods(

List<String> methodNames = new ArrayList<>();
List<String> subscriptionNames = new ArrayList<>();
Map<String, RuntimeValue> recordedValues = new HashMap<>();
for (BuildTimeActionBuildItem actions : buildTimeActions) {
String extensionPathName = actions.getExtensionPathName(curateOutcomeBuildItem);
for (BuildTimeAction bta : actions.getActions()) {
String fullName = extensionPathName + "." + bta.getMethodName();
DevConsoleManager.register(fullName, bta.getAction());
if (bta.hasRuntimeValue()) {
recordedValues.put(fullName, bta.getRuntimeValue());
} else {
DevConsoleManager.register(fullName, bta.getAction());
}
methodNames.add(fullName);
}
for (BuildTimeAction bts : actions.getSubscriptions()) {
String fullName = extensionPathName + "." + bts.getMethodName();
DevConsoleManager.register(fullName, bts.getAction());
if (bts.hasRuntimeValue()) {
recordedValues.put(fullName, bts.getRuntimeValue());
} else {
DevConsoleManager.register(fullName, bts.getAction());
}
subscriptionNames.add(fullName);
}
}

return new DeploymentMethodBuildItem(methodNames, subscriptionNames);
return new DeploymentMethodBuildItem(methodNames, subscriptionNames, recordedValues);
}

private Map<String, Object> getBuildTimeDataForPage(AbstractPageBuildItem pageBuildItem) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package io.quarkus.devui.deployment;

import java.util.List;
import java.util.Map;

import io.quarkus.builder.item.SimpleBuildItem;
import io.quarkus.runtime.RuntimeValue;

/**
* Hold add discovered build time methods that can be executed via json-rpc
Expand All @@ -11,10 +13,13 @@ public final class DeploymentMethodBuildItem extends SimpleBuildItem {

private final List<String> methods;
private final List<String> subscriptions;
private final Map<String, RuntimeValue> recordedValues;

public DeploymentMethodBuildItem(List<String> methods, List<String> subscriptions) {
public DeploymentMethodBuildItem(List<String> methods, List<String> subscriptions,
Map<String, RuntimeValue> recordedValues) {
this.methods = methods;
this.subscriptions = subscriptions;
this.recordedValues = recordedValues;
}

public List<String> getMethods() {
Expand All @@ -32,4 +37,12 @@ public List<String> getSubscriptions() {
public boolean hasSubscriptions() {
return this.subscriptions != null && !this.subscriptions.isEmpty();
}

public Map<String, RuntimeValue> getRecordedValues() {
return this.recordedValues;
}

public boolean hasRecordedValues() {
return this.recordedValues != null && !this.recordedValues.isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ void findAllJsonRPCMethods(BuildProducer<JsonRPCRuntimeMethodsBuildItem> jsonRPC
}

@BuildStep(onlyIf = IsDevelopment.class)
@Record(ExecutionTime.STATIC_INIT)
@Record(ExecutionTime.RUNTIME_INIT)
void createJsonRpcRouter(DevUIRecorder recorder,
BeanContainerBuildItem beanContainer,
JsonRPCRuntimeMethodsBuildItem jsonRPCMethodsBuildItem,
Expand All @@ -417,7 +417,7 @@ void createJsonRpcRouter(DevUIRecorder recorder,
DevConsoleManager.setGlobal(DevUIRecorder.DEV_MANAGER_GLOBALS_JSON_MAPPER_FACTORY,
JsonMapper.Factory.deploymentLinker().createLinkData(new DevUIDatabindCodec.Factory()));
recorder.createJsonRpcRouter(beanContainer.getValue(), extensionMethodsMap, deploymentMethodBuildItem.getMethods(),
deploymentMethodBuildItem.getSubscriptions());
deploymentMethodBuildItem.getSubscriptions(), deploymentMethodBuildItem.getRecordedValues());
}
}

Expand All @@ -437,13 +437,17 @@ void processFooterLogs(BuildProducer<BuildTimeActionBuildItem> buildTimeActionPr
String name = footerLogBuildItem.getName().replaceAll(" ", "");

BuildTimeActionBuildItem devServiceLogActions = new BuildTimeActionBuildItem(FOOTER_LOG_NAMESPACE);
devServiceLogActions.addSubscription(name + "Log", ignored -> {
try {
return footerLogBuildItem.getPublisher();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
if (footerLogBuildItem.hasRuntimePublisher()) {
devServiceLogActions.addSubscription(name + "Log", footerLogBuildItem.getRuntimePublisher());
} else {
devServiceLogActions.addSubscription(name + "Log", ignored -> {
try {
return footerLogBuildItem.getPublisher();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
devServiceLogs.add(devServiceLogActions);

// Create the Footer in the Dev UI
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.vertx.http.deployment;

import java.util.concurrent.SubmissionPublisher;

import io.quarkus.builder.item.SimpleBuildItem;
import io.quarkus.runtime.RuntimeValue;

/**
* Used to create the publisher for the vertx access log in dev ui
*/
public final class VertxDevUILogBuildItem extends SimpleBuildItem {

private final RuntimeValue<SubmissionPublisher<String>> publisher;

public VertxDevUILogBuildItem(RuntimeValue<SubmissionPublisher<String>> publisher) {
this.publisher = publisher;
}

public RuntimeValue<SubmissionPublisher<String>> getPublisher() {
return this.publisher;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.SubmissionPublisher;
import java.util.logging.Level;
import java.util.stream.Collectors;

Expand All @@ -28,6 +29,7 @@
import io.quarkus.builder.BuildException;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
Expand All @@ -50,6 +52,7 @@
import io.quarkus.deployment.pkg.steps.GraalVM;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.deployment.pkg.steps.NoopNativeImageBuildRunner;
import io.quarkus.devui.spi.buildtime.FooterLogBuildItem;
import io.quarkus.kubernetes.spi.KubernetesPortBuildItem;
import io.quarkus.netty.runtime.virtual.VirtualServerChannel;
import io.quarkus.runtime.ErrorPageAction;
Expand Down Expand Up @@ -327,6 +330,17 @@ BodyHandlerBuildItem bodyHandler(VertxHttpRecorder recorder) {
return new BodyHandlerBuildItem(recorder.createBodyHandler());
}

@BuildStep(onlyIf = IsDevelopment.class)
@Record(ExecutionTime.RUNTIME_INIT)
void createDevUILog(BuildProducer<FooterLogBuildItem> footerLogProducer,
VertxHttpRecorder recorder,
BuildProducer<VertxDevUILogBuildItem> vertxDevUILogBuildItem) {

RuntimeValue<SubmissionPublisher<String>> publisher = recorder.createAccessLogPublisher();
footerLogProducer.produce(new FooterLogBuildItem("HTTP", publisher));
vertxDevUILogBuildItem.produce(new VertxDevUILogBuildItem(publisher));
}

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
ServiceStartBuildItem finalizeRouter(Optional<LoggingDecorateBuildItem> decorateBuildItem,
Expand All @@ -348,7 +362,8 @@ ServiceStartBuildItem finalizeRouter(Optional<LoggingDecorateBuildItem> decorate
LiveReloadConfig lrc,
CoreVertxBuildItem core, // Injected to be sure that Vert.x has been produced before calling this method.
ExecutorBuildItem executorBuildItem,
TlsRegistryBuildItem tlsRegistryBuildItem) // Injected to be sure that the TLS registry has been produced before calling this method.
TlsRegistryBuildItem tlsRegistryBuildItem, // Injected to be sure that the TLS registry has been produced before calling this method.
Optional<VertxDevUILogBuildItem> vertxDevUILogBuildItem)
throws BuildException {

Optional<DefaultRouteBuildItem> defaultRoute;
Expand Down Expand Up @@ -409,6 +424,12 @@ ServiceStartBuildItem finalizeRouter(Optional<LoggingDecorateBuildItem> decorate
knowClasses = decorateBuildItem.get().getKnowClasses();
}

Optional<RuntimeValue<SubmissionPublisher<String>>> publisher = Optional.empty();

if (vertxDevUILogBuildItem.isPresent()) {
publisher = Optional.of(vertxDevUILogBuildItem.get().getPublisher());
}

recorder.finalizeRouter(beanContainer.getValue(),
defaultRoute.map(DefaultRouteBuildItem::getRoute).orElse(null),
listOfFilters, listOfManagementInterfaceFilters,
Expand All @@ -423,7 +444,8 @@ ServiceStartBuildItem finalizeRouter(Optional<LoggingDecorateBuildItem> decorate
logBuildTimeConfig,
srcMainJava,
knowClasses,
combinedActions);
combinedActions,
publisher);

return new ServiceStartBuildItem("vertx-http");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,17 @@ export class JsonRpc {
var jsonrpcpayload = JSON.stringify(message);

if (jsonRPCSubscriptions.includes(method)) {
if(JsonRpc.observerQueue.has(uid)){
JsonRpc.observerQueue.get(uid).observer.cancel();
}
// Observer
var observer = new Observer(uid);
JsonRpc.observerQueue.set(uid, {
observer: observer,
log: this._logTraffic
});
JsonRpc.sendJsonRPCMessage(jsonrpcpayload, this._logTraffic);
return observer;
return observer;
} else if(jsonRPCMethods.includes(method)){
// Promise
var _resolve, _reject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
export class LogController {
static _controllers = new Map();
static listener;

host;
tab;
items = [];

constructor(host) {
(this.host = host).addController(this);
this.tab = host.tagName.toLowerCase();
this.tab = host.title;
}

hostConnected() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class QwcFooterLog extends QwcAbstractLogElement {

constructor() {
super();

this.logControl
.addToggle("On/off switch", true, (e) => {
this._toggleOnOffClicked(e);
Expand Down Expand Up @@ -130,6 +130,7 @@ export class QwcFooterLog extends QwcAbstractLogElement {
hotReload(){
this._clearLog();
if(this._observer != null){
this._toggleOnOff(false);
this._toggleOnOff(true);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,9 @@ export class QwcFooter extends observeState(LitElement) {
this._selectedTab = index;
var selectedComponentName = devuiState.footer[this._selectedTab];
if(selectedComponentName){
this._controlButtons = LogController.getItemsForTab(devuiState.footer[this._selectedTab].componentName);
this._controlButtons = LogController.getItemsForTab(devuiState.footer[this._selectedTab].title);
}else{
this._controlButtons = LogController.getItemsForTab(devuiState.footer[0].componentName);
this._controlButtons = LogController.getItemsForTab(devuiState.footer[0].title);
this._selectedTab = 0;
}
this.storageControl.set('selected-tab', this._selectedTab);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Map;
import java.util.function.Function;

import io.quarkus.runtime.RuntimeValue;

/**
* Define a action that can be executed against the deployment classpath in runtime
* This means a call will still be make with Json-RPC to the backend, but fall through to this action
Expand All @@ -11,13 +13,22 @@ public class BuildTimeAction {

private final String methodName;
private final Function<Map<String, String>, ?> action;
private final RuntimeValue runtimeValue;

protected <T> BuildTimeAction(String methodName,
Function<Map<String, String>, T> action) {

this.methodName = methodName;
this.action = action;
this.runtimeValue = null;
}

protected <T> BuildTimeAction(String methodName,
RuntimeValue runtimeValue) {

this.methodName = methodName;
this.action = null;
this.runtimeValue = runtimeValue;
}

public String getMethodName() {
Expand All @@ -27,4 +38,12 @@ public String getMethodName() {
public Function<Map<String, String>, ?> getAction() {
return action;
}

public RuntimeValue getRuntimeValue() {
return runtimeValue;
}

public boolean hasRuntimeValue() {
return this.runtimeValue != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.function.Function;

import io.quarkus.devui.spi.AbstractDevUIBuildItem;
import io.quarkus.runtime.RuntimeValue;

/**
* Holds any Build time actions for Dev UI the extension has
Expand All @@ -32,6 +33,11 @@ public <T> void addAction(String methodName,
this.addAction(new BuildTimeAction(methodName, action));
}

public <T> void addAction(String methodName,
RuntimeValue runtimeValue) {
this.addAction(new BuildTimeAction(methodName, runtimeValue));
}

public List<BuildTimeAction> getActions() {
return actions;
}
Expand All @@ -45,6 +51,11 @@ public <T> void addSubscription(String methodName,
this.addSubscription(new BuildTimeAction(methodName, action));
}

public <T> void addSubscription(String methodName,
RuntimeValue runtimeValue) {
this.addSubscription(new BuildTimeAction(methodName, runtimeValue));
}

public List<BuildTimeAction> getSubscriptions() {
return subscriptions;
}
Expand Down
Loading

0 comments on commit cf4cd34

Please sign in to comment.