Skip to content
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 storage efficiency card on persistent dashboard. #6104

Merged

Conversation

a2batic
Copy link
Contributor

@a2batic a2batic commented Jul 25, 2020

Screenshot from 2020-07-27 19-32-02

Thanks James Espy, Paul Cuzner , for the providing the metrics.
Signed-off-by: Kanika Murarka kmurarka@redhat.com

@@ -87,6 +89,13 @@ export const CAPACITY_BREAKDOWN_QUERIES = {
'max(ceph_pool_max_avail * on (pool_id) group_left(name)ceph_pool_metadata{name=~"(.*file.*)|(.*block.*)"})',
};

export const POOL_STORAGE_EFFICIENCY_QUERIES = {
Copy link
Member

Choose a reason for hiding this comment

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

FYI @openshift/openshift-team-monitoring

Copy link
Contributor

Choose a reason for hiding this comment

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

nice, thank you!

Copy link
Contributor

Choose a reason for hiding this comment

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

that is an incarnation of centralizing queries, correct?

Copy link
Member

Choose a reason for hiding this comment

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

Ah no. The centralizing PR is #6128


import './storage-efficiency-card.scss';

const getGaugeValue = (data) => _.get(data, 'data.result[0].value[1]');
Copy link
Contributor

Choose a reason for hiding this comment

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

types

Copy link
Contributor

@afreen23 afreen23 Jul 27, 2020

Choose a reason for hiding this comment

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

Can you move this to utils , so that we can reuse this in other cards ?
We wont miss the item this way during refactoring phase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 27, 2020
const savingsValue = Number(saved);
if (saved) {
const savedBytes = humanizeBinaryBytes(savingsValue).string;
stats = savingsValue <= 0 ? 'No Savings' : savedBytes;
Copy link
Contributor

Choose a reason for hiding this comment

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

Will you ever get a negative value here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, no, it can be 0 or more only


import './storage-efficiency-card.scss';

const getGaugeValue = (data) => _.get(data, 'data.result[0].value[1]');
Copy link
Contributor

@afreen23 afreen23 Jul 27, 2020

Choose a reason for hiding this comment

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

Can you move this to utils , so that we can reuse this in other cards ?
We wont miss the item this way during refactoring phase.

Comment on lines 16 to 18
<div className="co-inventory-card__item">
<div className="ceph-storage-efficiency-card__row-title">{title}</div>
<div className="ceph-storage-efficiency-card__row-status-item">
Copy link
Contributor

@afreen23 afreen23 Jul 27, 2020

Choose a reason for hiding this comment

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

Since these are rows for the ItemBody and to make BEM naming align with the actual purpose

Suggested change
<div className="co-inventory-card__item">
<div className="ceph-storage-efficiency-card__row-title">{title}</div>
<div className="ceph-storage-efficiency-card__row-status-item">
<div className="co-inventory-card__row-item">
<div className="ceph-storage-efficiency-card__row-item-title">{title}</div>
<div className="ceph-storage-efficiency-card__row-item-status">

Copy link
Contributor

Choose a reason for hiding this comment

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

Also ItemBody can be RowItem

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, I missed in flow :D

Copy link
Contributor

Choose a reason for hiding this comment

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

I dont find this naming right though.

@cloudbehl
Copy link
Contributor

@a2batic can you add screenshots?

@afreen23
Copy link
Contributor

@a2batic We too want ot make it generic just like breakdown card. Instead of maintaining same copies for different plugins.
It can be done in a followup PR as well !

Comment on lines 59 to 78
const compressionRatioProps = {
ratio,
isLoading: !poolCapacityRatioResult,
error: !!poolCapacityRatioResultError,
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const compressionRatioProps = {
ratio,
isLoading: !poolCapacityRatioResult,
error: !!poolCapacityRatioResultError,
};
const compressionRatioProps = {
ratio,
isLoading: !poolCapacityRatioResult,
error: !!poolCapacityRatioResultError,
infotext: infotext
handler: getCompressionRatio,
};

Comment on lines 4 to 24
const ItemBody: React.FC<ItemBodyProps> = React.memo(
({ title, stats, infoText, isLoading, error }) => {
let status: React.ReactElement;
if (isLoading) {
status = <div className="skeleton-text ceph-storage-efficiency-card__item-body--loading" />;
} else if (error || !stats) {
status = <span className="co-dashboard-text--small text-muted">Not available</span>;
} else {
status = <span className="ceph-storage-efficiency-card__item-text">{stats}</span>;
}
return (
<div className="co-inventory-card__item">
<div className="ceph-storage-efficiency-card__item-title">{title}</div>
<div className="ceph-storage-efficiency-card__item-status">
{status}
<FieldLevelHelp>{infoText}</FieldLevelHelp>
</div>
</div>
);
},
);
Copy link
Contributor

Choose a reason for hiding this comment

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

We can make this component more generic, renaming to StorageEfficiencyItem and avoid using SavedItem, CompressionItem.

You can pass one handler function to it to get the stats:

({ title, data, infoText, isLoading, error, handler }) => {
    let status: React.ReactElement;
    const stats = handler(data);

The handler will be your extracted logic for :

   if (ratio) {
      const capacityRatio = Number(ratio);
      stats = capacityRatio === 0 ? '1:1' : `${Math.round(capacityRatio)}:1`;
    }

  if (ratio) {
      const capacityRatio = Number(ratio);
      stats = capacityRatio === 0 ? '1:1' : `${Math.round(capacityRatio)}:1`;
    }

which you can pass as prop;

You can call directly StorageEfficiencyItem as:

<DashboardCardBody className="co-dashboard-card__body--no-padding">
        <StorageEfficiencyItem {...compressionRatioProps} />
        <StorageEfficiencyItem {...savingsProps} />
    </DashboardCardBody>

export const EfficiencyItemBody: React.FC<EfficiencyItemBodyProps> = React.memo(
({ title, stats, infoText, isLoading, error, handler }) => {
let status: React.ReactElement;
const metricStats = stats ? handler() : null;
Copy link
Contributor

@afreen23 afreen23 Jul 28, 2020

Choose a reason for hiding this comment

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

As per the below suggestion:

Suggested change
const metricStats = stats ? handler() : null;

Comment on lines +57 to +69
const ratio = getGaugeValue(poolCapacityRatioResult);
const saved = getGaugeValue(poolSavedResult);

const compressionStats = () => {
const capacityRatio = Number(ratio);
return capacityRatio === 0 ? '1:1' : `${Math.round(capacityRatio)}:1`;
};

const savingStats = () => {
const savingsValue = Number(saved);
const savedBytes = humanizeBinaryBytes(savingsValue).string;
return savingsValue === 0 ? 'No Savings' : savedBytes;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

When getGaugeValue(poolCapacityRatioResult) returns undefined.
Then you will have capacityRatio and savingsValue as 0 and it will render a text 1:1 and No savings.
You dont want to show that , instead you want to have Not available.

You can have :

const compressionStats = () => {
   if (capacityRatio) {
       const capacityRatio = Number(ratio);
       return capacityRatio === 0 ? '1:1' : `${Math.round(capacityRatio)}:1`;
    };
     return capacityRatio;
  };

  const savingStats = () => {
      if(savingsValue) {
          const savingsValue = Number(saved);
          const savedBytes = humanizeBinaryBytes(savingsValue).string;
          return savingsValue === 0 ? 'No Savings' : savedBytes;
       }
       return savingsValue;
  };

Copy link
Contributor Author

@a2batic a2batic Jul 28, 2020

Choose a reason for hiding this comment

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

@afreen23 if getGaugeValue(poolCapacityRatioResult) returns undefined, capacityRatio and ratio will be NaN, becasue Number(undefined) gives NaN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number.

Therefore, we dont need to put if, because I am checking for value to be 0 or not. wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

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

@a2batic you are missing my point here. What I pointed above is if capacityRatio and savingsValue wont be 0 and they will default to the text. Instead I would at least prefer to set for such cases Not available.
An improvement over stats ? handler() : null; , we can avoid explicitly setting null and let the handler itself respond.

I am alright if you want to keep it that way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@afreen23, thanks for clarifying, I understand your point, only reasons to put it in element, So we dont have to check for every item in their respective functions.

Copy link
Contributor

Choose a reason for hiding this comment

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

What about doing this way #6104 (review) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

@a2batic
Copy link
Contributor Author

a2batic commented Jul 28, 2020

/retest

@afreen23
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jul 28, 2020
@afreen23
Copy link
Contributor

/lgtm cancel

#6104 (comment)

@openshift-ci-robot openshift-ci-robot removed the lgtm Indicates that a PR is ready to be merged. label Jul 28, 2020
Copy link
Contributor

@afreen23 afreen23 left a comment

Choose a reason for hiding this comment

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

Lets do this way

const savingsProps = {
stats: saved,
isLoading: !poolSavedResult,
error: !!poolSavedResultError,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
error: !!poolSavedResultError,
error: !!poolSavedResultError || !saved

const compressionRatioProps = {
stats: ratio,
isLoading: !poolCapacityRatioResult,
error: !!poolCapacityRatioResultError,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
error: !!poolCapacityRatioResultError,
error: !!poolCapacityRatioResultError || !ratio

} else if (error || !metricStats) {
status = <span className="co-dashboard-text--small text-muted">Not available</span>;
} else {
status = <span className="ceph-storage-efficiency-card__item-text">{metricStats}</span>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
status = <span className="ceph-storage-efficiency-card__item-text">{metricStats}</span>;
status = <span className="ceph-storage-efficiency-card__item-text">{getStats()}</span>;

const metricStats = stats ? handler() : null;
if (isLoading) {
status = <div className="skeleton-text ceph-storage-efficiency-card__item-body--loading" />;
} else if (error || !metricStats) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
} else if (error || !metricStats) {
} else if (error) {

import { FieldLevelHelp } from '@console/internal/components/utils';

export const EfficiencyItemBody: React.FC<EfficiencyItemBodyProps> = React.memo(
({ title, stats, infoText, isLoading, error, handler }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
({ title, stats, infoText, isLoading, error, handler }) => {
({ title, stats, infoText, isLoading, error, getStats }) => {

Signed-off-by: Kanika Murarka <kmurarka@redhat.com>
@afreen23
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jul 29, 2020
@openshift-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: a2batic, afreen23, gnehapk

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit 8d10a88 into openshift:master Jul 29, 2020
@spadgett spadgett added this to the v4.6 milestone Jul 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. component/ceph Related to ceph-storage-plugin lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants