Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HTTP Access Log to Dev UI #43441

Merged
merged 1 commit into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading