deepflowio / deepflow

eBPF Observability - Distributed Tracing and Profiling
https://deepflow.io
Apache License 2.0
2.97k stars 333 forks source link

[FR] 提供Java代码帮助分析 #6994

Closed numachen closed 4 months ago

numachen commented 5 months ago

Search before asking

Description

提供代码分析on-cpu

Use case

public Result<List<ClientAreaPageResp>> clientWorkBenchQueryV3(ClientAreaPageV2Req request) {
        Integer clientType = request.getClientType();
        AuthReq req = BeanConverterUtil.map(request, AuthReq.class);
        // 走缓存
        Result<Set<String>> menuKeyResult = orgCenterService.authCodes(req);
        if (!menuKeyResult.isStatus()) {
            return Result.failureData(menuKeyResult.exceptionInfo());
        }
        AppArea appArea = areaManager.queryByKey(request.getAreaKey());
        Set<String> menuKeys = menuKeyResult.getData();
        // 【权限点为空】 或者 【没有区域】
        if (CollectionUtils.isEmpty(menuKeys) || Objects.isNull(appArea)) {
            Logger.build().event("客户端工作台").putMessage("权限点为空或区域为空").info();
            return Result.successData(Lists.newArrayList());
        }
        if (!appArea.hasAuth(menuKeys)) {
            Logger.build().event("客户端工作台").putMessage("区域权限限制").putMessage("menuKeys", menuKeys).putMessage("menuId", appArea.getMenuId()).putMessage("menuKey", appArea.getMenuKey()).info();
            return Result.successData(Lists.newArrayList());
        }
        Long appAreaId = appArea.getId();
        // 查询区域下应用子页面列表
        List<AppRelationAreaModule> relations = relationManager.listByAreaId(appAreaId);
        Set<String> appIds = relations.stream().map(AppRelationAreaModule::getAppId).collect(Collectors.toSet());
        // 查询客户端应用 && 过滤出当前账户包含的应用
        List<AppModule> appModuleList = appModuleManager.listForClientV3(request.getSellerId(), clientType, appIds).getData().stream().filter(item -> menuKeys.contains(item.getMenuKey())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(appModuleList)) {
            Logger.build().event("客户端工作台").indexed("clientType", clientType).indexed("sellerId", request.getSellerId()).putMessage("应用列表为空").info();
            return Result.successData(Lists.newArrayList());
        }
        Set<Long> appGroupIds = appModuleList.stream().map(AppModule::getGroupId).collect(Collectors.toSet());
        // 授权的分组id
        List<Long> authGroupIds = ModelMaps.authGroupIds(groupConfigManager.listByIds(appGroupIds), menuKeys);
        // 过滤已授权的分组应用 && 应用有对应的客户端版本
        appModuleList = appModuleList.stream().filter(item -> authGroupIds.contains(item.getGroupId())).filter(module -> Objects.nonNull(module.clientVersion(clientType))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(appModuleList)) {
            Logger.build().event("客户端工作台").indexed("clientType", clientType).indexed("sellerId", request.getSellerId()).putMessage("应用列表为空").info();
            return Result.successData(Lists.newArrayList());
        }
        Set<String> authAppIds = appModuleList.stream().map(AppModule::getAppId).collect(Collectors.toSet());
        Set<Long> versionIds = appModuleList.stream().map(module -> module.clientVersion(clientType)).collect(Collectors.toSet());
        // 有效的应用对应的关系
        relations = relations.stream().filter(item -> authAppIds.contains(item.getAppId())).collect(Collectors.toList());
        Map<Long, List<AppRelationAreaModule>> relationGroup = ModelMaps.relationGroup(relations);
        Set<Long> pageIds = relations.stream().map(AppRelationAreaModule::getPageId).collect(Collectors.toSet());
        // 过滤符合子页面权限的page
        Map<Long, AppModulePage> pageMap = ModelMaps.authPageMap(pageManager.listByIds(pageIds), menuKeys);
        List<AppModuleVersion> versions = versionManager.list(versionIds);
        Map<Long, List<AppRelationProperties>> relationPropertyGroup = ModelMaps.appRelationPropertyGroups(relationPropertiesManager.listByRelations(ModelMaps.relationIds(relations)));
        // 整合数据map
        Map<String, AppModule> moduleMap = ModelMaps.moduleMap(appModuleList);
        Map<Long, AppModuleVersion> versionMap = ModelMaps.versionMap(versions);
        Map<String, List<AppModuleProperties>> propertyGroup = ModelMaps.appModulePropertyGroups(propertiesManager.listByAppIds(moduleMap.keySet()));
        List<ClientAreaPageResp> result = Lists.newArrayList();
        List<AppAreaGroup> groups = groupManager.listByArea(appAreaId);
        for (AppAreaGroup group: groups) {
            List<ClientAreaPageResp.Module> list = relationGroup.getOrDefault(group.getId(), Lists.newArrayList()).stream().filter(relation -> moduleMap.containsKey(relation.getAppId()))
                    .sorted((i1, i2) -> i1.getSeq().compareTo(i2.getSeq()))
                    .map(relation -> {
                        String appId = relation.getAppId();
                        AppModule module = moduleMap.get(appId);
                        if (Objects.isNull(module)) {
                            return null;
                        }
                        AppModuleVersion version = versionMap.get(module.clientVersion(clientType));
                        List<AppRelationProperties> relationProperties = relationPropertyGroup.getOrDefault(relation.getId(), Lists.newArrayList());
                        List<AppModuleProperties> properties = propertyGroup.getOrDefault(appId, Lists.newArrayList());
                        return ClientRspUtil.toRsp(module, version, pageMap.get(relation.getPageId()), properties, relationProperties, request.getOrgType());
                    }).filter(Objects::nonNull)
                    .collect(Collectors.toList());
            // 分组下应用不存在,过滤分组
            if (CollectionUtils.isNotEmpty(list)) {
                result.add(new ClientAreaPageResp(group, list));
            }
        }
        return Result.successData(result);
    }

Related issues

No response

Are you willing to submit a PR?

Code of Conduct

lemonlinger commented 5 months ago

好像企业版里面有这个功能。

sharang commented 4 months ago

https://github.com/deepflowio/deepflow/blob/main/server/agent_config/example.yaml#L1370

    ## Java compliant update latency time
    ## Default: 600s. Range: [5, 3600]s
    ## Note:
    ##   When deepflow-agent finds that an unresolved function name appears in the function call stack
    ##   of a Java process, it will trigger the regeneration of the symbol file of the process.
    ##   Because Java utilizes the Just-In-Time (JIT) compilation mechanism, to obtain more symbols for
    ##   Java processes, the regeneration will be deferred for a period of time.
    #java-symbol-file-refresh-defer-interval: 600s

Reducing the java-symbol-file-refresh-defer-interval can decrease the likelihood of function addresses failing to resolve to function names.