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

AIRAVATA-3594-admin-dashboard-additions #184

Open
wants to merge 24 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7ccc3fe
Compute Resource with atleast 1 job submitted within the selected period
Jul 13, 2023
8605db3
AIRAVATA-3594: compute resource statistics container refactoring
Jul 25, 2023
019380a
Merge branch 'apache:master' into AIRAVATA-3594-admin-dashboard-addit…
SauravKumarJhaNITW Jul 25, 2023
02c7c7a
Merge branch 'AIRAVATA-3594-admin-dashboard-additions' of https://git…
Jul 25, 2023
ad2475c
AIRAVATA-3594: removed hardcoded result
Jul 25, 2023
64eeb10
resource row label changed
Jul 31, 2023
f49d114
code refinement
Jul 31, 2023
7644d95
code refinement
Jul 31, 2023
bf87761
AIRAVATA-3594: added List applications and number of jobs for each ap…
Aug 1, 2023
0e00588
AIRAVATA-3594: added Number of users that at least submitted a single…
Aug 3, 2023
8ba0662
AIRAVATA-3594: removed hardcoded stats
Aug 3, 2023
1955088
Merge branch 'develop' of /~https://github.com/SauravKumarJhaNITW/airav…
Aug 7, 2023
a7a7da3
added Total number of Unique Users and their Emails who have created …
Aug 8, 2023
8201a2b
AIRAVATA-3594: refinement
Aug 12, 2023
48f199f
AIRAVATA-3594: added User groups created within a given period, and h…
Aug 12, 2023
f8ac1ec
AIRAVATA-3594: added User Registration trends
Aug 19, 2023
f8ae67c
AIRAVATA-3594: removed log file from commit
Aug 19, 2023
c8b59c0
AIRAVATA-3594: added cpu hours consumed by users and application with…
Aug 22, 2023
a15f5bb
AIRAVATA-3594: refactored statistics containers to use common date se…
Aug 22, 2023
5f6ec5e
AIRAVATA-3594: error fix
Aug 24, 2023
d26f97e
AIRAVATA-3594: code refinement
Aug 26, 2023
f247452
Merge branch 'develop' of /~https://github.com/SauravKumarJhaNITW/airav…
Nov 9, 2023
82dc688
AIRAVATA-3594: CpuUsages view limited to admins only
SauravKumarJhaNITW Nov 13, 2023
86774aa
AIRAVATA-3594: removed todo
SauravKumarJhaNITW Nov 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,84 +1,73 @@
<template>
<b-card header="Experiments count grouped by applications">
<div class="row">
<div class="col">
<b-card header="Filter Options">
<b-input-group class="w-100 mb-2">
<b-input-group-prepend is-text>
<i class="fa fa-calendar-week" aria-hidden="true"></i>
</b-input-group-prepend>
<flat-pickr :value="dateRange" :config="dateConfig" @on-change="dateRangeChanged"
class="form-control" />
<b-input-group-append>
<b-button @click="getPast24Hours" variant="outline-secondary">Past 24 Hours</b-button>
<b-button @click="getPastWeek" variant="outline-secondary">Past Week</b-button>
</b-input-group-append>
</b-input-group>
<template slot="footer">
<div class="d-flex justify-content-end">
<b-button @click="loadStatistics" class="ml-auto" variant="primary">Get
Statistics</b-button>
</div>
</template>
</b-card>
<div>
<b-card header="Experiments count grouped by applications within the selected period">
<div class="row" v-if="items.length > 0">
<div class="col">
<b-card>
<b-table :fields="fields" :items="items">
<template slot="cell(applicationName)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(allExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(runningExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(completedExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(cancelledExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(failedExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(createdExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
</b-table>
</b-card>
</div>
</div>
</div>
<div class="row" v-if="items.length > 0">
<div class="col">
<b-card>
<b-table :fields="fields" :items="items">
<template slot="cell(applicationName)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(allExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(runningExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(completedExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(cancelledExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(failedExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
<template slot="cell(createdExperimentCount)" slot-scope="data">
{{ data.value }}
</template>
</b-table>
</b-card>
</b-card>
<b-card header="CPU hours used by application within the selected period">
<div class="w-50">
<BarChart :chart-data="cpuHoursConsumedByApplication" />
</div>
</div>
</b-card>
</b-card>
</div>
</template>

<script>
import { services } from "django-airavata-api";

import moment from "moment";
import { components } from "django-airavata-common-ui";

export default {
name: 'application-statistics-container',
props: {
fromTime: {
type: Date,
required: true,
},
toTime: {
type: Date,
required: true,
}
},
data() {
const fromTime = new Date().fp_incr(0);
const toTime = new Date().fp_incr(1);
return {
fromTime: fromTime,
toTime: toTime,
dateRange: [fromTime, toTime],
items: [],
dateConfig: {
mode: "range",
wrap: true,
dateFormat: "Y-m-d",
maxDate: new Date().fp_incr(1),
},
appInterfaces: null,
cpuUsages: null,
};
},
components: {
BarChart: components.BarChart,
},
created() {
this.loadAppInterfaces();
this.loadCpuUsages();
this.loadStatistics();
},
computed: {
Expand Down Expand Up @@ -113,22 +102,61 @@ export default {
label: "Created Experiment",
},
];
},
cpuHoursConsumedByApplication() {
let cpuUsageMap = new Map();
if(this.appInterfaces) this.appInterfaces.forEach(({applicationInterfaceId}) => cpuUsageMap.set(applicationInterfaceId, 0));
if(this.cpuUsages){
this.cpuUsages.forEach(({executionId, cpuHours}) => {
cpuUsageMap.set(executionId, cpuHours + (cpuUsageMap.has(executionId) ? cpuUsageMap.get(executionId) : 0));
});
}

let cpuUsageSortedList = Array.from(cpuUsageMap.keys()).map((applicationInterfaceId) => {
return {
applicationInterfaceId,
cpuHours: cpuUsageMap.get(applicationInterfaceId),
};
}).sort((a, b) => b.cpuHours - a.cpuHours);

if(cpuUsageSortedList.length > 11){
const firstTenApplications = cpuUsageSortedList.slice(0, 10);
const remainingApplications = cpuUsageSortedList.slice(10, cpuUsageSortedList.length);
const average = arr => arr.reduce( ( p, c ) => p + c, 0 ) / arr.length;
const remainingAvgUsage = Math.floor(average(remainingApplications.map(({cpuHours}) => cpuHours)));
cpuUsageSortedList = [...firstTenApplications, {applicationInterfaceId: "Avg of other " + remainingApplications.length + " applications", cpuHours: remainingAvgUsage}]
}
let appInterfaceNameMap = new Map();
if (this.appInterfaces)
this.appInterfaces.forEach(({applicationInterfaceId, applicationName}) => appInterfaceNameMap.set(applicationInterfaceId, applicationName));
const keys = cpuUsageSortedList.map(({applicationInterfaceId}) => appInterfaceNameMap.get(applicationInterfaceId) ? appInterfaceNameMap.get(applicationInterfaceId) : applicationInterfaceId);
const values = cpuUsageSortedList.map(({cpuHours}) => cpuHours);
return this.mapToBarChartData(keys, values);
},
},
watch: {
fromTime() {
this.reloadAfterPropsChange();
},
toTime() {
this.reloadAfterPropsChange();
}
},
methods: {
dateRangeChanged(selectedDates) {
[this.fromTime, this.toTime] = selectedDates;
reloadAfterPropsChange() {
if (this.fromTime && this.toTime) {
this.loadCpuUsages();
this.loadStatistics();
}
},
loadStatistics() {
let appInterfaceList = [];
loadAppInterfaces() {
services.ApplicationInterfaceService.list().then(
(appInterfaces) => {
appInterfaceList = appInterfaces;
this.appInterfaces = appInterfaces;
}
);
},
loadStatistics() {
const requestData = {
fromTime: this.fromTime.toJSON(),
toTime: this.toTime.toJSON(),
Expand All @@ -142,7 +170,7 @@ export default {
const failedExperiments = "failedExperiments" in results ? results["failedExperiments"] : [];
const cancelledExperiments = "cancelledExperiments" in results ? results["cancelledExperiments"] : [];
const createdExperiments = "createdExperiments" in results ? results["createdExperiments"] : [];
this.items = appInterfaceList.map(({ applicationInterfaceId, applicationName }) => {
this.items = this.appInterfaces ? this.appInterfaces.map(({ applicationInterfaceId, applicationName }) => {
return {
applicationName,
allExperimentCount: allExperiments.filter(({ executionId }) => executionId === applicationInterfaceId).length,
Expand All @@ -152,27 +180,33 @@ export default {
cancelledExperimentCount: cancelledExperiments.filter(({ executionId }) => executionId === applicationInterfaceId).length,
createdExperimentCount: createdExperiments.filter(({ executionId }) => executionId === applicationInterfaceId).length,
}
});
}) : [];

}
);
},
getPast24Hours() {
this.fromTime = new Date().fp_incr(0);
//this.fromTime = new Date(this.fromTime.setHours(0,0,0));
this.toTime = new Date().fp_incr(1);
this.updateDateRange();
},
getPastWeek() {
this.fromTime = new Date().fp_incr(-7);
this.toTime = new Date().fp_incr(1);
this.updateDateRange();
loadCpuUsages() {
const requestData = {
fromTime: this.fromTime.toJSON(),
toTime: this.toTime.toJSON(),
};
services.CpuUsageService.get(requestData).then(
(cpuUsages) => {
this.cpuUsages = cpuUsages;
}
);
},
updateDateRange() {
this.dateRange = [
moment(this.fromTime).format("YYYY-MM-DD"),
moment(this.toTime).format("YYYY-MM-DD"),
];
mapToBarChartData(keys, values) {
return {
labels: keys,
datasets: [
{
label: 'CPU Hours',
data: values,
backgroundColor: '#FFC0CB'
}
]
};
},
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
<template>
<b-card header="Compute Resource with Atleast one Job Submitted">
<div class="row">
<div class="col">
<b-card header="Filter Options">
<b-input-group class="w-100 mb-2">
<b-input-group-prepend is-text>
<i class="fa fa-calendar-week" aria-hidden="true"></i>
</b-input-group-prepend>
<flat-pickr :value="dateRange" :config="dateConfig" @on-change="dateRangeChanged"
class="form-control" />
<b-input-group-append>
<b-button @click="getPast24Hours" variant="outline-secondary">Past 24 Hours</b-button>
<b-button @click="getPastWeek" variant="outline-secondary">Past Week</b-button>
</b-input-group-append>
</b-input-group>
<template slot="footer">
<div class="d-flex justify-content-end">
<b-button @click="loadStatistics" class="ml-auto" variant="primary">Get
Statistics</b-button>
</div>
</template>
</b-card>
</div>
</div>
<b-card header="Compute Resource with Atleast one Job Submitted within the selected period">
<div class="row" v-if="items.length > 0">
<div class="col">
<b-card>
Expand All @@ -44,17 +21,28 @@
import { services } from "django-airavata-api";
import { components } from "django-airavata-common-ui";

import moment from "moment";

export default {
name: 'compute-resource-statistics-container',
props: {
fromTime: {
type: Date,
required: true,
},
toTime: {
type: Date,
required: true,
}
},
watch: {
fromTime() {
this.reloadAfterPropsChange();
},
toTime() {
this.reloadAfterPropsChange();
}
},
data() {
const fromTime = new Date().fp_incr(0);
const toTime = new Date().fp_incr(1);
return {
fromTime: fromTime,
toTime: toTime,
dateRange: [fromTime, toTime],
items: [],
dateConfig: {
mode: "range",
Expand Down Expand Up @@ -85,9 +73,8 @@ export default {
}
},
methods: {
dateRangeChanged(selectedDates) {
[this.fromTime, this.toTime] = selectedDates;
if (this.fromTime && this.toTime) {
reloadAfterPropsChange() {
if(this.fromTime && this.toTime) {
this.loadStatistics();
}
},
Expand All @@ -112,23 +99,6 @@ export default {
}
);
},
getPast24Hours() {
this.fromTime = new Date().fp_incr(0);
//this.fromTime = new Date(this.fromTime.setHours(0,0,0));
this.toTime = new Date().fp_incr(1);
this.updateDateRange();
},
getPastWeek() {
this.fromTime = new Date().fp_incr(-7);
this.toTime = new Date().fp_incr(1);
this.updateDateRange();
},
updateDateRange() {
this.dateRange = [
moment(this.fromTime).format("YYYY-MM-DD"),
moment(this.toTime).format("YYYY-MM-DD"),
];
},
}
};
</script>
Loading