├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── codeql │ ├── codeql-actions.yml │ ├── codeql-go.yml │ └── codeql-javascript-typescript.yml └── workflows │ ├── apo-ci.yml │ ├── build-arm-image.yml │ ├── build-backend-image.yml │ ├── build-frontend-image.yml │ ├── codeql.yml │ └── release-image.yml ├── .gitignore ├── .gitmodules ├── .licenserc.yaml ├── LICENSE ├── README.md ├── backend ├── .gitignore ├── Dev-API.md ├── Dockerfile ├── README.md ├── cmd │ └── handlergen │ │ └── main.go ├── config │ ├── apo.yml │ ├── config.go │ ├── constant.go │ └── init.sql ├── deploy │ └── apo-backend-deploy.yml ├── docs │ ├── docs.go │ ├── swagger.json │ └── swagger.yaml ├── go.mod ├── go.sum ├── main.go ├── pkg │ ├── api │ │ ├── alertinput │ │ │ ├── func_checkschemaisused.go │ │ │ ├── func_cleardefaultalertenrichrule.go │ │ │ ├── func_createalertsource.go │ │ │ ├── func_createcluster.go │ │ │ ├── func_createschema.go │ │ │ ├── func_deletealertsource.go │ │ │ ├── func_deletecluster.go │ │ │ ├── func_deleteschema.go │ │ │ ├── func_getalertsource.go │ │ │ ├── func_getalertsourceenrichrule.go │ │ │ ├── func_getdefaultalertenrichrule.go │ │ │ ├── func_getschemacolumns.go │ │ │ ├── func_getschemadata.go │ │ │ ├── func_jsonhandler.go │ │ │ ├── func_listalertsource.go │ │ │ ├── func_listcluster.go │ │ │ ├── func_listschema.go │ │ │ ├── func_listschemawithcolumns.go │ │ │ ├── func_listtargettags.go │ │ │ ├── func_setdefaultalertenrichrule.go │ │ │ ├── func_sourcehandler.go │ │ │ ├── func_updatealertsource.go │ │ │ ├── func_updatealertsourceenrichrule.go │ │ │ ├── func_updatecluster.go │ │ │ ├── func_updateschemadata.go │ │ │ └── handler.go │ │ ├── alerts │ │ │ ├── func_addalertmanagerconfigreceiver.go │ │ │ ├── func_addalertrule.go │ │ │ ├── func_alerteventclassify.go │ │ │ ├── func_alerteventdetail.go │ │ │ ├── func_alerteventlist.go │ │ │ ├── func_checkalertrule.go │ │ │ ├── func_deletealertmanagerconfigreceiver.go │ │ │ ├── func_deletealertrule.go │ │ │ ├── func_forwardtodingtalk.go │ │ │ ├── func_getalertmanagerconfigreceiver.go │ │ │ ├── func_getalertrulefile.go │ │ │ ├── func_getalertrules.go │ │ │ ├── func_getalertslientconfig.go │ │ │ ├── func_getgrouplist.go │ │ │ ├── func_getmetricpql.go │ │ │ ├── func_inputalertmanager.go │ │ │ ├── func_listalertslientconfig.go │ │ │ ├── func_markalertresolvedmanually.go │ │ │ ├── func_removealertslientconfig.go │ │ │ ├── func_setalertslientconfig.go │ │ │ ├── func_updatealertmanagerconfigreceiver.go │ │ │ ├── func_updatealertrule.go │ │ │ ├── func_updatealertrulefile.go │ │ │ └── handler.go │ │ ├── config │ │ │ ├── func_getttl.go │ │ │ ├── func_setsingletablettl.go │ │ │ ├── func_setttl.go │ │ │ └── handler.go │ │ ├── data │ │ │ ├── func_createdatagroup.go │ │ │ ├── func_datagroupoperation.go │ │ │ ├── func_deletedatagroup.go │ │ │ ├── func_getdatagroup.go │ │ │ ├── func_getdatasource.go │ │ │ ├── func_getgroupdatasource.go │ │ │ ├── func_getgroupsubs.go │ │ │ ├── func_getsubjectdatagroup.go │ │ │ ├── func_getuserdatagroup.go │ │ │ ├── func_groupsubsoperation.go │ │ │ ├── func_updatedatagroup.go │ │ │ └── handler.go │ │ ├── health │ │ │ ├── func_healthcheck.go │ │ │ └── handler.go │ │ ├── integration │ │ │ ├── func_createcluster.go │ │ │ ├── func_deletecluster.go │ │ │ ├── func_getcluster.go │ │ │ ├── func_getintegrationinstallconfigfile.go │ │ │ ├── func_getintegrationinstalldoc.go │ │ │ ├── func_getstaticintegration.go │ │ │ ├── func_listcluster.go │ │ │ ├── func_triggeradapterupdate.go │ │ │ ├── func_updatecluster.go │ │ │ └── handler.go │ │ ├── k8s │ │ │ ├── func_getnamespaceinfo.go │ │ │ ├── func_getnamespacelist.go │ │ │ ├── func_getpodinfo.go │ │ │ ├── func_getpodlist.go │ │ │ └── handler.go │ │ ├── log │ │ │ ├── func_addothertable.go │ │ │ ├── func_addparserule.go │ │ │ ├── func_deleteothertable.go │ │ │ ├── func_deleteparserule.go │ │ │ ├── func_getfaultlogcontent.go │ │ │ ├── func_getfaultloglist.go │ │ │ ├── func_getlogchart.go │ │ │ ├── func_getlogindex.go │ │ │ ├── func_getlogparserule.go │ │ │ ├── func_getlogtableinfo.go │ │ │ ├── func_getserviceroute.go │ │ │ ├── func_othertable.go │ │ │ ├── func_othertableinfo.go │ │ │ ├── func_querylog.go │ │ │ ├── func_querylogcontext.go │ │ │ ├── func_updatelogparserule.go │ │ │ └── handler.go │ │ ├── metric │ │ │ ├── func_listmetrics.go │ │ │ ├── func_querymetrics.go │ │ │ └── handler.go │ │ ├── network │ │ │ ├── func_getpodmap.go │ │ │ ├── func_getspansegments.go │ │ │ └── handler.go │ │ ├── permission │ │ │ ├── func_checkrouterpermission.go │ │ │ ├── func_configuremenu.go │ │ │ ├── func_getfeature.go │ │ │ ├── func_getsubjectfeature.go │ │ │ ├── func_getuserconfig.go │ │ │ ├── func_permissionoperation.go │ │ │ └── handler.go │ │ ├── role │ │ │ ├── func_createrole.go │ │ │ ├── func_deleterole.go │ │ │ ├── func_getrole.go │ │ │ ├── func_getuserrole.go │ │ │ ├── func_roleoperation.go │ │ │ ├── func_updaterole.go │ │ │ └── handler.go │ │ ├── service │ │ │ ├── func_countk8sevents.go │ │ │ ├── func_getalertevents.go │ │ │ ├── func_getalerteventssample.go │ │ │ ├── func_getdescendantmetrics.go │ │ │ ├── func_getdescendantrelevance.go │ │ │ ├── func_geterrorinstance.go │ │ │ ├── func_geterrorinstancelogs.go │ │ │ ├── func_getloglogs.go │ │ │ ├── func_getlogmetrics.go │ │ │ ├── func_getnamespacelist.go │ │ │ ├── func_getpolarisinfer.go │ │ │ ├── func_getserviceendpointlist.go │ │ │ ├── func_getserviceendpointrelation.go │ │ │ ├── func_getserviceendpointtopology.go │ │ │ ├── func_getserviceentryendpoints.go │ │ │ ├── func_getserviceinstance.go │ │ │ ├── func_getserviceinstanceinfolist.go │ │ │ ├── func_getserviceinstancelist.go │ │ │ ├── func_getserviceinstanceoptions.go │ │ │ ├── func_getservicelist.go │ │ │ ├── func_getserviceredcharts.go │ │ │ ├── func_getsqlmetrics.go │ │ │ ├── func_gettracelogs.go │ │ │ ├── func_gettracemetrics.go │ │ │ └── handler.go │ │ ├── serviceoverview │ │ │ ├── func_getendpointsdata.go │ │ │ ├── func_getmonitorstatus.go │ │ │ ├── func_getryglight.go │ │ │ ├── func_getservicemoreurllist.go │ │ │ ├── func_getservicesalert.go │ │ │ ├── func_getthreshold.go │ │ │ ├── func_setthreshold.go │ │ │ └── handler.go │ │ ├── team │ │ │ ├── func_createteam.go │ │ │ ├── func_deleteteam.go │ │ │ ├── func_getteam.go │ │ │ ├── func_getteamuser.go │ │ │ ├── func_teamoperation.go │ │ │ ├── func_teamuseroperation.go │ │ │ ├── func_updateteam.go │ │ │ └── handler.go │ │ ├── trace │ │ │ ├── func_getflamegraphdata.go │ │ │ ├── func_getonoffcpu.go │ │ │ ├── func_getprocessflamegraph.go │ │ │ ├── func_getsingletraceinfo.go │ │ │ ├── func_gettracefilters.go │ │ │ ├── func_gettracefiltervalue.go │ │ │ ├── func_gettracepagelist.go │ │ │ └── handler.go │ │ └── user │ │ │ ├── func_createuser.go │ │ │ ├── func_getuserinfo.go │ │ │ ├── func_getuserlist.go │ │ │ ├── func_getuserteam.go │ │ │ ├── func_login.go │ │ │ ├── func_logout.go │ │ │ ├── func_refreshtoken.go │ │ │ ├── func_removeuser.go │ │ │ ├── func_resetpassword.go │ │ │ ├── func_updateselfinfo.go │ │ │ ├── func_updateuseremail.go │ │ │ ├── func_updateuserinfo.go │ │ │ ├── func_updateuserpassword.go │ │ │ ├── func_updateuserphone.go │ │ │ └── handler.go │ ├── code │ │ ├── README.md │ │ ├── code.go │ │ ├── en.go │ │ └── zh-cn.go │ ├── core │ │ ├── context.go │ │ ├── context_key.go │ │ ├── core.go │ │ ├── error.go │ │ └── static_ctx.go │ ├── logger │ │ ├── gorm_logger.go │ │ ├── logger.go │ │ └── timeutil.go │ ├── middleware │ │ ├── auth_middleware.go │ │ ├── middleware.go │ │ └── permission_middleware.go │ ├── model │ │ ├── alert_event.go │ │ ├── alert_event_tags.go │ │ ├── alert_status.go │ │ ├── amconfig │ │ │ ├── config.go │ │ │ ├── doc.go │ │ │ ├── httpconfig │ │ │ │ ├── config.go │ │ │ │ ├── headers.go │ │ │ │ └── http_config.go │ │ │ ├── notifiers.go │ │ │ ├── scan.go │ │ │ ├── slienceconfig │ │ │ │ └── slience.go │ │ │ ├── types.go │ │ │ └── url.go │ │ ├── anormal_event.go │ │ ├── config_table.go │ │ ├── constants.go │ │ ├── flame_graph.go │ │ ├── flame_graph_test.go │ │ ├── integration │ │ │ ├── alert │ │ │ │ ├── alert.go │ │ │ │ ├── alert_enrich.go │ │ │ │ ├── alert_event.go │ │ │ │ ├── alert_event_filter.go │ │ │ │ ├── alert_event_processed.go │ │ │ │ ├── alert_event_tags.go │ │ │ │ ├── alert_source.go │ │ │ │ ├── constants.go │ │ │ │ ├── errors.go │ │ │ │ ├── req.go │ │ │ │ ├── resp.go │ │ │ │ ├── severity.go │ │ │ │ ├── status.go │ │ │ │ └── target_tag.go │ │ │ ├── cluster.go │ │ │ ├── config2json.go │ │ │ ├── integration_config.go │ │ │ ├── req.go │ │ │ └── resp.go │ │ ├── middleware_instance.go │ │ ├── minheap.go │ │ ├── model.go │ │ ├── profile │ │ │ ├── feature.go │ │ │ ├── role.go │ │ │ ├── team.go │ │ │ └── user.go │ │ ├── related_instance.go │ │ ├── request │ │ │ ├── alert_event.go │ │ │ ├── alert_input.go │ │ │ ├── alert_slience.go │ │ │ ├── config_req.go │ │ │ ├── data_req.go │ │ │ ├── k8s_req.go │ │ │ ├── log_info.go │ │ │ ├── log_other.go │ │ │ ├── log_parse.go │ │ │ ├── log_query.go │ │ │ ├── log_req.go │ │ │ ├── log_table.go │ │ │ ├── network.go │ │ │ ├── role_req.go │ │ │ ├── service_req.go │ │ │ ├── span_trace.go │ │ │ ├── sql_metric.go │ │ │ ├── team_req.go │ │ │ ├── trace_req.go │ │ │ └── user_req.go │ │ ├── response │ │ │ ├── alert_event.go │ │ │ ├── alert_input.go │ │ │ ├── alert_slience.go │ │ │ ├── config_resp.go │ │ │ ├── data_resp.go │ │ │ ├── k8s_resp.go │ │ │ ├── log_chart.go │ │ │ ├── log_index.go │ │ │ ├── log_info.go │ │ │ ├── log_other.go │ │ │ ├── log_parse.go │ │ │ ├── log_query.go │ │ │ ├── log_resp.go │ │ │ ├── log_table.go │ │ │ ├── network.go │ │ │ ├── service_resp.go │ │ │ ├── span_trace.go │ │ │ ├── sql_metric.go │ │ │ ├── team_resp.go │ │ │ ├── trace_resp.go │ │ │ └── user_resp.go │ │ ├── service_instance.go │ │ ├── topology.go │ │ ├── user.go │ │ └── workflow_records.go │ ├── receiver │ │ ├── dingtalk │ │ │ ├── notification │ │ │ │ └── default.tmpl │ │ │ ├── notifier.go │ │ │ └── notifier_test.go │ │ ├── handle_record.go │ │ ├── receiver.go │ │ ├── receiver_config.go │ │ ├── receiver_test.go │ │ └── slient_config.go │ ├── repository │ │ ├── cache │ │ │ └── cache.go │ │ ├── clickhouse │ │ │ ├── alert_event_filter.go │ │ │ ├── dao.go │ │ │ ├── dao_alert_analyze_relation.go │ │ │ ├── dao_alert_event_detail.go │ │ │ ├── dao_alert_event_with_workflow.go │ │ │ ├── dao_alert_events.go │ │ │ ├── dao_alert_notify.go │ │ │ ├── dao_alert_test.go │ │ │ ├── dao_alerts_with_event_count.go │ │ │ ├── dao_config.go │ │ │ ├── dao_error_propagation.go │ │ │ ├── dao_flame_graph.go │ │ │ ├── dao_k8s_event.go │ │ │ ├── dao_k8s_event_test.go │ │ │ ├── dao_log_chart.go │ │ │ ├── dao_log_index.go │ │ │ ├── dao_log_table.go │ │ │ ├── dao_network_span_segments.go │ │ │ ├── dao_other_log_table.go │ │ │ ├── dao_profilling_event.go │ │ │ ├── dao_query_all_log.go │ │ │ ├── dao_query_app_logs.go │ │ │ ├── dao_query_log_context.go │ │ │ ├── dao_query_rows.go │ │ │ ├── dao_service_k8s_events.go │ │ │ ├── dao_service_relationship.go │ │ │ ├── dao_span_trace.go │ │ │ ├── dao_test.go │ │ │ ├── dao_workflow_records.go │ │ │ ├── factory │ │ │ │ ├── buffer.go │ │ │ │ ├── conn.go │ │ │ │ ├── factory.go │ │ │ │ ├── log.go │ │ │ │ ├── null.go │ │ │ │ └── view.go │ │ │ ├── integration │ │ │ │ ├── alert.go │ │ │ │ └── input.go │ │ │ ├── sql_builder.go │ │ │ ├── sql_builder_test.go │ │ │ ├── sub_sql_builder.go │ │ │ ├── sub_sql_builder_test.go │ │ │ ├── testdata │ │ │ │ └── config.yml │ │ │ └── wrapped_driver.go │ │ ├── database │ │ │ ├── alert_manager.go │ │ │ ├── dao.go │ │ │ ├── dao_api.go │ │ │ ├── dao_auth_data_group.go │ │ │ ├── dao_data_group.go │ │ │ ├── dao_feature.go │ │ │ ├── dao_i18n.go │ │ │ ├── dao_insert_page.go │ │ │ ├── dao_logtableinfo.go │ │ │ ├── dao_menu.go │ │ │ ├── dao_othertableinfo.go │ │ │ ├── dao_permission.go │ │ │ ├── dao_quick_alert_rule_metric.go │ │ │ ├── dao_receiver.go │ │ │ ├── dao_role.go │ │ │ ├── dao_router.go │ │ │ ├── dao_team.go │ │ │ ├── dao_threshold.go │ │ │ ├── dao_user.go │ │ │ ├── driver │ │ │ │ ├── db.go │ │ │ │ ├── db_ensure_exist.go │ │ │ │ ├── db_initsql.go │ │ │ │ ├── db_mysql.go │ │ │ │ ├── db_postgres.go │ │ │ │ └── db_sqllite.go │ │ │ ├── init_api.go │ │ │ ├── init_feature.go │ │ │ ├── init_feature_mapping.go │ │ │ ├── init_i18n.go │ │ │ ├── init_insert_page.go │ │ │ ├── init_menu_item.go │ │ │ ├── init_permission.go │ │ │ ├── init_role.go │ │ │ ├── init_router.go │ │ │ ├── init_router_page.go │ │ │ ├── integration │ │ │ │ ├── alert │ │ │ │ │ ├── dao.go │ │ │ │ │ ├── dao_list_alert_target_tags.go │ │ │ │ │ ├── dao_load_alert_enrich_rule.go │ │ │ │ │ ├── dao_manage_alert_source.go │ │ │ │ │ ├── dao_manage_enrich_conditions.go │ │ │ │ │ ├── dao_manage_enrich_rule.go │ │ │ │ │ ├── dao_manage_enrich_schema_target.go │ │ │ │ │ ├── dao_manage_schema.go │ │ │ │ │ ├── dao_search_schema_target.go │ │ │ │ │ └── dao_slient.go │ │ │ │ ├── dao.go │ │ │ │ ├── dao_integration_config.go │ │ │ │ └── dao_manage_cluster.go │ │ │ ├── migrate_receiver.go │ │ │ ├── transaction.go │ │ │ ├── transaction_test.go │ │ │ └── validation_test.go │ │ ├── dify │ │ │ ├── async_alert_check.go │ │ │ ├── async_workflow.go │ │ │ ├── client.go │ │ │ ├── dao.go │ │ │ ├── dao_test.go │ │ │ ├── handle.go │ │ │ ├── user.go │ │ │ ├── workflow_req.go │ │ │ └── workflow_worker.go │ │ ├── jaeger │ │ │ ├── dao.go │ │ │ └── trace.go │ │ ├── kubernetes │ │ │ ├── alert_rules.go │ │ │ ├── dao.go │ │ │ ├── dao_alert_manager_config.go │ │ │ ├── dao_alert_rule.go │ │ │ ├── dao_alert_rule_test.go │ │ │ ├── dao_namespace.go │ │ │ ├── dao_pod.go │ │ │ ├── dao_vector_config.go │ │ │ ├── k8s_api.go │ │ │ ├── metadata.go │ │ │ └── utils.go │ │ ├── polarisanalyzer │ │ │ ├── dao.go │ │ │ ├── dao_polaris_infer.go │ │ │ └── dao_relevance.go │ │ └── prometheus │ │ │ ├── agg_pqls_with_filter.go │ │ │ ├── dao.go │ │ │ ├── dao_agg_metrics_with_filter.go │ │ │ ├── dao_db_duration_bucket.go │ │ │ ├── dao_db_instances.go │ │ │ ├── dao_external_duration_bucket.go │ │ │ ├── dao_labels.go │ │ │ ├── dao_logparser_level_count.go │ │ │ ├── dao_mq_duration_bucket.go │ │ │ ├── dao_namespace_list.go │ │ │ ├── dao_query.go │ │ │ ├── dao_range_agg_metrics_with_filter.go │ │ │ ├── dao_span_trace_duration_bucket.go │ │ │ ├── dao_span_trace_duration_count.go │ │ │ ├── dao_test.go │ │ │ ├── end_point_metrics.go │ │ │ ├── endpoints_map.go │ │ │ ├── helper.go │ │ │ ├── instance_metrics.go │ │ │ ├── metric_keys.go │ │ │ ├── metric_map.go │ │ │ ├── p9x_builder.go │ │ │ ├── p9x_builder_test.go │ │ │ ├── process_starttime.go │ │ │ ├── query.go │ │ │ ├── red_metric_groups.go │ │ │ └── wrapped_api.go │ ├── router │ │ ├── extra_router.go │ │ ├── router.go │ │ └── router_api.go │ ├── services │ │ ├── alerts │ │ │ ├── alertmanager.go │ │ │ ├── alertmanager_test.go │ │ │ ├── inputs_alertmanager.go │ │ │ ├── notification │ │ │ │ ├── assets.go │ │ │ │ ├── default.tmpl │ │ │ │ ├── funcs.go │ │ │ │ ├── notification.go │ │ │ │ └── template.go │ │ │ ├── service.go │ │ │ ├── service_add_alert_rule.go │ │ │ ├── service_alert_event_classify.go │ │ │ ├── service_alert_event_detail.go │ │ │ ├── service_alert_event_list.go │ │ │ ├── service_alert_slient_config.go │ │ │ ├── service_amconfig_receiver.go │ │ │ ├── service_check_alert_rule.go │ │ │ ├── service_forward_to_dingtalk.go │ │ │ ├── service_get_alert_rule.go │ │ │ ├── service_get_group_list.go │ │ │ ├── service_get_metric_pql.go │ │ │ └── service_update_alert_rule.go │ │ ├── config │ │ │ ├── service.go │ │ │ ├── service_getttl.go │ │ │ └── service_setttl.go │ │ ├── data │ │ │ ├── datasource_permission_test.go │ │ │ ├── service.go │ │ │ ├── service_check_datasource_permission.go │ │ │ ├── service_data_group.go │ │ │ ├── service_data_group_operation.go │ │ │ ├── service_datasource.go │ │ │ ├── service_get_group_subs.go │ │ │ ├── service_get_subject_data_group.go │ │ │ └── service_group_subs_operation.go │ │ ├── integration │ │ │ ├── alert │ │ │ │ ├── decoder │ │ │ │ │ ├── decoder.go │ │ │ │ │ ├── json_decoder.go │ │ │ │ │ ├── json_decoder_test.go │ │ │ │ │ ├── prom_decoder.go │ │ │ │ │ └── zabbix_decoder.go │ │ │ │ ├── dispatch.go │ │ │ │ ├── enrich │ │ │ │ │ ├── enrich.go │ │ │ │ │ └── tag_enricher.go │ │ │ │ ├── service.go │ │ │ │ ├── service_alert_source.go │ │ │ │ ├── service_clusters.go │ │ │ │ ├── service_create_alert_source.go │ │ │ │ ├── service_default_alert_source.go │ │ │ │ ├── service_get_alert_enrich_rule.go │ │ │ │ ├── service_get_alert_enrich_rule_tags.go │ │ │ │ ├── service_process_alert_events.go │ │ │ │ ├── service_schema.go │ │ │ │ └── service_update_alert_enrich_rule.go │ │ │ ├── service.go │ │ │ ├── service_clusters.go │ │ │ ├── service_create_cluster.go │ │ │ ├── service_get_cluster_integration.go │ │ │ ├── service_integration_config.go │ │ │ ├── service_integration_doc.go │ │ │ ├── service_static_integration.go │ │ │ ├── service_trigger_adapter_update.go │ │ │ └── service_update_cluster_integration.go │ │ ├── k8s │ │ │ ├── service.go │ │ │ ├── service_get_namespace.go │ │ │ └── servie_get_pod.go │ │ ├── log │ │ │ ├── service.go │ │ │ ├── service_add_log_parse_rule.go │ │ │ ├── service_add_other_table.go │ │ │ ├── service_delete_log_parse_rule.go │ │ │ ├── service_delete_other_table.go │ │ │ ├── service_get_fault_log_contents.go │ │ │ ├── service_get_fault_log_page_list.go │ │ │ ├── service_get_log_chart.go │ │ │ ├── service_get_log_parse_rule.go │ │ │ ├── service_get_log_table_info.go │ │ │ ├── service_get_service_route.go │ │ │ ├── service_log_index.go │ │ │ ├── service_log_table.go │ │ │ ├── service_other_log.go │ │ │ ├── service_other_log_info.go │ │ │ ├── service_query_log.go │ │ │ ├── service_query_log_context.go │ │ │ ├── service_update_log_parse_rule.go │ │ │ └── vector │ │ │ │ └── factory.go │ │ ├── metric │ │ │ ├── model.go │ │ │ ├── query_dict.go │ │ │ ├── service.go │ │ │ └── service_predefined_metrics.go │ │ ├── network │ │ │ ├── service.go │ │ │ ├── service_get_pod_map.go │ │ │ └── service_get_segments_network.go │ │ ├── permission │ │ │ ├── check_router_test.go │ │ │ ├── service.go │ │ │ ├── service_check_api_permission.go │ │ │ ├── service_check_router.go │ │ │ ├── service_configure_menu.go │ │ │ ├── service_get_user_permission.go │ │ │ ├── service_permission.go │ │ │ └── service_user_configs.go │ │ ├── role │ │ │ ├── service.go │ │ │ ├── service_create_role.go │ │ │ ├── service_delete_role.go │ │ │ ├── service_update_role.go │ │ │ └── service_user_role.go │ │ ├── service │ │ │ ├── service.go │ │ │ ├── service_count_k8s_events.go │ │ │ ├── service_filldata.go │ │ │ ├── service_get_alert_events.go │ │ │ ├── service_get_descendant_metrics.go │ │ │ ├── service_get_descendant_relevance.go │ │ │ ├── service_get_error_instance.go │ │ │ ├── service_get_errorinstance_logs.go │ │ │ ├── service_get_log_logs.go │ │ │ ├── service_get_log_metrics.go │ │ │ ├── service_get_namespace_list.go │ │ │ ├── service_get_polaris_infer.go │ │ │ ├── service_get_red_charts.go │ │ │ ├── service_get_service_endpoint_list.go │ │ │ ├── service_get_service_endpoint_relation.go │ │ │ ├── service_get_service_endpoint_topology.go │ │ │ ├── service_get_service_entry_endpoints.go │ │ │ ├── service_get_service_instance_list.go │ │ │ ├── service_get_service_instance_options.go │ │ │ ├── service_get_service_list.go │ │ │ ├── service_get_sql_metrics.go │ │ │ ├── service_get_trace_logs.go │ │ │ ├── service_get_trace_metrics.go │ │ │ └── service_instance_new.go │ │ ├── serviceoverview │ │ │ ├── const_data.go │ │ │ ├── escape_test.go │ │ │ ├── log_filldata.go │ │ │ ├── model_dao.go │ │ │ ├── service.go │ │ │ ├── service_alert.go │ │ │ ├── service_filldata.go │ │ │ ├── service_get_endpoints_data.go │ │ │ ├── service_get_endpoints_data_with_chart.go │ │ │ ├── service_get_entry_data.go │ │ │ ├── service_get_monitor_status.go │ │ │ ├── service_get_threshold.go │ │ │ ├── service_moreurl.go │ │ │ ├── service_ryg_light.go │ │ │ ├── service_set_threshold.go │ │ │ └── sortrule.go │ │ ├── team │ │ │ ├── service.go │ │ │ ├── service_create_team.go │ │ │ ├── service_delete_team.go │ │ │ ├── service_get_team.go │ │ │ ├── service_get_team_user.go │ │ │ ├── service_team_opreation.go │ │ │ ├── service_team_user_operation.go │ │ │ └── service_update_team.go │ │ ├── trace │ │ │ ├── check_util_test.go │ │ │ ├── service.go │ │ │ ├── service_get_flame_data.go │ │ │ ├── service_get_on_off_cpu.go │ │ │ ├── service_get_process_flame_data.go │ │ │ ├── service_get_single_trace_info.go │ │ │ ├── service_get_trace_filter_values.go │ │ │ ├── service_get_trace_filters.go │ │ │ └── service_get_trace_page_list.go │ │ ├── user │ │ │ ├── service.go │ │ │ ├── service_create_user.go │ │ │ ├── service_get_user_info.go │ │ │ ├── service_get_user_team.go │ │ │ ├── service_login.go │ │ │ ├── service_logout.go │ │ │ ├── service_refresh_token.go │ │ │ ├── service_remove_user.go │ │ │ └── service_update_info.go │ │ └── utils │ │ │ └── filter.go │ └── util │ │ ├── array.go │ │ ├── id_generator.go │ │ ├── id_generator_test.go │ │ ├── jwt │ │ └── jwt.go │ │ ├── shutdown.go │ │ ├── sql_validator_test.go │ │ ├── validate.go │ │ ├── validate_sql.go │ │ ├── wrap_funcs.go │ │ └── zap2slog.go ├── sqlscripts │ ├── api.yml │ ├── feature_api.yml │ ├── i18n.yml │ ├── quick_alert_rule_metric.sql │ ├── target_tags.sql │ └── upgrade │ │ ├── quick_alert_rule_metric │ │ └── 1.5.0-upgrade.sql │ │ └── target_tags │ │ ├── 1.5.0-upgrade.sql │ │ └── 1.5.1-upgrade.sql └── static │ ├── integration-tmpl │ ├── dockercompose │ │ ├── install.md.tmpl │ │ └── installCfg.sh.tmpl │ └── kubernetes │ │ ├── apo-one-agent-values.yaml.tmpl │ │ └── install.md.tmpl │ └── predefined-metrics │ ├── default │ ├── ClusterOverview.json │ ├── Infrastructure.json │ ├── Node-Exporter-Full.json │ ├── Originx-Polaris-Metrics-Thread.json │ ├── Originx-Polaris-Metrics.json │ └── Service-MiddleWare-Metrics.json │ └── middleware-dashboard │ ├── es.json │ ├── kafka.json │ ├── mysql-temp-zh-cn.json │ ├── rabbitmq-exporter.json │ ├── rabbitmq-official.json │ └── redis.json ├── docs └── img │ ├── alert-events.png │ ├── apo-select-tools.png │ ├── charts-verifiability.png │ ├── data-plane.png │ ├── service-detail.png │ ├── service-map.png │ └── workflows-list.png ├── frontend ├── .browserslistrc ├── .editorconfig ├── .env ├── .gitattributes ├── .gitignore ├── .prettierignore ├── .prettierrc.js ├── Dockerfile ├── README.md ├── apo-front-deploy.yml ├── eslint.config.js ├── grafana-deploy.yaml ├── index.html ├── nginx.conf ├── package.json ├── postcss.config.js ├── public │ ├── bg.jpg │ ├── config.js │ ├── favicon.ico │ ├── locales │ │ ├── en │ │ │ ├── common.json │ │ │ ├── core │ │ │ │ ├── CustomSelect.json │ │ │ │ ├── DateTime.json │ │ │ │ ├── alertsIntegration.json │ │ │ │ ├── customSelect.json │ │ │ │ ├── dataGroup.json │ │ │ │ ├── dataIntegration.json │ │ │ │ ├── dateTime.json │ │ │ │ ├── empty.json │ │ │ │ ├── login.json │ │ │ │ ├── mask.json │ │ │ │ ├── menuManage.json │ │ │ │ ├── permission.json │ │ │ │ ├── polarisMetrics.json │ │ │ │ ├── roleManage.json │ │ │ │ ├── routes.json │ │ │ │ ├── systemConfiguration.json │ │ │ │ ├── table.json │ │ │ │ ├── team.json │ │ │ │ ├── userManage.json │ │ │ │ ├── userPage.json │ │ │ │ └── userToolBox.json │ │ │ └── oss │ │ │ │ ├── alert.json │ │ │ │ ├── alertEvents.json │ │ │ │ ├── config.json │ │ │ │ ├── faultSiteLogs.json │ │ │ │ ├── fullLogs.json │ │ │ │ ├── middleware.json │ │ │ │ ├── service.json │ │ │ │ ├── serviceInfo.json │ │ │ │ ├── trace.json │ │ │ │ └── workflow.json │ │ └── zh │ │ │ ├── common.json │ │ │ ├── core │ │ │ ├── alertsIntegration.json │ │ │ ├── customSelect.json │ │ │ ├── dataGroup.json │ │ │ ├── dataIntegration.json │ │ │ ├── dateTime.json │ │ │ ├── empty.json │ │ │ ├── login.json │ │ │ ├── mask.json │ │ │ ├── menuManage.json │ │ │ ├── permission.json │ │ │ ├── polarisMetrics.json │ │ │ ├── roleManage.json │ │ │ ├── routes.json │ │ │ ├── systemConfiguration.json │ │ │ ├── table.json │ │ │ ├── team.json │ │ │ ├── userManage.json │ │ │ ├── userPage.json │ │ │ └── userToolBox.json │ │ │ └── oss │ │ │ ├── alert.json │ │ │ ├── alertEvents.json │ │ │ ├── config.json │ │ │ ├── faultSiteLogs.json │ │ │ ├── fullLogs.json │ │ │ ├── middleware.json │ │ │ ├── service.json │ │ │ ├── serviceInfo.json │ │ │ ├── trace.json │ │ │ └── workflow.json │ ├── logo.svg │ ├── manifest.json │ └── mini_logo.png ├── src │ ├── App.js │ ├── _nav.js │ ├── constants.js │ ├── core │ │ ├── api │ │ │ ├── alertInput.ts │ │ │ ├── alerts.js │ │ │ ├── config.js │ │ │ ├── dataGroup.ts │ │ │ ├── integration.tsx │ │ │ ├── logs.js │ │ │ ├── permission.js │ │ │ ├── role.ts │ │ │ ├── service.js │ │ │ ├── serviceInfo.js │ │ │ ├── team.ts │ │ │ ├── trace.js │ │ │ ├── user.js │ │ │ └── workflows.ts │ │ ├── assets │ │ │ ├── alertsIntegration │ │ │ │ └── zabbix │ │ │ │ │ ├── image-1.png │ │ │ │ │ ├── image-2.png │ │ │ │ │ ├── image-3.png │ │ │ │ │ ├── image-4.png │ │ │ │ │ ├── image-5.png │ │ │ │ │ └── image-6.png │ │ │ ├── brand │ │ │ │ ├── bg-light.png │ │ │ │ ├── bg.jpg │ │ │ │ ├── logo.js │ │ │ │ ├── logo.svg │ │ │ │ └── sygnet.js │ │ │ ├── dataCollector │ │ │ │ ├── aliyun.svg │ │ │ │ ├── clickhouse.svg │ │ │ │ ├── cloudEvent.svg │ │ │ │ ├── elastic.svg │ │ │ │ ├── huawei.svg │ │ │ │ ├── kafka.svg │ │ │ │ ├── loki.svg │ │ │ │ ├── opentelemetry.svg │ │ │ │ ├── other.svg │ │ │ │ ├── pinpoint.png │ │ │ │ ├── prometheus.svg │ │ │ │ ├── setting.svg │ │ │ │ ├── skywalking.svg │ │ │ │ ├── tcop.svg │ │ │ │ ├── tianyiyun.svg │ │ │ │ ├── tingyun.svg │ │ │ │ ├── victoriametrics.svg │ │ │ │ └── zabbix.svg │ │ │ ├── errorPage.svg │ │ │ ├── icons │ │ │ │ └── thumbsUp.svg │ │ │ ├── images │ │ │ │ ├── angular.jpg │ │ │ │ ├── avatars │ │ │ │ │ ├── 1.jpg │ │ │ │ │ ├── 2.jpg │ │ │ │ │ ├── 3.jpg │ │ │ │ │ ├── 4.jpg │ │ │ │ │ ├── 5.jpg │ │ │ │ │ ├── 6.jpg │ │ │ │ │ ├── 7.jpg │ │ │ │ │ ├── 8.jpg │ │ │ │ │ └── 9.jpg │ │ │ │ ├── commingSoon.svg │ │ │ │ ├── empty.svg │ │ │ │ ├── filter.svg │ │ │ │ ├── flameGraph.png │ │ │ │ ├── hexagon-red.svg │ │ │ │ ├── k8s.png │ │ │ │ ├── logo.svg │ │ │ │ ├── node │ │ │ │ │ ├── hexagon-green.svg │ │ │ │ │ ├── hexagon-grey.svg │ │ │ │ │ └── hexagon-red.svg │ │ │ │ ├── polaris.png │ │ │ │ ├── react.jpg │ │ │ │ ├── tooltip3.png │ │ │ │ ├── unknown.png │ │ │ │ └── vue.jpg │ │ │ └── snapshot │ │ │ │ ├── dark │ │ │ │ ├── en │ │ │ │ │ ├── alert.png │ │ │ │ │ ├── cpu.png │ │ │ │ │ ├── dashboard.png │ │ │ │ │ ├── entry.png │ │ │ │ │ ├── exception.png │ │ │ │ │ ├── instance.png │ │ │ │ │ ├── k8s.png │ │ │ │ │ ├── logs.png │ │ │ │ │ ├── polaris.png │ │ │ │ │ └── trace.png │ │ │ │ └── zh │ │ │ │ │ ├── alert.png │ │ │ │ │ ├── cpu.png │ │ │ │ │ ├── dashboard.png │ │ │ │ │ ├── entry.png │ │ │ │ │ ├── exception.png │ │ │ │ │ ├── instance.png │ │ │ │ │ ├── k8s.png │ │ │ │ │ ├── logs.png │ │ │ │ │ ├── polaris.png │ │ │ │ │ └── trace.png │ │ │ │ └── light │ │ │ │ ├── en │ │ │ │ ├── alert.png │ │ │ │ ├── cpu.png │ │ │ │ ├── dashboard.png │ │ │ │ ├── entry.png │ │ │ │ ├── exception.png │ │ │ │ ├── instance.png │ │ │ │ ├── k8s.png │ │ │ │ ├── logs.png │ │ │ │ ├── polaris.png │ │ │ │ └── trace.png │ │ │ │ └── zh │ │ │ │ ├── alert.png │ │ │ │ ├── cpu.png │ │ │ │ ├── dashboard.png │ │ │ │ ├── entry.png │ │ │ │ ├── exception.png │ │ │ │ ├── instance.png │ │ │ │ ├── k8s.png │ │ │ │ ├── logs.png │ │ │ │ ├── polaris.png │ │ │ │ └── trace.png │ │ ├── components │ │ │ ├── AppBreadcrumb.js │ │ │ ├── AppContent.js │ │ │ ├── AppFooter.js │ │ │ ├── AppHeader.js │ │ │ ├── AppSidebar.js │ │ │ ├── AppSidebarNav.js │ │ │ ├── AuthRouter.tsx │ │ │ ├── Card │ │ │ │ ├── BasicCard.tsx │ │ │ │ └── CardSlots.tsx │ │ │ ├── Chart │ │ │ │ ├── BarChart.jsx │ │ │ │ ├── ChartTempCell.tsx │ │ │ │ ├── DelayLineChart.jsx │ │ │ │ └── LineAreaChart.jsx │ │ │ ├── CopyButton.jsx │ │ │ ├── CopyPre.tsx │ │ │ ├── Dashboard │ │ │ │ └── IframeDashboard.jsx │ │ │ ├── DataGroupTabs │ │ │ │ └── index.tsx │ │ │ ├── DateTime │ │ │ │ ├── DateTimeCombine.jsx │ │ │ │ ├── DateTimeRangePicker.jsx │ │ │ │ ├── DateTimeRangePickerCom.jsx │ │ │ │ ├── RefreshDateTime.jsx │ │ │ │ ├── TimeSinceRefresh.jsx │ │ │ │ └── index.css │ │ │ ├── DocsCallout.js │ │ │ ├── DocsExample.js │ │ │ ├── DocsLink.js │ │ │ ├── Editor │ │ │ │ └── MonacoEditor.jsx │ │ │ ├── Empty │ │ │ │ └── Empty.jsx │ │ │ ├── ErrorBoundary.jsx │ │ │ ├── ErrorInstance │ │ │ │ ├── ErrorCell.jsx │ │ │ │ └── ErrorChain.jsx │ │ │ ├── FallbackPage.tsx │ │ │ ├── Filter │ │ │ │ ├── FilterSelector.jsx │ │ │ │ └── TableFilter.jsx │ │ │ ├── HighlightCode │ │ │ │ └── HighlightCode.tsx │ │ │ ├── LanguageSwitcher.jsx │ │ │ ├── Mask │ │ │ │ └── CoachMask.jsx │ │ │ ├── Modal │ │ │ │ ├── CommonModal.tsx │ │ │ │ └── FormModal.tsx │ │ │ ├── Pagination │ │ │ │ ├── CustomPagination.jsx │ │ │ │ └── index.css │ │ │ ├── PermissionAuthorize │ │ │ │ ├── DaraGroupPermission.tsx │ │ │ │ ├── DataGroupAuthorizeModal.tsx │ │ │ │ └── index.module.scss │ │ │ ├── PermissionTree │ │ │ │ └── index.tsx │ │ │ ├── PolarisMetrics │ │ │ │ └── GlossaryTable.jsx │ │ │ ├── ReactFlow │ │ │ │ ├── ArrowEdges.jsx │ │ │ │ ├── LoopEdges.jsx │ │ │ │ ├── MoreNode.jsx │ │ │ │ ├── ServiceNode.jsx │ │ │ │ ├── Topology.jsx │ │ │ │ └── index.css │ │ │ ├── Select │ │ │ │ ├── CustomSelect.jsx │ │ │ │ └── index.js │ │ │ ├── Spinner.jsx │ │ │ ├── StatusInfo.jsx │ │ │ ├── Table │ │ │ │ ├── NestedTd.jsx │ │ │ │ ├── TempCell.jsx │ │ │ │ ├── basicPagination.jsx │ │ │ │ ├── basicTable.jsx │ │ │ │ ├── index.css │ │ │ │ ├── tableBody.jsx │ │ │ │ └── tableRow.jsx │ │ │ ├── Tag │ │ │ │ ├── BorderTag.jsx │ │ │ │ └── Tag.jsx │ │ │ ├── ThemeSwitcher.tsx │ │ │ ├── TimeLine │ │ │ │ ├── index.css │ │ │ │ └── index.jsx │ │ │ ├── Toast │ │ │ │ └── ToastContext.js │ │ │ ├── UserToolBox.jsx │ │ │ ├── header │ │ │ │ ├── AppHeaderDropdown.js │ │ │ │ └── index.js │ │ │ └── index.js │ │ ├── contexts │ │ │ ├── AlertIntegrationContext.tsx │ │ │ ├── ChartsContext.tsx │ │ │ ├── LogsContext.js │ │ │ ├── MessageContext.js │ │ │ ├── PropsContext.js │ │ │ └── UserContext.js │ │ ├── hooks │ │ │ └── useApiParams.ts │ │ ├── layout │ │ │ ├── DefaultLayout.js │ │ │ └── index.css │ │ ├── scss │ │ │ ├── _custom.scss │ │ │ ├── _theme.scss │ │ │ ├── _variables.scss │ │ │ ├── examples.scss │ │ │ ├── style.scss │ │ │ ├── theme │ │ │ │ ├── dark.scss │ │ │ │ ├── index.scss │ │ │ │ └── light.scss │ │ │ └── vendors │ │ │ │ └── simplebar.scss │ │ ├── store │ │ │ ├── persist │ │ │ │ ├── groupLabelPresistConfig.js │ │ │ │ ├── logsPresistConfig.js │ │ │ │ ├── settingPresistConfig.js │ │ │ │ ├── timeRangePersistConfig.js │ │ │ │ ├── topologyPresistConfig.js │ │ │ │ ├── urlParamsPresistConfig.js │ │ │ │ └── userPresistConfig.js │ │ │ ├── reducers │ │ │ │ ├── groupLabelReducer.js │ │ │ │ ├── logsReducer.js │ │ │ │ ├── rootReducer.js │ │ │ │ ├── settingReducer.js │ │ │ │ ├── timeRangeReducer.js │ │ │ │ ├── topologyReducer.js │ │ │ │ ├── urlParamsReducer.js │ │ │ │ └── userReducer.js │ │ │ └── store.js │ │ ├── types │ │ │ ├── alertIntegration.ts │ │ │ ├── common.ts │ │ │ ├── dataGroup.ts │ │ │ ├── role.ts │ │ │ ├── team.ts │ │ │ └── user.ts │ │ ├── utils │ │ │ ├── notify.ts │ │ │ ├── request.js │ │ │ ├── step.js │ │ │ ├── time.js │ │ │ ├── toast.js │ │ │ └── trace.js │ │ └── views │ │ │ ├── DataGroup │ │ │ ├── DataGroupFilter.tsx │ │ │ ├── DatasourceSelector.tsx │ │ │ ├── InfoModal.tsx │ │ │ ├── PermissionModal │ │ │ │ └── index.tsx │ │ │ ├── component │ │ │ │ └── DatasourceTag.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ │ ├── IntegrationCenter │ │ │ ├── AlertsIntegration │ │ │ │ ├── AlertsDatasourceList │ │ │ │ │ └── index.tsx │ │ │ │ ├── AlertsIntegrationTable │ │ │ │ │ └── index.tsx │ │ │ │ ├── ConfigDrawer │ │ │ │ │ ├── BaseInfoContent │ │ │ │ │ │ ├── BaseInfoDescriptions.tsx │ │ │ │ │ │ ├── ClusterSelector.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── SourceTypeInfo │ │ │ │ │ │ ├── JsonInfo.tsx │ │ │ │ │ │ ├── PrometheusInfo.tsx │ │ │ │ │ │ ├── ZabbixInfo.tsx │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── TagContent │ │ │ │ │ │ ├── TagContactRule │ │ │ │ │ │ │ ├── ConditionsFormList.tsx │ │ │ │ │ │ │ ├── SchemaFormList.tsx │ │ │ │ │ │ │ ├── SchemaSource.tsx │ │ │ │ │ │ │ ├── TagRuleFormListCom.tsx │ │ │ │ │ │ │ ├── TagRulePreview.tsx │ │ │ │ │ │ │ ├── TargetTagSelector.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── preview.module.scss │ │ │ │ │ │ │ └── segmented.module.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── index.tsx │ │ │ ├── DataIntegration │ │ │ │ ├── ClusterTable.tsx │ │ │ │ ├── Integration │ │ │ │ │ ├── Document │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── InstallCmd │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── SettingsForm │ │ │ │ │ │ ├── APOCollectorFormItem │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── LogsFormItem │ │ │ │ │ │ │ ├── DbTypeRadio.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── MetricsFormItem │ │ │ │ │ │ │ ├── DsTypeRadio.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── TraceFormItem │ │ │ │ │ │ │ ├── ApmTypeRadio.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── index.module.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ └── index.tsx │ │ │ ├── components │ │ │ │ ├── DatasourceItem.tsx │ │ │ │ ├── DatasourceList.tsx │ │ │ │ └── datasourceList.module.scss │ │ │ ├── constant.tsx │ │ │ └── types.ts │ │ │ ├── Login │ │ │ ├── Login.jsx │ │ │ └── Login.module.css │ │ │ ├── MenuManage │ │ │ ├── index.tsx │ │ │ └── useMenuPermission.ts │ │ │ ├── RoleManage │ │ │ ├── components │ │ │ │ ├── AddRoleModal.tsx │ │ │ │ ├── EditRoleModal.tsx │ │ │ │ ├── PermissionModal.tsx │ │ │ │ └── RoleTable.tsx │ │ │ ├── index.module.css │ │ │ ├── index.tsx │ │ │ └── useRoleManage.ts │ │ │ ├── SystemConfiguration │ │ │ └── index.jsx │ │ │ ├── Team │ │ │ ├── InfoModal │ │ │ │ └── index.tsx │ │ │ └── index.tsx │ │ │ ├── UserManage │ │ │ ├── components │ │ │ │ ├── AddUserModal.tsx │ │ │ │ ├── EditUserModal.tsx │ │ │ │ ├── SearchBar.tsx │ │ │ │ └── UserTable.tsx │ │ │ ├── hooks │ │ │ │ ├── useRoleActions.ts │ │ │ │ └── useUserActions.ts │ │ │ ├── index.module.css │ │ │ └── index.tsx │ │ │ └── UserPage │ │ │ ├── component │ │ │ ├── UpdatePassword.jsx │ │ │ └── UserInfo.jsx │ │ │ └── index.jsx │ ├── i18n.js │ ├── index.css │ ├── index.js │ ├── oss │ │ ├── components │ │ │ ├── Filter │ │ │ │ └── LogsTraceFilter.jsx │ │ │ └── TranslationCom.jsx │ │ ├── contexts │ │ │ └── ServiceInfoContext.tsx │ │ ├── routes.js │ │ └── views │ │ │ ├── alertEvents │ │ │ ├── PieChart.tsx │ │ │ ├── components │ │ │ │ └── AlertInfoCom.tsx │ │ │ ├── detail │ │ │ │ ├── CurrentEventDetail.tsx │ │ │ │ ├── Events.tsx │ │ │ │ ├── SilentAlert.tsx │ │ │ │ └── index.tsx │ │ │ └── index.tsx │ │ │ ├── alerts │ │ │ ├── AlertsNotify.jsx │ │ │ ├── AlertsRule.jsx │ │ │ ├── index.js │ │ │ └── modal │ │ │ │ ├── ALertConditionCom.jsx │ │ │ │ ├── ModifyAlertNotifyModal.jsx │ │ │ │ ├── ModifyAlertRuleModal.jsx │ │ │ │ └── compontents │ │ │ │ ├── DingTalkConfigsFormList.jsx │ │ │ │ ├── EmailConfigsFormList.jsx │ │ │ │ ├── WeChatConfigsFormList.jsx │ │ │ │ ├── WebhookConfigsFormList.jsx │ │ │ │ ├── WebhookConfigsHeaderFormList.jsx │ │ │ │ └── defaultHTMLcontext.js │ │ │ ├── camera │ │ │ ├── component │ │ │ │ └── Topology.jsx │ │ │ └── index.js │ │ │ ├── config │ │ │ ├── configTTL │ │ │ │ ├── ConfigTTL.jsx │ │ │ │ └── TTLTable.jsx │ │ │ └── index.jsx │ │ │ ├── dashboard │ │ │ ├── ApplicationDashboard.jsx │ │ │ ├── BasicDashboard.jsx │ │ │ ├── MiddlewareDashboard.jsx │ │ │ └── SystemDashboard.jsx │ │ │ ├── logs │ │ │ ├── FaultSiteLogs.jsx │ │ │ ├── FullLogsPage.jsx │ │ │ ├── component │ │ │ │ ├── FullLogs │ │ │ │ │ ├── component │ │ │ │ │ │ ├── ConfigLogRuleModal │ │ │ │ │ │ │ ├── component │ │ │ │ │ │ │ │ ├── LogRouteRuleFormList.jsx │ │ │ │ │ │ │ │ ├── LogStructRuleFormList.jsx │ │ │ │ │ │ │ │ └── ParseRuleTabs.jsx │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ ├── ConfigTableModal │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ ├── IndexList │ │ │ │ │ │ │ ├── component │ │ │ │ │ │ │ │ ├── IndexCollapse.jsx │ │ │ │ │ │ │ │ ├── IndexCollapse.module.less │ │ │ │ │ │ │ │ └── IndexCollapseItem.jsx │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ ├── LogQueryResult │ │ │ │ │ │ │ ├── ContextModal │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ ├── Histogram │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ ├── QueryList │ │ │ │ │ │ │ │ ├── LogItem │ │ │ │ │ │ │ │ │ ├── component │ │ │ │ │ │ │ │ │ │ ├── LogItemDetail.jsx │ │ │ │ │ │ │ │ │ │ ├── LogItemFold.jsx │ │ │ │ │ │ │ │ │ │ ├── LogKeyTag.jsx │ │ │ │ │ │ │ │ │ │ ├── LogKeyTagValue.jsx │ │ │ │ │ │ │ │ │ │ ├── LogTagDropdown.jsx │ │ │ │ │ │ │ │ │ │ └── LogValueTag.jsx │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ ├── SerarchBar │ │ │ │ │ │ │ ├── RawLogQuery │ │ │ │ │ │ │ │ ├── CodeMirrorSearch │ │ │ │ │ │ │ │ │ ├── MySQLKeyWord.ts │ │ │ │ │ │ │ │ │ ├── WhereBox │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.less │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── index.less │ │ │ │ │ │ │ │ ├── FullTextSearch │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── index.less │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ └── Sider │ │ │ │ │ │ │ ├── DataSourceTree │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ ├── LogRuleList │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ ├── index.css │ │ │ │ │ └── index.jsx │ │ │ │ └── LogContent.jsx │ │ │ └── index.js │ │ │ ├── pages │ │ │ ├── login │ │ │ │ └── Login.js │ │ │ ├── page404 │ │ │ │ └── Page404.js │ │ │ ├── page500 │ │ │ │ └── Page500.js │ │ │ └── register │ │ │ │ └── Register.js │ │ │ ├── service │ │ │ ├── ServiceTable.jsx │ │ │ ├── component │ │ │ │ ├── EndpointTableModal.jsx │ │ │ │ └── ThresholdConfigModal.jsx │ │ │ ├── index.js │ │ │ └── mock.json │ │ │ ├── serviceInfo │ │ │ ├── component │ │ │ │ ├── dependent │ │ │ │ │ ├── DependentTable.jsx │ │ │ │ │ ├── TimelapseLineChart.jsx │ │ │ │ │ ├── TopologyModal.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── index.module.scss │ │ │ │ ├── infoUni │ │ │ │ │ ├── AlertInfo │ │ │ │ │ │ ├── AlertInfoTable.jsx │ │ │ │ │ │ └── AlertInfoTabs.jsx │ │ │ │ │ ├── EntryImpact.jsx │ │ │ │ │ ├── ErrorInstance │ │ │ │ │ │ └── ErrorInstanceInfo.jsx │ │ │ │ │ ├── HighLightCode.jsx │ │ │ │ │ ├── InstanceInfo.jsx │ │ │ │ │ ├── K8sInfo.jsx │ │ │ │ │ ├── LogsInfo.jsx │ │ │ │ │ ├── MetricsDashboard.jsx │ │ │ │ │ ├── PolarisMetricsInfo │ │ │ │ │ │ └── PolarisMetricsInfo.jsx │ │ │ │ │ ├── SingleLinkTopology.jsx │ │ │ │ │ ├── SqlMetrics.jsx │ │ │ │ │ ├── TimeLine.jsx │ │ │ │ │ ├── TraceInfo.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── timeline.css │ │ │ │ └── mock.js │ │ │ └── index.js │ │ │ ├── trace │ │ │ ├── FaultSiteTrace.jsx │ │ │ ├── FullTrace.jsx │ │ │ ├── TraceMoreFilters.jsx │ │ │ ├── component │ │ │ │ ├── JaegerIframeModal.jsx │ │ │ │ └── TraceErrorType.jsx │ │ │ └── mock.js │ │ │ └── workflows │ │ │ ├── index.tsx │ │ │ └── workflowsIframe.tsx │ └── routes.js ├── tailwind.config.js ├── tsconfig.json └── vite.config.mjs └── one-agent └── README.md /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. MacOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Server (please complete the following information):** 32 | - OS: [e.g. Debian GNU/Linux 12] 33 | - Kernel [e.g. 6.1.0-21-amd64] 34 | - Arch: amd64 35 | 36 | **Additional context** 37 | Add any other context about the problem here. 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Feature]" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/codeql/codeql-actions.yml: -------------------------------------------------------------------------------- 1 | # .github/codeql/codeql-go.yml 2 | name: "CodeQL Go Configuration" 3 | 4 | # Specify paths relevant to Go analysis 5 | paths: 6 | - .github/workflows/ 7 | 8 | # Specify query suites/queries for Go 9 | queries: 10 | - uses: security-extended -------------------------------------------------------------------------------- /.github/codeql/codeql-go.yml: -------------------------------------------------------------------------------- 1 | # .github/codeql/codeql-actions.yml 2 | name: "CodeQL Go Configuration" 3 | 4 | # Specify paths relevant to Go analysis 5 | paths: 6 | - backend/ 7 | 8 | # Specify patterns to ignore for Go analysis (can be Go-specific or general) 9 | paths-ignore: 10 | - '**/*.txt' 11 | - '**/*.json' 12 | - '**/*.md' 13 | - '**/*.yml' 14 | - '**/*.yaml' 15 | # Add other Go-specific ignores if needed 16 | # - 'backend/testdata/' 17 | 18 | # Specify query suites/queries for Go 19 | queries: 20 | - uses: security-extended -------------------------------------------------------------------------------- /.github/codeql/codeql-javascript-typescript.yml: -------------------------------------------------------------------------------- 1 | # .github/codeql/codeql-javascript-typescript.yml 2 | name: "CodeQL Javascript/Typescript Configuration" 3 | 4 | # Specify paths relevant to JS/TS analysis 5 | paths: 6 | - frontend/ 7 | 8 | # Specify patterns to ignore for JS/TS analysis (can be JS/TS-specific or general) 9 | paths-ignore: 10 | - '**/*.txt' 11 | - '**/*.json' 12 | - '**/*.md' 13 | - '**/*.yml' 14 | - '**/*.yaml' 15 | 16 | # Specify query suites/queries for JS/TS 17 | queries: 18 | - uses: security-extended -------------------------------------------------------------------------------- /.github/workflows/apo-ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | schedule: 6 | - cron: "0 18 * * *" # TimeZone: UTC 0 7 | 8 | concurrency: 9 | group: apo-${{ github.event.pull_request.number || github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | check-license-header: 14 | if: (github.event_name == 'schedule' && github.repository == 'CloudDetail/apo') || (github.event_name != 'schedule') 15 | name: Check License header 16 | runs-on: ubuntu-latest 17 | permissions: 18 | contents: read 19 | pull-requests: write 20 | timeout-minutes: 10 21 | steps: 22 | - uses: actions/checkout@v3 23 | with: 24 | submodules: false 25 | - name: Check license header 26 | uses: apache/skywalking-eyes@cd7b195c51fd3d6ad52afceb760719ddc6b3ee91 27 | 28 | 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "one-agent/node-agent"] 2 | path = one-agent/node-agent 3 | url = https://github.com/CloudDetail/node-agent 4 | [submodule "one-agent/preload"] 5 | path = one-agent/preload 6 | url = https://github.com/CloudDetail/preload.git 7 | [submodule "one-agent/ilogtail"] 8 | path = one-agent/ilogtail 9 | url = https://github.com/CloudDetail/ilogtail.git 10 | [submodule "one-agent/odigos"] 11 | path = one-agent/odigos 12 | url = https://github.com/CloudDetail/odigos.git 13 | branch = apo-v1.0.76 14 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | /apo 2 | /handlergen 3 | logs/*.log 4 | .idea 5 | *.exe 6 | database-apo.db 7 | logs/*.log.gz 8 | .DS_Store 9 | backend 10 | -------------------------------------------------------------------------------- /backend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.8-bookworm AS builder 2 | LABEL authors="apo" 3 | WORKDIR /build 4 | 5 | COPY go.mod go.sum ./ 6 | RUN go mod download && go mod verify 7 | 8 | COPY . . 9 | RUN go build -v -o apo-backend 10 | 11 | FROM debian:bookworm-slim AS runner 12 | WORKDIR /app 13 | 14 | RUN apt-get update && \ 15 | apt-get install -y sqlite3 ca-certificates && \ 16 | rm -rf /var/lib/apt/lists/* 17 | COPY config/apo.yml /app/config/apo.yml 18 | COPY --from=builder /build/apo-backend /app/ 19 | COPY pkg/receiver/dingtalk/notification/default.tmpl /app/notification/default.tmpl 20 | COPY sqlscripts /app/sqlscripts 21 | COPY static /app/static 22 | 23 | CMD ["/app/apo-backend"] 24 | -------------------------------------------------------------------------------- /backend/README.md: -------------------------------------------------------------------------------- 1 | # originx-apo-backend 2 | 3 | ## 构建 4 | > go build -v -o apo -------------------------------------------------------------------------------- /backend/config/constant.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package config 5 | 6 | const ( 7 | // Prometheus 8 | PROM_STORAGE_PROM = "prom" 9 | // VictoriaMetrics 10 | PROM_STORAGE_VM = "vm" 11 | 12 | // MySql 13 | DB_MYSQL = "mysql" 14 | // sqllite 15 | DB_SQLLITE = "sqllite" 16 | // postgres 17 | DB_POSTGRES = "postgres" 18 | ) 19 | -------------------------------------------------------------------------------- /backend/config/init.sql: -------------------------------------------------------------------------------- 1 | sqllite3 database-apo.db 2 | 3 | CREATE TABLE IF NOT EXISTS mock ( 4 | id INTEGER PRIMARY KEY AUTOINCREMENT, 5 | name TEXT 6 | ); -------------------------------------------------------------------------------- /backend/pkg/api/alerts/func_getgrouplist.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alerts 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | ) 9 | 10 | // GetGroupList get the corresponding interfaces of group and label 11 | // @Summary get the corresponding interfaces of group and label 12 | // @Description get the corresponding interfaces of group and label 13 | // @Tags API.alerts 14 | // @Accept application/x-www-form-urlencoded 15 | // @Produce json 16 | // @Param Authorization header string false "Bearer accessToken" 17 | // @Success 200 {object} response.GetGroupListResponse 18 | // @Failure 400 {object} code.Failure 19 | // @Router /api/alerts/rule/groups [get] 20 | func (h *handler) GetGroupList() core.HandlerFunc { 21 | return func(c core.Context) { 22 | resp := h.alertService.GetGroupList(c) 23 | c.Payload(resp) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /backend/pkg/api/config/func_getttl.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package config 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/CloudDetail/apo/backend/pkg/code" 10 | "github.com/CloudDetail/apo/backend/pkg/core" 11 | ) 12 | 13 | // GetTTL Get TTL 14 | // @Summary get TTL 15 | // @Description get TTL 16 | // @Tags API.config 17 | // @Accept application/x-www-form-urlencoded 18 | // @Produce json 19 | // @Param Authorization header string false "Bearer accessToken" 20 | // @Success 200 {object} response.GetTTLResponse 21 | // @Failure 400 {object} code.Failure 22 | // @Router /api/config/getTTL [get] 23 | func (h *handler) GetTTL() core.HandlerFunc { 24 | return func(c core.Context) { 25 | resp, err := h.configService.GetTTL(c) 26 | if err != nil { 27 | c.AbortWithError( 28 | http.StatusBadRequest, 29 | code.GetTTLError, 30 | err, 31 | ) 32 | return 33 | } 34 | c.Payload(resp) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backend/pkg/api/data/func_getdatasource.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package data 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/CloudDetail/apo/backend/pkg/code" 10 | "github.com/CloudDetail/apo/backend/pkg/core" 11 | ) 12 | 13 | // GetDatasource Gets all datasource. 14 | // @Summary Gets all datasource. 15 | // @Description Gets all datasource. 16 | // @Tags API.data 17 | // @Accept application/x-www-form-urlencoded 18 | // @Produce json 19 | // @Param Authorization header string false "Bearer accessToken" 20 | // @Success 200 {object} response.GetDatasourceResponse 21 | // @Failure 400 {object} code.Failure 22 | // @Router /api/data/datasource [get] 23 | func (h *handler) GetDatasource() core.HandlerFunc { 24 | return func(c core.Context) { 25 | resp, err := h.dataService.GetDataSource(c) 26 | if err != nil { 27 | c.AbortWithError( 28 | http.StatusBadRequest, 29 | code.GetDatasourceError, 30 | err, 31 | ) 32 | return 33 | } 34 | c.Payload(resp) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backend/pkg/api/health/func_healthcheck.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package health 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | ) 9 | 10 | // HealthCheck for k8s to check backend health status 11 | // @Summary for k8s to check backend health status 12 | // @Description for k8s to check backend health status 13 | // @Tag API.health 14 | // @Accept application/x-www-form-urlencoded 15 | // @Produce json 16 | // @Success 200 {object} string "ok" 17 | // @Failure 400 {object} code.Failure 18 | // @Router /api/health [get] 19 | func (h *handler) HealthCheck() core.HandlerFunc { 20 | return func(c core.Context) { 21 | c.Payload("ok") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /backend/pkg/api/health/handler.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package health 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | ) 9 | 10 | type Handler interface { 11 | // HealthCheck for k8s to check backend health status 12 | // @Tags API.health 13 | // @Router /api/health [get] 14 | HealthCheck() core.HandlerFunc 15 | } 16 | 17 | type handler struct { 18 | } 19 | 20 | func New() Handler { 21 | return &handler{} 22 | } 23 | -------------------------------------------------------------------------------- /backend/pkg/api/integration/func_getstaticintegration.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package integration 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | ) 9 | 10 | // GetStaticIntegration 11 | // @Summary 12 | // @Description 13 | // @Tags API.integration 14 | // @Accept application/x-www-form-urlencoded 15 | // @Produce json 16 | // @Failure 400 {object} code.Failure 17 | // @Router /api/integration/configuration [get] 18 | func (h *handler) GetStaticIntegration() core.HandlerFunc { 19 | return func(c core.Context) { 20 | storeIntegration := h.integrationService.GetStaticIntegration(c) 21 | c.Payload(storeIntegration) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /backend/pkg/api/k8s/func_getnamespacelist.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package k8s 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/CloudDetail/apo/backend/pkg/code" 10 | "github.com/CloudDetail/apo/backend/pkg/core" 11 | ) 12 | 13 | // GetNamespaceList get all namespace information 14 | // @Summary get all namespace information 15 | // @Description get all namespace information 16 | // @Tags API.k8s 17 | // @Accept application/x-www-form-urlencoded 18 | // @Produce json 19 | // @Success 200 {object} string 20 | // @Failure 400 {object} code.Failure 21 | // @Router /api/k8s/namespaces [get] 22 | func (h *handler) GetNamespaceList() core.HandlerFunc { 23 | return func(c core.Context) { 24 | 25 | resp, err := h.k8sService.GetNamespaceList(c) 26 | if err != nil { 27 | c.AbortWithError( 28 | http.StatusBadRequest, 29 | code.K8sGetResourceError, 30 | err, 31 | ) 32 | return 33 | } 34 | c.Payload(resp) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backend/pkg/api/metric/func_listmetrics.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package metric 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | ) 9 | 10 | // ListMetrics 11 | // @Summary 12 | // @Description 13 | // @Tags API.metric 14 | // @Accept application/x-www-form-urlencoded 15 | // @Produce json 16 | // @Success 200 {object} []QueryInfo 17 | // @Failure 400 {object} code.Failure 18 | // @Router /api/metric/list [get] 19 | func (h *handler) ListMetrics() core.HandlerFunc { 20 | return func(c core.Context) { 21 | resp := h.metricService.ListPreDefinedMetrics(c) 22 | c.Payload(resp) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/pkg/api/metric/func_querymetrics.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package metric 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/CloudDetail/apo/backend/pkg/code" 10 | "github.com/CloudDetail/apo/backend/pkg/core" 11 | "github.com/CloudDetail/apo/backend/pkg/services/metric" 12 | ) 13 | 14 | // QueryMetrics 15 | // @Summary 16 | // @Description 17 | // @Tags API.metric 18 | // @Accept application/x-www-form-urlencoded 19 | // @Produce json 20 | // @Success 200 {object} metric.QueryMetricsResult 21 | // @Failure 400 {object} code.Failure 22 | // @Router /api/metric/query [post] 23 | func (h *handler) QueryMetrics() core.HandlerFunc { 24 | return func(c core.Context) { 25 | req := new(metric.QueryMetricsRequest) 26 | if err := c.ShouldBindJSON(req); err != nil { 27 | c.AbortWithError( 28 | http.StatusBadRequest, 29 | code.ParamBindError, 30 | err, 31 | ) 32 | return 33 | } 34 | 35 | resp := h.metricService.QueryMetrics(c, req) 36 | c.Payload(resp) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /backend/pkg/api/metric/handler.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package metric 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/repository/prometheus" 9 | "github.com/CloudDetail/apo/backend/pkg/services/metric" 10 | "go.uber.org/zap" 11 | ) 12 | 13 | type Handler interface { 14 | 15 | // ListMetrics 16 | // @Tags API.metric 17 | // @Router /api/metric/list [get] 18 | ListMetrics() core.HandlerFunc 19 | 20 | // QueryMetrics 21 | // @Tags API.metric 22 | // @Router /api/metric/query [post] 23 | QueryMetrics() core.HandlerFunc 24 | } 25 | 26 | type handler struct { 27 | logger *zap.Logger 28 | metricService metric.Service 29 | } 30 | 31 | func New(logger *zap.Logger, promRepo prometheus.Repo) Handler { 32 | return &handler{ 33 | logger: logger, 34 | metricService: metric.New(promRepo), 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backend/pkg/api/role/func_getrole.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package role 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/CloudDetail/apo/backend/pkg/code" 10 | "github.com/CloudDetail/apo/backend/pkg/core" 11 | ) 12 | 13 | // GetRole Gets all roles. 14 | // @Summary Gets all roles. 15 | // @Description Gets all roles. 16 | // @Tags API.role 17 | // @Accept application/x-www-form-urlencoded 18 | // @Produce json 19 | // @Param Authorization header string true "Bearer accessToken" 20 | // @Success 200 {object} response.GetRoleResponse 21 | // @Failure 400 {object} code.Failure 22 | // @Router /api/role/roles [get] 23 | func (h *handler) GetRole() core.HandlerFunc { 24 | return func(c core.Context) { 25 | 26 | resp, err := h.roleService.GetRoles(c) 27 | if err != nil { 28 | c.AbortWithError( 29 | http.StatusBadRequest, 30 | code.UserGetRolesERROR, 31 | err, 32 | ) 33 | } 34 | c.Payload(resp) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backend/pkg/code/README.md: -------------------------------------------------------------------------------- 1 | # 错误码规则 2 | 3 | - 错误码需在 `code` 包中进行定义。 4 | 5 | ## 系统级错误 6 | 格式 - AXXXX 7 | XXXX - 4位数自增编号 8 | 9 | ## 用户自定义错误 10 | 格式 - BXXYY 11 | XX - 2位数模块ID 12 | YY - 2位数业务ID -------------------------------------------------------------------------------- /backend/pkg/core/context_key.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package core 5 | 6 | const ( 7 | UserIDKey = "_user_id_" 8 | ) 9 | -------------------------------------------------------------------------------- /backend/pkg/core/static_ctx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package core 5 | 6 | import "github.com/gin-gonic/gin" 7 | 8 | func EmptyCtx() Context { 9 | ctx := &context{ctx: &gin.Context{}} 10 | // ctx.Set(UserIDKey, 0) 11 | return ctx 12 | } 13 | -------------------------------------------------------------------------------- /backend/pkg/middleware/permission_middleware.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package middleware 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/CloudDetail/apo/backend/pkg/code" 10 | "github.com/CloudDetail/apo/backend/pkg/core" 11 | ) 12 | 13 | func (m *middleware) PermissionMiddleware() core.HandlerFunc { 14 | return func(c core.Context) { 15 | userID := c.UserID() 16 | if userID == 0 { 17 | c.AbortWithError(http.StatusUnauthorized, code.UnAuth, nil) 18 | return 19 | } 20 | method, path := c.GetMethodPath() 21 | 22 | can, err := m.permissionService.CheckApiPermission(c, userID, method, path) 23 | if err != nil { 24 | c.AbortWithError(http.StatusForbidden, code.AuthError, err) 25 | return 26 | } 27 | 28 | if !can { 29 | c.AbortWithError(http.StatusForbidden, code.UserNoPermissionError, nil) 30 | return 31 | } 32 | 33 | c.Next() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /backend/pkg/model/amconfig/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package amconfig 5 | 6 | // Configuration file for parsing and deleting alertmanager 7 | // Body from github.com/prometheus/alertmanager@v0.27.0/config 8 | 9 | /** 10 | Modified: 11 | -Change SecretURL to URL to avoid losing information in Marshal/Unmarshal 12 | -Modify the JSON tag of all configurations to form a small hump 13 | -Removes the logic of transferring different verification information to the header in the Validate, only checks 14 | -Modify the JSON tag of other alarm methods other than EmailConfigs/WebhookConfigs to hide, and gradually open it later. 15 | **/ 16 | -------------------------------------------------------------------------------- /backend/pkg/model/amconfig/types.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package amconfig 5 | 6 | func HasEmailOrWebhookConfig(r Receiver) bool { 7 | if r.EmailConfigs != nil { 8 | return true 9 | } else if r.WebhookConfigs != nil && len(r.WebhookConfigs) > 0 { 10 | return true 11 | } else if r.WechatConfigs != nil && len(r.WechatConfigs) > 0 { 12 | return true 13 | } 14 | 15 | return false 16 | } 17 | -------------------------------------------------------------------------------- /backend/pkg/model/anormal_event.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package model 5 | 6 | type EndpointKey struct { 7 | ServiceName string `json:"serviceName"` 8 | Endpoint string `json:"endpoint"` 9 | } 10 | -------------------------------------------------------------------------------- /backend/pkg/model/integration/alert/alert_event_filter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alert 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/model" 8 | ) 9 | 10 | type AlertEventFilter struct { 11 | Source string 12 | Group string 13 | Name string 14 | EventID string 15 | Severity string 16 | Status string 17 | WithMutation bool 18 | 19 | *AlertTagsFilter 20 | } 21 | 22 | // TagsFilter using field:tags to filter alert 23 | // Use OR to connect different conditions 24 | type AlertTagsFilter struct { 25 | ServiceEndpoints []model.EndpointKey 26 | model.RelatedInstances 27 | } 28 | -------------------------------------------------------------------------------- /backend/pkg/model/integration/alert/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | package alert 4 | 5 | const ( 6 | JSONType string = "json" 7 | PrometheusType string = "prometheus" 8 | ZabbixType string = "zabbix" 9 | ) 10 | 11 | const ( 12 | StatusFiring = "firing" 13 | StatusResolved = "resolved" 14 | ) 15 | 16 | const ( 17 | SeverityCriticalLevel = "critical" 18 | SeverityErrorLevel = "error" 19 | SeverityWarnLevel = "warning" 20 | SeverityInfoLevel = "info" 21 | SeverityUnknownLevel = "unknown" 22 | ) 23 | 24 | const ( 25 | ZabbixSeverityDisaster = "Disaster" 26 | ZabbixSeverityHigh = "High" 27 | ZabbixSeverityAverage = "Average" 28 | ZabbixSeverityWarning = "Warning" 29 | ZabbixSeverityInfo = "Information" 30 | ZabbixSeverityUnknown = "Not classified" 31 | ) 32 | 33 | const ( 34 | ZabbixStatusOK = "OK" 35 | ZabbixStatusProblem = "PROBLEM" 36 | ) 37 | -------------------------------------------------------------------------------- /backend/pkg/model/integration/alert/status.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alert 5 | 6 | import "strconv" 7 | 8 | func ConvertStatus(sourceType string, status string) string { 9 | switch sourceType { 10 | case PrometheusType: 11 | return status 12 | case ZabbixType: 13 | if code, err := strconv.Atoi(status); err == nil { 14 | switch code { 15 | case 0: 16 | return StatusResolved 17 | case 1: 18 | return StatusFiring 19 | } 20 | } else { 21 | switch status { 22 | case ZabbixStatusOK: 23 | return StatusResolved 24 | case ZabbixStatusProblem: 25 | return StatusFiring 26 | } 27 | } 28 | default: 29 | switch status { 30 | case "resolved": 31 | return StatusResolved 32 | case "firing": 33 | return StatusFiring 34 | default: 35 | return StatusFiring 36 | } 37 | } 38 | 39 | return status 40 | } 41 | -------------------------------------------------------------------------------- /backend/pkg/model/integration/alert/target_tag.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alert 5 | 6 | type TargetTag struct { 7 | ID uint `gorm:"primaryKey;autoIncrement" json:"id"` 8 | TagName string `gorm:"type:varchar(255);column:tag_name" json:"tagName"` 9 | TagNameEN string `gorm:"type:varchar(255);column:tag_name_en" json:"-"` 10 | Describe string `gorm:"type:varchar(255);column:describe" json:"describe"` 11 | DescribeEN string `gorm:"type:varchar(255);column:describe_en" json:"-"` 12 | Field string `gorm:"type:varchar(255);column:field" json:"targetTag"` 13 | } 14 | 15 | func (TargetTag) TableName() string { 16 | return "target_tags" 17 | } 18 | -------------------------------------------------------------------------------- /backend/pkg/model/integration/req.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package integration 5 | 6 | type GetCInstallRequest struct { 7 | ClusterID string `json:"clusterId" form:"clusterId"` 8 | } 9 | 10 | type TriggerAdapterUpdateRequest struct { 11 | LastUpdateTS int64 `form:"lastUpdateTS" json:"lastUpdateTS"` 12 | } 13 | -------------------------------------------------------------------------------- /backend/pkg/model/integration/resp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package integration 5 | 6 | type ListClusterResponse struct { 7 | Clusters []Cluster `json:"clusters"` 8 | } 9 | 10 | type GetCInstallDocResponse struct { 11 | InstallMD []byte `json:"installMd"` 12 | } 13 | 14 | type GetCInstallConfigResponse struct { 15 | FileName string `json:"fileName"` 16 | Content []byte `json:"content"` 17 | } 18 | -------------------------------------------------------------------------------- /backend/pkg/model/middleware_instance.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | package model 4 | 5 | type MiddlewareInstance struct { 6 | DatabaseURL string 7 | DatabaseIP string 8 | DatabasePort string 9 | } 10 | -------------------------------------------------------------------------------- /backend/pkg/model/model.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package model 5 | 6 | type Pagination struct { 7 | Total int64 `json:"total"` // total number of records 8 | CurrentPage int `json:"currentPage"` // current page number 9 | PageSize int `json:"pageSize"` // number of entries per page 10 | } 11 | 12 | type I18nLanguage struct { 13 | Language string `json:"language" form:"language"` // I18n language 14 | } 15 | -------------------------------------------------------------------------------- /backend/pkg/model/profile/feature.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package profile 5 | 6 | type Feature struct { 7 | FeatureID int `gorm:"column:feature_id;primary_key;auto_increment" json:"featureId"` 8 | FeatureName string `gorm:"column:feature_name;type:varchar(20)" json:"featureName"` 9 | ParentID *int `gorm:"column:parent_id" json:"-"` 10 | Custom bool `gorm:"column:custom;default:false" json:"-"` 11 | 12 | Children []Feature `gorm:"-" json:"children,omitempty" swaggerignore:"true"` 13 | Source string `gorm:"-" json:"source,omitempty"` 14 | } 15 | 16 | func (t *Feature) TableName() string { 17 | return "feature" 18 | } 19 | -------------------------------------------------------------------------------- /backend/pkg/model/profile/role.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package profile 5 | 6 | // Role is a collection of feature permission. 7 | type Role struct { 8 | RoleID int `gorm:"column:role_id;primary_key;auto_increment" json:"roleId"` 9 | RoleName string `gorm:"column:role_name;type:varchar(20);uniqueIndex" json:"roleName"` 10 | Description string `gorm:"column:description;type:varchar(50)" json:"description"` 11 | } 12 | 13 | func (t *Role) TableName() string { 14 | return "role" 15 | } 16 | 17 | type UserRole struct { 18 | UserID int64 `gorm:"column:user_id;primary_key"` 19 | RoleID int `gorm:"column:role_id;primary_key"` 20 | } 21 | 22 | func (t *UserRole) TableName() string { 23 | return "user_role" 24 | } 25 | -------------------------------------------------------------------------------- /backend/pkg/model/profile/team.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package profile 5 | 6 | type Team struct { 7 | TeamID int64 `gorm:"column:team_id;primary_key" json:"teamId"` 8 | TeamName string `gorm:"column:team_name;type:varchar(20)" json:"teamName"` 9 | Description string `gorm:"column:description;type:varchar(50)" json:"description"` 10 | 11 | UserList []User `gorm:"-" json:"userList,omitempty"` 12 | FeatureList []Feature `gorm:"-" json:"featureList,omitempty"` 13 | } 14 | 15 | type UserTeam struct { 16 | UserID int64 `gorm:"column:user_id;primary_key"` 17 | TeamID int64 `gorm:"column:team_id;primary_key"` 18 | } 19 | 20 | func (UserTeam) TableName() string { 21 | return "user_team" 22 | } 23 | 24 | func (Team) TableName() string { 25 | return "team" 26 | } 27 | -------------------------------------------------------------------------------- /backend/pkg/model/profile/user.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package profile 5 | 6 | type User struct { 7 | UserID int64 `gorm:"column:user_id;primary_key" json:"userId,omitempty"` 8 | Username string `gorm:"column:username;uniqueIdx;type:varchar(20)" json:"username,omitempty"` 9 | Password string `gorm:"column:password;type:varchar(200)" json:"-"` 10 | Phone string `gorm:"column:phone;type:varchar(20)" json:"phone,omitempty"` 11 | Email string `gorm:"column:email;type:varchar(50)" json:"email,omitempty"` 12 | Corporation string `gorm:"column:corporation;type:varchar(50)" json:"corporation,omitempty"` 13 | 14 | RoleList []Role `gorm:"-" json:"roleList,omitempty"` 15 | TeamList []Team `gorm:"-" json:"teamList,omitempty"` 16 | FeatureList []Feature `gorm:"-" json:"featureList,omitempty"` 17 | } 18 | 19 | func (t *User) TableName() string { 20 | return "user" 21 | } 22 | -------------------------------------------------------------------------------- /backend/pkg/model/related_instance.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | package model 4 | 5 | type RelatedInstances struct { 6 | SIs []*ServiceInstance 7 | MIs []MiddlewareInstance 8 | } 9 | -------------------------------------------------------------------------------- /backend/pkg/model/request/alert_slience.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package request 5 | 6 | type RemoveAlertSlienceConfigRequest struct { 7 | AlertID string `json:"alertId" form:"alertId"` 8 | } 9 | 10 | type GetAlertSlienceConfigRequest struct { 11 | AlertID string `json:"alertId" form:"alertId"` 12 | } 13 | 14 | type SetAlertSlienceConfigRequest struct { 15 | AlertID string `json:"alertId" form:"alertId"` 16 | ForDuration string `json:"forDuration" form:"forDuration"` 17 | } 18 | -------------------------------------------------------------------------------- /backend/pkg/model/request/config_req.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package request 5 | 6 | type SetTTLRequest struct { 7 | DataType string `json:"dataType" binding:"required,oneof=logs trace k8s other topology"` // type (log, trace, Kubernetes, other) 8 | Day int `json:"day" binding:"required"` // save data cycle days 9 | } 10 | 11 | type SetSingleTTLRequest struct { 12 | Name string `json:"name" binding:"required"` // table name 13 | Day int `json:"day" binding:"required"` // save data cycle days 14 | } 15 | -------------------------------------------------------------------------------- /backend/pkg/model/request/k8s_req.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package request 5 | 6 | type GetNamespaceInfoRequest struct { 7 | Namespace string `form:"namespace" binding:"required"` 8 | } 9 | 10 | type GetPodListRequest struct { 11 | Namespace string `form:"namespace" binding:"required"` 12 | } 13 | 14 | type GetPodInfoRequest struct { 15 | Namespace string `form:"namespace" binding:"required"` 16 | Pod string `form:"pod" binding:"required"` 17 | } 18 | -------------------------------------------------------------------------------- /backend/pkg/model/request/log_info.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package request 5 | 6 | type LogTableInfoRequest struct { 7 | } 8 | -------------------------------------------------------------------------------- /backend/pkg/model/request/network.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package request 5 | 6 | type PodMapRequest struct { 7 | StartTime int64 `form:"startTime" json:"startTime" binding:"required,min=0"` // query start time 8 | EndTime int64 `form:"endTime" json:"endTime" binding:"required,gtfield=StartTime"` // query end time 9 | Namespace string `form:"namespace"` 10 | Workload string `form:"workload"` 11 | Protocol string `form:"protocol"` 12 | } 13 | 14 | type SpanSegmentMetricsRequest struct { 15 | TraceId string `form:"traceId" binding:"required"` 16 | SpanId string `form:"spanId"` 17 | } 18 | -------------------------------------------------------------------------------- /backend/pkg/model/request/role_req.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package request 5 | 6 | type RoleOperationRequest struct { 7 | UserID int64 `form:"userId" binding:"required"` 8 | RoleList []int `form:"roleList" binding:"required"` 9 | } 10 | 11 | type CreateRoleRequest struct { 12 | RoleName string `form:"roleName" binding:"required"` 13 | Description string `form:"description"` 14 | PermissionList []int `form:"permissionList"` 15 | UserList []int64 `form:"userList"` 16 | } 17 | 18 | type UpdateRoleRequest struct { 19 | RoleID int `form:"roleId" binding:"required"` 20 | RoleName string `form:"roleName" binding:"required"` 21 | Description string `form:"description"` 22 | PermissionList []int `form:"permissionList"` 23 | } 24 | 25 | type DeleteRoleRequest struct { 26 | RoleID int `form:"roleId" binding:"required"` 27 | } 28 | -------------------------------------------------------------------------------- /backend/pkg/model/request/sql_metric.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package request 5 | 6 | type GetSQLMetricsRequest struct { 7 | StartTime int64 `form:"startTime" binding:"min=0"` // query start time 8 | EndTime int64 `form:"endTime" binding:"required,gtfield=StartTime"` // query end time 9 | Service string `form:"service" binding:"required"` // query service name 10 | Step int64 `form:"step" binding:"min=1000000"` // query step size (us) 11 | 12 | SortBy string `form:"sortBy"` // sorting method,(latency,errorRate,tps) is sorted by latency by default 13 | *PageParam // Paging Parameters 14 | } 15 | -------------------------------------------------------------------------------- /backend/pkg/model/response/alert_slience.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import "github.com/CloudDetail/apo/backend/pkg/model/amconfig/slienceconfig" 7 | 8 | type GetAlertSlienceConfigResponse struct { 9 | Slience *slienceconfig.AlertSlienceConfig `json:"slience"` 10 | } 11 | 12 | type ListAlertSlienceConfigResponse struct { 13 | Sliences []slienceconfig.AlertSlienceConfig `json:"sliences"` 14 | } 15 | -------------------------------------------------------------------------------- /backend/pkg/model/response/config_resp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/model" 8 | ) 9 | 10 | type GetTTLResponse struct { 11 | Logs []model.ModifyTableTTLMap `json:"logs"` 12 | Trace []model.ModifyTableTTLMap `json:"trace"` 13 | K8s []model.ModifyTableTTLMap `json:"k8s"` 14 | Topology []model.ModifyTableTTLMap `json:"topology"` 15 | Other []model.ModifyTableTTLMap `json:"other"` 16 | } 17 | -------------------------------------------------------------------------------- /backend/pkg/model/response/data_resp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/model" 8 | "github.com/CloudDetail/apo/backend/pkg/repository/database" 9 | ) 10 | 11 | type GetDatasourceResponse struct { 12 | NamespaceList []model.Datasource `json:"namespaceList"` 13 | ServiceList []model.Datasource `json:"serviceList"` 14 | } 15 | 16 | type GetDataGroupResponse struct { 17 | DataGroupList []database.DataGroup `json:"dataGroupList"` 18 | model.Pagination `json:",inline"` 19 | } 20 | 21 | type GetGroupDatasourceResponse struct { 22 | NamespaceMap map[string][]string `json:"namespaceMap"` // namespace: services 23 | ServiceMap map[string][]string `json:"serviceMap"` // service: endpoints 24 | } 25 | 26 | type GetSubjectDataGroupResponse []database.DataGroup 27 | 28 | type GetGroupSubsResponse []database.AuthDataGroup 29 | -------------------------------------------------------------------------------- /backend/pkg/model/response/k8s_resp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import v1 "k8s.io/api/core/v1" 7 | 8 | type GetNamespaceListResponse struct { 9 | *v1.NamespaceList 10 | } 11 | 12 | type GetPodListResponse struct { 13 | *v1.PodList 14 | } 15 | 16 | type GetNamespaceInfoResponse struct { 17 | *v1.Namespace 18 | } 19 | 20 | type GetPodInfoResponse struct { 21 | *v1.Pod 22 | } 23 | -------------------------------------------------------------------------------- /backend/pkg/model/response/log_chart.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | type LogChartResponse struct { 7 | Histograms []*LogHistogram `json:"histograms"` 8 | Count uint64 `json:"count"` 9 | Progress string `json:"progress"` 10 | Err string `json:"error"` 11 | } 12 | 13 | type LogHistogram struct { 14 | Count uint64 `json:"count"` 15 | Progress string `json:"progress"` 16 | From int64 `json:"from"` 17 | To int64 `json:"to"` 18 | } 19 | -------------------------------------------------------------------------------- /backend/pkg/model/response/log_index.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | type LogIndexResponse struct { 7 | Indexs []IndexItem `json:"indexs"` 8 | } 9 | 10 | type IndexItem struct { 11 | IndexName string `json:"indexName"` 12 | Count uint64 `json:"count"` 13 | Percent float64 `json:"percent"` 14 | } 15 | -------------------------------------------------------------------------------- /backend/pkg/model/response/log_info.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | type LogTableInfoResponse struct { 7 | Parses []Parse `json:"parses"` 8 | Instances []Instance `json:"instances"` 9 | } 10 | 11 | type Parse struct { 12 | DataBase string `json:"dataBase"` 13 | TableName string `json:"tableName"` 14 | ParseName string `json:"parseName"` 15 | ParseInfo string `json:"parseInfo"` 16 | } 17 | 18 | type Instance struct { 19 | InstanceName string `json:"instanceName"` 20 | DataBases []DBInfo `json:"dataBases"` 21 | } 22 | 23 | type DBInfo struct { 24 | DataBase string `json:"dataBase"` 25 | Tables []LogTableInfo `json:"tables"` 26 | } 27 | 28 | type LogTableInfo struct { 29 | Cluster string `json:"cluster"` 30 | TableName string `json:"tableName"` 31 | TimeField string `json:"timeField"` 32 | LogField string `json:"logField"` 33 | } 34 | -------------------------------------------------------------------------------- /backend/pkg/model/response/log_other.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | type OtherTableResponse struct { 7 | OtherTables []OtherDB `json:"otherTables"` 8 | } 9 | 10 | type OtherDB struct { 11 | DataBase string `json:"dataBase"` 12 | Tables []OtherTable `json:"tables"` 13 | } 14 | 15 | type OtherTable struct { 16 | TableName string `json:"tableName"` 17 | } 18 | 19 | type OtherTableInfoResponse struct { 20 | Columns []Column `json:"columns"` 21 | Err string `json:"error"` 22 | } 23 | 24 | type Column struct { 25 | Name string `json:"name"` 26 | Type string `json:"type"` 27 | } 28 | 29 | type AddOtherTableResponse struct { 30 | Err string `json:"error"` 31 | } 32 | 33 | type DeleteOtherTableResponse struct { 34 | Err string `json:"error"` 35 | } 36 | -------------------------------------------------------------------------------- /backend/pkg/model/response/log_parse.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import "github.com/CloudDetail/apo/backend/pkg/model/request" 7 | 8 | type LogParseResponse struct { 9 | ParseInfo string `json:"parseInfo"` 10 | Service []string `json:"serviceName"` 11 | ParseName string `json:"parseName"` 12 | RouteRule map[string]string `json:"routeRule"` 13 | ParseRule string `json:"parseRule"` 14 | LogFields []request.Field `json:"tableFields"` 15 | IsStructured bool `json:"isStructured"` 16 | } 17 | 18 | type GetServiceRouteResponse struct { 19 | RouteRule map[string]string `json:"routeRule"` 20 | } 21 | -------------------------------------------------------------------------------- /backend/pkg/model/response/log_query.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | type LogQueryResponse struct { 7 | Limited int `json:"limited"` 8 | // log field 9 | HiddenFields []string `json:"hiddenFields"` 10 | // tag field 11 | DefaultFields []string `json:"defaultFields"` 12 | Logs []LogItem `json:"logs"` 13 | Query string `json:"query"` 14 | Cost int64 `json:"cost"` 15 | Err string `json:"error"` 16 | } 17 | 18 | type LogItem struct { 19 | Content interface{} `json:"content"` 20 | Tags map[string]interface{} `json:"tags"` 21 | LogFields map[string]interface{} `json:"logFields"` 22 | Time int64 `json:"timestamp"` 23 | } 24 | 25 | type LogQueryContextResponse struct { 26 | Front []LogItem `json:"front"` 27 | Back []LogItem `json:"back"` 28 | } 29 | -------------------------------------------------------------------------------- /backend/pkg/model/response/log_resp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/model" 8 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 9 | ) 10 | 11 | type GetFaultLogPageListResponse struct { 12 | List []clickhouse.FaultLogResult `json:"list"` 13 | Pagination *model.Pagination `json:"pagination"` 14 | } 15 | 16 | type GetFaultLogContentResponse struct { 17 | Sources []string `json:"sources"` 18 | LogContents *clickhouse.Logs `json:"logContents"` 19 | } 20 | -------------------------------------------------------------------------------- /backend/pkg/model/response/log_table.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | type LogTableResponse struct { 7 | Sqls []string `json:"sqls"` 8 | Err string `json:"error"` 9 | } 10 | -------------------------------------------------------------------------------- /backend/pkg/model/response/span_trace.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/model/request" 8 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 9 | ) 10 | 11 | type GetTraceFilterValueResponse struct { 12 | TraceFilterOptions clickhouse.SpanTraceOptions `json:"traceFilterOptions"` 13 | } 14 | 15 | type GetTraceFiltersResponse struct { 16 | TraceFilters []request.SpanTraceFilter `json:"traceFilters"` 17 | } 18 | -------------------------------------------------------------------------------- /backend/pkg/model/response/sql_metric.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/model" 8 | "github.com/CloudDetail/apo/backend/pkg/repository/prometheus" 9 | ) 10 | 11 | type GetSQLMetricsResponse struct { 12 | Pagination model.Pagination `json:"pagination"` 13 | SQLOperationDetails []SQLOperationDetail `json:"sqlOperationDetails"` 14 | } 15 | 16 | type SQLOperationDetail struct { 17 | prometheus.SQLKey 18 | 19 | Latency TempChartObject `json:"latency"` 20 | ErrorRate TempChartObject `json:"errorRate"` 21 | // FIXME Tps name is tps, actual requests per minute 22 | Tps TempChartObject `json:"tps"` 23 | } 24 | -------------------------------------------------------------------------------- /backend/pkg/model/response/team_resp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/model" 8 | "github.com/CloudDetail/apo/backend/pkg/model/profile" 9 | ) 10 | 11 | type GetTeamResponse struct { 12 | TeamList []profile.Team `json:"teamList"` 13 | model.Pagination `json:",inline"` 14 | } 15 | 16 | type GetTeamUserResponse []profile.User 17 | -------------------------------------------------------------------------------- /backend/pkg/model/response/trace_resp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package response 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/model" 8 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 9 | ) 10 | 11 | type GetTracePageListResponse struct { 12 | List []clickhouse.QueryTraceResult `json:"list"` 13 | Pagination *model.Pagination `json:"pagination"` 14 | } 15 | 16 | type GetOnOffCPUResponse struct { 17 | ProfilingEvent *[]clickhouse.ProfilingEvent `json:"profilingEvent"` 18 | } 19 | 20 | type GetSingleTraceInfoResponse string 21 | 22 | type GetFlameDataResponse clickhouse.FlameGraphData 23 | 24 | type GetProcessFlameGraphResponse clickhouse.FlameGraphData 25 | -------------------------------------------------------------------------------- /backend/pkg/model/workflow_records.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package model 5 | 6 | type WorkflowRecord struct { 7 | WorkflowRunID string `json:"workflowRunId" ch:"workflow_run_id"` 8 | 9 | WorkflowID string `json:"workflowId" ch:"workflow_id"` 10 | WorkflowName string `json:"workflowName" ch:"workflow_name"` 11 | 12 | Ref string `json:"ref" ch:"ref"` 13 | Input string `json:"input" ch:"input"` 14 | Output string `json:"output" ch:"output"` 15 | 16 | CreatedAt int64 `json:"createdAt" ch:"created_at"` 17 | RoundedTime int64 `json:"-" ch:"rounded_time"` 18 | 19 | InputRef any `json:"-" ch:"-"` 20 | } 21 | 22 | type AlertNotifyRecord struct { 23 | AlertID string `json:"alertId" ch:"alert_id"` 24 | CreatedAt int64 `json:"createdAt" ch:"created_at"` 25 | EventID string `json:"eventId" ch:"event_id"` 26 | Success string `json:"success" ch:"success"` 27 | Failed string `json:"failed" ch:"failed"` 28 | } 29 | -------------------------------------------------------------------------------- /backend/pkg/repository/clickhouse/dao_alert_notify.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package clickhouse 5 | 6 | import ( 7 | "time" 8 | 9 | core "github.com/CloudDetail/apo/backend/pkg/core" 10 | "github.com/CloudDetail/apo/backend/pkg/model" 11 | ) 12 | 13 | func (ch *chRepo) CreateAlertNotifyRecord(ctx core.Context, record model.AlertNotifyRecord) error { 14 | batch, err := ch.GetContextDB(ctx).PrepareBatch(ctx.GetContext(), ` 15 | INSERT INTO alert_notify_record (alert_id, created_at, event_id, success,failed) 16 | VALUES 17 | `) 18 | if err != nil { 19 | return err 20 | } 21 | if err := batch.Append( 22 | record.AlertID, 23 | time.UnixMicro(record.CreatedAt), 24 | record.EventID, 25 | record.Success, 26 | record.Failed, 27 | ); err != nil { 28 | return err 29 | } 30 | if err := batch.Send(); err != nil { 31 | return err 32 | } 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /backend/pkg/repository/clickhouse/dao_alert_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package clickhouse 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/spf13/viper" 10 | 11 | "github.com/CloudDetail/apo/backend/pkg/logger" 12 | ) 13 | 14 | func NewTestRepo(t *testing.T) Repo { 15 | viper.SetConfigFile("testdata/config.yml") 16 | viper.ReadInConfig() 17 | 18 | address := viper.GetString("clickhouse.address") 19 | database := viper.GetString("clickhouse.database") 20 | username := viper.GetString("clickhouse.username") 21 | password := viper.GetString("clickhouse.password") 22 | 23 | zapLog := logger.NewLogger(logger.WithLevel("debug")) 24 | repo, err := New(zapLog, []string{address}, database, username, password) 25 | if err != nil { 26 | t.Fatalf("Error to connect clickhouse: %v", err) 27 | } 28 | return repo 29 | } 30 | -------------------------------------------------------------------------------- /backend/pkg/repository/clickhouse/dao_k8s_event_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package clickhouse 5 | 6 | import ( 7 | "fmt" 8 | "log" 9 | "testing" 10 | "time" 11 | 12 | "github.com/CloudDetail/apo/backend/pkg/core" 13 | "github.com/CloudDetail/apo/backend/pkg/model" 14 | ) 15 | 16 | func TestChRepo_K8sAlert(t *testing.T) { 17 | repo := NewTestRepo(t) 18 | currentTime := time.Now() 19 | // Get the time 1 hour ago 20 | oneHourAgo := currentTime.Add(-1 * time.Hour) 21 | instances := []*model.ServiceInstance{ 22 | { 23 | PodName: "apisix-etcd-0", 24 | NodeName: "worker-23", 25 | }, 26 | } 27 | k8sAlert, err := repo.GetK8sAlertEventsSample(core.EmptyCtx(), oneHourAgo, currentTime, instances) 28 | if err != nil { 29 | t.Fatalf("Error to get k8sAlert: %v", err) 30 | } 31 | for _, event := range k8sAlert { 32 | info := fmt.Sprintf("%s: %s %s:%s", event.Timestamp.Format("15:04:05"), event.GetObjName(), event.GetReason(), event.Body) 33 | log.Println(info) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /backend/pkg/repository/clickhouse/dao_other_log_table.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package clickhouse 5 | 6 | import ( 7 | "fmt" 8 | 9 | core "github.com/CloudDetail/apo/backend/pkg/core" 10 | "github.com/CloudDetail/apo/backend/pkg/model/request" 11 | ) 12 | 13 | const queryOtherTablesSQL = ` 14 | SELECT 15 | database, 16 | name, 17 | FROM system.tables; 18 | ` 19 | 20 | const queryOtherTableInfoSQL = ` 21 | SELECT 22 | name,type 23 | FROM 24 | system.columns 25 | WHERE database = '%s' And table = '%s'; 26 | ` 27 | 28 | func (ch *chRepo) OtherLogTable(ctx core.Context) ([]map[string]any, error) { 29 | return ch.queryRowsData(ctx, queryOtherTablesSQL) 30 | } 31 | 32 | func (ch *chRepo) OtherLogTableInfo(ctx core.Context, req *request.OtherTableInfoRequest) ([]map[string]any, error) { 33 | sql := fmt.Sprintf(queryOtherTableInfoSQL, req.DataBase, req.TableName) 34 | return ch.queryRowsData(ctx, sql) 35 | } 36 | -------------------------------------------------------------------------------- /backend/pkg/repository/clickhouse/factory/conn.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package factory 5 | 6 | import ( 7 | "github.com/ClickHouse/clickhouse-go/v2/lib/driver" 8 | "github.com/CloudDetail/apo/backend/pkg/core" 9 | ) 10 | 11 | type Conn struct { 12 | driver.Conn 13 | } 14 | 15 | func (c *Conn) GetContextDB(ctx core.Context) driver.Conn { 16 | return c.Conn 17 | } 18 | -------------------------------------------------------------------------------- /backend/pkg/repository/clickhouse/integration/input.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package integration 5 | 6 | import ( 7 | "github.com/ClickHouse/clickhouse-go/v2/lib/driver" 8 | core "github.com/CloudDetail/apo/backend/pkg/core" 9 | "github.com/CloudDetail/apo/backend/pkg/model/integration/alert" 10 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse/factory" 11 | ) 12 | 13 | type Input interface { 14 | InsertAlertEvent(ctx core.Context, alertEvents []alert.AlertEvent, sourceFrom alert.SourceFrom) error 15 | } 16 | 17 | var _ Input = &chRepo{} 18 | 19 | type chRepo struct { 20 | factory.Conn 21 | database string 22 | } 23 | 24 | func NewInputRepo(conn driver.Conn, database string) (*chRepo, error) { 25 | c := factory.Conn{Conn: conn} 26 | return &chRepo{ 27 | Conn: c, 28 | database: database, 29 | }, nil 30 | } 31 | -------------------------------------------------------------------------------- /backend/pkg/repository/clickhouse/testdata/config.yml: -------------------------------------------------------------------------------- 1 | clickhouse: 2 | address: "localhost:9000" 3 | username: admin 4 | password: Apo@123456 5 | database: apo 6 | -------------------------------------------------------------------------------- /backend/pkg/repository/database/dao_api.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package database 5 | 6 | import 7 | 8 | // API represents an API endpoint definition 9 | core "github.com/CloudDetail/apo/backend/pkg/core" 10 | 11 | type API struct { 12 | ID int `gorm:"primary_key;auto_increment"` 13 | Path string `gorm:"column:path;type:varchar(255);index:idx_path_method,unique" mapstructure:"path"` 14 | Method string `gorm:"column:method;type:varchar(10);index:idx_path_method,unique" mapstructure:"method"` 15 | Enabled bool `gorm:"column:enabled;default:true"` 16 | } 17 | 18 | func (API) TableName() string { 19 | return "api" 20 | } 21 | 22 | func (repo *daoRepo) GetAPIByPath(ctx core.Context, path string, method string) (*API, error) { 23 | var api API 24 | err := repo.GetContextDB(ctx).Where("path = ? AND method = ?", path, method).Find(&api).Error 25 | return &api, err 26 | } 27 | -------------------------------------------------------------------------------- /backend/pkg/repository/database/driver/db.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package driver 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | "gorm.io/gorm" 9 | ) 10 | 11 | const ( 12 | _transactionCtxKey = "__transaction__" 13 | ) 14 | 15 | type DB struct { 16 | *gorm.DB 17 | } 18 | 19 | func (d *DB) GetContextDB(ctx core.Context) *gorm.DB { 20 | if ctx == nil { 21 | return d.DB 22 | } 23 | 24 | ctxDB, exist := ctx.Get(_transactionCtxKey) 25 | if exist && ctxDB != nil { 26 | tx, ok := ctxDB.(*gorm.DB) 27 | if !ok { 28 | return nil 29 | } 30 | return tx 31 | } 32 | return d.WithContext(ctx.GetContext()) 33 | } 34 | 35 | func (d *DB) WithTransaction(ctx core.Context, tx *gorm.DB) core.Context { 36 | ctx.Set(_transactionCtxKey, tx) 37 | return ctx 38 | } 39 | -------------------------------------------------------------------------------- /backend/pkg/repository/database/driver/db_sqllite.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package driver 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/config" 8 | 9 | "gorm.io/driver/sqlite" 10 | "gorm.io/gorm" 11 | ) 12 | 13 | func NewSqlliteDialector() gorm.Dialector { 14 | return sqlite.Open(config.Get().Database.Sqllite.Database) 15 | } 16 | -------------------------------------------------------------------------------- /backend/pkg/repository/database/init_api.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package database 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/spf13/viper" 9 | "gorm.io/gorm/clause" 10 | ) 11 | 12 | func (repo *daoRepo) initApi(ctx core.Context) error { 13 | var apis []API 14 | viper.SetConfigType("yaml") 15 | viper.SetConfigFile("./sqlscripts/api.yml") 16 | if err := viper.ReadInConfig(); err != nil { 17 | return err 18 | } 19 | if err := viper.UnmarshalKey("apis", &apis); err != nil { 20 | return err 21 | } 22 | 23 | return repo.GetContextDB(ctx).Clauses(clause.OnConflict{ 24 | Columns: []clause.Column{{Name: "path"}, {Name: "method"}}, 25 | UpdateAll: true, 26 | }).Create(&apis).Error 27 | } 28 | -------------------------------------------------------------------------------- /backend/pkg/repository/database/init_role.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package database 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model" 9 | "github.com/CloudDetail/apo/backend/pkg/model/profile" 10 | "gorm.io/gorm" 11 | "gorm.io/gorm/clause" 12 | ) 13 | 14 | var validRoles = []profile.Role{ 15 | {RoleName: model.ROLE_ADMIN}, 16 | {RoleName: model.ROLE_VIEWER}, 17 | {RoleName: model.ROLE_ANONYMOS}, 18 | } 19 | 20 | func (repo *daoRepo) initRole(ctx core.Context) error { 21 | return repo.GetContextDB(ctx).Transaction(func(tx *gorm.DB) error { 22 | return tx.Clauses(clause.OnConflict{ 23 | Columns: []clause.Column{{Name: "role_name"}}, 24 | DoNothing: true, 25 | }).Create(validRoles).Error 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /backend/pkg/repository/database/transaction.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package database 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | ) 9 | 10 | func (repo *daoRepo) Transaction(ctx core.Context, funcs ...func(txCtx core.Context) error) (err error) { 11 | tx := repo.GetContextDB(ctx).Begin() 12 | defer func() { 13 | if r := recover(); r != nil { 14 | tx.Rollback() 15 | } 16 | }() 17 | 18 | txCtx := repo.WithTransaction(ctx, tx) 19 | for _, f := range funcs { 20 | if err = f(txCtx); err != nil { 21 | tx.Rollback() 22 | return 23 | } 24 | } 25 | if err = tx.Commit().Error; err != nil { 26 | tx.Rollback() 27 | } 28 | return 29 | } 30 | -------------------------------------------------------------------------------- /backend/pkg/repository/dify/handle.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package dify 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/CloudDetail/apo/backend/pkg/core" 10 | "github.com/CloudDetail/apo/backend/pkg/model" 11 | "go.uber.org/zap" 12 | ) 13 | 14 | type Handle func(ctx core.Context, record *model.WorkflowRecord) error 15 | 16 | func HandleRecords(ctx context.Context, logger *zap.Logger, records <-chan *model.WorkflowRecord, handlers ...Handle) { 17 | for record := range records { 18 | for _, handler := range handlers { 19 | err := handler(core.EmptyCtx(), record) 20 | if err != nil { 21 | logger.Error("handle workflow records failed", zap.Error(err)) 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /backend/pkg/repository/jaeger/dao.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package jaeger 5 | 6 | import ( 7 | "net/http" 8 | ) 9 | 10 | type JaegerRepo interface { 11 | GetSingleTrace(traceId string) (string, error) 12 | } 13 | 14 | type jaegerRepo struct { 15 | cli *http.Client 16 | } 17 | 18 | func New() (JaegerRepo, error) { 19 | client := &http.Client{} 20 | return &jaegerRepo{cli: client}, nil 21 | } 22 | -------------------------------------------------------------------------------- /backend/pkg/repository/jaeger/trace.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package jaeger 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/config" 8 | "io" 9 | ) 10 | 11 | const trace_path = "/jaeger/api/traces/" 12 | 13 | func (j *jaegerRepo) GetSingleTrace(traceId string) (string, error) { 14 | jaegerConf := config.Get().Jaeger 15 | url := jaegerConf.Address + trace_path + traceId 16 | 17 | resp, err := j.cli.Get(url) 18 | if err != nil { 19 | return "", err 20 | } 21 | defer resp.Body.Close() 22 | info, err := io.ReadAll(resp.Body) 23 | if err != nil { 24 | return "", err 25 | } 26 | return string(info), nil 27 | } 28 | -------------------------------------------------------------------------------- /backend/pkg/repository/kubernetes/dao_namespace.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package kubernetes 5 | 6 | import ( 7 | "context" 8 | "go.uber.org/zap" 9 | v1 "k8s.io/api/core/v1" 10 | "sigs.k8s.io/controller-runtime/pkg/client" 11 | ) 12 | 13 | func (k *k8sApi) GetNamespaceList() (*v1.NamespaceList, error) { 14 | list := &v1.NamespaceList{} 15 | err := k.cli.List(context.Background(), list) 16 | if err != nil { 17 | k.logger.Error("Get namespace error: ", zap.Error(err)) 18 | return nil, err 19 | } 20 | return list, nil 21 | } 22 | 23 | func (k *k8sApi) GetNamespaceInfo(namespace string) (*v1.Namespace, error) { 24 | namespaceInfo := &v1.Namespace{} 25 | err := k.cli.Get(context.Background(), client.ObjectKey{Name: namespace}, namespaceInfo) 26 | if err != nil { 27 | k.logger.Error("Get namespace error: ", zap.Error(err)) 28 | return nil, err 29 | } 30 | return namespaceInfo, nil 31 | } 32 | -------------------------------------------------------------------------------- /backend/pkg/repository/kubernetes/dao_pod.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package kubernetes 5 | 6 | import ( 7 | "context" 8 | "go.uber.org/zap" 9 | v1 "k8s.io/api/core/v1" 10 | "sigs.k8s.io/controller-runtime/pkg/client" 11 | ) 12 | 13 | func (k *k8sApi) GetPodList(namespace string) (*v1.PodList, error) { 14 | list := &v1.PodList{} 15 | err := k.cli.List(context.Background(), list, &client.ListOptions{Namespace: namespace}) 16 | if err != nil { 17 | return nil, err 18 | } 19 | return list, nil 20 | } 21 | 22 | func (k *k8sApi) GetPodInfo(namespace string, pod string) (*v1.Pod, error) { 23 | podInfo := &v1.Pod{} 24 | key := client.ObjectKey{ 25 | Name: pod, 26 | Namespace: namespace, 27 | } 28 | err := k.cli.Get(context.Background(), key, podInfo) 29 | if err != nil { 30 | k.logger.Error("Get pod error: ", zap.Error(err)) 31 | return nil, err 32 | } 33 | 34 | return podInfo, nil 35 | } 36 | -------------------------------------------------------------------------------- /backend/pkg/repository/kubernetes/dao_vector_config.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package kubernetes 5 | 6 | func (k *k8sApi) GetVectorConfigFile() (map[string]string, error) { 7 | return k.getConfigMap(k.VectorCMName, k.VectorFileName) 8 | } 9 | 10 | func (k *k8sApi) UpdateVectorConfigFile(content []byte) error { 11 | return k.updateConfigMap(k.VectorCMName, k.VectorFileName, content) 12 | } 13 | -------------------------------------------------------------------------------- /backend/pkg/repository/prometheus/dao_namespace_list.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package prometheus 5 | 6 | import ( 7 | "fmt" 8 | "time" 9 | 10 | core "github.com/CloudDetail/apo/backend/pkg/core" 11 | prometheus_model "github.com/prometheus/common/model" 12 | ) 13 | 14 | func (repo *promRepo) GetNamespaceList(ctx core.Context, startTime int64, endTime int64) ([]string, error) { 15 | query := fmt.Sprintf(TEMPLATE_GET_NAMESPACES, VecFromS2E(startTime, endTime)) 16 | value, _, err := repo.GetApi().Query(ctx.GetContext(), query, time.UnixMicro(endTime)) 17 | 18 | if err != nil { 19 | return nil, err 20 | } 21 | result := make([]string, 0) 22 | vector, ok := value.(prometheus_model.Vector) 23 | if !ok { 24 | return result, nil 25 | } 26 | for _, sample := range vector { 27 | result = append(result, string(sample.Metric["namespace"])) 28 | } 29 | return result, nil 30 | } 31 | -------------------------------------------------------------------------------- /backend/pkg/services/alerts/service_add_alert_rule.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alerts 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/code" 8 | core "github.com/CloudDetail/apo/backend/pkg/core" 9 | "github.com/CloudDetail/apo/backend/pkg/model/request" 10 | ) 11 | 12 | func (s *service) AddAlertRule(ctx core.Context, req *request.AddAlertRuleRequest) error { 13 | if !checkOrFillGroupsLabel(req.AlertRule.Group, req.AlertRule.Labels) { 14 | return core.Error(code.AlertGroupAndLabelMismatchError, "gourp and group label mismatch") 15 | } 16 | 17 | return s.k8sApi.AddAlertRule(req.AlertRuleFile, req.AlertRule) 18 | } 19 | -------------------------------------------------------------------------------- /backend/pkg/services/alerts/service_check_alert_rule.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alerts 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | ) 11 | 12 | func (s *service) CheckAlertRule(ctx core.Context, req *request.CheckAlertRuleRequest) (response.CheckAlertRuleResponse, error) { 13 | var resp response.CheckAlertRuleResponse 14 | find, err := s.k8sApi.CheckAlertRule(req.AlertRuleFile, req.Group, req.Alert) 15 | if err != nil { 16 | resp.Available = false 17 | return resp, err 18 | } 19 | 20 | resp.Available = find 21 | return resp, nil 22 | } 23 | -------------------------------------------------------------------------------- /backend/pkg/services/alerts/service_get_group_list.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alerts 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/code" 8 | "github.com/CloudDetail/apo/backend/pkg/core" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | "github.com/CloudDetail/apo/backend/pkg/repository/kubernetes" 11 | ) 12 | 13 | func (s *service) GetGroupList(ctx core.Context) response.GetGroupListResponse { 14 | var lang = code.LANG_EN 15 | if ctx != nil { 16 | lang = ctx.LANG() 17 | } 18 | if lang == code.LANG_ZH { 19 | return response.GetGroupListResponse{ 20 | GroupsLabel: kubernetes.GroupsCNLabel, 21 | } 22 | } else { 23 | return response.GetGroupListResponse{ 24 | GroupsLabel: kubernetes.GroupsENLabel, 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /backend/pkg/services/alerts/service_get_metric_pql.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alerts 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/response" 9 | ) 10 | 11 | func (s *service) GetMetricPQL(ctx core.Context) (*response.GetMetricPQLResponse, error) { 12 | alertMetrics, err := s.dbRepo.ListQuickAlertRuleMetric(ctx) 13 | if err != nil { 14 | return nil, err 15 | } 16 | return &response.GetMetricPQLResponse{ 17 | AlertMetricsData: alertMetrics, 18 | }, nil 19 | } 20 | -------------------------------------------------------------------------------- /backend/pkg/services/config/service.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package config 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 11 | ) 12 | 13 | var _ Service = (*service)(nil) 14 | 15 | type Service interface { 16 | SetTTL(ctx core.Context, req *request.SetTTLRequest) error 17 | SetSingleTableTTL(ctx core.Context, req *request.SetSingleTTLRequest) error 18 | GetTTL(ctx core.Context) (*response.GetTTLResponse, error) 19 | } 20 | 21 | type service struct { 22 | chRepo clickhouse.Repo 23 | } 24 | 25 | func New(chRepo clickhouse.Repo) Service { 26 | return &service{ 27 | chRepo: chRepo, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /backend/pkg/services/integration/alert/service_clusters.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alert 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | input "github.com/CloudDetail/apo/backend/pkg/model/integration" 9 | "github.com/google/uuid" 10 | ) 11 | 12 | func (s *service) CreateCluster(ctx core.Context, cluster *input.Cluster) error { 13 | cluster.ID = uuid.NewString() 14 | return s.dbRepo.CreateCluster(ctx, cluster) 15 | } 16 | 17 | func (s *service) ListCluster(ctx core.Context) ([]input.Cluster, error) { 18 | return s.dbRepo.ListCluster(ctx) 19 | } 20 | 21 | func (s *service) UpdateCluster(ctx core.Context, cluster *input.Cluster) error { 22 | return s.dbRepo.UpdateCluster(ctx, cluster) 23 | } 24 | 25 | func (s *service) DeleteCluster(ctx core.Context, cluster *input.Cluster) error { 26 | return s.dbRepo.DeleteCluster(ctx, cluster) 27 | } 28 | -------------------------------------------------------------------------------- /backend/pkg/services/integration/alert/service_get_alert_enrich_rule_tags.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package alert 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/integration/alert" 9 | ) 10 | 11 | func (s *service) GetAlertEnrichRuleTags(ctx core.Context) ([]alert.TargetTag, error) { 12 | return s.dbRepo.ListAlertTargetTags(ctx) 13 | } 14 | -------------------------------------------------------------------------------- /backend/pkg/services/integration/service_clusters.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package integration 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/integration" 9 | ) 10 | 11 | func (s *service) ListCluster(ctx core.Context) ([]integration.Cluster, error) { 12 | return s.dbRepo.ListCluster(ctx) 13 | } 14 | 15 | func (s *service) DeleteCluster(ctx core.Context, cluster *integration.Cluster) error { 16 | err := s.dbRepo.DeleteCluster(ctx, cluster) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | return s.dbRepo.DeleteIntegrationConfig(ctx, cluster.ID) 22 | } 23 | -------------------------------------------------------------------------------- /backend/pkg/services/integration/service_get_cluster_integration.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package integration 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/integration" 9 | ) 10 | 11 | func (s *service) GetClusterIntegration(ctx core.Context, clusterID string) (*integration.ClusterIntegrationVO, error) { 12 | config, err := s.dbRepo.GetIntegrationConfig(ctx, clusterID) 13 | if err != nil { 14 | return nil, err 15 | } 16 | 17 | return &integration.ClusterIntegrationVO{ 18 | ClusterIntegration: config.RemoveSecret(), 19 | ChartVersion: apoChartVersion, 20 | DeployVersion: apoComposeDeployVersion, 21 | }, nil 22 | } 23 | -------------------------------------------------------------------------------- /backend/pkg/services/k8s/service.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package k8s 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | "github.com/CloudDetail/apo/backend/pkg/repository/kubernetes" 11 | ) 12 | 13 | type Service interface { 14 | GetNamespaceList(ctx core.Context) (*response.GetNamespaceListResponse, error) 15 | GetNamespaceInfo(ctx core.Context, req *request.GetNamespaceInfoRequest) (*response.GetNamespaceInfoResponse, error) 16 | GetPodList(ctx core.Context, req *request.GetPodListRequest) (*response.GetPodListResponse, error) 17 | GetPodInfo(ctx core.Context, req *request.GetPodInfoRequest) (*response.GetPodInfoResponse, error) 18 | } 19 | 20 | type service struct { 21 | k8sRepo kubernetes.Repo 22 | } 23 | 24 | func New(k8sRepo kubernetes.Repo) Service { 25 | return &service{ 26 | k8sRepo: k8sRepo, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /backend/pkg/services/k8s/service_get_namespace.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package k8s 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | ) 11 | 12 | func (s service) GetNamespaceList(ctx core.Context) (*response.GetNamespaceListResponse, error) { 13 | list, err := s.k8sRepo.GetNamespaceList() 14 | if err != nil { 15 | return nil, err 16 | } 17 | return &response.GetNamespaceListResponse{ 18 | NamespaceList: list, 19 | }, nil 20 | } 21 | 22 | func (s service) GetNamespaceInfo(ctx core.Context, req *request.GetNamespaceInfoRequest) (*response.GetNamespaceInfoResponse, error) { 23 | info, err := s.k8sRepo.GetNamespaceInfo(req.Namespace) 24 | if err != nil { 25 | return nil, err 26 | } 27 | return &response.GetNamespaceInfoResponse{ 28 | Namespace: info, 29 | }, nil 30 | } 31 | -------------------------------------------------------------------------------- /backend/pkg/services/k8s/servie_get_pod.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package k8s 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | ) 11 | 12 | func (s service) GetPodList(ctx core.Context, req *request.GetPodListRequest) (*response.GetPodListResponse, error) { 13 | list, err := s.k8sRepo.GetPodList(req.Namespace) 14 | if err != nil { 15 | return nil, err 16 | } 17 | return &response.GetPodListResponse{ 18 | PodList: list, 19 | }, nil 20 | } 21 | 22 | func (s service) GetPodInfo(ctx core.Context, req *request.GetPodInfoRequest) (*response.GetPodInfoResponse, error) { 23 | info, err := s.k8sRepo.GetPodInfo(req.Namespace, req.Pod) 24 | if err != nil { 25 | return nil, err 26 | } 27 | return &response.GetPodInfoResponse{ 28 | Pod: info, 29 | }, nil 30 | } 31 | -------------------------------------------------------------------------------- /backend/pkg/services/log/service_delete_other_table.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package log 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | "github.com/CloudDetail/apo/backend/pkg/repository/database" 11 | ) 12 | 13 | func (s *service) DeleteOtherTable(ctx core.Context, req *request.DeleteOtherTableRequest) (*response.DeleteOtherTableResponse, error) { 14 | res := &response.DeleteOtherTableResponse{} 15 | model := &database.OtherLogTable{ 16 | DataBase: req.DataBase, 17 | Instance: req.Instance, 18 | Table: req.TableName, 19 | } 20 | err := s.dbRepo.OperatorOtherLogTable(ctx, model, database.DELETE) 21 | if err != nil { 22 | res.Err = err.Error() 23 | } 24 | return res, nil 25 | } 26 | -------------------------------------------------------------------------------- /backend/pkg/services/log/service_get_fault_log_contents.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package log 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | ) 11 | 12 | // GetFaultLogContent implements Service. 13 | func (s *service) GetFaultLogContent(ctx core.Context, req *request.GetFaultLogContentRequest) (*response.GetFaultLogContentResponse, error) { 14 | logContest, sources, err := s.chRepo.QueryApplicationLogs(ctx, req) 15 | if err != nil { 16 | return nil, err 17 | } 18 | return &response.GetFaultLogContentResponse{ 19 | Sources: sources, 20 | LogContents: logContest, 21 | }, nil 22 | } 23 | -------------------------------------------------------------------------------- /backend/pkg/services/log/service_log_index.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package log 5 | 6 | import ( 7 | "sort" 8 | 9 | core "github.com/CloudDetail/apo/backend/pkg/core" 10 | "github.com/CloudDetail/apo/backend/pkg/model/request" 11 | "github.com/CloudDetail/apo/backend/pkg/model/response" 12 | ) 13 | 14 | func (s *service) GetLogIndex(ctx core.Context, req *request.LogIndexRequest) (*response.LogIndexResponse, error) { 15 | res := &response.LogIndexResponse{} 16 | list, sum, err := s.chRepo.GetLogIndex(ctx, req) 17 | if err != nil { 18 | return nil, err 19 | } 20 | indexs := make([]response.IndexItem, 0) 21 | var count uint64 22 | for k, v := range list { 23 | count += v 24 | indexs = append(indexs, response.IndexItem{ 25 | IndexName: k, 26 | Count: v, 27 | Percent: float64(v) * 100 / float64(sum), 28 | }) 29 | } 30 | sort.Slice(indexs, func(i, j int) bool { 31 | return indexs[i].Count > indexs[j].Count 32 | }) 33 | res.Indexs = indexs 34 | return res, nil 35 | } 36 | -------------------------------------------------------------------------------- /backend/pkg/services/log/service_other_log_info.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package log 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | ) 11 | 12 | func (s *service) OtherTableInfo(ctx core.Context, req *request.OtherTableInfoRequest) (*response.OtherTableInfoResponse, error) { 13 | res := &response.OtherTableInfoResponse{} 14 | rows, err := s.chRepo.OtherLogTableInfo(ctx, req) 15 | if err != nil { 16 | res.Err = err.Error() 17 | return res, nil 18 | } 19 | columns := make([]response.Column, 0, len(rows)) 20 | for _, row := range rows { 21 | columns = append(columns, response.Column{ 22 | Name: row["name"].(string), 23 | Type: row["type"].(string), 24 | }) 25 | } 26 | res.Columns = columns 27 | return res, nil 28 | } 29 | -------------------------------------------------------------------------------- /backend/pkg/services/metric/service.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package metric 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/repository/prometheus" 9 | ) 10 | 11 | var _ Service = (*service)(nil) 12 | 13 | type Service interface { 14 | ListPreDefinedMetrics(ctx core.Context) []QueryInfo 15 | ListQuerys(ctx core.Context) []Query 16 | QueryMetrics(ctx core.Context, req *QueryMetricsRequest) *QueryMetricsResult 17 | } 18 | 19 | type service struct { 20 | promRepo prometheus.Repo 21 | } 22 | 23 | func New(promRepo prometheus.Repo) Service { 24 | return &service{ 25 | promRepo: promRepo, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /backend/pkg/services/network/service.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package network 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 11 | ) 12 | 13 | var _ Service = (*service)(nil) 14 | 15 | type Service interface { 16 | GetPodMap(ctx core.Context, req *request.PodMapRequest) (*response.PodMapResponse, error) 17 | GetSpanSegmentsMetrics(ctx core.Context, req *request.SpanSegmentMetricsRequest) (response.SpanSegmentMetricsResponse, error) 18 | } 19 | 20 | type service struct { 21 | chRepo clickhouse.Repo 22 | } 23 | 24 | func New(chRepo clickhouse.Repo) Service { 25 | return &service{ 26 | chRepo: chRepo, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_errorinstance_logs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 10 | ) 11 | 12 | func (s *service) GetErrorInstanceLogs(ctx core.Context, req *request.GetErrorInstanceLogsRequest) ([]clickhouse.FaultLogResult, error) { 13 | // Get the error instance fault site log 14 | query := &clickhouse.FaultLogQuery{ 15 | StartTime: req.StartTime, 16 | EndTime: req.EndTime, 17 | Service: req.Service, 18 | Instance: req.Instance, 19 | EndPoint: req.Endpoint, 20 | Type: 1, // Error Only 21 | PageNum: 1, 22 | PageSize: 5, 23 | } 24 | list, _, err := s.chRepo.GetFaultLogPageList(ctx, query) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return list, nil 29 | } 30 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_log_logs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 10 | ) 11 | 12 | func (s *service) GetLogLogs(ctx core.Context, req *request.GetLogLogsRequest) ([]clickhouse.FaultLogResult, error) { 13 | // Get Log fault field log 14 | query := &clickhouse.FaultLogQuery{ 15 | StartTime: req.StartTime, 16 | EndTime: req.EndTime, 17 | Service: req.Service, 18 | Instance: req.Instance, 19 | NodeName: req.NodeName, 20 | ContainerId: req.ContainerId, 21 | Pid: req.Pid, 22 | EndPoint: req.Endpoint, 23 | Type: 0, // Slow && Error & Profiled 24 | PageNum: 1, 25 | PageSize: 5, 26 | } 27 | list, _, err := s.chRepo.GetFaultLogPageList(ctx, query) 28 | if err != nil { 29 | return nil, err 30 | } 31 | return list, nil 32 | } 33 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_namespace_list.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | ) 11 | 12 | func (s *service) GetServiceNamespaceList(ctx core.Context, req *request.GetServiceNamespaceListRequest) (response.GetServiceNamespaceListResponse, error) { 13 | list, err := s.promRepo.GetNamespaceList(ctx, req.StartTime, req.EndTime) 14 | var resp response.GetServiceNamespaceListResponse 15 | if err != nil { 16 | return resp, err 17 | } 18 | 19 | resp.NamespaceList = list 20 | return resp, nil 21 | } 22 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_polaris_infer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | ) 11 | 12 | // GetPolarisInfer implements Service. 13 | func (s *service) GetPolarisInfer(ctx core.Context, req *request.GetPolarisInferRequest) (*response.GetPolarisInferResponse, error) { 14 | return s.polRepo.QueryPolarisInfer(req) 15 | } 16 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_service_endpoint_list.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | ) 10 | 11 | func (s *service) GetServiceEndPointList(ctx core.Context, req *request.GetServiceEndPointListRequest) ([]string, error) { 12 | // Get the list of service Endpoint 13 | return s.promRepo.GetServiceEndPointList(ctx, req.StartTime, req.EndTime, req.ServiceName) 14 | } 15 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_service_entry_endpoints.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 10 | ) 11 | 12 | func (s *service) GetServiceEntryEndpoints(ctx core.Context, req *request.GetServiceEntryEndpointsRequest) ([]clickhouse.EntryNode, error) { 13 | return s.chRepo.ListEntryEndpoints(ctx, req) 14 | } 15 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_service_instance_options.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model" 9 | "github.com/CloudDetail/apo/backend/pkg/model/request" 10 | ) 11 | 12 | func (s *service) GetServiceInstanceOptions(ctx core.Context, req *request.GetServiceInstanceOptionsRequest) (map[string]*model.ServiceInstance, error) { 13 | // Get the list of active service instances 14 | instances, err := s.promRepo.GetActiveInstanceList(ctx, req.StartTime, req.EndTime, []string{req.ServiceName}) 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | return instances.GetInstanceIdMap(), nil 20 | } 21 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_service_list.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | ) 10 | 11 | func (s *service) GetServiceList(ctx core.Context, req *request.GetServiceListRequest) ([]string, error) { 12 | return s.promRepo.GetServiceList(ctx, req.StartTime, req.EndTime, req.Namespace) 13 | } 14 | -------------------------------------------------------------------------------- /backend/pkg/services/service/service_get_trace_logs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package service 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 10 | ) 11 | 12 | func (s *service) GetTraceLogs(ctx core.Context, req *request.GetTraceLogsRequest) ([]clickhouse.FaultLogResult, error) { 13 | // Get trace fault site log 14 | query := &clickhouse.FaultLogQuery{ 15 | StartTime: req.StartTime, 16 | EndTime: req.EndTime, 17 | Service: req.Service, 18 | Instance: req.Instance, 19 | NodeName: req.NodeName, 20 | ContainerId: req.ContainerId, 21 | Pid: req.Pid, 22 | EndPoint: req.Endpoint, 23 | Type: 0, // Slow && Error 24 | PageNum: 1, 25 | PageSize: 5, 26 | } 27 | list, _, err := s.chRepo.GetFaultLogPageList(ctx, query) 28 | if err != nil { 29 | return nil, err 30 | } 31 | return list, nil 32 | } 33 | -------------------------------------------------------------------------------- /backend/pkg/services/serviceoverview/const_data.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package serviceoverview 5 | 6 | // Error rate, delay, TPS sort weight 7 | const ErrorCount = 1 8 | const TPSCount = 1 9 | const LatencyCount = 1 10 | -------------------------------------------------------------------------------- /backend/pkg/services/serviceoverview/service_get_threshold.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package serviceoverview 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/response" 9 | ) 10 | 11 | func (s *service) GetThreshold(ctx core.Context, level string, serviceName string, endPoint string) (res response.GetThresholdResponse, err error) { 12 | threshold, err := s.dbRepo.GetOrCreateThreshold(ctx, serviceName, endPoint, level) 13 | if err != nil { 14 | return res, err 15 | } 16 | res.Log = threshold.Log 17 | res.ErrorRate = threshold.ErrorRate 18 | res.Tps = threshold.Tps 19 | res.Latency = threshold.Latency 20 | return res, nil 21 | } 22 | -------------------------------------------------------------------------------- /backend/pkg/services/serviceoverview/service_set_threshold.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package serviceoverview 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/response" 9 | "github.com/CloudDetail/apo/backend/pkg/repository/database" 10 | ) 11 | 12 | func (s *service) SetThreshold(ctx core.Context, level string, serviceName string, endPoint string, latency float64, errorRate float64, tps float64, log float64) (res response.SetThresholdResponse, err error) { 13 | threshold := &database.Threshold{ 14 | Latency: latency, 15 | Tps: tps, 16 | ErrorRate: errorRate, 17 | Log: log, 18 | } 19 | if level == database.GLOBAL { 20 | threshold.Level = database.GLOBAL 21 | } 22 | err = s.dbRepo.CreateOrUpdateThreshold(ctx, threshold) 23 | return res, err 24 | 25 | } 26 | -------------------------------------------------------------------------------- /backend/pkg/services/team/service_get_team.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package team 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model" 9 | "github.com/CloudDetail/apo/backend/pkg/model/request" 10 | "github.com/CloudDetail/apo/backend/pkg/model/response" 11 | ) 12 | 13 | func (s *service) GetTeamList(ctx core.Context, req *request.GetTeamRequest) (resp response.GetTeamResponse, err error) { 14 | teams, count, err := s.dbRepo.GetTeamList(ctx, req) 15 | if err != nil { 16 | return 17 | } 18 | 19 | resp = response.GetTeamResponse{ 20 | TeamList: teams, 21 | Pagination: model.Pagination{ 22 | CurrentPage: req.CurrentPage, 23 | Total: count, 24 | PageSize: req.PageSize, 25 | }, 26 | } 27 | return 28 | } 29 | -------------------------------------------------------------------------------- /backend/pkg/services/team/service_get_team_user.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package team 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/code" 8 | core "github.com/CloudDetail/apo/backend/pkg/core" 9 | "github.com/CloudDetail/apo/backend/pkg/model" 10 | "github.com/CloudDetail/apo/backend/pkg/model/request" 11 | "github.com/CloudDetail/apo/backend/pkg/model/response" 12 | ) 13 | 14 | func (s *service) GetTeamUser(ctx core.Context, req *request.GetTeamUserRequest) (resp response.GetTeamUserResponse, err error) { 15 | filter := model.TeamFilter{ 16 | ID: req.TeamID, 17 | } 18 | exists, err := s.dbRepo.TeamExist(ctx, filter) 19 | if err != nil { 20 | return 21 | } 22 | 23 | if !exists { 24 | err = core.Error(code.TeamNotExistError, "team does not exist") 25 | return 26 | } 27 | 28 | users, err := s.dbRepo.GetTeamUserList(ctx, req.TeamID) 29 | if err != nil { 30 | return 31 | } 32 | resp = users 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /backend/pkg/services/trace/service_get_flame_data.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package trace 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | "go.uber.org/zap" 11 | ) 12 | 13 | func (s *service) GetFlameGraphData(ctx core.Context, req *request.GetFlameDataRequest) (resp response.GetFlameDataResponse, err error) { 14 | flameData, err := s.chRepo.GetFlameGraphData(ctx, req.StartTime, req.EndTime, req.NodeName, 15 | req.PID, req.TID, req.SampleType, req.SpanID, req.TraceID) 16 | if err != nil { 17 | return 18 | } 19 | 20 | if len(*flameData) == 0 { 21 | return 22 | } 23 | if len(*flameData) > 1 { 24 | s.logger.Warn("invoke level flame graph should have one flame data", zap.Int("got", len(*flameData))) 25 | } 26 | resp = (response.GetFlameDataResponse)((*flameData)[0]) 27 | return 28 | } 29 | -------------------------------------------------------------------------------- /backend/pkg/services/trace/service_get_on_off_cpu.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package trace 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | ) 11 | 12 | func (s *service) GetOnOffCPU(ctx core.Context, req *request.GetOnOffCPURequest) (*response.GetOnOffCPUResponse, error) { 13 | result, err := s.chRepo.GetOnOffCPU(ctx, req.PID, req.NodeName, req.StartTime, req.EndTime) 14 | if err != nil { 15 | return nil, err 16 | } 17 | resp := &response.GetOnOffCPUResponse{ 18 | ProfilingEvent: result, 19 | } 20 | return resp, nil 21 | } 22 | -------------------------------------------------------------------------------- /backend/pkg/services/trace/service_get_single_trace_info.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package trace 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | ) 10 | 11 | func (s *service) GetSingleTraceID(ctx core.Context, req *request.GetSingleTraceInfoRequest) (string, error) { 12 | result, err := s.jaegerRepo.GetSingleTrace(req.TraceID) 13 | if err != nil { 14 | return "", err 15 | } 16 | return result, nil 17 | } 18 | -------------------------------------------------------------------------------- /backend/pkg/services/trace/service_get_trace_filter_values.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package trace 5 | 6 | import ( 7 | "time" 8 | 9 | core "github.com/CloudDetail/apo/backend/pkg/core" 10 | "github.com/CloudDetail/apo/backend/pkg/model/request" 11 | "github.com/CloudDetail/apo/backend/pkg/model/response" 12 | "github.com/CloudDetail/apo/backend/pkg/repository/clickhouse" 13 | ) 14 | 15 | func (s *service) GetTraceFilterValues(ctx core.Context, startTime, endTime time.Time, searchText string, filter request.SpanTraceFilter) (*response.GetTraceFilterValueResponse, error) { 16 | option, err := s.chRepo.GetFieldValues(ctx, searchText, &filter, startTime, endTime) 17 | if err != nil { 18 | return &response.GetTraceFilterValueResponse{ 19 | TraceFilterOptions: clickhouse.SpanTraceOptions{ 20 | SpanTraceFilter: filter, 21 | Options: []string{}, 22 | }, 23 | }, err 24 | } 25 | 26 | return &response.GetTraceFilterValueResponse{ 27 | TraceFilterOptions: *option, 28 | }, nil 29 | } 30 | -------------------------------------------------------------------------------- /backend/pkg/services/trace/service_get_trace_filters.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package trace 5 | 6 | import ( 7 | "time" 8 | 9 | core "github.com/CloudDetail/apo/backend/pkg/core" 10 | "github.com/CloudDetail/apo/backend/pkg/model/request" 11 | "github.com/CloudDetail/apo/backend/pkg/model/response" 12 | ) 13 | 14 | func (s *service) GetTraceFilters(ctx core.Context, startTime, endTime time.Time, needUpdate bool) (*response.GetTraceFiltersResponse, error) { 15 | filters, err := s.chRepo.GetAvailableFilterKey(ctx, startTime, endTime, needUpdate) 16 | if err != nil { 17 | return &response.GetTraceFiltersResponse{ 18 | TraceFilters: []request.SpanTraceFilter{}, 19 | }, err 20 | } 21 | 22 | return &response.GetTraceFiltersResponse{ 23 | TraceFilters: filters, 24 | }, nil 25 | } 26 | -------------------------------------------------------------------------------- /backend/pkg/services/trace/service_get_trace_page_list.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package trace 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model" 9 | "github.com/CloudDetail/apo/backend/pkg/model/request" 10 | "github.com/CloudDetail/apo/backend/pkg/model/response" 11 | ) 12 | 13 | func (s *service) GetTracePageList(ctx core.Context, req *request.GetTracePageListRequest) (*response.GetTracePageListResponse, error) { 14 | list, total, err := s.chRepo.GetTracePageList(ctx, req) 15 | if err != nil { 16 | return nil, err 17 | } 18 | return &response.GetTracePageListResponse{ 19 | Pagination: &model.Pagination{ 20 | Total: total, 21 | CurrentPage: req.PageNum, 22 | PageSize: req.PageSize, 23 | }, 24 | List: list, 25 | }, nil 26 | } 27 | -------------------------------------------------------------------------------- /backend/pkg/services/user/service_get_user_team.go: -------------------------------------------------------------------------------- 1 | // Copyright 2025 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package user 5 | 6 | import ( 7 | "github.com/CloudDetail/apo/backend/pkg/code" 8 | core "github.com/CloudDetail/apo/backend/pkg/core" 9 | "github.com/CloudDetail/apo/backend/pkg/model/request" 10 | "github.com/CloudDetail/apo/backend/pkg/model/response" 11 | ) 12 | 13 | func (s *service) GetUserTeam(ctx core.Context, req *request.GetUserTeamRequest) (response.GetUserTeamResponse, error) { 14 | exists, err := s.dbRepo.UserExists(ctx, req.UserID) 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | if !exists { 20 | return nil, core.Error(code.UserNotExistsError, "user does not exist") 21 | } 22 | 23 | return s.dbRepo.GetAssignedTeam(ctx, req.UserID) 24 | } 25 | -------------------------------------------------------------------------------- /backend/pkg/services/user/service_login.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package user 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | "github.com/CloudDetail/apo/backend/pkg/model/response" 10 | "github.com/CloudDetail/apo/backend/pkg/util/jwt" 11 | ) 12 | 13 | func (s *service) Login(ctx core.Context, req *request.LoginRequest) (response.LoginResponse, error) { 14 | user, err := s.dbRepo.Login(ctx, req.Username, req.Password) 15 | if err != nil { 16 | return response.LoginResponse{}, err 17 | } 18 | accessToken, refreshToken, err := jwt.GenerateTokens(user.Username, user.UserID) 19 | if err != nil { 20 | return response.LoginResponse{}, err 21 | } 22 | resp := response.LoginResponse{ 23 | AccessToken: accessToken, 24 | RefreshToken: refreshToken, 25 | User: *user, 26 | } 27 | return resp, nil 28 | } 29 | -------------------------------------------------------------------------------- /backend/pkg/services/user/service_logout.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package user 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/request" 9 | ) 10 | 11 | func (s *service) Logout(ctx core.Context, req *request.LogoutRequest) error { 12 | err := s.cacheRepo.AddToken(ctx, req.AccessToken) 13 | if err != nil { 14 | return err 15 | } 16 | 17 | err = s.cacheRepo.AddToken(ctx, req.RefreshToken) 18 | if err != nil { 19 | return err 20 | } 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /backend/pkg/services/user/service_refresh_token.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package user 5 | 6 | import ( 7 | core "github.com/CloudDetail/apo/backend/pkg/core" 8 | "github.com/CloudDetail/apo/backend/pkg/model/response" 9 | "github.com/CloudDetail/apo/backend/pkg/util/jwt" 10 | ) 11 | 12 | func (s *service) RefreshToken(ctx core.Context, token string) (response.RefreshTokenResponse, error) { 13 | accessToken, err := jwt.RefreshToken(token) 14 | var resp response.RefreshTokenResponse 15 | if err != nil { 16 | return resp, err 17 | } 18 | resp.AccessToken = accessToken 19 | return resp, nil 20 | } 21 | 22 | func (s *service) IsInBlacklist(ctx core.Context, token string) (bool, error) { 23 | return s.cacheRepo.IsInBlacklist(ctx, token) 24 | } 25 | -------------------------------------------------------------------------------- /backend/pkg/services/utils/filter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package utils 5 | 6 | type Filter interface { 7 | ExtractFilterStr() []string 8 | } 9 | -------------------------------------------------------------------------------- /backend/pkg/util/array.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | func ContainsStr(arr []string, target string) bool { 7 | for _, value := range arr { 8 | if value == target { 9 | return true 10 | } 11 | } 12 | return false 13 | } 14 | -------------------------------------------------------------------------------- /backend/pkg/util/id_generator.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "sync" 8 | "time" 9 | ) 10 | 11 | const ( 12 | epoch = int64(1726588800000) 13 | sequenceBits = 5 14 | maxSequence = -1 ^ (-1 << sequenceBits) 15 | timeShift = sequenceBits 16 | ) 17 | 18 | type IDGenerator struct { 19 | mu sync.Mutex 20 | lastTime int64 21 | sequence int64 22 | } 23 | 24 | var Generator = &IDGenerator{} 25 | 26 | func (g *IDGenerator) GenerateID() int64 { 27 | g.mu.Lock() 28 | defer g.mu.Unlock() 29 | 30 | now := time.Now().UnixMilli() 31 | 32 | if now == g.lastTime { 33 | g.sequence = (g.sequence + 1) & maxSequence 34 | if g.sequence == 0 { 35 | for now <= g.lastTime { 36 | now = time.Now().UnixMilli() 37 | } 38 | } 39 | } else { 40 | g.sequence = 0 41 | } 42 | 43 | g.lastTime = now 44 | 45 | id := ((now - epoch) << timeShift) | g.sequence 46 | return id 47 | } 48 | -------------------------------------------------------------------------------- /backend/pkg/util/id_generator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "fmt" 8 | "github.com/stretchr/testify/assert" 9 | "sync" 10 | "testing" 11 | ) 12 | 13 | func TestGenerator(t *testing.T) { 14 | ch := make(chan int64, 100) 15 | wg := sync.WaitGroup{} 16 | for i := 0; i < 10; i++ { 17 | wg.Add(1) 18 | go func() { 19 | defer wg.Done() 20 | for j := 0; j < 10; j++ { 21 | ch <- Generator.GenerateID() 22 | } 23 | }() 24 | } 25 | 26 | m := make(map[int64]struct{}) 27 | go func() { 28 | for id := range ch { 29 | _, ok := m[id] 30 | fmt.Println(id) 31 | assert.False(t, ok) 32 | } 33 | }() 34 | 35 | wg.Wait() 36 | } 37 | -------------------------------------------------------------------------------- /backend/pkg/util/validate_sql.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "fmt" 8 | "strings" 9 | ) 10 | 11 | func ValidateSQL(sql string) (string, error) { 12 | sql = strings.TrimSpace(sql) 13 | if sql == "" { 14 | return "", fmt.Errorf("SQL statement is empty") 15 | } 16 | 17 | sqlLower := strings.ToLower(sql) 18 | 19 | if strings.Contains(sqlLower, "delete from") { 20 | if !strings.Contains(sqlLower, "where") { 21 | return "", fmt.Errorf("DELETE without WHERE clause is not allowed") 22 | } 23 | } 24 | 25 | validCommands := []string{"select", "insert", "update", "delete", "create", "alter", "drop", "truncate"} 26 | hasValidCommand := false 27 | for _, cmd := range validCommands { 28 | if strings.Contains(sqlLower, cmd) { 29 | hasValidCommand = true 30 | break 31 | } 32 | } 33 | if !hasValidCommand { 34 | return "", fmt.Errorf("SQL statement lacks a recognized command (e.g., SELECT, INSERT, UPDATE)") 35 | } 36 | 37 | return sql, nil 38 | } 39 | -------------------------------------------------------------------------------- /backend/pkg/util/wrap_funcs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 CloudDetail 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func WrapHandlerFunctions(rawFuncs ...http.HandlerFunc) []gin.HandlerFunc { 13 | funcs := make([]gin.HandlerFunc, len(rawFuncs)) 14 | for i, f := range rawFuncs { 15 | funcs[i] = func(c *gin.Context) { 16 | f(c.Writer, c.Request) 17 | } 18 | } 19 | 20 | return funcs 21 | } 22 | -------------------------------------------------------------------------------- /backend/sqlscripts/feature_api.yml: -------------------------------------------------------------------------------- 1 | 服务概览: 2 | - path: "/api/service/endpoints" 3 | method: "GET" -------------------------------------------------------------------------------- /backend/sqlscripts/upgrade/target_tags/1.5.1-upgrade.sql: -------------------------------------------------------------------------------- 1 | -- id is an auto-increment primary key 2 | -- 0 has a special meaning during execution and must not be used 3 | 4 | UPDATE target_tags SET id = 100 WHERE id = 0; 5 | UPDATE alert_enrich_rules SET target_tag_id = 100 WHERE target_tag_id = 0; -------------------------------------------------------------------------------- /backend/static/integration-tmpl/dockercompose/install.md.tmpl: -------------------------------------------------------------------------------- 1 | # 安装命令 2 | 3 | 传统服务器中使用Docker Compose安装和管理oneAgent服务. 4 | 5 | 在需要监控的服务器上依次执行: 6 | 1. 下载配置文件 7 | 2. 下载部署包并执行安装命令 8 | 9 | 10 | ## 1.下载配置文件 11 | 12 | ```bash 13 | curl -Lo installCfg.sh \ 14 | http://{{ .apoCollector.collectorGatewayAddr }}:{{ default .apoCollector.ports.apoBackend 31363 }}/api/integration/cluster/install/config?clusterId={{ .id}} 15 | ``` 16 | 17 | ## 2.下载部署包并执行安装命令 18 | 19 | 使用下面的命令下载部署包并进行安装 20 | 21 | ```bash 22 | curl -Lo apo-one-agent-compose-{{ ._deploy_version }}.tgz \ 23 | https://apo-ce.oss-cn-hangzhou.aliyuncs.com/apo-one-agent-compose-{{ ._deploy_version }}.tgz 24 | bash ./installCfg.sh 25 | ``` 26 | -------------------------------------------------------------------------------- /backend/static/integration-tmpl/dockercompose/installCfg.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # global 6 | export DEPLOY_VERSION={{ ._deploy_version }} 7 | export JAVA_AGENT_TYPE={{ default ._java_agent_type "OPENTELEMETRY" }} 8 | export TRACE_MODE={{ default ._modes.trace "trace" }} 9 | 10 | # network 11 | export APO_COLLECTOR_PORT={{ default .apoCollector.ports.apoCollector 30044 }} 12 | export APO_OTEL_COLLECTOR_GRPCPORT={{ default .apoCollector.ports.apoOtelCollectorGatewayGrpc 30317 }} 13 | export APO_VECTOR_PORT={{ default .apoCollector.ports.apoVector 30310 }} 14 | 15 | echo "Unzip docker compose tarball: apo-one-agent-compose-{{ ._deploy_version }}.tgz" 16 | tar -zxvf apo-one-agent-compose-{{ ._deploy_version }}.tgz 17 | 18 | cd apo-one-agent-compose && bash deploy.sh init {{ .apoCollector.collectorGatewayAddr }} 19 | -------------------------------------------------------------------------------- /backend/static/integration-tmpl/kubernetes/install.md.tmpl: -------------------------------------------------------------------------------- 1 | # 安装命令 2 | 3 | ## 通过helm安装 4 | 5 | 在需要监控的集群的主机上依次执行: 6 | 7 | 1. 下载安装配置 8 | 2. 使用helm命令安装 9 | 10 | ### 1.下载安装配置 11 | 12 | 使用下面的命令下载配置文件,或点击下面的集群安装配置按钮下载配置文件. 13 | 14 | ```bash 15 | curl -Lo apo-one-agent-values.yaml \ 16 | http://{{ .apoCollector.collectorGatewayAddr }}:{{ default .apoCollector.ports.apoBackend 31363 }}/api/integration/cluster/install/config?clusterId={{ .id}} 17 | ``` 18 | 19 | ### 2.使用helm命令安装 20 | 21 | ```bash 22 | helm repo add apo https://apo-charts.oss-cn-hangzhou.aliyuncs.com 23 | helm repo update apo 24 | helm install apo-one-agent apo/apo-one-agent -n apo \ 25 | --create-namespace \ 26 | --version {{ ._chart_version }} \ 27 | -f apo-one-agent-values.yaml 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/img/alert-events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/docs/img/alert-events.png -------------------------------------------------------------------------------- /docs/img/apo-select-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/docs/img/apo-select-tools.png -------------------------------------------------------------------------------- /docs/img/charts-verifiability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/docs/img/charts-verifiability.png -------------------------------------------------------------------------------- /docs/img/data-plane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/docs/img/data-plane.png -------------------------------------------------------------------------------- /docs/img/service-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/docs/img/service-detail.png -------------------------------------------------------------------------------- /docs/img/service-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/docs/img/service-map.png -------------------------------------------------------------------------------- /docs/img/workflows-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/docs/img/workflows-list.png -------------------------------------------------------------------------------- /frontend/.browserslistrc: -------------------------------------------------------------------------------- 1 | # https://github.com/browserslist/browserslist#readme 2 | 3 | [production] 4 | >0.2% 5 | not dead 6 | not op_mini all 7 | 8 | [development] 9 | last 1 chrome version 10 | last 1 firefox version 11 | last 1 safari version 12 | -------------------------------------------------------------------------------- /frontend/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | max_line_length = off 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /frontend/.env: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | VITE_APP_CODE_VERSION = "CE" 7 | VITE_DARK_THEME_MAIN_COLOR= "#1677ff" 8 | VITE_LIGHT_THEME_MAIN_COLOR= "#1677ff" 9 | # VITE_LIGHT_THEME_MAIN_COLOR= "#02706b" 10 | -------------------------------------------------------------------------------- /frontend/.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | package-lock.json 6 | yarn.lock 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .eslintcache 16 | .DS_Store 17 | .idea 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /frontend/.prettierignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /frontend/.prettierrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | module.exports = { 7 | semi: false, 8 | trailingComma: 'all', 9 | singleQuote: true, 10 | printWidth: 100, 11 | tabWidth: 2, 12 | } 13 | -------------------------------------------------------------------------------- /frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:22.3.0-alpine3.19 as build 2 | 3 | WORKDIR /app/ 4 | 5 | COPY package.json ./ 6 | 7 | RUN yarn install 8 | 9 | COPY . . 10 | 11 | ENV NODE_OPTIONS --openssl-legacy-provider 12 | ARG VITE_PUBLIC_POSTHOG_HOST 13 | ARG VITE_PUBLIC_POSTHOG_KEY 14 | 15 | RUN yarn build 16 | 17 | FROM nginx:alpine 18 | 19 | COPY --from=build /app/build /usr/share/nginx/html 20 | COPY ./nginx.conf /etc/nginx/conf.d/default.conf 21 | 22 | EXPOSE 80 23 | 24 | CMD ["nginx", "-g", "daemon off;"] 25 | 26 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | ### Installation 2 | 3 | ``` bash 4 | $ npm install 5 | ``` 6 | 7 | or 8 | 9 | ``` bash 10 | $ yarn install 11 | ``` 12 | 13 | ### Basic usage 14 | 15 | ``` bash 16 | # dev server with hot reload at http://localhost:3000 17 | $ npm start 18 | ``` 19 | 20 | or 21 | 22 | ``` bash 23 | # dev server with hot reload at http://localhost:3000 24 | $ yarn start 25 | ``` 26 | 27 | Navigate to [http://localhost:3000](http://localhost:3000). The app will automatically reload if you change any of the source files. 28 | 29 | #### Build 30 | 31 | Run `build` to build the project. The build artifacts will be stored in the `build/` directory. 32 | 33 | ```bash 34 | # build for production with minification 35 | $ npm run build 36 | ``` 37 | 38 | or 39 | 40 | ```bash 41 | # build for production with minification 42 | $ yarn build 43 | ``` -------------------------------------------------------------------------------- /frontend/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/public/bg.jpg -------------------------------------------------------------------------------- /frontend/public/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | window.__APP_CONFIG__ = { 7 | themes: { 8 | light: { 9 | // colorPrimary: '#02706b', 10 | colorPrimary: '#1677ff', 11 | }, 12 | dark: { 13 | colorPrimary: '#1677ff', 14 | }, 15 | }, 16 | apoChartVersion: 'v1.2.0', 17 | } 18 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/locales/en/core/CustomSelect.json: -------------------------------------------------------------------------------- 1 | { 2 | "placeholderText": "Please Select" 3 | } 4 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/customSelect.json: -------------------------------------------------------------------------------- 1 | { 2 | "placeholderText": "Please Select" 3 | } 4 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "noData": "No data" 3 | } 4 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "title": "APO", 4 | "username": "Username", 5 | "password": "Password", 6 | "login": "Login", 7 | "loginSuccess": "Login successful", 8 | "enterUsername": "Please enter username", 9 | "enterPassword": "Please enter password" 10 | }, 11 | "request": { 12 | "notLoggedIn": "Not logged in, please log in first", 13 | "loginExpired": "Login expired, please log in again", 14 | "accessDenied": "Access denied", 15 | "requestFailed": "Request failed" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/menuManage.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "selectAll": "Select All", 4 | "save": "Save", 5 | "menuConfigSuccess": "Menu configuration successful", 6 | "errorFetchingPermissions": "Error fetching permissions", 7 | "roleList": "Role List", 8 | "menuPermissionSetting": "Menu Permissions Setting", 9 | "selectRole": "Please select a role", 10 | "menuSetSuccess": "Menu setting successful" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/permission.json: -------------------------------------------------------------------------------- 1 | { 2 | "permissions": "Data Group Permissions", 3 | "authorized": "Authorization Data Group", 4 | "authorizedSuccess": "Authorization data group successfully", 5 | "dataGroupName": "Data Group Name", 6 | "dataGroupDes": "Data Group Description", 7 | "datasource": "Data Source", 8 | "username": "Username", 9 | "teamName": "Team Name", 10 | "dataGroupAlert": "Data group permissions of the user's team", 11 | "tagTooltip": "This data group originates from the user's team.", 12 | "permissionsFromTeam": " Data group permissions inherited from the team", 13 | "permissionsFromUser": "User-managed data group permissions" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/polarisMetrics.json: -------------------------------------------------------------------------------- 1 | { 2 | "glossaryTable": { 3 | "type": "Type", 4 | "meaning": "Meaning" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/systemConfiguration.json: -------------------------------------------------------------------------------- 1 | { 2 | "configItem": "Configuration Item", 3 | "language": "Language", 4 | "languageSuccess": "Language switch success" 5 | } 6 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/table.json: -------------------------------------------------------------------------------- 1 | { 2 | "unsort": "Unsorted", 3 | "desc": "Click to sort in descending order", 4 | "asc": "Click to sort in ascending order", 5 | "pagination": "Total {{total}} items" 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/team.json: -------------------------------------------------------------------------------- 1 | { 2 | "teamName": "Team Name", 3 | "authorize": "Data Permissions", 4 | "description": "Description", 5 | "team": "Team", 6 | "userList": "Members", 7 | "confirmDelete": "Are you sure you want to delete the team {{teamName}}?" 8 | } 9 | -------------------------------------------------------------------------------- /frontend/public/locales/en/core/userToolBox.json: -------------------------------------------------------------------------------- 1 | { 2 | "personalCenter": "Profile", 3 | "logout": "Logout", 4 | "logoutSuccess": "Logout successfully", 5 | "login": "Login" 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/locales/en/oss/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "configTTL": { 3 | "title": "Data Retention", 4 | "updateInfo": "Changes may take a moment to apply. Refresh the page later to see updates.", 5 | "confirmUpdate": "After confirmation, the data retention period for all tables under {{type}} data will be updated synchronously", 6 | "confirm": "Confirm", 7 | "cancel": "Cancel", 8 | "update": "Update", 9 | "days": "days", 10 | "data": "" 11 | }, 12 | "TTLTable": { 13 | "tableName": "Table Name", 14 | "dataRetention": "Data Retention (days)", 15 | "operation": "Operation", 16 | "update": "Update", 17 | "cancel": "Cancel", 18 | "edit": "Edit", 19 | "updateInfo": "Data retention configuration may take some time to take effect, please refresh the page later to see the results", 20 | "validationMessage": "{{title}} must be a number greater than 0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/public/locales/en/oss/faultSiteLogs.json: -------------------------------------------------------------------------------- 1 | { 2 | "faultSiteLogs": { 3 | "faultLogTableToast1": "Console logs are collected by default. Refer to ", 4 | "faultLogTableToast2": " for file-based log collection setup.", 5 | "documentText": "Configure Log Collection", 6 | "faultLogsText": "FaultLogs", 7 | "endpoint": "Endpoint", 8 | "timeOfFailure": "Time", 9 | "specificLogInformation": "Specific log information", 10 | "enterSWTraceId": "Enter the SkyWalking traceid, it will be automatically converted" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /frontend/public/locales/en/oss/middleware.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "toastMessage": "For configuration of middleware metrics collection, please refer to \u00A0", 4 | "documentation": "Middleware Monitoring Configuration Guide" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/locales/en/oss/trace.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "faultSite": "Fault Tracese", 4 | "full": "All Traces" 5 | }, 6 | "trace": { 7 | "serviceName": "Application", 8 | "namespace": "Namespace", 9 | "instanceName": "Instance", 10 | "endpoint": "Endpoint", 11 | "faultStatus": "Status", 12 | "slowFault": "Slow: Response time exceeds historical baseline", 13 | "errorFault": "Error: Error status code or code exception", 14 | "noFault": "OK: Normal sampled data", 15 | "responseTime": "Duration", 16 | "occurTime": "Time", 17 | "traceId": "TraceID", 18 | "operation": "Action", 19 | "viewLogs": "View Logs" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /frontend/public/locales/en/oss/workflow.json: -------------------------------------------------------------------------------- 1 | { 2 | "workflowError": "Workflow Error. Please contact the administrator " 3 | } 4 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/customSelect.json: -------------------------------------------------------------------------------- 1 | { 2 | "placeholderText": "请选择" 3 | } 4 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/dataGroup.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": "数据组", 3 | "deleteSuccess": "删除成功", 4 | "dataGroupName": "数据组名", 5 | "dataGroupDes": "数据组描述", 6 | "datasource": "数据源", 7 | "operation": "操作", 8 | "confirmDelete": "是否确定删除数据组{{groupName}}?", 9 | "confirm": "确定", 10 | "cancel": "取消", 11 | "delete": "删除", 12 | "authorize": "授权", 13 | "add": "新增", 14 | "saveSuccess": "保存数据组成功", 15 | "edit": "编辑", 16 | "save": "保存", 17 | "nsView": "命名空间视图", 18 | "serviceView": "服务名视图", 19 | "savePermissionSuccess": "数据组授权成功", 20 | "dataGroupAuthorize": "数据组授权", 21 | "authorizeToUser": "授权用户", 22 | "authorizeToTeam": "授权团队", 23 | "groupManage": "管理数据组", 24 | "nested": "服务名所属的命名空间", 25 | "nsViewAlert1": "整体监控:选中命名空间节点,自动监控该命名空间下的所有服务,服务变化时自动更新。", 26 | "nsViewAlert2": "精细监控:可单独选择服务节点,仅监控该服务。", 27 | "appAlert": "仅监控所选服务,独立于命名空间。" 28 | } 29 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/dateTime.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTimeRangePicker": { 3 | "selectCorrectTimeRangeFeedback": "请输入或选择正确的日期", 4 | "startTimeLongerThanEndTime": "开始时间不能晚于结束时间", 5 | "endTimeLessThanStartTime": "结束时间不能早于开始时间", 6 | "endTimeLongerThanCurrentTimeFeedback": "结束时间不能超过当前时间", 7 | "absoluteTimeRangeTitle": "绝对时间范围", 8 | "startTitle": "开始", 9 | "endTitle": "结束", 10 | "applyTimeRangeButtonText": "应用时间范围", 11 | "quickRangeTitle": "快速范围" 12 | }, 13 | "refreshDateTime": { 14 | "RefreshDateTimeOffText": "关" 15 | }, 16 | "timeSinceRefresh": { 17 | "dayText": "天", 18 | "hourText": "小时", 19 | "minuteText": "分钟", 20 | "secondText": "秒", 21 | "refreshTipText": "刷新于", 22 | "refreshTipTextAgo": "前" 23 | }, 24 | "dataTimeCombine": { 25 | "absoluteTimeText": "绝对时间", 26 | "relativeTimeText": "相对时间" 27 | }, 28 | "group": "自动刷新间隔", 29 | "refresh": "刷新时间" 30 | } 31 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "noData": "暂无数据" 3 | } 4 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "title": "向导式可观测平台", 4 | "username": "用户名", 5 | "password": "密码", 6 | "login": "登录", 7 | "loginSuccess": "登录成功", 8 | "enterUsername": "请输入用户名", 9 | "enterPassword": "请输入密码" 10 | }, 11 | "request": { 12 | "notLoggedIn": "未登录,请先登录", 13 | "loginExpired": "登录过期,请重新登录", 14 | "accessDenied": "拒绝访问", 15 | "requestFailed": "请求失败" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/mask.json: -------------------------------------------------------------------------------- 1 | { 2 | "coachMaskTitle": "服务详情指南", 3 | "scenes": { 4 | "alertAnalysis": "告警分析", 5 | "impactAnalysis": "影响面分析", 6 | "cascadeAlertAnalysis": "级联告警影响分析", 7 | "saturationAnalysis": "饱和度分析", 8 | "networkQualityAnalysis": "网络质量分析", 9 | "errorClosedLoop": "错误闭环", 10 | "latencyClosedLoop": "延时闭环", 11 | "faultEvidence": "故障佐证", 12 | "environmentImpact": "环境影响" 13 | }, 14 | "descriptions": { 15 | "alertInfo": "接口自身的告警信息、应用层告警和资源层告警", 16 | "entryImpact": "可能受该接口影响的所有服务入口分析", 17 | "cascadeAlert": "接口的下游依赖告警关联", 18 | "instanceMetrics": "接口的实例和节点的资源指标", 19 | "networkMetrics": "接口的网络指标", 20 | "errorLogs": "接口的代码Exception,以及含有Exception的日志", 21 | "polarisMetrics": "接口执行的北极星指标", 22 | "logs": "接口执行的日志", 23 | "trace": "接口执行的Trace", 24 | "k8sEvents": "接口所依赖的容器环境关键事件" 25 | }, 26 | "comingSoon": "敬请期待", 27 | "closeGuide": "关闭指南", 28 | "clickToEnlarge": "点击放大" 29 | } 30 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/menuManage.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "selectAll": "选择全部", 4 | "save": "保存", 5 | "menuConfigSuccess": "菜单配置成功", 6 | "errorFetchingPermissions": "获取权限时出错", 7 | "roleList": "角色列表", 8 | "menuPermissionSetting": "菜单权限配置", 9 | "selectRole": "请选择角色", 10 | "menuSetSuccess": "菜单配置成功" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/permission.json: -------------------------------------------------------------------------------- 1 | { 2 | "permissions": "数据组权限", 3 | "authorized": "授权数据组", 4 | "authorizedSuccess": "授权数据组成功", 5 | "dataGroupName": "数据组名", 6 | "dataGroupDes": "数据组描述", 7 | "datasource": "数据源", 8 | "username": "用户名", 9 | "teamName": "团队名", 10 | "dataGroupAlert": "可为用户单独配置数据组权限,不可删除的数据组来自用户所属团队。", 11 | "tagTooltip": "该数据组来自用户所属团队。", 12 | "permissionsFromTeam": "用户继承自团队的数据组权限", 13 | "permissionsFromUser": "用户可自行配置的数据组权限" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/polarisMetrics.json: -------------------------------------------------------------------------------- 1 | { 2 | "glossaryTable": { 3 | "type": "类型", 4 | "meaning": "含义" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "servicesName": "服务概览", 3 | "serviceDetailName": "服务详情", 4 | "faultLogsName": "故障现场日志", 5 | "allLogsName": "全量日志", 6 | "faultSiteTraces": "故障现场链路", 7 | "allTrace": "全量链路", 8 | "infrastructureDashboardName": "应用基础设施大盘", 9 | "overviewDashboardName": "全局资源大盘", 10 | "applicationDashboardName": "应用指标大盘", 11 | "middlewareDashboardName": "中间件大盘", 12 | "alertRulesName": "告警规则", 13 | "notificationChannelsName": "告警通知", 14 | "configurationsName": "配置中心", 15 | "systemSettingsName": "系统管理", 16 | "userManageName": "用户管理", 17 | "userCenterName": "个人中心", 18 | "menuManageName": "菜单管理", 19 | "roleManageName": "角色管理", 20 | "systemConfigName": "系统配置", 21 | "alertsIntegration": "告警接入", 22 | "dataGroup": "数据组管理", 23 | "team": "团队管理", 24 | "dataIntegration": "数据接入", 25 | "dataIntegrationSettings": "集群接入", 26 | "alertEvents": "告警事件", 27 | "workflows": "工作流", 28 | "eventDetail": "告警事件详情" 29 | } 30 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/systemConfiguration.json: -------------------------------------------------------------------------------- 1 | { 2 | "configItem": "配置项", 3 | "language": "语言", 4 | "languageSuccess": "语言切换成功" 5 | } 6 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/table.json: -------------------------------------------------------------------------------- 1 | { 2 | "unsort": "取消排序", 3 | "desc": "点击降序", 4 | "asc": "点击升序", 5 | "pagination": "总计{{total}}条数据" 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/team.json: -------------------------------------------------------------------------------- 1 | { 2 | "teamName": "团队名", 3 | "authorize": "数据权限", 4 | "description": "描述", 5 | "team": "团队", 6 | "userList": "团队成员", 7 | "confirmDelete": "是否确认删除名为{{teamName}}的团队?" 8 | } 9 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/core/userToolBox.json: -------------------------------------------------------------------------------- 1 | { 2 | "personalCenter": "个人中心", 3 | "logout": "退出登录", 4 | "logoutSuccess": "退出登录成功", 5 | "login": "登录" 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/oss/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "configTTL": { 3 | "title": "数据保留周期配置", 4 | "updateInfo": "更新可能需一定时间生效,请稍后刷新页面查看结果。", 5 | "confirmUpdate": "确认后将同步更新{{type}}数据下所有表格的数据保留周期", 6 | "confirm": "确认", 7 | "cancel": "取消", 8 | "update": "更新", 9 | "days": "天", 10 | "data": "数据" 11 | }, 12 | "TTLTable": { 13 | "tableName": "表名", 14 | "dataRetention": "数据保留(天)", 15 | "operation": "操作", 16 | "update": "更新", 17 | "cancel": "取消", 18 | "edit": "编辑", 19 | "updateInfo": "配置数据保留周期可能需一定时间生效,请稍后刷新页面查看结果", 20 | "validationMessage": "{{title}}必须为大于0 的数字" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/oss/faultSiteLogs.json: -------------------------------------------------------------------------------- 1 | { 2 | "faultSiteLogs": { 3 | "faultLogTableToast": "默认采集控制台日志,从文件中采集日志的配置方式请参考", 4 | "documentText": "配置采集日志", 5 | "faultLogsText": "故障现场日志", 6 | "endpoint": "服务端点", 7 | "timeOfFailure": "故障发生时间", 8 | "specificLogInformation": "具体日志信息" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/oss/middleware.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "toastMessage": "采集中间件指标的配置方式请参考", 4 | "documentation": "监控中间件配置指南" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/oss/trace.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "faultSite": "故障现场链路", 4 | "full": "全量链路" 5 | }, 6 | "trace": { 7 | "serviceName": "服务名", 8 | "namespace": "命名空间", 9 | "instanceName": "实例名", 10 | "endpoint": "服务端点", 11 | "faultStatus": "故障状态", 12 | "slowFault": "慢故障:响应时间超过历史基线", 13 | "errorFault": "错误故障:存在错误状态码或代码异常", 14 | "noFault": "无异常:被采样的正常数据", 15 | "responseTime": "响应时间", 16 | "occurTime": "发生时间", 17 | "traceId": "TraceID", 18 | "operation": "操作", 19 | "viewLogs": "查看日志" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /frontend/public/locales/zh/oss/workflow.json: -------------------------------------------------------------------------------- 1 | { "workflowError": "工作流获取异常,请联系管理员" } 2 | -------------------------------------------------------------------------------- /frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /frontend/public/mini_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/public/mini_logo.png -------------------------------------------------------------------------------- /frontend/src/core/api/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { get, post } from 'src/core/utils/request' 7 | 8 | // 获取TTL 9 | export const getTTLApi = () => { 10 | return get(`/api/config/getTTL`) 11 | } 12 | //设置TTL 13 | export const setTTLApi = (params) => { 14 | return post(`/api/config/setTTL`, params) 15 | } 16 | //设置单个TTL 17 | export const setSingleTableTTLApi = (params) => { 18 | return post(`/api/config/setSingleTableTTL`, params) 19 | } 20 | -------------------------------------------------------------------------------- /frontend/src/core/api/permission.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { get, headers, post } from '../utils/request' 7 | 8 | //获取用户权限(菜单+路由) 9 | export function getUserPermissionApi(params) { 10 | return get('/api/permission/config', params) 11 | } 12 | //获取所有可配置权限 13 | export function getAllPermissionApi(params) { 14 | return get('/api/permission/feature', params) 15 | } 16 | //配置全局菜单 17 | export function configMenuApi(params) { 18 | return post('/api/permission/menu/configure', params, headers.formUrlencoded) 19 | } 20 | //获取所有角色列表 21 | export function getAllRoleList() { 22 | return get('/api/permission/roles') 23 | } 24 | 25 | //获取角色或用户的所有权限列表 26 | export function getSubjectPermissionApi(params) { 27 | return get('/api/permission/sub/feature', params) 28 | } 29 | 30 | // Get router permission 31 | export function getRouterPermissionApi(params) { 32 | return get('/api/permission/router', params) 33 | } 34 | -------------------------------------------------------------------------------- /frontend/src/core/api/role.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { get, headers, post } from '../utils/request' 7 | 8 | export interface Role { 9 | roleId: number; // Role ID 10 | roleName: string; // Role Name 11 | description: string; // Role Description 12 | } 13 | 14 | export function getAllRolesApi() { 15 | return get('/api/role/roles'); 16 | } 17 | 18 | export function revokeUserRoleApi(params) { 19 | return post(`/api/role/operation`, params, headers.formUrlencoded) 20 | } 21 | 22 | export function deleteRoleApi(params) { 23 | return post(`/api/role/delete`, params, headers.formUrlencoded) 24 | } 25 | 26 | export function createRoleApi(params) { 27 | return post(`/api/role/create`, params, headers.formUrlencoded) 28 | } 29 | 30 | export function updateRoleApi(params) { 31 | return post(`/api/role/update`, params, headers.formUrlencoded) 32 | } -------------------------------------------------------------------------------- /frontend/src/core/api/team.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { GetTeamParams, SaveTeamParams, TeamParams } from '../types/team' 7 | import { get, headers, post } from '../utils/request' 8 | 9 | export function getTeamsApi(params: GetTeamParams) { 10 | return get('/api/team', params) 11 | } 12 | 13 | export function addTeamApi(params: SaveTeamParams) { 14 | return post('/api/team/create', params) 15 | } 16 | export function updateTeamApi(params: SaveTeamParams) { 17 | return post('/api/team/update', params) 18 | } 19 | export function deleteTeamApi(teamId: string) { 20 | return post('/api/team/delete', { teamId }, headers.formUrlencoded) 21 | } 22 | -------------------------------------------------------------------------------- /frontend/src/core/api/trace.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { post } from 'src/core/utils/request' 7 | 8 | // 获取trace日志 9 | export const getTracePageListApi = (params) => { 10 | return post(`/api/trace/pagelist`, params) 11 | } 12 | -------------------------------------------------------------------------------- /frontend/src/core/api/workflows.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { get, post } from "../utils/request" 7 | 8 | 9 | export const workflowLoginApi = (params) =>{ 10 | return post('/dify/console/api/login/apo',params) 11 | } 12 | export const workflowLogoutApi = () =>{ 13 | return get('/dify/console/api/logout') 14 | } 15 | export const workflowAnonymousLoginApi = (params) =>{ 16 | return post('/dify/console/api/login/apo/anonymous',params) 17 | } -------------------------------------------------------------------------------- /frontend/src/core/assets/alertsIntegration/zabbix/image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/alertsIntegration/zabbix/image-1.png -------------------------------------------------------------------------------- /frontend/src/core/assets/alertsIntegration/zabbix/image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/alertsIntegration/zabbix/image-2.png -------------------------------------------------------------------------------- /frontend/src/core/assets/alertsIntegration/zabbix/image-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/alertsIntegration/zabbix/image-3.png -------------------------------------------------------------------------------- /frontend/src/core/assets/alertsIntegration/zabbix/image-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/alertsIntegration/zabbix/image-4.png -------------------------------------------------------------------------------- /frontend/src/core/assets/alertsIntegration/zabbix/image-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/alertsIntegration/zabbix/image-5.png -------------------------------------------------------------------------------- /frontend/src/core/assets/alertsIntegration/zabbix/image-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/alertsIntegration/zabbix/image-6.png -------------------------------------------------------------------------------- /frontend/src/core/assets/brand/bg-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/brand/bg-light.png -------------------------------------------------------------------------------- /frontend/src/core/assets/brand/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/brand/bg.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/brand/sygnet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | export const sygnet = [ 7 | '102 115', 8 | ` 9 | 10 | 11 | `, 12 | ] 13 | -------------------------------------------------------------------------------- /frontend/src/core/assets/dataCollector/clickhouse.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /frontend/src/core/assets/dataCollector/other.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/core/assets/dataCollector/pinpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/dataCollector/pinpoint.png -------------------------------------------------------------------------------- /frontend/src/core/assets/icons/thumbsUp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/core/assets/images/angular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/angular.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/1.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/2.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/3.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/4.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/5.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/6.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/7.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/8.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/avatars/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/avatars/9.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/flameGraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/flameGraph.png -------------------------------------------------------------------------------- /frontend/src/core/assets/images/hexagon-red.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/core/assets/images/k8s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/k8s.png -------------------------------------------------------------------------------- /frontend/src/core/assets/images/node/hexagon-green.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/core/assets/images/node/hexagon-grey.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/core/assets/images/node/hexagon-red.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/core/assets/images/polaris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/polaris.png -------------------------------------------------------------------------------- /frontend/src/core/assets/images/react.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/react.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/images/tooltip3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/tooltip3.png -------------------------------------------------------------------------------- /frontend/src/core/assets/images/unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/unknown.png -------------------------------------------------------------------------------- /frontend/src/core/assets/images/vue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/images/vue.jpg -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/alert.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/cpu.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/dashboard.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/entry.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/exception.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/instance.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/k8s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/k8s.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/logs.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/polaris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/polaris.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/en/trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/en/trace.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/alert.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/cpu.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/dashboard.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/entry.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/exception.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/instance.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/k8s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/k8s.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/logs.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/polaris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/polaris.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/dark/zh/trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/dark/zh/trace.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/alert.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/cpu.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/dashboard.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/entry.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/exception.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/instance.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/k8s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/k8s.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/logs.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/polaris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/polaris.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/en/trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/en/trace.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/alert.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/cpu.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/dashboard.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/entry.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/exception.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/instance.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/k8s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/k8s.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/logs.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/polaris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/polaris.png -------------------------------------------------------------------------------- /frontend/src/core/assets/snapshot/light/zh/trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudDetail/apo/04834f30151be80a0071a0903c76ef43859f4e7c/frontend/src/core/assets/snapshot/light/zh/trace.png -------------------------------------------------------------------------------- /frontend/src/core/components/AppFooter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import React from 'react' 7 | import { CFooter } from '@coreui/react' 8 | 9 | const AppFooter = () => { 10 | return ( 11 | 12 |
13 | 14 | CoreUI 15 | 16 | © 2024 creativeLabs. 17 |
18 |
19 | Powered by 20 | 21 | CoreUI React Admin & Dashboard Template 22 | 23 |
24 |
25 | ) 26 | } 27 | 28 | export default React.memo(AppFooter) 29 | -------------------------------------------------------------------------------- /frontend/src/core/components/Card/CardSlots.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | export const SLOT_TYPES = { 7 | LOADING: Symbol('CardLoading'), 8 | HEADER: Symbol('CardHeader'), 9 | TABLE: Symbol('CardTable'), 10 | MODAL: Symbol('CardModal') 11 | } 12 | 13 | export const CardHeader: React.FC & { slotType?: symbol } = ({ children }) => { 14 | return <>{children}; 15 | }; 16 | CardHeader.slotType = SLOT_TYPES.HEADER; 17 | 18 | export const CardTable: React.FC & { slotType?: symbol } = ({ children }) => { 19 | return <>{children}; 20 | }; 21 | CardTable.slotType = SLOT_TYPES.TABLE; -------------------------------------------------------------------------------- /frontend/src/core/components/CopyPre.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import CopyButton from 'src/core/components/CopyButton' 7 | 8 | const CopyPre = ({ code, iconText = 'COPY' }) => { 9 | return ( 10 |
11 |
12 |         {code}
13 |       
14 |
15 | 16 |
17 |
18 | ) 19 | } 20 | export default CopyPre 21 | -------------------------------------------------------------------------------- /frontend/src/core/components/DateTime/index.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | .rdrCalendarWrapper { 7 | background: none; 8 | } 9 | 10 | .rdrDayNumber span { 11 | color: var(--text-color); 12 | } 13 | 14 | .rdrMonthAndYearPickers select { 15 | color: var(--text-color) 16 | } 17 | 18 | .rdrDayDisabled { 19 | background-color: var(--body-bg); 20 | font-size: 0; 21 | } 22 | 23 | .rdrDayPassive .rdrDayNumber span { 24 | color: var(--disabled-color); 25 | } 26 | 27 | .rdrDayPassive { 28 | cursor: no-drop !important; 29 | } 30 | 31 | .refresh-date-time .ant-dropdown-button .ant-dropdown-trigger { 32 | width: auto; 33 | padding: 0 10px; 34 | } 35 | 36 | .rdrDaySelected, 37 | .rdrInRange, 38 | .rdrStartEdge, 39 | .rdrEndEdge { 40 | background: var(--ant-color-primary) !important; 41 | } -------------------------------------------------------------------------------- /frontend/src/core/components/DocsLink.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import PropTypes from 'prop-types' 7 | import React from 'react' 8 | import { CLink } from '@coreui/react' 9 | 10 | const DocsLink = (props) => { 11 | const { href, name, text, ...rest } = props 12 | 13 | const _href = name ? `https://coreui.io/react/docs/components/${name}` : href 14 | 15 | return ( 16 |
17 | 24 | {text || 'docs'} 25 | 26 |
27 | ) 28 | } 29 | 30 | DocsLink.propTypes = { 31 | href: PropTypes.string, 32 | name: PropTypes.string, 33 | text: PropTypes.string, 34 | } 35 | 36 | export default React.memo(DocsLink) 37 | -------------------------------------------------------------------------------- /frontend/src/core/components/Empty/Empty.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { CImage } from '@coreui/react' 7 | import React, { useEffect, useState } from 'react' 8 | import emptyImg from 'src/core/assets/images/empty.svg' 9 | import { useTranslation } from 'react-i18next' 10 | function Empty({ context = '', width = 100 }) { 11 | const [stateContext, setStateContext] = useState('No data') 12 | const { i18n } = useTranslation() 13 | useEffect(() => { 14 | if (context) { 15 | setStateContext(context) 16 | return 17 | } 18 | setStateContext(i18n.language === 'en' ? 'No data' : '暂无数据') 19 | }, [i18n.language]) 20 | return ( 21 |
22 | 23 | {stateContext} 24 |
25 | ) 26 | } 27 | export default Empty 28 | -------------------------------------------------------------------------------- /frontend/src/core/components/FallbackPage.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { Spin, Image } from 'antd' 7 | import ErrorPage from 'src/core/assets/errorPage.svg' 8 | import { t } from 'i18next' 9 | 10 | interface FallbackPageProps { 11 | errorInfo?: string 12 | } 13 | 14 | const FallbackPage = ({ errorInfo }: FallbackPageProps) => { 15 | return ( 16 |
17 | 18 |
19 | { errorInfo ? errorInfo : t('common:error') } 20 |
21 |
22 | ) 23 | } 24 | 25 | export default FallbackPage -------------------------------------------------------------------------------- /frontend/src/core/components/Filter/FilterSelector.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2025 CloudDetail 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | import { Select } from 'antd' 7 | import React from 'react' 8 | 9 | const FilterSelector = ({ label, placeholder, value, onChange, options, id }) => ( 10 |
11 | {label}: 12 | setSearchGroupName(e.target.value)}> 17 | 18 | 19 |

数据源:

20 |