Skip to content

Commit 8f15865

Browse files
committed
api,server,schema,plugin,client: logs web server
This feature enables administrators to view management server logs directly in the UI through a dedicated API call. It leverages a Netty-based websocket server to stream logs in real time, offering an efficient way to monitor and debug server operations. Note that the plugin is disabled by default and must be enabled manually. Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent c361409 commit 8f15865

File tree

45 files changed

+2785
-31
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2785
-31
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ public class ApiConstants {
101101
public static final String CONVERT_INSTANCE_HOST_ID = "convertinstancehostid";
102102
public static final String CONVERT_INSTANCE_STORAGE_POOL_ID = "convertinstancepoolid";
103103
public static final String ENABLED_REVOCATION_CHECK = "enabledrevocationcheck";
104-
public static final String CLIENT_ADDRESS = "clientaddress";
105104
public static final String COMBINED_CAPACITY_ORDERING = "COMBINED";
105+
public static final String CONTEXT_ID = "contextid";
106106
public static final String CONTROLLER = "controller";
107107
public static final String CONTROLLER_UNIT = "controllerunit";
108108
public static final String CONSOLE_ENDPOINT_CREATOR_ADDRESS = "consoleendpointcreatoraddress";
@@ -127,6 +127,7 @@ public class ApiConstants {
127127
public static final String DEST_CIDR_LIST = "destcidrlist";
128128
public static final String CLEANUP = "cleanup";
129129
public static final String MAKEREDUNDANT = "makeredundant";
130+
public static final String CLIENT_ADDRESS = "clientaddress";
130131
public static final String CLUSTER_ID = "clusterid";
131132
public static final String CLUSTER_IDS = "clusterids";
132133
public static final String CLUSTER_NAME = "clustername";
@@ -140,12 +141,14 @@ public class ApiConstants {
140141
public static final String CNI_CONFIG_NAME = "cniconfigname";
141142
public static final String CSI_ENABLED = "csienabled";
142143
public static final String COMPONENT = "component";
144+
public static final String CONNECTED = "connected";
143145
public static final String CPU = "CPU";
144146
public static final String CPU_CORE_PER_SOCKET = "cpucorepersocket";
145147
public static final String CPU_NUMBER = "cpunumber";
146148
public static final String CPU_SPEED = "cpuspeed";
147149
public static final String CPU_LOAD_AVERAGE = "cpuloadaverage";
148150
public static final String CREATED = "created";
151+
public static final String CREATOR_ADDRESS = "creatoraddress";
149152
public static final String CROSS_ZONE_INSTANCE_CREATION = "crosszoneinstancecreation";
150153
public static final String CTX_ACCOUNT_ID = "ctxaccountid";
151154
public static final String CTX_DETAILS = "ctxDetails";
@@ -164,6 +167,7 @@ public class ApiConstants {
164167
public static final String ENCRYPT_ROOT = "encryptroot";
165168
public static final String ENCRYPTION_SUPPORTED = "encryptionsupported";
166169
public static final String ETCD_IPS = "etcdips";
170+
public static final String FILTERS = "filters";
167171
public static final String MIN_IOPS = "miniops";
168172
public static final String MAX_IOPS = "maxiops";
169173
public static final String HYPERVISOR_SNAPSHOT_RESERVE = "hypervisorsnapshotreserve";
@@ -1332,6 +1336,8 @@ public class ApiConstants {
13321336
public static final String WEBHOOK_ID = "webhookid";
13331337
public static final String WEBHOOK_NAME = "webhookname";
13341338

1339+
public static final String WEBSOCKET = "websocket";
1340+
13351341
public static final String NFS_MOUNT_OPTIONS = "nfsmountopts";
13361342
public static final String MOUNT_OPTIONS = "mountopts";
13371343

@@ -1348,6 +1354,8 @@ public class ApiConstants {
13481354
public static final String OBJECT_STORAGE_LIMIT = "objectstoragelimit";
13491355
public static final String OBJECT_STORAGE_TOTAL = "objectstoragetotal";
13501356

1357+
public static final String LOGS_WEB_SERVER_ENABLED = "logswebserverenabled";
1358+
13511359
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
13521360
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
13531361
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +

api/src/main/java/org/apache/cloudstack/api/BaseResponse.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public abstract class BaseResponse implements ResponseObject {
3232
@Param(description = "The current status of the latest async job acting on this object")
3333
private Integer jobStatus;
3434

35+
@SerializedName(ApiConstants.CONTEXT_ID)
36+
@Param(description = "the ID of the executing context")
37+
private String contextId;
38+
3539
public BaseResponse() {
3640
}
3741

@@ -83,4 +87,14 @@ public Integer getJobStatus() {
8387
public void setJobStatus(Integer jobStatus) {
8488
this.jobStatus = jobStatus;
8589
}
90+
91+
@Override
92+
public String getContextId() {
93+
return contextId;
94+
}
95+
96+
@Override
97+
public void setContextId(String contextId) {
98+
this.contextId = contextId;
99+
}
86100
}

api/src/main/java/org/apache/cloudstack/api/ResponseObject.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ public interface ResponseObject {
7676
*/
7777
void setJobStatus(Integer jobStatus);
7878

79+
String getContextId();
80+
void setContextId(String contextId);
81+
7982
public enum ResponseView {
8083
Full,
8184
Restricted

api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public void execute() {
9393
Map<String, Object> vpnCustomerGatewayParameters = (Map<String, Object>) capabilities.get(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS);
9494
response.setVpnCustomerGatewayParameters(vpnCustomerGatewayParameters);
9595
}
96+
response.setLogsWebServerEnabled((Boolean)capabilities.get(ApiConstants.LOGS_WEB_SERVER_ENABLED));
9697
response.setObjectName("capability");
9798
response.setResponseName(getCommandName());
9899
this.setResponseObject(response);

api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ public class CapabilitiesResponse extends BaseResponse {
163163
@Param(description = "Excluded and obsolete VPN customer gateway cryptographic parameters")
164164
private Map<String, Object> vpnCustomerGatewayParameters;
165165

166+
@SerializedName(ApiConstants.LOGS_WEB_SERVER_ENABLED)
167+
@Param(description = "true if Logs Web Server plugin is enabled, false otherwise", since = "4.21.0")
168+
private boolean logsWebServerEnabled;
169+
166170
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
167171
this.securityGroupsEnabled = securityGroupsEnabled;
168172
}
@@ -293,6 +297,11 @@ public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) {
293297

294298
public void setAdditionalConfigEnabled(Boolean additionalConfigEnabled) {
295299
this.additionalConfigEnabled = additionalConfigEnabled;
300+
301+
}
302+
303+
public void setLogsWebServerEnabled(boolean logsWebServerEnabled) {
304+
this.logsWebServerEnabled = logsWebServerEnabled;
296305
}
297306

298307
public void setVpnCustomerGatewayParameters(Map<String, Object> vpnCustomerGatewayParameters) {

client/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@
246246
<artifactId>cloud-plugin-user-two-factor-authenticator-staticpin</artifactId>
247247
<version>${project.version}</version>
248248
</dependency>
249+
<dependency>
250+
<groupId>org.apache.cloudstack</groupId>
251+
<artifactId>cloud-plugin-logs-web-server</artifactId>
252+
<version>${project.version}</version>
253+
</dependency>
249254
<dependency>
250255
<groupId>org.apache.cloudstack</groupId>
251256
<artifactId>cloud-plugin-metrics</artifactId>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.util;
19+
20+
import com.fasterxml.jackson.core.JsonProcessingException;
21+
import com.fasterxml.jackson.databind.ObjectMapper;
22+
import javax.persistence.AttributeConverter;
23+
import javax.persistence.Converter;
24+
import java.io.IOException;
25+
import java.util.List;
26+
27+
@Converter
28+
public class StringListJsonConverter implements AttributeConverter<List<String>, String> {
29+
30+
private static final ObjectMapper mapper = new ObjectMapper();
31+
32+
@Override
33+
public String convertToDatabaseColumn(List<String> attribute) {
34+
try {
35+
return attribute == null ? null : mapper.writeValueAsString(attribute);
36+
} catch (JsonProcessingException e) {
37+
throw new IllegalArgumentException("Error converting list to JSON", e);
38+
}
39+
}
40+
41+
@Override
42+
public List<String> convertToEntityAttribute(String dbData) {
43+
try {
44+
return dbData == null ? null : mapper.readValue(dbData, List.class);
45+
} catch (IOException e) {
46+
throw new IllegalArgumentException("Error converting JSON to list", e);
47+
}
48+
}
49+
}
50+

engine/schema/src/main/resources/META-INF/db/schema-42010to42100-cleanup.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@
1818
--;
1919
-- Schema upgrade cleanup from 4.20.1.0 to 4.21.0.0
2020
--;
21+
22+
DROP TABLE IF EXISTS `cloud`.`logs_web_session`;

engine/schema/src/main/resources/META-INF/db/schema-42010to42100.sql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ SET `sort_key` = CASE
208208
END;
209209
-- End: Changes for Guest OS category cleanup
210210

211+
<<<<<<< HEAD
211212
-- Update description for configuration: host.capacityType.to.order.clusters
212213
UPDATE `cloud`.`configuration` SET
213214
`description` = 'The host capacity type (CPU, RAM or COMBINED) is used by deployment planner to order clusters during VM resource allocation'
@@ -757,3 +758,19 @@ SET `cs`.`domain_id` = (
757758

758759
-- Re-apply VPC: update default network offering for vpc tier to conserve_mode=1 (#8309)
759760
UPDATE `cloud`.`network_offerings` SET conserve_mode = 1 WHERE name = 'DefaultIsolatedNetworkOfferingForVpcNetworks';
761+
762+
-- Create table for logs web session
763+
CREATE TABLE IF NOT EXISTS `cloud`.`logs_web_session` (
764+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
765+
`uuid` varchar(40) NOT NULL COMMENT 'UUID generated for the session',
766+
`filter` varchar(64) DEFAULT NULL COMMENT 'Filter keyword for the session',
767+
`created` datetime NOT NULL COMMENT 'When the session was created',
768+
`domain_id` bigint(20) unsigned NOT NULL COMMENT 'Domain of the account who generated the session',
769+
`account_id` bigint(20) unsigned NOT NULL COMMENT 'Account who generated the session',
770+
`creator_address` VARCHAR(45) DEFAULT NULL COMMENT 'Address of the creator of the session',
771+
`connections` int unsigned NOT NULL DEFAULT 0 COMMENT 'Number of connections for the session',
772+
`connected_time` datetime DEFAULT NULL COMMENT 'When the session was connected',
773+
`client_address` VARCHAR(45) DEFAULT NULL COMMENT 'Address of the client that connected to the session',
774+
`removed` datetime COMMENT 'When the session was removed/used',
775+
CONSTRAINT `uc_logs_web_session__uuid` UNIQUE (`uuid`)
776+
);

plugins/logs-web-server/pom.xml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
20+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
21+
<modelVersion>4.0.0</modelVersion>
22+
<artifactId>cloud-plugin-logs-web-server</artifactId>
23+
<name>Apache CloudStack Plugin - Logs Web Server</name>
24+
<parent>
25+
<groupId>org.apache.cloudstack</groupId>
26+
<artifactId>cloudstack-plugins</artifactId>
27+
<version>4.21.0.0-SNAPSHOT</version>
28+
<relativePath>../pom.xml</relativePath>
29+
</parent>
30+
<dependencies>
31+
<dependency>
32+
<groupId>org.apache.cloudstack</groupId>
33+
<artifactId>cloud-api</artifactId>
34+
<version>${project.version}</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>io.netty</groupId>
38+
<artifactId>netty-all</artifactId>
39+
</dependency>
40+
</dependencies>
41+
</project>

0 commit comments

Comments
 (0)