mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
improve how metrics are queried & displayed
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
11595abc93
commit
029694a3ca
@ -3,6 +3,7 @@ import { IPodContainer } from "./pods.api";
|
|||||||
import { IAffinity, WorkloadKubeObject } from "../workload-kube-object";
|
import { IAffinity, WorkloadKubeObject } from "../workload-kube-object";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { KubeApi } from "../kube-api";
|
import { KubeApi } from "../kube-api";
|
||||||
|
import { IResourceMetrics, metricsApi } from "./metrics.api";
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
export class DaemonSet extends WorkloadKubeObject {
|
export class DaemonSet extends WorkloadKubeObject {
|
||||||
@ -71,6 +72,24 @@ export class DaemonSet extends WorkloadKubeObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const daemonSetApi = new KubeApi({
|
|
||||||
|
export class DaemonSetApi extends KubeApi<DaemonSet> {
|
||||||
|
getMetrics(daemonsets: DaemonSet[], namespace: string, selector = ""): Promise<IResourceMetrics> {
|
||||||
|
const podSelector = daemonsets.map(daemonset => `${daemonset.getName()}-[[:alnum:]]{5}`).join("|");
|
||||||
|
const opts = { category: "pods", pods: podSelector, namespace, selector };
|
||||||
|
|
||||||
|
return metricsApi.getMetrics({
|
||||||
|
cpuUsage: opts,
|
||||||
|
memoryUsage: opts,
|
||||||
|
fsUsage: opts,
|
||||||
|
networkReceive: opts,
|
||||||
|
networkTransmit: opts,
|
||||||
|
}, {
|
||||||
|
namespace,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const daemonSetApi = new DaemonSetApi({
|
||||||
objectConstructor: DaemonSet,
|
objectConstructor: DaemonSet,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import moment from "moment";
|
|||||||
import { IAffinity, WorkloadKubeObject } from "../workload-kube-object";
|
import { IAffinity, WorkloadKubeObject } from "../workload-kube-object";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { KubeApi } from "../kube-api";
|
import { KubeApi } from "../kube-api";
|
||||||
|
import { IResourceMetrics, metricsApi } from "./metrics.api";
|
||||||
|
|
||||||
export class DeploymentApi extends KubeApi<Deployment> {
|
export class DeploymentApi extends KubeApi<Deployment> {
|
||||||
protected getScaleApiUrl(params: { namespace: string; name: string }) {
|
protected getScaleApiUrl(params: { namespace: string; name: string }) {
|
||||||
@ -44,6 +45,21 @@ export class DeploymentApi extends KubeApi<Deployment> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMetrics(deployments: Deployment[], namespace: string, selector = ""): Promise<IResourceMetrics> {
|
||||||
|
const podSelector = deployments.map(deployment => `${deployment.getName()}-[[:alnum:]]{9,}-[[:alnum:]]{5}`).join("|");
|
||||||
|
const opts = { category: "pods", pods: podSelector, namespace, selector };
|
||||||
|
|
||||||
|
return metricsApi.getMetrics({
|
||||||
|
cpuUsage: opts,
|
||||||
|
memoryUsage: opts,
|
||||||
|
fsUsage: opts,
|
||||||
|
networkReceive: opts,
|
||||||
|
networkTransmit: opts,
|
||||||
|
}, {
|
||||||
|
namespace,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IContainerProbe {
|
interface IContainerProbe {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { IAffinity, WorkloadKubeObject } from "../workload-kube-object";
|
|||||||
import { IPodContainer } from "./pods.api";
|
import { IPodContainer } from "./pods.api";
|
||||||
import { KubeApi } from "../kube-api";
|
import { KubeApi } from "../kube-api";
|
||||||
import { JsonApiParams } from "../json-api";
|
import { JsonApiParams } from "../json-api";
|
||||||
|
import { IResourceMetrics, metricsApi } from "./metrics.api";
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
export class Job extends WorkloadKubeObject {
|
export class Job extends WorkloadKubeObject {
|
||||||
@ -107,6 +108,24 @@ export class Job extends WorkloadKubeObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const jobApi = new KubeApi({
|
|
||||||
|
export class JobApi extends KubeApi<Job> {
|
||||||
|
getMetrics(jobs: Job[], namespace: string, selector = ""): Promise<IResourceMetrics> {
|
||||||
|
const podSelector = jobs.map(job => `${job.getName()}-[[:alnum:]]{5}`).join("|");
|
||||||
|
const opts = { category: "pods", pods: podSelector, namespace, selector };
|
||||||
|
|
||||||
|
return metricsApi.getMetrics({
|
||||||
|
cpuUsage: opts,
|
||||||
|
memoryUsage: opts,
|
||||||
|
fsUsage: opts,
|
||||||
|
networkReceive: opts,
|
||||||
|
networkTransmit: opts,
|
||||||
|
}, {
|
||||||
|
namespace,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const jobApi = new JobApi({
|
||||||
objectConstructor: Job,
|
objectConstructor: Job,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -33,6 +33,15 @@ export interface IMetricsReqParams {
|
|||||||
namespace?: string; // rbac-proxy validation param
|
namespace?: string; // rbac-proxy validation param
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IResourceMetrics<T = IMetrics> {
|
||||||
|
[metric: string]: T;
|
||||||
|
cpuUsage: T;
|
||||||
|
memoryUsage: T;
|
||||||
|
fsUsage: T;
|
||||||
|
networkReceive: T;
|
||||||
|
networkTransmit: T;
|
||||||
|
}
|
||||||
|
|
||||||
export const metricsApi = {
|
export const metricsApi = {
|
||||||
async getMetrics<T = IMetricsQuery>(query: T, reqParams: IMetricsReqParams = {}): Promise<T extends object ? { [K in keyof T]: IMetrics } : IMetrics> {
|
async getMetrics<T = IMetricsQuery>(query: T, reqParams: IMetricsReqParams = {}): Promise<T extends object ? { [K in keyof T]: IMetrics } : IMetrics> {
|
||||||
const { range = 3600, step = 60, namespace } = reqParams;
|
const { range = 3600, step = 60, namespace } = reqParams;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { KubeApi } from "../kube-api";
|
import { KubeApi } from "../kube-api";
|
||||||
import { KubeObject } from "../kube-object";
|
import { KubeObject } from "../kube-object";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
|
import { IResourceMetrics, metricsApi } from "./metrics.api";
|
||||||
|
|
||||||
export enum NamespaceStatus {
|
export enum NamespaceStatus {
|
||||||
ACTIVE = "Active",
|
ACTIVE = "Active",
|
||||||
@ -22,6 +23,22 @@ export class Namespace extends KubeObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const namespacesApi = new KubeApi({
|
export class NamespaceApi extends KubeApi<Namespace> {
|
||||||
|
getMetrics(namespace: string, selector = ""): Promise<IResourceMetrics> {
|
||||||
|
const opts = { category: "pods", pods: ".*", namespace, selector };
|
||||||
|
|
||||||
|
return metricsApi.getMetrics({
|
||||||
|
cpuUsage: opts,
|
||||||
|
memoryUsage: opts,
|
||||||
|
fsUsage: opts,
|
||||||
|
networkReceive: opts,
|
||||||
|
networkTransmit: opts,
|
||||||
|
}, {
|
||||||
|
namespace,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const namespacesApi = new NamespaceApi({
|
||||||
objectConstructor: Namespace,
|
objectConstructor: Namespace,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { autobind } from "../../utils";
|
|||||||
import { WorkloadKubeObject } from "../workload-kube-object";
|
import { WorkloadKubeObject } from "../workload-kube-object";
|
||||||
import { IPodContainer, Pod } from "./pods.api";
|
import { IPodContainer, Pod } from "./pods.api";
|
||||||
import { KubeApi } from "../kube-api";
|
import { KubeApi } from "../kube-api";
|
||||||
|
import { IResourceMetrics, metricsApi } from "./metrics.api";
|
||||||
|
|
||||||
export class ReplicaSetApi extends KubeApi<ReplicaSet> {
|
export class ReplicaSetApi extends KubeApi<ReplicaSet> {
|
||||||
protected getScaleApiUrl(params: { namespace: string; name: string }) {
|
protected getScaleApiUrl(params: { namespace: string; name: string }) {
|
||||||
@ -25,6 +26,21 @@ export class ReplicaSetApi extends KubeApi<ReplicaSet> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMetrics(replicasets: ReplicaSet[], namespace: string, selector = ""): Promise<IResourceMetrics> {
|
||||||
|
const podSelector = replicasets.map(replicaset => `${replicaset.getName()}-[[:alnum:]]{5}`).join("|");
|
||||||
|
const opts = { category: "pods", pods: podSelector, namespace, selector };
|
||||||
|
|
||||||
|
return metricsApi.getMetrics({
|
||||||
|
cpuUsage: opts,
|
||||||
|
memoryUsage: opts,
|
||||||
|
fsUsage: opts,
|
||||||
|
networkReceive: opts,
|
||||||
|
networkTransmit: opts,
|
||||||
|
}, {
|
||||||
|
namespace,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { IPodContainer } from "./pods.api";
|
|||||||
import { IAffinity, WorkloadKubeObject } from "../workload-kube-object";
|
import { IAffinity, WorkloadKubeObject } from "../workload-kube-object";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { KubeApi } from "../kube-api";
|
import { KubeApi } from "../kube-api";
|
||||||
|
import { IResourceMetrics, metricsApi } from "./metrics.api";
|
||||||
|
|
||||||
export class StatefulSetApi extends KubeApi<StatefulSet> {
|
export class StatefulSetApi extends KubeApi<StatefulSet> {
|
||||||
protected getScaleApiUrl(params: { namespace: string; name: string }) {
|
protected getScaleApiUrl(params: { namespace: string; name: string }) {
|
||||||
@ -25,6 +26,21 @@ export class StatefulSetApi extends KubeApi<StatefulSet> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMetrics(statefulSets: StatefulSet[], namespace: string, selector = ""): Promise<IResourceMetrics> {
|
||||||
|
const podSelector = statefulSets.map(statefulset => `${statefulset.getName()}-[[:digit:]]+`).join("|");
|
||||||
|
const opts = { category: "pods", pods: podSelector, namespace, selector };
|
||||||
|
|
||||||
|
return metricsApi.getMetrics({
|
||||||
|
cpuUsage: opts,
|
||||||
|
memoryUsage: opts,
|
||||||
|
fsUsage: opts,
|
||||||
|
networkReceive: opts,
|
||||||
|
networkTransmit: opts,
|
||||||
|
}, {
|
||||||
|
namespace,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
|
|||||||
@ -12,6 +12,9 @@ import { Spinner } from "../spinner";
|
|||||||
import { resourceQuotaStore } from "../+config-resource-quotas/resource-quotas.store";
|
import { resourceQuotaStore } from "../+config-resource-quotas/resource-quotas.store";
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
||||||
|
import { namespaceStore } from "./namespace.store";
|
||||||
|
import { ResourceMetrics } from "../resource-metrics";
|
||||||
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Namespace> {
|
interface Props extends KubeObjectDetailsProps<Namespace> {
|
||||||
}
|
}
|
||||||
@ -33,9 +36,18 @@ export class NamespaceDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
if (!namespace) return;
|
if (!namespace) return;
|
||||||
const status = namespace.getStatus();
|
const status = namespace.getStatus();
|
||||||
|
const metrics = namespaceStore.metrics;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="NamespaceDetails">
|
<div className="NamespaceDetails">
|
||||||
|
{namespaceStore.isLoaded && (
|
||||||
|
<ResourceMetrics
|
||||||
|
loader={() => namespaceStore.loadMetrics(namespace)}
|
||||||
|
tabs={podMetricTabs} object={namespace} params={{ metrics }}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
)}
|
||||||
<KubeObjectMeta object={namespace}/>
|
<KubeObjectMeta object={namespace}/>
|
||||||
|
|
||||||
<DrawerItem name="Status">
|
<DrawerItem name="Status">
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { action, comparer, observable, reaction } from "mobx";
|
import { action, comparer, observable, reaction } from "mobx";
|
||||||
import { autobind, createStorage } from "../../utils";
|
import { autobind, createStorage } from "../../utils";
|
||||||
import { KubeObjectStore } from "../../kube-object.store";
|
import { KubeObjectStore } from "../../kube-object.store";
|
||||||
import { Namespace, namespacesApi } from "../../api/endpoints";
|
import { INamespaceMetrics, Namespace, namespacesApi } from "../../api/endpoints";
|
||||||
import { createPageParam } from "../../navigation";
|
import { createPageParam } from "../../navigation";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
import { isAllowedResource } from "../../../common/rbac";
|
import { isAllowedResource } from "../../../common/rbac";
|
||||||
@ -22,12 +22,17 @@ export const namespaceUrlParam = createPageParam<string[]>({
|
|||||||
export class NamespaceStore extends KubeObjectStore<Namespace> {
|
export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||||
api = namespacesApi;
|
api = namespacesApi;
|
||||||
contextNs = observable.array<string>();
|
contextNs = observable.array<string>();
|
||||||
|
@observable metrics: INamespaceMetrics = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async loadMetrics(namespace: Namespace) {
|
||||||
|
this.metrics = await namespacesApi.getMetrics(namespace.getName(), "");
|
||||||
|
}
|
||||||
|
|
||||||
private init() {
|
private init() {
|
||||||
this.setContext(this.initNamespaces);
|
this.setContext(this.initNamespaces);
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { KubeObjectStore } from "../../kube-object.store";
|
import { KubeObjectStore } from "../../kube-object.store";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { DaemonSet, daemonSetApi, IPodMetrics, Pod, podsApi, PodStatus } from "../../api/endpoints";
|
import { DaemonSet, daemonSetApi, IDaemonSetMetrics, Pod, PodStatus } from "../../api/endpoints";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
|
||||||
@ -9,12 +9,10 @@ import { apiManager } from "../../api/api-manager";
|
|||||||
export class DaemonSetStore extends KubeObjectStore<DaemonSet> {
|
export class DaemonSetStore extends KubeObjectStore<DaemonSet> {
|
||||||
api = daemonSetApi;
|
api = daemonSetApi;
|
||||||
|
|
||||||
@observable metrics: IPodMetrics = null;
|
@observable metrics: IDaemonSetMetrics = null;
|
||||||
|
|
||||||
async loadMetrics(daemonSet: DaemonSet) {
|
async loadMetrics(daemonSet: DaemonSet) {
|
||||||
const pods = this.getChildPods(daemonSet);
|
this.metrics = await daemonSetApi.getMetrics([daemonSet], daemonSet.getNs(), "");
|
||||||
|
|
||||||
this.metrics = await podsApi.getMetrics(pods, daemonSet.getNs(), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildPods(daemonSet: DaemonSet): Pod[] {
|
getChildPods(daemonSet: DaemonSet): Pod[] {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { Deployment, deploymentApi, IPodMetrics, podsApi, PodStatus } from "../../api/endpoints";
|
import { Deployment, deploymentApi, IDeploymentMetrics, PodStatus } from "../../api/endpoints";
|
||||||
import { KubeObjectStore } from "../../kube-object.store";
|
import { KubeObjectStore } from "../../kube-object.store";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
@ -8,7 +8,7 @@ import { apiManager } from "../../api/api-manager";
|
|||||||
@autobind()
|
@autobind()
|
||||||
export class DeploymentStore extends KubeObjectStore<Deployment> {
|
export class DeploymentStore extends KubeObjectStore<Deployment> {
|
||||||
api = deploymentApi;
|
api = deploymentApi;
|
||||||
@observable metrics: IPodMetrics = null;
|
@observable metrics: IDeploymentMetrics = null;
|
||||||
|
|
||||||
protected sortItems(items: Deployment[]) {
|
protected sortItems(items: Deployment[]) {
|
||||||
return super.sortItems(items, [
|
return super.sortItems(items, [
|
||||||
@ -17,9 +17,7 @@ export class DeploymentStore extends KubeObjectStore<Deployment> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadMetrics(deployment: Deployment) {
|
async loadMetrics(deployment: Deployment) {
|
||||||
const pods = this.getChildPods(deployment);
|
this.metrics = await deploymentApi.getMetrics([deployment], deployment.getNs(), "");
|
||||||
|
|
||||||
this.metrics = await podsApi.getMetrics(pods, deployment.getNs(), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatuses(deployments?: Deployment[]) {
|
getStatuses(deployments?: Deployment[]) {
|
||||||
|
|||||||
@ -18,6 +18,8 @@ import { PodDetailsList } from "../+workloads-pods/pod-details-list";
|
|||||||
import { lookupApiLink } from "../../api/kube-api";
|
import { lookupApiLink } from "../../api/kube-api";
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
||||||
|
import { ResourceMetrics } from "../resource-metrics";
|
||||||
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<Job> {
|
interface Props extends KubeObjectDetailsProps<Job> {
|
||||||
}
|
}
|
||||||
@ -40,9 +42,18 @@ export class JobDetails extends React.Component<Props> {
|
|||||||
const childPods = jobStore.getChildPods(job);
|
const childPods = jobStore.getChildPods(job);
|
||||||
const ownerRefs = job.getOwnerRefs();
|
const ownerRefs = job.getOwnerRefs();
|
||||||
const condition = job.getCondition();
|
const condition = job.getCondition();
|
||||||
|
const metrics = jobStore.metrics;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="JobDetails">
|
<div className="JobDetails">
|
||||||
|
{jobStore.isLoaded && (
|
||||||
|
<ResourceMetrics
|
||||||
|
loader={() => jobStore.loadMetrics(job)}
|
||||||
|
tabs={podMetricTabs} object={job} params={{ metrics }}
|
||||||
|
>
|
||||||
|
<PodCharts />
|
||||||
|
</ResourceMetrics>
|
||||||
|
)}
|
||||||
<KubeObjectMeta object={job}/>
|
<KubeObjectMeta object={job}/>
|
||||||
<DrawerItem name="Selector" labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,14 +1,21 @@
|
|||||||
import { KubeObjectStore } from "../../kube-object.store";
|
import { KubeObjectStore } from "../../kube-object.store";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { Job, jobApi } from "../../api/endpoints/job.api";
|
import { IJobMetrics, Job, jobApi } from "../../api/endpoints/job.api";
|
||||||
import { CronJob, Pod, PodStatus } from "../../api/endpoints";
|
import { CronJob, Pod, PodStatus } from "../../api/endpoints";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
import { observable } from "mobx";
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
export class JobStore extends KubeObjectStore<Job> {
|
export class JobStore extends KubeObjectStore<Job> {
|
||||||
api = jobApi;
|
api = jobApi;
|
||||||
|
|
||||||
|
@observable metrics: IJobMetrics = null;
|
||||||
|
|
||||||
|
async loadMetrics(job: Job) {
|
||||||
|
this.metrics = await jobApi.getMetrics([job], job.getNs(), "");
|
||||||
|
}
|
||||||
|
|
||||||
getChildPods(job: Job): Pod[] {
|
getChildPods(job: Job): Pod[] {
|
||||||
return podsStore.getPodsByOwner(job);
|
return podsStore.getPodsByOwner(job);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { isMetricsEmpty, normalizeMetrics } from "../../api/endpoints/metrics.ap
|
|||||||
import { NoMetrics } from "../resource-metrics/no-metrics";
|
import { NoMetrics } from "../resource-metrics/no-metrics";
|
||||||
import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metrics";
|
import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metrics";
|
||||||
import { themeStore } from "../../theme.store";
|
import { themeStore } from "../../theme.store";
|
||||||
|
import { mapValues } from "lodash";
|
||||||
|
|
||||||
type IContext = IResourceMetricsValue<any, { metrics: IPodMetrics }>;
|
type IContext = IResourceMetricsValue<any, { metrics: IPodMetrics }>;
|
||||||
|
|
||||||
@ -16,10 +17,7 @@ export const ContainerCharts = observer(() => {
|
|||||||
if (!metrics) return null;
|
if (!metrics) return null;
|
||||||
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
|
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
|
||||||
|
|
||||||
const values = Object.values(metrics)
|
const {
|
||||||
.map(normalizeMetrics)
|
|
||||||
.map(({ data }) => data.result[0].values);
|
|
||||||
const [
|
|
||||||
cpuUsage,
|
cpuUsage,
|
||||||
cpuRequests,
|
cpuRequests,
|
||||||
cpuLimits,
|
cpuLimits,
|
||||||
@ -27,7 +25,7 @@ export const ContainerCharts = observer(() => {
|
|||||||
memoryRequests,
|
memoryRequests,
|
||||||
memoryLimits,
|
memoryLimits,
|
||||||
fsUsage
|
fsUsage
|
||||||
] = values;
|
} = mapValues(metrics, metric => normalizeMetrics(metric).data.result[0].values);
|
||||||
|
|
||||||
const datasets = [
|
const datasets = [
|
||||||
// CPU
|
// CPU
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { isMetricsEmpty, normalizeMetrics } from "../../api/endpoints/metrics.ap
|
|||||||
import { NoMetrics } from "../resource-metrics/no-metrics";
|
import { NoMetrics } from "../resource-metrics/no-metrics";
|
||||||
import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metrics";
|
import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metrics";
|
||||||
import { WorkloadKubeObject } from "../../api/workload-kube-object";
|
import { WorkloadKubeObject } from "../../api/workload-kube-object";
|
||||||
import { themeStore } from "../../theme.store";
|
import { mapValues } from "lodash";
|
||||||
|
|
||||||
export const podMetricTabs = [
|
export const podMetricTabs = [
|
||||||
"CPU",
|
"CPU",
|
||||||
@ -19,27 +19,20 @@ type IContext = IResourceMetricsValue<WorkloadKubeObject, { metrics: IPodMetrics
|
|||||||
|
|
||||||
export const PodCharts = observer(() => {
|
export const PodCharts = observer(() => {
|
||||||
const { params: { metrics }, tabId, object } = useContext<IContext>(ResourceMetricsContext);
|
const { params: { metrics }, tabId, object } = useContext<IContext>(ResourceMetricsContext);
|
||||||
const { chartCapacityColor } = themeStore.activeTheme.colors;
|
|
||||||
const id = object.getId();
|
const id = object.getId();
|
||||||
|
|
||||||
if (!metrics) return null;
|
if (!metrics) return null;
|
||||||
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
|
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
|
||||||
|
|
||||||
const options = tabId == 0 ? cpuOptions : memoryOptions;
|
const options = tabId == 0 ? cpuOptions : memoryOptions;
|
||||||
const values = Object.values(metrics)
|
|
||||||
.map(normalizeMetrics)
|
const {
|
||||||
.map(({ data }) => data.result[0].values);
|
|
||||||
const [
|
|
||||||
cpuUsage,
|
cpuUsage,
|
||||||
cpuRequests,
|
|
||||||
cpuLimits,
|
|
||||||
memoryUsage,
|
memoryUsage,
|
||||||
memoryRequests,
|
|
||||||
memoryLimits,
|
|
||||||
fsUsage,
|
fsUsage,
|
||||||
networkReceive,
|
networkReceive,
|
||||||
networkTransmit
|
networkTransmit
|
||||||
] = values;
|
} = mapValues(metrics, metric => normalizeMetrics(metric).data.result[0].values);
|
||||||
|
|
||||||
const datasets = [
|
const datasets = [
|
||||||
// CPU
|
// CPU
|
||||||
@ -50,20 +43,6 @@ export const PodCharts = observer(() => {
|
|||||||
tooltip: `Container CPU cores usage`,
|
tooltip: `Container CPU cores usage`,
|
||||||
borderColor: "#3D90CE",
|
borderColor: "#3D90CE",
|
||||||
data: cpuUsage.map(([x, y]) => ({ x, y }))
|
data: cpuUsage.map(([x, y]) => ({ x, y }))
|
||||||
},
|
|
||||||
{
|
|
||||||
id: `${id}-cpuRequests`,
|
|
||||||
label: `Requests`,
|
|
||||||
tooltip: `Container CPU requests`,
|
|
||||||
borderColor: "#30b24d",
|
|
||||||
data: cpuRequests.map(([x, y]) => ({ x, y }))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: `${id}-cpuLimits`,
|
|
||||||
label: `Limits`,
|
|
||||||
tooltip: `CPU limits`,
|
|
||||||
borderColor: chartCapacityColor,
|
|
||||||
data: cpuLimits.map(([x, y]) => ({ x, y }))
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
// Memory
|
// Memory
|
||||||
@ -74,20 +53,6 @@ export const PodCharts = observer(() => {
|
|||||||
tooltip: `Container memory usage`,
|
tooltip: `Container memory usage`,
|
||||||
borderColor: "#c93dce",
|
borderColor: "#c93dce",
|
||||||
data: memoryUsage.map(([x, y]) => ({ x, y }))
|
data: memoryUsage.map(([x, y]) => ({ x, y }))
|
||||||
},
|
|
||||||
{
|
|
||||||
id: `${id}-memoryRequests`,
|
|
||||||
label: `Requests`,
|
|
||||||
tooltip: `Container memory requests`,
|
|
||||||
borderColor: "#30b24d",
|
|
||||||
data: memoryRequests.map(([x, y]) => ({ x, y }))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: `${id}-memoryLimits`,
|
|
||||||
label: `Limits`,
|
|
||||||
tooltip: `Container memory limits`,
|
|
||||||
borderColor: chartCapacityColor,
|
|
||||||
data: memoryLimits.map(([x, y]) => ({ x, y }))
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
// Network
|
// Network
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { KubeObjectStore } from "../../kube-object.store";
|
import { KubeObjectStore } from "../../kube-object.store";
|
||||||
import { Deployment, IPodMetrics, podsApi, ReplicaSet, replicaSetApi } from "../../api/endpoints";
|
import { Deployment, IReplicaSetMetrics, ReplicaSet, replicaSetApi } from "../../api/endpoints";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
import { PodStatus } from "../../api/endpoints/pods.api";
|
import { PodStatus } from "../../api/endpoints/pods.api";
|
||||||
@ -9,12 +9,10 @@ import { PodStatus } from "../../api/endpoints/pods.api";
|
|||||||
@autobind()
|
@autobind()
|
||||||
export class ReplicaSetStore extends KubeObjectStore<ReplicaSet> {
|
export class ReplicaSetStore extends KubeObjectStore<ReplicaSet> {
|
||||||
api = replicaSetApi;
|
api = replicaSetApi;
|
||||||
@observable metrics: IPodMetrics = null;
|
@observable metrics: IReplicaSetMetrics = null;
|
||||||
|
|
||||||
async loadMetrics(replicaSet: ReplicaSet) {
|
async loadMetrics(replicaSet: ReplicaSet) {
|
||||||
const pods = this.getChildPods(replicaSet);
|
this.metrics = await replicaSetApi.getMetrics([replicaSet], replicaSet.getNs(), "");
|
||||||
|
|
||||||
this.metrics = await podsApi.getMetrics(pods, replicaSet.getNs(), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildPods(replicaSet: ReplicaSet) {
|
getChildPods(replicaSet: ReplicaSet) {
|
||||||
|
|||||||
@ -1,19 +1,17 @@
|
|||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { KubeObjectStore } from "../../kube-object.store";
|
import { KubeObjectStore } from "../../kube-object.store";
|
||||||
import { IPodMetrics, podsApi, PodStatus, StatefulSet, statefulSetApi } from "../../api/endpoints";
|
import { IStatefulSetMetrics, PodStatus, StatefulSet, statefulSetApi } from "../../api/endpoints";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
export class StatefulSetStore extends KubeObjectStore<StatefulSet> {
|
export class StatefulSetStore extends KubeObjectStore<StatefulSet> {
|
||||||
api = statefulSetApi;
|
api = statefulSetApi;
|
||||||
@observable metrics: IPodMetrics = null;
|
@observable metrics: IStatefulSetMetrics = null;
|
||||||
|
|
||||||
async loadMetrics(statefulSet: StatefulSet) {
|
async loadMetrics(statefulSet: StatefulSet) {
|
||||||
const pods = this.getChildPods(statefulSet);
|
this.metrics = await statefulSetApi.getMetrics([statefulSet], statefulSet.getNs(), "");
|
||||||
|
|
||||||
this.metrics = await podsApi.getMetrics(pods, statefulSet.getNs(), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildPods(statefulSet: StatefulSet) {
|
getChildPods(statefulSet: StatefulSet) {
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { IPodMetrics } from "../../api/endpoints";
|
import { getMetricLastPoints, IResourceMetrics, IMetrics } from "../../api/endpoints/metrics.api";
|
||||||
import { getMetricLastPoints, IMetrics } from "../../api/endpoints/metrics.api";
|
|
||||||
import { bytesToUnits } from "../../utils";
|
import { bytesToUnits } from "../../utils";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
metrics: IPodMetrics<IMetrics>;
|
metrics: IResourceMetrics<IMetrics>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ResourceMetricsText(props: Props) {
|
export function ResourceMetricsText(props: Props) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user