Skip to content

[#960][part-1] feat(dashboard): Add some dashboard interfaces. - #1053

Merged
roryqi merged 1 commit into
apache:masterfrom
yl09099:uniffle-960-1
Nov 9, 2023
Merged

[#960][part-1] feat(dashboard): Add some dashboard interfaces.#1053
roryqi merged 1 commit into
apache:masterfrom
yl09099:uniffle-960-1

Conversation

@yl09099

@yl09099 yl09099 commented Jul 30, 2023

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Add a web dashboard for uniffle, providing some dashboard apis

Why are the changes needed?

Provide data support for dashboard

Fix: #960

Does this PR introduce any user-facing change?

Users can obtain relevant metrics information through the new API

How was this patch tested?

Existing UT.

@roryqi
roryqi requested a review from advancedxy July 30, 2023 13:24
@codecov-commenter

codecov-commenter commented Jul 30, 2023

Copy link
Copy Markdown

Codecov Report

Merging #1053 (c723014) into master (59e08e5) will increase coverage by 0.73%.
The diff coverage is 0.78%.

@@             Coverage Diff              @@
##             master    #1053      +/-   ##
============================================
+ Coverage     53.67%   54.40%   +0.73%     
+ Complexity     2691     2690       -1     
============================================
  Files           403      388      -15     
  Lines         23456    21218    -2238     
  Branches       1992     2003      +11     
============================================
- Hits          12589    11543    -1046     
+ Misses        10092     8972    -1120     
+ Partials        775      703      -72     
Files Coverage Δ
.../apache/uniffle/coordinator/CoordinatorServer.java 57.46% <100.00%> (+0.31%) ⬆️
...java/org/apache/uniffle/common/config/RssConf.java 29.65% <0.00%> (-0.21%) ⬇️
.../uniffle/coordinator/web/resource/APIResource.java 0.00% <0.00%> (ø)
...a/org/apache/uniffle/coordinator/web/Response.java 0.00% <0.00%> (ø)
...iffle/coordinator/web/resource/ServerResource.java 0.00% <0.00%> (ø)
.../uniffle/coordinator/web/vo/CoordinatorConfVO.java 0.00% <0.00%> (ø)
...pache/uniffle/coordinator/web/vo/UserAppNumVO.java 0.00% <0.00%> (ø)
...inator/web/resource/CoordinatorServerResource.java 0.00% <0.00%> (ø)
...g/apache/uniffle/coordinator/web/vo/AppInfoVO.java 0.00% <0.00%> (ø)
.../coordinator/web/resource/ApplicationResource.java 0.00% <0.00%> (ø)

... and 21 files with indirect coverage changes

📣 Codecov offers a browser extension for seamless coverage viewing on GitHub. Try it in Chrome or Firefox today!

@yl09099
yl09099 force-pushed the uniffle-960-1 branch 2 times, most recently from d02cbc2 to a8b4b43 Compare July 31, 2023 02:13
return this.settings.toString();
}

public Set<Map.Entry<String, Object>> getAllEntry() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why cors should be enabled?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why cors should be enabled?

The port exposed on the front-end page is different from the Coordinator port. As a result, cross-domain request data may occur.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If users don't need access Coordinator API directly, we don't need to consider the problem of cross-domain. But I found in current implementation(#1055 ), users access Coordinator API directly, right? @yl09099
But as we discuss in #963 (comment), some operations will be executed in the dashboard module. @jerqi
I feel like the goal is not very clear.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should discuss this thread first. WDYT? @advancedxy @jerqi @yl09099

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should discuss this thread first. WDYT? @advancedxy @jerqi @yl09099

What's wrong with this cross-domain approach? I'm not familiar with it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should discuss this thread first. WDYT? @advancedxy @jerqi @yl09099

If we want to collect my metrics or events, we can finish them in the dashboard module. Dashboard will help us to analyze the jobs in the future. Which job write most data? Which job give the biggest pressure? It's the most important thing for coordinator is stable enough.

But it seems that the current design can't achieve this goal. @jerqi Right? @yl09099

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should discuss this thread first. WDYT? @advancedxy @jerqi @yl09099

If we want to collect my metrics or events, we can finish them in the dashboard module. Dashboard will help us to analyze the jobs in the future. Which job write most data? Which job give the biggest pressure? It's the most important thing for coordinator is stable enough.

But it seems that the current design can't achieve this goal. @jerqi Right? @yl09099

Do the demonstration first, and then gradually improve the management function.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the controversial cross-domain issues, do I need to change the others? @xianjingfeng @jerqi

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we discuss this issue at our meeting this Wednesday. @yl09099 @jerqi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we discuss this issue at our meeting this Wednesday. @yl09099 @jerqi

OK for me.

Comment on lines +51 to +58
@Path("/{id}")
public Response<ServerNode> node(@PathParam("id") String id) {
return execute(() -> getClusterManager().getServerNodeById(id));
}

@GET
@Path("/nodes")
public Response<List<ServerNode>> nodes(@QueryParam("status") String status) {
public Response<List<ServerNode>> nodes() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the right REST api to add.

I think we have agreed to use /nodes/, '/nodes/:id` as our REST API style in the #1000

return execute(
() -> {
CoordinatorConf coordinatorConf = getCoordinatorServer().getCoordinatorConf();
Set<Map.Entry<String, Object>> allEntry = coordinatorConf.getAllEntry();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see why getAllEntry is added.

But I'd rather to defined it as Map<String, String> getAll()

}

@GET
@Path("/nodes/{status}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

}

@GET
@Path("/nodestatustotal")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe /nodes/summary would be better.

Comment on lines +64 to +65
private static final String LOSTNODES_URL = URL_PREFIX + "server/nodes/LOST";
private static final String UNHEALTHYNODES_URL = URL_PREFIX + "server/nodes/UNHEALTHY";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like commented earlier, this would be inappropriate


package org.apache.uniffle.coordinator.web.vo;

public class AppInfoVO {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does VO stands for? And is there any design principle for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VO is the data used for display, whether it is displayed in a web page, a client, or an APP, as long as this thing is seen by people, it is called VO

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use org.apache.uniffle.common.Application directly.

@Context protected ServletContext servletContext;

@GET
@Path("/info")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems the api route is wrong.
This is more like coordinator conf.

The L63-L65 lines are more like a info path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems the api route is wrong. This is more like coordinator conf.

The L63-L65 lines are more like a info path.

OK,Yeah, I'll fix it

import org.apache.uniffle.coordinator.web.vo.UserAppNumVO;

@Produces({MediaType.APPLICATION_JSON})
public class ApplicationResource extends BaseResource {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slfan1989 added some related applications interface in #964 , Maybe you guys should be in sync and decide which paths to added

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asfsecurity Thank you for your help reviewing the code! I discussed offline with @yl09099, we plan to merge #964 first, and then yl09099 will improve. I will improve the code of #964 in 1-2 days.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@advancedxy @jerqi Could you continue to review this for me?

@yl09099
yl09099 force-pushed the uniffle-960-1 branch 2 times, most recently from c3581b8 to 177b535 Compare August 1, 2023 02:01
List<AppInfoVO> userToAppList = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Map<String, Map<String, Long>> currentUserAndApp =
getApplicationManager().getQuotaManager().getCurrentUserAndApp();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quotaManager may be null

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you miss this thread? @yl09099

Set<String> appIds = getApplicationManager().getAppIds();
Map<String, Integer> appTotalityMap = new HashMap<>();
appTotalityMap.put("appTotality", appIds.size());
return appTotalityMap;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about returning appIds.size() directly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about returning appIds.size() directly?

It feels better to have a unique identifier on the front end to get this value.


@GET
@Path("/info")
public Response<Map> getCoodConf() {

@xianjingfeng xianjingfeng Aug 18, 2023

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public Response<Map> getCoodConf() {
public Response<Map<String, Object>> getCoordinatorConf() {

@yl09099 yl09099 closed this Aug 18, 2023
@yl09099 yl09099 reopened this Aug 18, 2023
@yl09099
yl09099 requested a review from xianjingfeng August 21, 2023 05:39
.filter(node -> ServerStatus.DECOMMISSIONING.equals(node.getStatus()))
.peek(e -> decommissioningNodes.add(e))
.collect(Collectors.toList());
return decommissioningNodes;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this line, and line 279, 282.

} else if (ServerStatus.DECOMMISSIONED.name().equalsIgnoreCase(status)) {
serverList = clusterManager.getDecommissionedServerList();
} else if (ServerStatus.DECOMMISSIONING.name().equalsIgnoreCase(status)) {
serverList = clusterManager.getDecommissioningServerList();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove L74 to L77 because of #1174 .

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove L74 to L77 because of #1174 .

If this is removed, how can the two DECOMMISSIONED and DECOMMISSIONING servernodes be obtained?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


public static <T> Response<T> success(T data) {
return new Response<>(SUCCESS_CODE, data, null);
return new Response<>(SUCCESS_CODE, data, "success");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why returning success? What is the purpose?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why returning success? What is the purpose?

This method is the success method, but the return message does not have any message, the front end can also judge the success of the message.


@GET
@Path("/conf")
public Response<List<CoordinatorConfVO>> getCoordinatorInfo() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need CoordinatorConfVO, Returning Response<Map<String, Object>> is better.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public Response<List<CoordinatorConfVO>> getCoordinatorInfo() {
public Response<List<CoordinatorConfVO>> getCoordinatorConf() {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need CoordinatorConfVO, Returning Response<Map<String, Object>> is better.

I find the object code more readable and difficult to understand using Map form.


@GET
@Path("/usertotal")
public Response<List<UserAppNumVO>> getUserApps() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto. Returning Response<Map<String, Integer>> is better.

}

@GET
@Path("/appinfos")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Path("/appinfos")
@Path("/appInfos")

@yl09099 yl09099 closed this Sep 11, 2023
@yl09099 yl09099 reopened this Sep 11, 2023
@yl09099 yl09099 closed this Oct 7, 2023
@yl09099 yl09099 reopened this Oct 7, 2023
@yl09099
yl09099 force-pushed the uniffle-960-1 branch 2 times, most recently from 53c225e to 060b0ac Compare October 7, 2023 02:49
@yl09099

yl09099 commented Oct 7, 2023

Copy link
Copy Markdown
Contributor Author

@jerqi @xianjingfeng Please trigger the compilation for me again, I didn't change anything in Tez

@roryqi

roryqi commented Oct 7, 2023

Copy link
Copy Markdown
Contributor

@jerqi @xianjingfeng Please trigger the compilation for me again, I didn't change anything in Tez

done.

@yl09099
yl09099 force-pushed the uniffle-960-1 branch 4 times, most recently from bf5e5e3 to d77aa60 Compare November 7, 2023 06:18

@xianjingfeng xianjingfeng left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Please take another look. @jerqi @advancedxy

@roryqi
roryqi dismissed advancedxy’s stale review November 7, 2023 11:56

LGTM, @advancedxy Any another suggestion?

@roryqi

roryqi commented Nov 7, 2023

Copy link
Copy Markdown
Contributor

Wait for two days. See @advancedxy whether has another suggestion.

@roryqi
roryqi merged commit c258076 into apache:master Nov 9, 2023
@roryqi

roryqi commented Nov 9, 2023

Copy link
Copy Markdown
Contributor

Merged. Thanks @advancedxy @yl09099 @xianjingfeng

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Umbrella] Uniffle needs to add a WebUI page

6 participants