Skip to content

Commit

Permalink
all api marge done ,, agent error need fix
Browse files Browse the repository at this point in the history
  • Loading branch information
axif0 committed Nov 6, 2024
1 parent 7ab5974 commit 5c9d04a
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 44 deletions.
2 changes: 1 addition & 1 deletion cmd/api/app/routes/metrics/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func getKarmadaAgentMetrics(podName string, clusterName string) (string, error)
if err != nil {
return "", fmt.Errorf("filed to parse metrics to JSON: %v", err)
}

fmt.Println("jsonMetrics", jsonMetrics)
return jsonMetrics, nil
}

Expand Down
Binary file modified karmada_agent.db
Binary file not shown.
Binary file modified karmada_controller_manager.db
Binary file not shown.
Binary file modified karmada_scheduler.db
Binary file not shown.
Empty file removed karmada_scheduler_estimator.db
Empty file.
Binary file modified karmada_scheduler_estimator_member1.db
Binary file not shown.
Binary file modified karmada_scheduler_estimator_member2.db
Binary file not shown.
Binary file removed sqlite_dbs/karmada_controller_manager.db
Binary file not shown.
122 changes: 122 additions & 0 deletions ui/apps/dashboard/src/pages/metrics/diagram.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React, { useEffect, useState } from 'react';
import { Tabs, Table, Card, Modal, Button, message } from 'antd';
import {GetMetricsDetails, MetricDetailsResponse } from '@/services/metrics';
interface MetricTabsProps {
activeTab: string;
setActiveTab: (key: string) => void;
componentName: string;
podsName: string;
metricName: string;
}
const graphData = [
{ time: '00:00', value: 30 },
{ time: '04:00', value: 50 },
{ time: '08:00', value: 80 },

];

const columns = [
{ title: 'Time', dataIndex: 'time', key: 'time' },
{ title: 'Value', dataIndex: 'value', key: 'value' },
];


const Diagram: React.FC<MetricTabsProps> = ({ activeTab, setActiveTab, componentName, podsName, metricName }) => {
const [visible, setVisible] = useState(false);
const [logs, setLogs] = useState<MetricDetailsResponse | null>(null);

const getLogs = async (componentName: string, podsName: string, metricName: string) => {
if (!componentName || !podsName || !metricName) {
console.error('Missing parameters for fetching metrics details');
return;
}

try {
const details = await GetMetricsDetails(componentName, podsName, metricName);
console.log('Metrics Details:', details);
setLogs(details);
} catch (error) {
console.error('Failed to fetch metrics details:', error);
}
}

useEffect(() => {
if (componentName && podsName && metricName) {
getLogs(componentName, podsName, metricName);
} else {

setLogs(null);
}
}, [componentName, podsName, metricName]);

// Demo date-time ranges
const dateTimeRanges = [
'2024-11-05T22:59:52+07:00',
'2024-11-06T23:00:53+08:00',
'2024-11-07T00:01:54+09:00',
'2024-11-07T01:02:55+10:00',
'2024-11-07T02:03:56+11:00'
];

const showModal = () => {
setVisible(true);
};

const handleDelete = (range: string) => {

console.log(`Deleting range: ${range}`);
};

return (
<div>
<Button type="primary" onClick={showModal} style={{ float: 'right', marginBottom: '16px' }}>
View Date-Time Ranges
</Button>
<Modal
title="Time Ranges"
visible={visible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
footer={null}
>
{dateTimeRanges.map((range, index) => (
<div key={index} style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '16px' }}>
<span>{range}</span>
<Button type="link" onClick={() => handleDelete(range)}>
Delete
</Button>
</div>
))}
</Modal>
<Tabs
activeKey={activeTab}
onChange={key => setActiveTab(key.toString())}
style={{ marginRight: '24px' }}
items={[
{
key: 'graph',
label: 'Graph',
children: (
<div>
<b>Here should be the histogram</b>
<Card title="Logs" style={{ marginTop: '16px' }}>
<div style={{ height: '200px', background: '#f5f5f5', overflowY: 'auto' }}>
{logs ? JSON.stringify(logs, null, 2) : 'No logs available'}
</div>
</Card>
</div>
),
},
{
key: 'query',
label: 'Query',
children: <div style={{ padding: '24px' }}>Query content will go here</div>,
},
]}
/>

</div>
);
};

export default Diagram;
84 changes: 46 additions & 38 deletions ui/apps/dashboard/src/pages/metrics/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useState, useEffect } from 'react';
import { Layout, Button, Tabs, Card, Space, Typography, Select, Input, Table } from 'antd';
import { Layout, Button, Card, Space, Typography, Select, Input, message } from 'antd';
import Panel from '@/components/panel';
import { GetMetricsDetails, GetMetricsInfo } from '@/services/metrics';
import {GetMetricsInfo, GetMetricsData } from '@/services/metrics';
import Diagram from '@/pages/metrics/diagram';

const { Sider, Content } = Layout;
const { Text } = Typography;
Expand All @@ -26,6 +27,7 @@ export default function Component() {
const [selectedPod, setSelectedPod] = useState<string>('');
const [metrics, setMetrics] = useState<Metric[]>([]);
const [pods, setPods] = useState<PodOption[]>([]);
const [syncStatus, setSyncStatus] = useState<'idle' | 'success' | 'error'>('idle');

const options = [
'karmada-scheduler-estimator-member1',
Expand All @@ -36,18 +38,6 @@ export default function Component() {
'karmada-scheduler',
];

const graphData = [
{ time: '00:00', value: 30 },
{ time: '04:00', value: 50 },
{ time: '08:00', value: 80 },

];

const columns = [
{ title: 'Time', dataIndex: 'time', key: 'time' },
{ title: 'Value', dataIndex: 'value', key: 'value' },
];

useEffect(() => {
const fetchMetrics = async () => {
if (!selectedOption) return;
Expand Down Expand Up @@ -103,6 +93,30 @@ export default function Component() {
setSelectedMetric(null);
};

const handleSync = async () => {
try {
if (selectedOption === '') {
message.error('Please select a component');
return;
} else {
const response = await GetMetricsData(selectedOption);
console.log("Sync response:", response);

if (response.status === 200) {
setSyncStatus('success');
message.success('Sync successful!');
setTimeout(() => setSyncStatus('idle'), 5000); // Reset status after 5 seconds
} else {
throw new Error('Sync failed with status: ' + response.status);
}
}
} catch (error) {
setSyncStatus('error');
message.error('Sync failed: ' + (error instanceof Error ? error.message : 'due to an unknown error'));
setTimeout(() => setSyncStatus('idle'), 5000); // Reset status after 5 seconds
}
};

return (
<Panel>
<Layout style={{ height: '100vh' }}>
Expand Down Expand Up @@ -178,37 +192,31 @@ export default function Component() {
</Card>
)}

<Tabs
activeKey={activeTab}
onChange={key => setActiveTab(key.toString())}
items={[
{
key: 'graph',
label: 'Graph',
children: (
<div>
<Table dataSource={graphData} columns={columns} pagination={false} />
<Card title="Logs" style={{ marginTop: '16px' }}>
<div style={{ height: '200px', background: '#f5f5f5' }}></div>
</Card>
</div>
),
},
{
key: 'query',
label: 'Query',
children: <div style={{ padding: '24px' }}>Query content will go here</div>,
},
]}
<Diagram
activeTab={activeTab}
setActiveTab={setActiveTab}
componentName={selectedOption}
podsName={selectedPod}
metricName={selectedMetric ? selectedMetric.name : ''}
/>
</Space>
</Sider>

<Content style={{ padding: '16px', background: '#fff' }}>
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '16px' }}>
<Space>
<Button>Sync</Button>
<Button danger>Delete</Button>
{syncStatus === 'success' ? (
<Button style={{ color: 'green' }} onClick={handleSync}>
Sync Successful
</Button>
) : syncStatus === 'error' ? (
<Button style={{ color: 'red' }} onClick={handleSync}>
Sync Failed - Retry?
</Button>
) : (
<Button onClick={handleSync}>Sync db</Button>
)}
{/* <Button danger>Delete</Button> */}
</Space>
</div>
</Content>
Expand Down
41 changes: 36 additions & 5 deletions ui/apps/dashboard/src/services/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,40 @@ export interface MetricDetailsResponse {
}


export async function GetMetricsDetails(componentName: string, metricName: string): Promise<MetricDetailsResponse> {
console.log("componentName", componentName, "metricName", metricName);
const resp = await karmadaClient.get<MetricDetailsResponse>(`/metrics/${componentName}?type=details&mname=${metricName}`);
console.log("resp.data", resp.data);
export async function GetMetricsDetails(componentName: string, podsName: string, metricName: string): Promise<MetricDetailsResponse> {
console.log("componentName", componentName, "podsName", podsName, "metricName", metricName);
const resp = await karmadaClient.get<MetricDetailsResponse>(`/metrics/${componentName}/${podsName}?type=details&mname=${metricName}`);
console.log("resp.data GetMetricsDetails", resp.data);
return resp.data;
}
}

export interface MetricDataResponse {
currentTime: string;
metrics: {
[metricName: string]: {
name: string;
help: string;
type: 'COUNTER' | 'GAUGE' | 'SUMMARY' | 'HISTOGRAM';
values: MetricValue[];
};
};
}

export async function GetMetricsData(componentName: string): Promise<{ status: number; data?: MetricDataResponse | any }> {
console.log("componentName", componentName);
const resp = await karmadaClient.get<MetricDataResponse>(`/metrics/${componentName}`);
console.log("resp.data GetMetricsData", resp.data);

if (resp.data && typeof resp.data.currentTime === 'string' && resp.data.metrics) {
const isValidMetrics = Object.values(resp.data.metrics).every(metric =>
metric.name && metric.help && metric.type && Array.isArray(metric.values)
);

if (isValidMetrics) {
return { status: 200 };
}
}


return { status: 400, data: resp.data };
}

0 comments on commit 5c9d04a

Please sign in to comment.