[ops]: get infra details (#32552)
Outputs on having the container up and running
On kubernetes:
```
root@ce32552-appsmith-66fc68d7f-97tjn:/opt/appsmith# cat /tmp/appsmith/infra.json
{"cloudProvider":"amazon","Tool":"kubernetes","EFS":"present","Hostname":"ce32552-appsmith-66fc68d7f-97tjn"}
```
On local setup:
```
root@26327db8d65a:/opt/appsmith# cat /tmp/appsmith/infra.json
{"cloudProvider":"local","Tool":"docker","EFS":"absent","Hostname":"26327db8d65a"}
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced infrastructure detection to enhance system insights,
including cloud provider, deployment tools, and host details.
- Enhanced analytics by incorporating deployment properties into event
tracking.
- **Refactor**
- Modified server configuration and initialization to integrate new
deployment properties.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Trisha Anand <trisha@appsmith.com>
This commit is contained in:
parent
fe1839a132
commit
947add2f20
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.appsmith.server.configurations;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Getter
|
||||||
|
public class DeploymentProperties extends DeploymentPropertiesCE {
|
||||||
|
public DeploymentProperties(ObjectMapper objectMapper) {
|
||||||
|
super(objectMapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.appsmith.server.configurations;
|
||||||
|
|
||||||
|
import com.appsmith.server.dtos.DeploymentInfo;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Slf4j
|
||||||
|
public class DeploymentPropertiesCE {
|
||||||
|
|
||||||
|
private final String INFO_JSON_PATH = "/tmp/appsmith/infra.json";
|
||||||
|
private String cloudProvider;
|
||||||
|
private String tool;
|
||||||
|
private String efs;
|
||||||
|
private String hostname;
|
||||||
|
private String deployedAt;
|
||||||
|
|
||||||
|
public String getEdition() {
|
||||||
|
return "CE";
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeploymentPropertiesCE(ObjectMapper objectMapper) {
|
||||||
|
try {
|
||||||
|
Path infoJsonPath = Paths.get(INFO_JSON_PATH);
|
||||||
|
if (Files.exists(infoJsonPath)) {
|
||||||
|
String jsonContent = Files.readString(infoJsonPath);
|
||||||
|
// Parse JSON content using the AppsmithInfo class
|
||||||
|
DeploymentInfo deploymentInfo = objectMapper.readValue(jsonContent, DeploymentInfo.class);
|
||||||
|
cloudProvider = deploymentInfo.getCloudProvider();
|
||||||
|
tool = deploymentInfo.getTool();
|
||||||
|
efs = deploymentInfo.getEfs();
|
||||||
|
hostname = deploymentInfo.getHostname();
|
||||||
|
deployedAt = deploymentInfo.getCurrentTime();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.debug("Error reading deployment properties from {} {}", INFO_JSON_PATH, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.appsmith.server.dtos;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class DeploymentInfo {
|
||||||
|
private String cloudProvider;
|
||||||
|
private String tool;
|
||||||
|
private String efs;
|
||||||
|
private String hostname;
|
||||||
|
private String currentTime;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.server.configurations.CommonConfig;
|
import com.appsmith.server.configurations.CommonConfig;
|
||||||
|
import com.appsmith.server.configurations.DeploymentProperties;
|
||||||
import com.appsmith.server.configurations.ProjectProperties;
|
import com.appsmith.server.configurations.ProjectProperties;
|
||||||
import com.appsmith.server.helpers.UserUtils;
|
import com.appsmith.server.helpers.UserUtils;
|
||||||
import com.appsmith.server.repositories.UserDataRepository;
|
import com.appsmith.server.repositories.UserDataRepository;
|
||||||
|
|
@ -22,7 +23,8 @@ public class AnalyticsServiceImpl extends AnalyticsServiceCEImpl implements Anal
|
||||||
ConfigService configService,
|
ConfigService configService,
|
||||||
UserUtils userUtils,
|
UserUtils userUtils,
|
||||||
ProjectProperties projectProperties,
|
ProjectProperties projectProperties,
|
||||||
UserDataRepository userDataRepository) {
|
UserDataRepository userDataRepository,
|
||||||
|
DeploymentProperties deploymentProperties) {
|
||||||
super(
|
super(
|
||||||
analytics,
|
analytics,
|
||||||
sessionUserService,
|
sessionUserService,
|
||||||
|
|
@ -30,6 +32,7 @@ public class AnalyticsServiceImpl extends AnalyticsServiceCEImpl implements Anal
|
||||||
configService,
|
configService,
|
||||||
userUtils,
|
userUtils,
|
||||||
projectProperties,
|
projectProperties,
|
||||||
|
deploymentProperties,
|
||||||
userDataRepository);
|
userDataRepository);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.appsmith.external.helpers.Identifiable;
|
||||||
import com.appsmith.external.models.ActionDTO;
|
import com.appsmith.external.models.ActionDTO;
|
||||||
import com.appsmith.external.models.BaseDomain;
|
import com.appsmith.external.models.BaseDomain;
|
||||||
import com.appsmith.server.configurations.CommonConfig;
|
import com.appsmith.server.configurations.CommonConfig;
|
||||||
|
import com.appsmith.server.configurations.DeploymentProperties;
|
||||||
import com.appsmith.server.configurations.ProjectProperties;
|
import com.appsmith.server.configurations.ProjectProperties;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.NewPage;
|
import com.appsmith.server.domains.NewPage;
|
||||||
|
|
@ -50,6 +51,7 @@ public class AnalyticsServiceCEImpl implements AnalyticsServiceCE {
|
||||||
private final UserUtils userUtils;
|
private final UserUtils userUtils;
|
||||||
|
|
||||||
private final ProjectProperties projectProperties;
|
private final ProjectProperties projectProperties;
|
||||||
|
private final DeploymentProperties deploymentProperties;
|
||||||
|
|
||||||
private final UserDataRepository userDataRepository;
|
private final UserDataRepository userDataRepository;
|
||||||
|
|
||||||
|
|
@ -61,6 +63,7 @@ public class AnalyticsServiceCEImpl implements AnalyticsServiceCE {
|
||||||
ConfigService configService,
|
ConfigService configService,
|
||||||
UserUtils userUtils,
|
UserUtils userUtils,
|
||||||
ProjectProperties projectProperties,
|
ProjectProperties projectProperties,
|
||||||
|
DeploymentProperties deploymentProperties,
|
||||||
UserDataRepository userDataRepository) {
|
UserDataRepository userDataRepository) {
|
||||||
this.analytics = analytics;
|
this.analytics = analytics;
|
||||||
this.sessionUserService = sessionUserService;
|
this.sessionUserService = sessionUserService;
|
||||||
|
|
@ -68,6 +71,7 @@ public class AnalyticsServiceCEImpl implements AnalyticsServiceCE {
|
||||||
this.configService = configService;
|
this.configService = configService;
|
||||||
this.userUtils = userUtils;
|
this.userUtils = userUtils;
|
||||||
this.projectProperties = projectProperties;
|
this.projectProperties = projectProperties;
|
||||||
|
this.deploymentProperties = deploymentProperties;
|
||||||
this.userDataRepository = userDataRepository;
|
this.userDataRepository = userDataRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,6 +259,13 @@ public class AnalyticsServiceCEImpl implements AnalyticsServiceCE {
|
||||||
analyticsProperties.put("originService", "appsmith-server");
|
analyticsProperties.put("originService", "appsmith-server");
|
||||||
analyticsProperties.put("instanceId", instanceId);
|
analyticsProperties.put("instanceId", instanceId);
|
||||||
analyticsProperties.put("version", projectProperties.getVersion());
|
analyticsProperties.put("version", projectProperties.getVersion());
|
||||||
|
analyticsProperties.put("edition", deploymentProperties.getEdition());
|
||||||
|
analyticsProperties.put("cloudProvider", deploymentProperties.getCloudProvider());
|
||||||
|
analyticsProperties.put("efs", deploymentProperties.getEfs());
|
||||||
|
analyticsProperties.put("tool", deploymentProperties.getTool());
|
||||||
|
analyticsProperties.put("hostname", deploymentProperties.getHostname());
|
||||||
|
analyticsProperties.put("deployedAt", deploymentProperties.getDeployedAt());
|
||||||
|
|
||||||
messageBuilder = messageBuilder.properties(analyticsProperties);
|
messageBuilder = messageBuilder.properties(analyticsProperties);
|
||||||
analytics.enqueue(messageBuilder);
|
analytics.enqueue(messageBuilder);
|
||||||
return instanceId;
|
return instanceId;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.appsmith.server.solutions;
|
package com.appsmith.server.solutions;
|
||||||
|
|
||||||
import com.appsmith.server.configurations.CommonConfig;
|
import com.appsmith.server.configurations.CommonConfig;
|
||||||
|
import com.appsmith.server.configurations.DeploymentProperties;
|
||||||
import com.appsmith.server.configurations.ProjectProperties;
|
import com.appsmith.server.configurations.ProjectProperties;
|
||||||
import com.appsmith.server.configurations.SegmentConfig;
|
import com.appsmith.server.configurations.SegmentConfig;
|
||||||
import com.appsmith.server.helpers.NetworkUtils;
|
import com.appsmith.server.helpers.NetworkUtils;
|
||||||
|
|
@ -38,9 +39,9 @@ public class PingScheduledTaskImpl extends PingScheduledTaskCEImpl implements Pi
|
||||||
DatasourceRepository datasourceRepository,
|
DatasourceRepository datasourceRepository,
|
||||||
UserRepository userRepository,
|
UserRepository userRepository,
|
||||||
ProjectProperties projectProperties,
|
ProjectProperties projectProperties,
|
||||||
|
DeploymentProperties deploymentProperties,
|
||||||
NetworkUtils networkUtils,
|
NetworkUtils networkUtils,
|
||||||
PermissionGroupService permissionGroupService) {
|
PermissionGroupService permissionGroupService) {
|
||||||
|
|
||||||
super(
|
super(
|
||||||
configService,
|
configService,
|
||||||
segmentConfig,
|
segmentConfig,
|
||||||
|
|
@ -52,6 +53,7 @@ public class PingScheduledTaskImpl extends PingScheduledTaskCEImpl implements Pi
|
||||||
datasourceRepository,
|
datasourceRepository,
|
||||||
userRepository,
|
userRepository,
|
||||||
projectProperties,
|
projectProperties,
|
||||||
|
deploymentProperties,
|
||||||
networkUtils,
|
networkUtils,
|
||||||
permissionGroupService);
|
permissionGroupService);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.appsmith.server.solutions.ce;
|
||||||
|
|
||||||
import com.appsmith.server.acl.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
import com.appsmith.server.configurations.CommonConfig;
|
import com.appsmith.server.configurations.CommonConfig;
|
||||||
|
import com.appsmith.server.configurations.DeploymentProperties;
|
||||||
import com.appsmith.server.configurations.ProjectProperties;
|
import com.appsmith.server.configurations.ProjectProperties;
|
||||||
import com.appsmith.server.configurations.SegmentConfig;
|
import com.appsmith.server.configurations.SegmentConfig;
|
||||||
import com.appsmith.server.helpers.NetworkUtils;
|
import com.appsmith.server.helpers.NetworkUtils;
|
||||||
|
|
@ -28,9 +29,11 @@ import reactor.util.function.Tuple6;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.util.Map.entry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents a scheduled task that pings a data point indicating that this server installation is live.
|
* This class represents a scheduled task that pings a data point indicating that this server installation is live.
|
||||||
* This ping is only invoked if the Appsmith server is NOT running in Appsmith Clouud & the user has given Appsmith
|
* This ping is only invoked if the Appsmith server is NOT running in Appsmith Cloud & the user has given Appsmith
|
||||||
* permissions to collect anonymized data
|
* permissions to collect anonymized data
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|
@ -49,6 +52,7 @@ public class PingScheduledTaskCEImpl implements PingScheduledTaskCE {
|
||||||
private final DatasourceRepository datasourceRepository;
|
private final DatasourceRepository datasourceRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final ProjectProperties projectProperties;
|
private final ProjectProperties projectProperties;
|
||||||
|
private final DeploymentProperties deploymentProperties;
|
||||||
private final NetworkUtils networkUtils;
|
private final NetworkUtils networkUtils;
|
||||||
private final PermissionGroupService permissionGroupService;
|
private final PermissionGroupService permissionGroupService;
|
||||||
|
|
||||||
|
|
@ -144,6 +148,23 @@ public class PingScheduledTaskCEImpl implements PingScheduledTaskCE {
|
||||||
applicationRepository.getAllApplicationsCountAccessibleToARoleWithPermission(
|
applicationRepository.getAllApplicationsCountAccessibleToARoleWithPermission(
|
||||||
AclPermission.READ_APPLICATIONS, publicPermissionGroupId)))
|
AclPermission.READ_APPLICATIONS, publicPermissionGroupId)))
|
||||||
.flatMap(statsData -> {
|
.flatMap(statsData -> {
|
||||||
|
Map<String, String> propertiesMap = Map.ofEntries(
|
||||||
|
entry("instanceId", statsData.getT1()),
|
||||||
|
entry("numOrgs", statsData.getT3().getT1().toString()),
|
||||||
|
entry("numApps", statsData.getT3().getT2().toString()),
|
||||||
|
entry("numPages", statsData.getT3().getT3().toString()),
|
||||||
|
entry("numActions", statsData.getT3().getT4().toString()),
|
||||||
|
entry("numDatasources", statsData.getT3().getT5().toString()),
|
||||||
|
entry("numUsers", statsData.getT3().getT6().toString()),
|
||||||
|
entry("numPublicApps", statsData.getT4().toString()),
|
||||||
|
entry("version", projectProperties.getVersion()),
|
||||||
|
entry("edition", deploymentProperties.getEdition()),
|
||||||
|
entry("cloudProvider", deploymentProperties.getCloudProvider()),
|
||||||
|
entry("efs", deploymentProperties.getEfs()),
|
||||||
|
entry("tool", deploymentProperties.getTool()),
|
||||||
|
entry("hostname", deploymentProperties.getHostname()),
|
||||||
|
entry("deployedAt", deploymentProperties.getDeployedAt()));
|
||||||
|
|
||||||
final String ipAddress = statsData.getT2();
|
final String ipAddress = statsData.getT2();
|
||||||
return WebClientUtils.create("https://api.segment.io")
|
return WebClientUtils.create("https://api.segment.io")
|
||||||
.post()
|
.post()
|
||||||
|
|
@ -151,25 +172,14 @@ public class PingScheduledTaskCEImpl implements PingScheduledTaskCE {
|
||||||
.headers(headers -> headers.setBasicAuth(ceKey, ""))
|
.headers(headers -> headers.setBasicAuth(ceKey, ""))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.body(BodyInserters.fromValue(Map.of(
|
.body(BodyInserters.fromValue(Map.of(
|
||||||
"userId", statsData.getT1(),
|
"userId",
|
||||||
"context", Map.of("ip", ipAddress),
|
statsData.getT1(),
|
||||||
|
"context",
|
||||||
|
Map.of("ip", ipAddress),
|
||||||
"properties",
|
"properties",
|
||||||
Map.of(
|
propertiesMap,
|
||||||
"instanceId", statsData.getT1(),
|
"event",
|
||||||
"numOrgs", statsData.getT3().getT1(),
|
"instance_stats")))
|
||||||
"numApps", statsData.getT3().getT2(),
|
|
||||||
"numPages",
|
|
||||||
statsData.getT3().getT3(),
|
|
||||||
"numActions",
|
|
||||||
statsData.getT3().getT4(),
|
|
||||||
"numDatasources",
|
|
||||||
statsData.getT3().getT5(),
|
|
||||||
"numUsers",
|
|
||||||
statsData.getT3().getT6(),
|
|
||||||
"numPublicApps", statsData.getT4(),
|
|
||||||
"version", projectProperties.getVersion(),
|
|
||||||
"edition", ProjectProperties.EDITION),
|
|
||||||
"event", "instance_stats")))
|
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(String.class);
|
.bodyToMono(String.class);
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -462,6 +462,10 @@ print_appsmith_info(){
|
||||||
tr '\n' ' ' < /opt/appsmith/info.json
|
tr '\n' ' ' < /opt/appsmith/info.json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function capture_infra_details(){
|
||||||
|
bash /opt/appsmith/generate-infra-details.sh || true
|
||||||
|
}
|
||||||
|
|
||||||
# Main Section
|
# Main Section
|
||||||
print_appsmith_info
|
print_appsmith_info
|
||||||
init_loading_pages
|
init_loading_pages
|
||||||
|
|
@ -499,6 +503,7 @@ export APPSMITH_LOG_DIR="${APPSMITH_LOG_DIR:-/appsmith-stacks/logs}"
|
||||||
mkdir -p "$APPSMITH_LOG_DIR"/{supervisor,backend,cron,editor,rts,mongodb,redis,postgres,appsmithctl}
|
mkdir -p "$APPSMITH_LOG_DIR"/{supervisor,backend,cron,editor,rts,mongodb,redis,postgres,appsmithctl}
|
||||||
|
|
||||||
setup_auto_heal
|
setup_auto_heal
|
||||||
|
capture_infra_details
|
||||||
|
|
||||||
# Handle CMD command
|
# Handle CMD command
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
|
||||||
61
deploy/docker/fs/opt/appsmith/generate-infra-details.sh
Executable file
61
deploy/docker/fs/opt/appsmith/generate-infra-details.sh
Executable file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
infra_file="$TMP/infra.json"
|
||||||
|
mount_path="/appsmith-stacks"
|
||||||
|
|
||||||
|
## Get cloudProvider details
|
||||||
|
function get_cloud_provider() {
|
||||||
|
release_details=$(uname -r)
|
||||||
|
if [[ $release_details == *"amzn"* ]];then
|
||||||
|
cloud_provider="amazon";
|
||||||
|
elif [[ $release_details == *"azure"* ]];then
|
||||||
|
cloud_provider="azure";
|
||||||
|
elif [[ $release_details == *"cloud"* ]];then
|
||||||
|
cloud_provider="gcp";
|
||||||
|
else
|
||||||
|
cloud_provider="local";
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## Get deployment tool details
|
||||||
|
function get_tool() {
|
||||||
|
if [[ -z "${KUBERNETES_SERVICE_HOST}" ]]; then
|
||||||
|
dep_tool="docker";
|
||||||
|
else
|
||||||
|
dep_tool="kubernetes";
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## Check if EFS is mounted
|
||||||
|
function check_for_efs() {
|
||||||
|
findmnt --mountpoint $mount_path | grep nfs && {
|
||||||
|
efs="present"
|
||||||
|
} || {
|
||||||
|
efs="absent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## Check hostname
|
||||||
|
function get_hostname() {
|
||||||
|
hostname="$(cat /etc/hostname)"
|
||||||
|
}
|
||||||
|
|
||||||
|
## Get current Time
|
||||||
|
function get_current_time(){
|
||||||
|
currentTime="$(date -u -Iseconds)"
|
||||||
|
}
|
||||||
|
|
||||||
|
## Main Block
|
||||||
|
get_cloud_provider
|
||||||
|
get_tool
|
||||||
|
get_hostname
|
||||||
|
check_for_efs
|
||||||
|
get_current_time
|
||||||
|
|
||||||
|
|
||||||
|
infra_json='{"cloudProvider":"'"$cloud_provider"'","tool":"'"$dep_tool"'","efs":"'"$efs"'","hostname":"'"$hostname"'", "currentTime": "'"$currentTime"'"}'
|
||||||
|
echo "$infra_json"
|
||||||
|
|
||||||
|
echo $infra_json > $infra_file
|
||||||
Loading…
Reference in New Issue
Block a user