diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ActionCollectionSpan.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ActionCollectionSpan.java new file mode 100644 index 0000000000..d385ce46ee --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ActionCollectionSpan.java @@ -0,0 +1,5 @@ +package com.appsmith.external.constants.spans; + +import com.appsmith.external.constants.spans.ce.ActionCollectionSpanCE; + +public class ActionCollectionSpan extends ActionCollectionSpanCE {} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/LayoutSpan.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/LayoutSpan.java new file mode 100644 index 0000000000..0e717763b3 --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/LayoutSpan.java @@ -0,0 +1,5 @@ +package com.appsmith.external.constants.spans; + +import com.appsmith.external.constants.spans.ce.LayoutSpanCE; + +public class LayoutSpan extends LayoutSpanCE {} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionCollectionSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionCollectionSpanCE.java new file mode 100644 index 0000000000..c95f431fac --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionCollectionSpanCE.java @@ -0,0 +1,21 @@ +package com.appsmith.external.constants.spans.ce; + +import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX; + +/** + * Please make sure that all span names start with `appsmith.` because span with any other naming format would get + * dropped / ignored as defined in TracingConfig.java + */ +public class ActionCollectionSpanCE { + // Action Collection spans + public static final String ACTION_COLLECTION_UPDATE = APPSMITH_SPAN_PREFIX + "update.actionCollection"; + public static final String GENERATE_ACTION_COLLECTION_BY_VIEW_MODE = + APPSMITH_SPAN_PREFIX + "generate.actionCollectionByViewMode"; + public static final String POPULATE_ACTION_COLLECTION_BY_VIEW_MODE = + APPSMITH_SPAN_PREFIX + "populate.actionCollectionByViewMode"; + public static final String SAVE_ACTION_COLLECTION_LAST_EDIT_INFO = + APPSMITH_SPAN_PREFIX + "save.actionCollectionLastEditInfo"; + + // Getter spans + public static final String GET_ACTION_COLLECTION_BY_ID = APPSMITH_SPAN_PREFIX + "get.actionCollectionById"; +} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionSpanCE.java index eec93d4a08..1cbec44a3a 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionSpanCE.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionSpanCE.java @@ -29,4 +29,12 @@ public class ActionSpanCE { public static final String VIEW_MODE_SET_PLUGIN_ID_AND_TYPE_ACTION = ACTIONS_VIEW_MODE_PREFIX + "set_action"; public static final String VIEW_MODE_FETCH_PLUGIN_FROM_DB = ACTIONS_VIEW_MODE_PREFIX + "plugindb"; public static final String VIEW_MODE_FETCH_ACTIONS_FROM_DB = ACTIONS_VIEW_MODE_PREFIX + "fetchactions"; + public static final String GET_ACTION_BY_ID = APPSMITH_SPAN_PREFIX + "get.actionById"; + + // Action creation, update and delete spans + public static final String UPDATE_SINGLE_ACTION = APPSMITH_SPAN_PREFIX + "update.single.action"; + public static final String UPDATE_ACTION_BASED_ON_CONTEXT = APPSMITH_SPAN_PREFIX + "update.action.context"; + public static final String CREATE_ACTION = APPSMITH_SPAN_PREFIX + "create.action"; + public static final String UPDATE_ACTION = APPSMITH_SPAN_PREFIX + "update.action"; + public static final String DELETE_ACTION = APPSMITH_SPAN_PREFIX + "delete.action"; } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/LayoutSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/LayoutSpanCE.java new file mode 100644 index 0000000000..98c972bd12 --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/LayoutSpanCE.java @@ -0,0 +1,18 @@ +package com.appsmith.external.constants.spans.ce; + +import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX; + +public class LayoutSpanCE { + public static final String UPDATE_LAYOUT = "updateLayout."; + public static final String UPDATE_PAGE_LAYOUT_BY_PAGE_ID = APPSMITH_SPAN_PREFIX + UPDATE_LAYOUT + "pageId"; + public static final String UPDATE_LAYOUT_METHOD = APPSMITH_SPAN_PREFIX + UPDATE_LAYOUT + "method"; + public static final String UPDATE_LAYOUT_DSL_METHOD = APPSMITH_SPAN_PREFIX + UPDATE_LAYOUT + "dsl.method"; + public static final String UPDATE_LAYOUT_BASED_ON_CONTEXT = APPSMITH_SPAN_PREFIX + UPDATE_LAYOUT + "context"; + + public static final String FIND_ALL_ON_LOAD_EXECUTABLES = + APPSMITH_SPAN_PREFIX + "onLoadExecutablesUtil.findAllOnLoadExecutables"; + public static final String UPDATE_EXECUTABLES_EXECUTE_ONLOAD = + APPSMITH_SPAN_PREFIX + "onLoadExecutablesUtil.updateExecutablesExecuteOnLoad"; + public static final String FIND_AND_UPDATE_LAYOUT = + APPSMITH_SPAN_PREFIX + "onLoadExecutablesUtil.findAndUpdateLayout"; +} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/PageSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/PageSpanCE.java index 42169197be..8f3e8f78ed 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/PageSpanCE.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/PageSpanCE.java @@ -1,5 +1,7 @@ package com.appsmith.external.constants.spans.ce; +import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX; + public class PageSpanCE { public static final String PAGES = "pages."; public static final String GET_PAGE = PAGES + "getpage"; @@ -11,4 +13,6 @@ public class PageSpanCE { public static final String MARK_RECENTLY_ACCESSED_RESOURCES_PAGES = PAGES + "update_recently_accessed_pages"; public static final String PREPARE_APPLICATION_PAGES_DTO_FROM_PAGES = PAGES + "generate_app_pages_dto"; public static final String MIGRATE_DSL = PAGES + "migrate_dsl"; + + public static final String GET_PAGE_BY_ID = APPSMITH_SPAN_PREFIX + "get.page.unpublished"; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java index b7d369ef72..7b062f6305 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java @@ -20,6 +20,7 @@ import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.BaseService; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.ApplicationPermission; +import io.micrometer.observation.ObservationRegistry; import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; @@ -28,6 +29,7 @@ import org.springframework.data.domain.Sort; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; +import reactor.core.observability.micrometer.Micrometer; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -41,6 +43,7 @@ import java.util.Objects; import java.util.Set; import java.util.UUID; +import static com.appsmith.external.constants.spans.ActionCollectionSpan.GET_ACTION_COLLECTION_BY_ID; import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject; import static java.lang.Boolean.TRUE; @@ -53,6 +56,7 @@ public class ActionCollectionServiceCEImpl extends BaseService findById(String id, AclPermission aclPermission) { - return repository.findById(id, aclPermission); + return repository + .findById(id, aclPermission) + .name(GET_ACTION_COLLECTION_BY_ID) + .tap(Micrometer.observation(observationRegistry)); } @Override diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceImpl.java index e24740b823..a9e2e3f2f1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceImpl.java @@ -7,6 +7,7 @@ import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.ApplicationPermission; +import io.micrometer.observation.ObservationRegistry; import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -22,7 +23,8 @@ public class ActionCollectionServiceImpl extends ActionCollectionServiceCEImpl i PolicyGenerator policyGenerator, ApplicationService applicationService, ApplicationPermission applicationPermission, - ActionPermission actionPermission) { + ActionPermission actionPermission, + ObservationRegistry observationRegistry) { super( validator, repository, @@ -31,6 +33,7 @@ public class ActionCollectionServiceImpl extends ActionCollectionServiceCEImpl i policyGenerator, applicationService, applicationPermission, - actionPermission); + actionPermission, + observationRegistry); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java old mode 100644 new mode 100755 index fa8747b8b9..d9d44d439f --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java @@ -25,12 +25,14 @@ import com.appsmith.server.services.SessionUserService; import com.appsmith.server.solutions.PagePermission; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import io.micrometer.observation.ObservationRegistry; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.minidev.json.JSONObject; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import reactor.core.observability.micrometer.Micrometer; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -46,6 +48,12 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Pattern; import java.util.stream.Collectors; +import static com.appsmith.external.constants.spans.LayoutSpan.FIND_ALL_ON_LOAD_EXECUTABLES; +import static com.appsmith.external.constants.spans.LayoutSpan.FIND_AND_UPDATE_LAYOUT; +import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_EXECUTABLES_EXECUTE_ONLOAD; +import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_LAYOUT_DSL_METHOD; +import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_LAYOUT_METHOD; +import static com.appsmith.external.constants.spans.PageSpan.GET_PAGE_BY_ID; import static com.appsmith.server.constants.CommonConstants.EVALUATION_VERSION; import static java.lang.Boolean.FALSE; @@ -60,8 +68,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { private final AnalyticsService analyticsService; private final PagePermission pagePermission; private final ApplicationService applicationService; - private final ObjectMapper objectMapper; + private final ObservationRegistry observationRegistry; private final String layoutOnLoadActionErrorToastMessage = "A cyclic dependency error has been encountered on current page, \nqueries on page load will not run. \n Please check debugger and Appsmith documentation for more information"; @@ -122,6 +130,7 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { try { dsl = extractAllWidgetNamesAndDynamicBindingsFromDSL( dsl, widgetNames, widgetDynamicBindingsMap, creatorId, layoutId, escapedWidgetNames, creatorType); + } catch (Throwable t) { return sendUpdateLayoutAnalyticsEvent(creatorId, layoutId, dsl, false, t, creatorType) .then(Mono.error(t)); @@ -155,6 +164,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { flatmapOnLoadExecutables, executablesUsedInDSL, creatorType) + .name(FIND_ALL_ON_LOAD_EXECUTABLES) + .tap(Micrometer.observation(observationRegistry)) .onErrorResume(AppsmithException.class, error -> { log.info(error.getMessage()); validOnLoadExecutables.set(FALSE); @@ -181,6 +192,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { return onLoadExecutablesUtil .updateExecutablesExecuteOnLoad( flatmapOnLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType) + .name(UPDATE_EXECUTABLES_EXECUTE_ONLOAD) + .tap(Micrometer.observation(observationRegistry)) .thenReturn(allOnLoadExecutables); }) // Now update the page layout with the page load executables and the graph. @@ -192,7 +205,10 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { // valid when last stored in the database. layout.setValidOnPageLoadActions(validOnLoadExecutables.get()); - return onLoadExecutablesUtil.findAndUpdateLayout(creatorId, creatorType, layoutId, layout); + return onLoadExecutablesUtil + .findAndUpdateLayout(creatorId, creatorType, layoutId, layout) + .name(FIND_AND_UPDATE_LAYOUT) + .tap(Micrometer.observation(observationRegistry)); }) .map(savedLayout -> { savedLayout.setDsl(this.unescapeMongoSpecialCharacters(savedLayout)); @@ -219,7 +235,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { if (evaluationVersion == null) { evaluationVersion = EVALUATION_VERSION; } - return updateLayoutDsl(pageId, layoutId, layout, evaluationVersion, CreatorContextType.PAGE); + return updateLayoutDsl(pageId, layoutId, layout, evaluationVersion, CreatorContextType.PAGE) + .name(UPDATE_LAYOUT_DSL_METHOD); }); } @@ -276,13 +293,17 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { return Mono.justOrEmpty(pageId) // fetch the unpublished page .flatMap(id -> newPageService.findPageById(id, pagePermission.getEditPermission(), false)) + .name(GET_PAGE_BY_ID) + .tap(Micrometer.observation(observationRegistry)) .flatMapMany(page -> { if (page.getLayouts() == null) { return Mono.empty(); } return Flux.fromIterable(page.getLayouts()).flatMap(layout -> { layout.setDsl(this.unescapeMongoSpecialCharacters(layout)); - return this.updateLayout(page.getId(), page.getApplicationId(), layout.getId(), layout); + return this.updateLayout(page.getId(), page.getApplicationId(), layout.getId(), layout) + .name(UPDATE_LAYOUT_METHOD) + .tap(Micrometer.observation(observationRegistry)); }); }) .collectList() @@ -324,7 +345,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { AtomicReference validOnLoadExecutables = new AtomicReference<>(Boolean.TRUE); - // setting the layoutOnLoadActionActionErrors to empty to remove the existing errors before new DAG calculation. + // setting the layoutOnLoadActionActionErrors to empty to remove the existing + // errors before new DAG calculation. layout.setLayoutOnLoadActionErrors(new ArrayList<>()); return onLoadExecutablesUtil @@ -364,13 +386,15 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { String widgetType = dsl.getAsString(FieldName.WIDGET_TYPE); if (widgetType.equals(FieldName.TABLE_WIDGET)) { // UnEscape Table widget keys - // Since this is a table widget, it wouldnt have children. We can safely return from here with updated + // Since this is a table widget, it wouldnt have children. We can safely return + // from here with updated // dsl return WidgetSpecificUtils.unEscapeTableWidgetPrimaryColumns(dsl); } } - // Fetch the children of the current node in the DSL and recursively iterate over them to extract bindings + // Fetch the children of the current node in the DSL and recursively iterate + // over them to extract bindings ArrayList children = (ArrayList) dsl.get(FieldName.CHILDREN); ArrayList newChildren = new ArrayList<>(); if (children != null) { @@ -392,9 +416,11 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { /** * Walks the DSL and extracts all the widget names from it. - * A widget is expected to have a few properties defining its own behaviour, with any mustache bindings present + * A widget is expected to have a few properties defining its own behaviour, + * with any mustache bindings present * in them aggregated in the field dynamicBindingsPathList. - * A widget may also have other widgets as children, each of which will follow the same structure + * A widget may also have other widgets as children, each of which will follow + * the same structure * Refer to FieldName.DEFAULT_PAGE_LAYOUT for a template * * @param dsl @@ -423,27 +449,33 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { String widgetId = dsl.getAsString(FieldName.WIDGET_ID); String widgetType = dsl.getAsString(FieldName.WIDGET_TYPE); - // Since we are parsing this widget in this, add it to the global set of widgets found so far in the DSL. + // Since we are parsing this widget in this, add it to the global set of widgets + // found so far in the DSL. widgetNames.add(widgetName); - // Start by picking all fields where we expect to find dynamic bindings for this particular widget + // Start by picking all fields where we expect to find dynamic bindings for this + // particular widget ArrayList dynamicallyBoundedPathList = (ArrayList) dsl.get(FieldName.DYNAMIC_BINDING_PATH_LIST); - // Widgets will not have FieldName.DYNAMIC_BINDING_PATH_LIST if there are no bindings in that widget. + // Widgets will not have FieldName.DYNAMIC_BINDING_PATH_LIST if there are no + // bindings in that widget. // Hence we skip over the extraction of the bindings from that widget. if (dynamicallyBoundedPathList != null) { - // Each of these might have nested structures, so we iterate through them to find the leaf node for each + // Each of these might have nested structures, so we iterate through them to + // find the leaf node for each for (Object x : dynamicallyBoundedPathList) { final String fieldPath = String.valueOf(((Map) x).get(FieldName.KEY)); String[] fields = fieldPath.split("[].\\[]"); - // For nested fields, the parent dsl to search in would shift by one level every iteration + // For nested fields, the parent dsl to search in would shift by one level every + // iteration Object parent = dsl; Iterator fieldsIterator = Arrays.stream(fields) .filter(fieldToken -> !fieldToken.isBlank()) .iterator(); boolean isLeafNode = false; Object oldParent; - // This loop will end at either a leaf node, or the last identified JSON field (by throwing an + // 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] @@ -510,7 +542,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { // Only extract mustache keys from leaf nodes if (isLeafNode) { - // We found the path. But if the path does not have any mustache bindings, throw the error + // We found the path. But if the path does not have any mustache bindings, throw + // the error if (!MustacheHelper.laxIsBindingPresentInString((String) parent)) { try { String bindingAsString = objectMapper.writeValueAsString(parent); @@ -551,7 +584,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { // Escape the widget keys if required and update dsl and escapedWidgetNames removeSpecialCharactersFromKeys(dsl, escapedWidgetNames); - // Fetch the children of the current node in the DSL and recursively iterate over them to extract bindings + // Fetch the children of the current node in the DSL and recursively iterate + // over them to extract bindings ArrayList children = (ArrayList) dsl.get(FieldName.CHILDREN); ArrayList newChildren = new ArrayList<>(); if (children != null) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java index 46ab98cc21..4d16899473 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java @@ -7,6 +7,7 @@ import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.solutions.PagePermission; import com.fasterxml.jackson.databind.ObjectMapper; +import io.micrometer.observation.ObservationRegistry; import org.springframework.stereotype.Service; @Service @@ -19,7 +20,8 @@ public class UpdateLayoutServiceImpl extends UpdateLayoutServiceCEImpl implement AnalyticsService analyticsService, PagePermission pagePermission, ApplicationService applicationService, - ObjectMapper objectMapper) { + ObjectMapper objectMapper, + ObservationRegistry observationRegistry) { super( onLoadExecutablesUtil, sessionUserService, @@ -27,6 +29,7 @@ public class UpdateLayoutServiceImpl extends UpdateLayoutServiceCEImpl implement analyticsService, pagePermission, applicationService, - objectMapper); + objectMapper, + observationRegistry); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java index 1c0737cbc7..cf61583245 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java @@ -8,6 +8,7 @@ import com.appsmith.server.refactors.applications.RefactoringService; import com.appsmith.server.services.ce.LayoutActionServiceCEImpl; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.PagePermission; +import io.micrometer.observation.ObservationRegistry; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -24,7 +25,9 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement UpdateLayoutService updateLayoutService, DatasourceService datasourceService, PagePermission pagePermission, - ActionPermission actionPermission) { + ActionPermission actionPermission, + ObservationRegistry observationRegistry) { + super( analyticsService, newPageService, @@ -34,6 +37,7 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement updateLayoutService, datasourceService, pagePermission, - actionPermission); + actionPermission, + observationRegistry); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutCollectionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutCollectionServiceImpl.java index 66ac121333..621b10bab4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutCollectionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutCollectionServiceImpl.java @@ -9,6 +9,7 @@ import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.services.ce.LayoutCollectionServiceCEImpl; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.PagePermission; +import io.micrometer.observation.ObservationRegistry; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -26,7 +27,8 @@ public class LayoutCollectionServiceImpl extends LayoutCollectionServiceCEImpl i AnalyticsService analyticsService, ActionCollectionRepository actionCollectionRepository, PagePermission pagePermission, - ActionPermission actionPermission) { + ActionPermission actionPermission, + ObservationRegistry observationRegistry) { super( newPageService, layoutActionService, @@ -37,6 +39,7 @@ public class LayoutCollectionServiceImpl extends LayoutCollectionServiceCEImpl i analyticsService, actionCollectionRepository, pagePermission, - actionPermission); + actionPermission, + observationRegistry); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java old mode 100644 new mode 100755 index f3d88efa89..43a29dcca1 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java @@ -23,14 +23,20 @@ import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.CollectionService; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.PagePermission; +import io.micrometer.observation.ObservationRegistry; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import reactor.core.observability.micrometer.Micrometer; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; +import static com.appsmith.external.constants.spans.ActionSpan.GET_ACTION_BY_ID; +import static com.appsmith.external.constants.spans.ActionSpan.UPDATE_ACTION_BASED_ON_CONTEXT; +import static com.appsmith.external.constants.spans.ActionSpan.UPDATE_SINGLE_ACTION; +import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_PAGE_LAYOUT_BY_PAGE_ID; import static java.util.stream.Collectors.toSet; @Slf4j @@ -47,6 +53,7 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { private final DatasourceService datasourceService; private final PagePermission pagePermission; private final ActionPermission actionPermission; + private final ObservationRegistry observationRegistry; /** * Called by Action controller to create Action @@ -214,7 +221,11 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { public Mono updateNewActionByBranchedId(String branchedId, ActionDTO actionDTO) { return newActionService .findById(branchedId, actionPermission.getEditPermission()) - .flatMap(newAction -> updateActionBasedOnContextType(newAction, actionDTO)); + .name(GET_ACTION_BY_ID) + .tap(Micrometer.observation(observationRegistry)) + .flatMap(newAction -> updateActionBasedOnContextType(newAction, actionDTO) + .name(UPDATE_ACTION_BASED_ON_CONTEXT) + .tap(Micrometer.observation(observationRegistry))); } /** @@ -227,8 +238,13 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { action.setApplicationId(null); action.setPageId(null); return updateSingleAction(newAction.getId(), action) - .flatMap(updatedAction -> - updateLayoutService.updatePageLayoutsByPageId(pageId).thenReturn(updatedAction)) + .name(UPDATE_SINGLE_ACTION) + .tap(Micrometer.observation(observationRegistry)) + .flatMap(updatedAction -> updateLayoutService + .updatePageLayoutsByPageId(pageId) + .name(UPDATE_PAGE_LAYOUT_BY_PAGE_ID) + .tap(Micrometer.observation(observationRegistry)) + .thenReturn(updatedAction)) .zipWhen(actionDTO -> newPageService.findPageById(pageId, pagePermission.getEditPermission(), false)) .map(tuple2 -> { ActionDTO actionDTO = tuple2.getT1(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java index 42a5d1b09a..d4cc9fcbdf 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java @@ -23,9 +23,11 @@ import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.LayoutActionService; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.PagePermission; +import io.micrometer.observation.ObservationRegistry; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import reactor.core.observability.micrometer.Micrometer; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -36,6 +38,14 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import static com.appsmith.external.constants.spans.ActionCollectionSpan.ACTION_COLLECTION_UPDATE; +import static com.appsmith.external.constants.spans.ActionCollectionSpan.GENERATE_ACTION_COLLECTION_BY_VIEW_MODE; +import static com.appsmith.external.constants.spans.ActionCollectionSpan.POPULATE_ACTION_COLLECTION_BY_VIEW_MODE; +import static com.appsmith.external.constants.spans.ActionCollectionSpan.SAVE_ACTION_COLLECTION_LAST_EDIT_INFO; +import static com.appsmith.external.constants.spans.ActionSpan.CREATE_ACTION; +import static com.appsmith.external.constants.spans.ActionSpan.DELETE_ACTION; +import static com.appsmith.external.constants.spans.ActionSpan.UPDATE_ACTION; +import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_LAYOUT_BASED_ON_CONTEXT; import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject; import static com.appsmith.server.helpers.ContextTypeUtils.isPageContext; import static java.util.stream.Collectors.toMap; @@ -55,6 +65,7 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE private final ActionCollectionRepository actionCollectionRepository; private final PagePermission pagePermission; private final ActionPermission actionPermission; + private final ObservationRegistry observationRegistry; @Override public Mono createCollection(ActionCollection actionCollection) { @@ -325,7 +336,10 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE actionDTO.setPluginId(actionCollectionDTO.getPluginId()); actionDTO.setBranchName(branchedActionCollection.getBranchName()); // actionCollectionService is a new action, we need to create one - return layoutActionService.createSingleAction(actionDTO, Boolean.TRUE); + return layoutActionService + .createSingleAction(actionDTO, Boolean.TRUE) + .name(CREATE_ACTION) + .tap(Micrometer.observation(observationRegistry)); } else { actionDTO.setCollectionId(null); // Client only knows about the default action ID, fetch branched action id to update the @@ -333,7 +347,10 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE String branchedActionId = actionDTO.getId(); actionDTO.setId(null); actionDTO.setBaseId(null); - return layoutActionService.updateNewActionByBranchedId(branchedActionId, actionDTO); + return layoutActionService + .updateNewActionByBranchedId(branchedActionId, actionDTO) + .name(UPDATE_ACTION) + .tap(Micrometer.observation(observationRegistry)); } }) .collect(toMap(actionDTO -> actionDTO.getBaseId(), ActionDTO::getId))); @@ -354,7 +371,9 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE log.error(throwable.getMessage()); return Mono.empty(); })) - .collectList(); + .collectList() + .name(DELETE_ACTION) + .tap(Micrometer.observation(observationRegistry)); return deleteNonExistingActionMono .then(newValidActionIdsMono) @@ -373,17 +392,27 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE }); }) .flatMap(actionCollection -> actionCollectionService.update(actionCollection.getId(), actionCollection)) + .name(ACTION_COLLECTION_UPDATE) + .tap(Micrometer.observation(observationRegistry)) .flatMap(actionCollectionRepository::setUserPermissionsInObject) - .flatMap(savedActionCollection -> - updateLayoutBasedOnContext(savedActionCollection).thenReturn(savedActionCollection)) + .flatMap(savedActionCollection -> updateLayoutBasedOnContext(savedActionCollection) + .name(UPDATE_LAYOUT_BASED_ON_CONTEXT) + .tap(Micrometer.observation(observationRegistry)) + .thenReturn(savedActionCollection)) .flatMap(savedActionCollection -> analyticsService.sendUpdateEvent( savedActionCollection, actionCollectionService.getAnalyticsProperties(savedActionCollection))) .flatMap(actionCollection -> actionCollectionService .generateActionCollectionByViewMode(actionCollection, false) + .name(GENERATE_ACTION_COLLECTION_BY_VIEW_MODE) + .tap(Micrometer.observation(observationRegistry)) .flatMap(actionCollectionDTO1 -> actionCollectionService .populateActionCollectionByViewMode(actionCollection.getUnpublishedCollection(), false) + .name(POPULATE_ACTION_COLLECTION_BY_VIEW_MODE) + .tap(Micrometer.observation(observationRegistry)) .flatMap(actionCollectionDTO2 -> actionCollectionService .saveLastEditInformationInParent(actionCollectionDTO2) + .name(SAVE_ACTION_COLLECTION_LAST_EDIT_INFO) + .tap(Micrometer.observation(observationRegistry)) .thenReturn(actionCollectionDTO2)))) .flatMap(branchedActionCollection -> sendErrorReportsFromPageToCollection(branchedActionCollection)); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java index 1f90c776f2..716779b165 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java @@ -28,6 +28,7 @@ import com.appsmith.server.solutions.PagePermission; import com.appsmith.server.solutions.PagePermissionImpl; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import io.micrometer.observation.ObservationRegistry; import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Assertions; @@ -86,6 +87,9 @@ public class ActionCollectionServiceImplTest { PagePermission pagePermission; ActionPermission actionPermission; + @MockBean + ObservationRegistry observationRegistry; + @MockBean private Validator validator; @@ -108,7 +112,8 @@ public class ActionCollectionServiceImplTest { policyGenerator, applicationService, applicationPermission, - actionPermission); + actionPermission, + observationRegistry); layoutCollectionService = new LayoutCollectionServiceImpl( newPageService, @@ -120,7 +125,8 @@ public class ActionCollectionServiceImplTest { analyticsService, actionCollectionRepository, pagePermission, - actionPermission); + actionPermission, + observationRegistry); Mockito.when(analyticsService.sendCreateEvent(Mockito.any())) .thenAnswer( @@ -149,6 +155,10 @@ public class ActionCollectionServiceImplTest { Mockito.when(analyticsService.sendArchiveEvent(Mockito.any(), Mockito.any())) .thenAnswer( invocationOnMock -> Mono.justOrEmpty(invocationOnMock.getArguments()[0])); + + ObservationRegistry.ObservationConfig mockObservationConfig = + Mockito.mock(ObservationRegistry.ObservationConfig.class); + Mockito.when(observationRegistry.observationConfig()).thenReturn(mockObservationConfig); } @Test