-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add JSON-style reports #18047
Add JSON-style reports #18047
Conversation
for (Map.Entry<String, MountPointInfo> entry : mountTable.entrySet()) { | ||
ObjectNode mountInfo = mapper.createObjectNode(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try to represent information as classes to json serialize instead of nodes. although you have to set up the setters/getters (maybe can find some way to help generate the code), a class is more friendly to be used by different formats.
public class MountInfoOutput {
public String mUri;
public String mMountPoint;
public String mUfsType;
public String mTotalCapacity;
public String mUsedCapacity;
public boolean mReadOnly;
public Shared mShared;
// add setter and getter methods for json to work on this object
}
for the two capacity values, it would be even better to use a long
type for the field and use an annotation to declare a custom serialization function that will execute the FormatUtils.getSizeFromBytes
actually i noticed that the original MountPointInfo
object is already mostly ready to be directly used to json serialize. the only field we don't want to show is the Properties
map. so there should be a way to add an annotation to tell the json serializer to avoid serializing the field. this is the best situation because it reuses the existing code as much as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one way to serialize the annotated field only:
- add annotations to all the fields you need:
@JsonProperty("readOnly")
public boolean mReadOnly;
- set
ObjectMapper
to ignore the getters/setters and only focus on the annotation:
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
String result = mapper.writeValueAsString(obj)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not very sure about this change. Does this mean if I'd like my command to print something more, instead of a println, now I need to update the object? I mean trying to objectify printouts seems awkward unless you have a very good reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Objectifying the printed output ensures consistency. Printlns are at the whims of the particular dev; the lack of consistency in general is why both the command line format (ex. Flags, arguments, command tree structure) and the output format are a total mess. Objectifying outputs also allows for various output format (ex. Json for machine parseable output, yaml for more human readable output)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks much cleaner now for the ufs command
dora/core/common/src/main/java/alluxio/wire/MountPointInfo.java
Outdated
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the work. I left some comments. PTAL thanks!
dora/shell/src/main/java/alluxio/cli/fsadmin/report/CapacityCommand.java
Outdated
Show resolved
Hide resolved
dora/shell/src/main/java/alluxio/cli/fsadmin/report/CapacityCommand.java
Outdated
Show resolved
Hide resolved
dora/shell/src/main/java/alluxio/cli/fsadmin/report/CapacityCommand.java
Outdated
Show resolved
Hide resolved
dora/shell/src/main/java/alluxio/cli/fsadmin/report/CapacityCommand.java
Outdated
Show resolved
Hide resolved
dora/shell/src/main/java/alluxio/cli/fsadmin/report/CapacityCommand.java
Outdated
Show resolved
Hide resolved
* @param name name of the metrics to check | ||
* @return true if a metric is an Alluxio metric, false otherwise | ||
*/ | ||
private boolean isAlluxioMetric(String name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this copied from some utility class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It comes from the original MetricsOutput class, still used in JSON format
dora/shell/src/main/java/alluxio/cli/fsadmin/report/SummaryCommand.java
Outdated
Show resolved
Hide resolved
public SummaryOutput(MasterInfo masterInfo, BlockMasterInfo blockMasterInfo, String dateFormatPattern) { | ||
// give values to internal properties | ||
mMasterAddress = masterInfo.getLeaderMasterAddress(); | ||
mWebPort = masterInfo.getWebPort(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the web port and raft journal port are all here, are they displayed too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As to the content to display, I followed the original format
dora/shell/src/main/java/alluxio/cli/fsadmin/report/SummaryOutput.java
Outdated
Show resolved
Hide resolved
overall looks good, but please fix the checkstyle and unit test problems in the build. for example, the unit test failure is:
|
Automated checks report:
Some checks failed. Please fix the reported issues and reply 'alluxio-bot, check this please' to re-run checks. |
Automated checks report:
All checks passed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the improvement. yay for deleting more lines!
@jiacheliu3 @Kai-Zhang do you want to review before merging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly LGTM with some comments, thanks for the work!
dora/shell/src/main/java/alluxio/cli/fsadmin/report/JobServiceMetricsCommand.java
Outdated
Show resolved
Hide resolved
dora/shell/src/main/java/alluxio/cli/fsadmin/report/MetricsOutput.java
Outdated
Show resolved
Hide resolved
mMetricsInfo = new ArrayList<>(); | ||
for (Map.Entry<String, MetricValue> entry : metrics.entrySet()) { | ||
String key = entry.getKey(); | ||
if (!isAlluxioMetric(key)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is not alluxio metric? Do you have an example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the metrics entry set has elements which don't start with instance types such as cluster, worker, etc. It is not an Alluxio metrics. I'm not quite sure when non-alluxio metrics will emerge, but the previous version did so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it
dora/shell/src/main/java/alluxio/cli/fsadmin/report/SummaryCommand.java
Outdated
Show resolved
Hide resolved
print("Tier: " + usedBytesTier.getKey() | ||
+ " Size: " + FormatUtils.getSizeFromBytes(usedBytesTier.getValue())); | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
SummaryOutput summaryInfo = new SummaryOutput(masterInfo, blockMasterInfo, mDateFormatPattern); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your JobServiceOutput
can follow this pattern, get the info by RPC and pass it to the output object purely for display.
And even if you cannot get certain info from RPC, you can still continue to display with broken information like:
BlockMasterInfo blockMasterInfo = null;
try {
blockMasterInfo = mBlockMasterClient.getBlockMasterInfo(blockMasterInfoFilter);
} catch (Exception e) {
// log the exception and actually you can try to continue, if that's necessary
}
SummaryOutput summaryInfo = new SummaryOutput(blockMasterInfo, ...)
And in SummaryOutput
when it tries to display, if certain info is null you can simply display something like "Failed to connect to master for Block/Worker information" and skip that part.
Actually you may choose to implement this in a follow-up PR (don't have to finish all that before merging).
dora/shell/src/test/java/alluxio/cli/fsadmin/report/MetricsCommandTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for the work!
alluxio-bot, merge this please |
Use jackson JSON as a standard format for reports.
Output example for
bin/alluxio info report summary
: