Added logs and analytics (#3622)
* Added logs and analytics * Fix in error string Co-authored-by: Shri <shrikant@appsmith.com> * Review fixes :) Co-authored-by: Shri <shrikant@appsmith.com> Co-authored-by: Shri <shrikant@appsmith.com>
This commit is contained in:
parent
bb1d0059d3
commit
93d5a061e2
|
|
@ -8,6 +8,7 @@ public enum AnalyticsEvents {
|
|||
DELETE,
|
||||
FIRST_LOGIN,
|
||||
EXECUTE_ACTION("execute_ACTION_TRIGGERED"),
|
||||
UPDATE_LAYOUT,
|
||||
;
|
||||
|
||||
private final String eventName;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ public enum AppsmithError {
|
|||
" \"widgetName\" : \"{1}\"," +
|
||||
" \"widgetId\" : \"{2}\"," +
|
||||
" \"pageId\" : \"{4}\"," +
|
||||
" \"layoutId\" : \"{5}\"",
|
||||
" \"layoutId\" : \"{5}\"," +
|
||||
" \"dynamicBinding\" : \"{6}\"",
|
||||
AppsmithErrorAction.LOG_EXTERNALLY),
|
||||
USER_ALREADY_EXISTS_IN_ORGANIZATION(400, 4021, "The user {0} has already been added to the organization with role {1}. To change the role, please navigate to `Manage Users` page.", AppsmithErrorAction.DEFAULT),
|
||||
UNAUTHORIZED_DOMAIN(401, 4019, "Invalid email domain {0} used for sign in/sign up. Please contact the administrator to configure this domain if this is unexpected.", AppsmithErrorAction.DEFAULT),
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@ package com.appsmith.server.services;
|
|||
|
||||
import com.appsmith.external.helpers.MustacheHelper;
|
||||
import com.appsmith.external.models.ActionConfiguration;
|
||||
import com.appsmith.server.constants.AnalyticsEvents;
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.domains.ActionDependencyEdge;
|
||||
import com.appsmith.server.domains.Layout;
|
||||
import com.appsmith.server.domains.NewPage;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.dtos.ActionDTO;
|
||||
import com.appsmith.server.dtos.ActionMoveDTO;
|
||||
import com.appsmith.server.dtos.DslActionDTO;
|
||||
|
|
@ -31,6 +34,7 @@ import reactor.core.publisher.Mono;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
|
@ -53,6 +57,8 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
private final NewPageService newPageService;
|
||||
private final NewActionService newActionService;
|
||||
private final PageLoadActionsUtil pageLoadActionsUtil;
|
||||
private final SessionUserService sessionUserService;
|
||||
|
||||
|
||||
/*
|
||||
* To replace fetchUsers in `{{JSON.stringify(fetchUsers)}}` with getUsers, the following regex is required :
|
||||
|
|
@ -65,12 +71,15 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
public LayoutActionServiceImpl(ObjectMapper objectMapper,
|
||||
AnalyticsService analyticsService,
|
||||
NewPageService newPageService,
|
||||
NewActionService newActionService, PageLoadActionsUtil pageLoadActionsUtil) {
|
||||
NewActionService newActionService,
|
||||
PageLoadActionsUtil pageLoadActionsUtil,
|
||||
SessionUserService sessionUserService) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.analyticsService = analyticsService;
|
||||
this.newPageService = newPageService;
|
||||
this.newActionService = newActionService;
|
||||
this.pageLoadActionsUtil = pageLoadActionsUtil;
|
||||
this.sessionUserService = sessionUserService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -310,7 +319,7 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
// For nested fields, the parent dsl to search in would shift by one level every iteration
|
||||
Object parent = dsl;
|
||||
Iterator<String> fieldsIterator = Arrays.stream(fields).filter(fieldToken -> !fieldToken.isBlank()).iterator();
|
||||
Boolean isLeafNode = false;
|
||||
boolean isLeafNode = false;
|
||||
// This loop will end at either a leaf node, or the last identified JSON field (by throwing an exception)
|
||||
// Valid forms of the fieldPath for this search could be:
|
||||
// root.field.list[index].childField.anotherList.indexWithDotOperator.multidimensionalList[index1][index2]
|
||||
|
|
@ -327,30 +336,30 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
} catch (IndexOutOfBoundsException e) {
|
||||
// The index being referred does not exist. Hence the path would not exist.
|
||||
throw new AppsmithException(AppsmithError.INVALID_DYNAMIC_BINDING_REFERENCE, widgetType,
|
||||
widgetName, widgetId, fieldPath, pageId, layoutId);
|
||||
widgetName, widgetId, fieldPath, pageId, layoutId, null);
|
||||
}
|
||||
} else {
|
||||
throw new AppsmithException(AppsmithError.INVALID_DYNAMIC_BINDING_REFERENCE, widgetType,
|
||||
widgetName, widgetId, fieldPath, pageId, layoutId);
|
||||
widgetName, widgetId, fieldPath, pageId, layoutId, null);
|
||||
}
|
||||
}
|
||||
// After updating the parent, check for the types
|
||||
if (parent == null) {
|
||||
throw new AppsmithException(AppsmithError.INVALID_DYNAMIC_BINDING_REFERENCE, widgetType,
|
||||
widgetName, widgetId, fieldPath, pageId, layoutId);
|
||||
widgetName, widgetId, fieldPath, pageId, layoutId, null);
|
||||
} else if (parent instanceof String) {
|
||||
// If we get String value, then this is a leaf node
|
||||
isLeafNode = true;
|
||||
}
|
||||
}
|
||||
// Only extract mustache keys from leaf nodes
|
||||
if (parent != null && isLeafNode) {
|
||||
if (isLeafNode) {
|
||||
Set<String> mustacheKeysFromFields = MustacheHelper.extractMustacheKeysFromFields(parent);
|
||||
|
||||
// We found the path. But if the path does not have any mustache bindings, throw the error
|
||||
if (mustacheKeysFromFields.isEmpty()) {
|
||||
throw new AppsmithException(AppsmithError.INVALID_DYNAMIC_BINDING_REFERENCE, widgetType,
|
||||
widgetName, widgetId, fieldPath, pageId, layoutId);
|
||||
widgetName, widgetId, fieldPath, pageId, layoutId, parent);
|
||||
}
|
||||
|
||||
dynamicBindings.addAll(mustacheKeysFromFields);
|
||||
|
|
@ -499,9 +508,38 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
.then(Mono.just(pageId));
|
||||
}
|
||||
|
||||
private Mono<Boolean> sendUpdateLayoutAnalyticsEvent(String pageId, String layoutId, JSONObject dsl, boolean isSuccess, Throwable error) {
|
||||
return Mono.zip(
|
||||
sessionUserService.getCurrentUser(),
|
||||
newPageService.getById(pageId)
|
||||
)
|
||||
.flatMap(tuple -> {
|
||||
User t1 = tuple.getT1();
|
||||
NewPage t2 = tuple.getT2();
|
||||
|
||||
final Map<String, Object> data = Map.of(
|
||||
"username", t1.getUsername(),
|
||||
"appId", t2.getApplicationId(),
|
||||
"pageId", pageId,
|
||||
"layoutId", layoutId,
|
||||
"dsl", dsl.toJSONString(),
|
||||
"isSuccessfulExecution", isSuccess,
|
||||
"error", error == null ? "" : error.getMessage()
|
||||
);
|
||||
|
||||
analyticsService.sendEvent(AnalyticsEvents.UPDATE_LAYOUT.getEventName(), t1.getUsername(), data);
|
||||
return Mono.just(isSuccess);
|
||||
})
|
||||
.onErrorResume(e -> {
|
||||
log.warn("Error sending action execution data point", e);
|
||||
return Mono.just(isSuccess);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<LayoutDTO> updateLayout(String pageId, String layoutId, Layout layout) {
|
||||
JSONObject dsl = layout.getDsl();
|
||||
final JSONObject dsl = layout.getDsl();
|
||||
if (dsl == null) {
|
||||
// There is no DSL here. No need to process anything. Return as is.
|
||||
return Mono.just(generateResponseDTO(layout));
|
||||
|
|
@ -512,7 +550,8 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
try {
|
||||
extractAllWidgetNamesAndDynamicBindingsFromDSL(dsl, widgetNames, jsSnippetsInDynamicBindings, pageId, layoutId);
|
||||
} catch (Throwable t) {
|
||||
return Mono.error(t);
|
||||
return sendUpdateLayoutAnalyticsEvent(pageId, layoutId, dsl, false, t)
|
||||
.then(Mono.error(t));
|
||||
}
|
||||
layout.setWidgetNames(widgetNames);
|
||||
|
||||
|
|
@ -581,11 +620,13 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
}
|
||||
return Mono.empty();
|
||||
})
|
||||
.map(savedLayout -> {
|
||||
.flatMap(savedLayout -> {
|
||||
LayoutDTO layoutDTO = generateResponseDTO(savedLayout);
|
||||
layoutDTO.setActionUpdates(actionUpdates);
|
||||
layoutDTO.setMessages(messages);
|
||||
return layoutDTO;
|
||||
|
||||
return sendUpdateLayoutAnalyticsEvent(pageId, layoutId, dsl, true, null)
|
||||
.thenReturn(layoutDTO);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user