Fix namespace historical analysis - use Kubernetes API for accurate pod count and remove duplicate function
This commit is contained in:
@@ -485,6 +485,7 @@ async def get_cluster_historical_summary(
|
|||||||
async def get_namespace_historical_analysis(
|
async def get_namespace_historical_analysis(
|
||||||
namespace: str,
|
namespace: str,
|
||||||
time_range: str = "24h",
|
time_range: str = "24h",
|
||||||
|
k8s_client=Depends(get_k8s_client),
|
||||||
prometheus_client=Depends(get_prometheus_client)
|
prometheus_client=Depends(get_prometheus_client)
|
||||||
):
|
):
|
||||||
"""Get historical analysis for a specific namespace"""
|
"""Get historical analysis for a specific namespace"""
|
||||||
@@ -493,7 +494,7 @@ async def get_namespace_historical_analysis(
|
|||||||
|
|
||||||
# Get historical analysis for the namespace
|
# Get historical analysis for the namespace
|
||||||
analysis = await historical_service.get_namespace_historical_analysis(
|
analysis = await historical_service.get_namespace_historical_analysis(
|
||||||
namespace, time_range
|
namespace, time_range, k8s_client
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ class HistoricalAnalysisService:
|
|||||||
logger.error(f"Error getting historical summary: {e}")
|
logger.error(f"Error getting historical summary: {e}")
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
async def get_namespace_historical_analysis(self, namespace: str, time_range: str):
|
async def get_namespace_historical_analysis(self, namespace: str, time_range: str, k8s_client=None):
|
||||||
"""Get historical analysis for a specific namespace"""
|
"""Get historical analysis for a specific namespace"""
|
||||||
try:
|
try:
|
||||||
logger.info(f"Getting historical analysis for namespace: {namespace}")
|
logger.info(f"Getting historical analysis for namespace: {namespace}")
|
||||||
@@ -520,11 +520,6 @@ class HistoricalAnalysisService:
|
|||||||
}})
|
}})
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Query for pod count by namespace
|
|
||||||
pod_count_query = f'''
|
|
||||||
count(kube_pod_info{{namespace="{namespace}"}})
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Execute queries
|
# Execute queries
|
||||||
cpu_usage = await self._query_prometheus(cpu_query,
|
cpu_usage = await self._query_prometheus(cpu_query,
|
||||||
datetime.now() - timedelta(seconds=self.time_ranges[time_range]),
|
datetime.now() - timedelta(seconds=self.time_ranges[time_range]),
|
||||||
@@ -538,9 +533,29 @@ class HistoricalAnalysisService:
|
|||||||
memory_requests = await self._query_prometheus(memory_requests_query,
|
memory_requests = await self._query_prometheus(memory_requests_query,
|
||||||
datetime.now() - timedelta(seconds=self.time_ranges[time_range]),
|
datetime.now() - timedelta(seconds=self.time_ranges[time_range]),
|
||||||
datetime.now())
|
datetime.now())
|
||||||
pod_count = await self._query_prometheus(pod_count_query,
|
|
||||||
|
# Get pod count using Kubernetes API (more reliable than Prometheus)
|
||||||
|
pod_count = 0
|
||||||
|
if k8s_client:
|
||||||
|
try:
|
||||||
|
pods = await k8s_client.get_all_pods()
|
||||||
|
namespace_pods = [pod for pod in pods if pod.namespace == namespace]
|
||||||
|
pod_count = len(namespace_pods)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Could not get pod count from Kubernetes API: {e}")
|
||||||
|
# Fallback to Prometheus query
|
||||||
|
pod_count_query = f'count(kube_pod_info{{namespace="{namespace}"}})'
|
||||||
|
pod_count_result = await self._query_prometheus(pod_count_query,
|
||||||
datetime.now() - timedelta(seconds=self.time_ranges[time_range]),
|
datetime.now() - timedelta(seconds=self.time_ranges[time_range]),
|
||||||
datetime.now())
|
datetime.now())
|
||||||
|
pod_count = int(self._safe_float(pod_count_result[0][1])) if pod_count_result else 0
|
||||||
|
else:
|
||||||
|
# Fallback to Prometheus query if no k8s_client
|
||||||
|
pod_count_query = f'count(kube_pod_info{{namespace="{namespace}"}})'
|
||||||
|
pod_count_result = await self._query_prometheus(pod_count_query,
|
||||||
|
datetime.now() - timedelta(seconds=self.time_ranges[time_range]),
|
||||||
|
datetime.now())
|
||||||
|
pod_count = int(self._safe_float(pod_count_result[0][1])) if pod_count_result else 0
|
||||||
|
|
||||||
# Calculate utilization percentages
|
# Calculate utilization percentages
|
||||||
cpu_utilization = 0
|
cpu_utilization = 0
|
||||||
|
|||||||
@@ -1648,56 +1648,6 @@
|
|||||||
let currentNamespace = null;
|
let currentNamespace = null;
|
||||||
let currentWorkload = null;
|
let currentWorkload = null;
|
||||||
|
|
||||||
async function loadNamespaceHistoricalAnalysis(namespace, timeRange = '24h') {
|
|
||||||
showLoading();
|
|
||||||
currentNamespace = namespace;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Para análise por namespace, vamos buscar todos os workloads do namespace
|
|
||||||
const response = await fetch(`/api/v1/cluster/status`);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
// Encontrar o namespace específico
|
|
||||||
const targetNamespace = data.namespaces.find(ns => ns.namespace === namespace);
|
|
||||||
if (!targetNamespace) {
|
|
||||||
showError('Namespace not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Agrupar pods por deployment
|
|
||||||
const deployments = {};
|
|
||||||
Object.values(targetNamespace.pods).forEach(pod => {
|
|
||||||
if (pod.validations && pod.validations.length > 0) {
|
|
||||||
const deploymentName = pod.pod_name.split('-').slice(0, -2).join('-') || 'unknown';
|
|
||||||
if (!deployments[deploymentName]) {
|
|
||||||
deployments[deploymentName] = [];
|
|
||||||
}
|
|
||||||
deployments[deploymentName].push(pod);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Se há apenas um deployment, usar análise de workload
|
|
||||||
const deploymentNames = Object.keys(deployments);
|
|
||||||
if (deploymentNames.length === 1) {
|
|
||||||
await loadWorkloadHistoricalAnalysis(namespace, deploymentNames[0], timeRange);
|
|
||||||
} else if (deploymentNames.length > 1) {
|
|
||||||
// Para múltiplos deployments, usar o primeiro
|
|
||||||
await loadWorkloadHistoricalAnalysis(namespace, deploymentNames[0], timeRange);
|
|
||||||
} else {
|
|
||||||
showError('No workloads found in namespace');
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
showError('Error loading namespace analysis: ' + error.message);
|
|
||||||
} finally {
|
|
||||||
hideLoading();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadWorkloadHistoricalAnalysis(namespace, workload, timeRange = '24h') {
|
async function loadWorkloadHistoricalAnalysis(namespace, workload, timeRange = '24h') {
|
||||||
showLoading();
|
showLoading();
|
||||||
|
|||||||
Reference in New Issue
Block a user