@@ -1062,16 +1062,34 @@ type TopologyNode struct {
10621062 CreationTime string `json:"creationTime,omitempty"`
10631063}
10641064
1065- func topologyRequestsFromPod (p kubernetes.PodInfo ) TopologyPodResources {
1065+ func ( s * Server ) topologyRequestsFromPod (p kubernetes.PodInfo ) TopologyPodResources {
10661066 var out TopologyPodResources
10671067 if p .Requests .CPU != "" {
10681068 if q , err := resource .ParseQuantity (p .Requests .CPU ); err == nil {
10691069 out .CPUCores = float64 (q .MilliValue ()) / 1000.0
1070+ } else {
1071+ debugLog (
1072+ s .config .Debug ,
1073+ "[topology] failed to parse CPU request for pod %s/%s (%q): %v\n " ,
1074+ p .Namespace ,
1075+ p .Name ,
1076+ p .Requests .CPU ,
1077+ err ,
1078+ )
10701079 }
10711080 }
10721081 if p .Requests .Memory != "" {
10731082 if q , err := resource .ParseQuantity (p .Requests .Memory ); err == nil {
10741083 out .MemoryGiB = float64 (q .Value ()) / (1024 * 1024 * 1024 )
1084+ } else {
1085+ debugLog (
1086+ s .config .Debug ,
1087+ "[topology] failed to parse memory request for pod %s/%s (%q): %v\n " ,
1088+ p .Namespace ,
1089+ p .Name ,
1090+ p .Requests .Memory ,
1091+ err ,
1092+ )
10751093 }
10761094 }
10771095 return out
@@ -1101,17 +1119,32 @@ func (s *Server) getTopology(c *gin.Context) {
11011119 if maxPodsPerNode > 1000 {
11021120 maxPodsPerNode = 1000
11031121 }
1122+ } else {
1123+ debugLog (
1124+ s .config .Debug ,
1125+ "[topology] invalid maxPodsPerNode query value %q, using default %d\n " ,
1126+ v ,
1127+ maxPodsPerNode ,
1128+ )
11041129 }
11051130 }
1131+ debugLog (
1132+ s .config .Debug ,
1133+ "[topology] request received remote=%s maxPodsPerNode=%d\n " ,
1134+ c .ClientIP (),
1135+ maxPodsPerNode ,
1136+ )
11061137
11071138 ctx , cancel := context .WithTimeout (context .Background (), 120 * time .Second )
11081139 defer cancel ()
11091140
11101141 nodes , err := s .k8sClient .GetAllNodesWithUsage (ctx )
11111142 if err != nil {
1143+ debugLog (s .config .Debug , "[topology] failed to fetch nodes: %v\n " , err )
11121144 c .JSON (500 , gin.H {"error" : err .Error ()})
11131145 return
11141146 }
1147+ debugLog (s .config .Debug , "[topology] fetched %d nodes\n " , len (nodes ))
11151148
11161149 nodeNames := make (map [string ]bool , len (nodes ))
11171150 for _ , n := range nodes {
@@ -1120,39 +1153,68 @@ func (s *Server) getTopology(c *gin.Context) {
11201153
11211154 allPods , err := s .k8sClient .GetPodsOnNodes (ctx , nodeNames )
11221155 if err != nil {
1156+ debugLog (s .config .Debug , "[topology] failed to fetch pods on nodes: %v\n " , err )
11231157 c .JSON (500 , gin.H {"error" : err .Error ()})
11241158 return
11251159 }
1160+ debugLog (s .config .Debug , "[topology] fetched %d pods across selected nodes\n " , len (allPods ))
11261161
11271162 podsByNode := make (map [string ][]kubernetes.PodInfo )
1163+ var terminalSkipped int
11281164 for _ , p := range allPods {
11291165 if p .Phase == "Succeeded" || p .Phase == "Failed" {
1166+ terminalSkipped ++
11301167 continue
11311168 }
11321169 podsByNode [p .NodeName ] = append (podsByNode [p .NodeName ], p )
11331170 }
1171+ debugLog (
1172+ s .config .Debug ,
1173+ "[topology] grouped pods by node: nodesWithPods=%d terminalPodsSkipped=%d\n " ,
1174+ len (podsByNode ),
1175+ terminalSkipped ,
1176+ )
11341177
11351178 out := make ([]TopologyNode , 0 , len (nodes ))
11361179 for _ , node := range nodes {
1137- list := podsByNode [node .Name ]
1180+ type podWithReq struct {
1181+ pod kubernetes.PodInfo
1182+ req TopologyPodResources
1183+ }
1184+
1185+ list := make ([]podWithReq , 0 , len (podsByNode [node .Name ]))
1186+ for _ , p := range podsByNode [node .Name ] {
1187+ list = append (list , podWithReq {
1188+ pod : p ,
1189+ req : s .topologyRequestsFromPod (p ),
1190+ })
1191+ }
1192+
11381193 sort .Slice (list , func (i , j int ) bool {
1139- return topologyRequestsFromPod ( list [i ]). CPUCores > topologyRequestsFromPod ( list [j ]) .CPUCores
1194+ return list [i ]. req . CPUCores > list [j ]. req .CPUCores
11401195 })
1196+ originalLen := len (list )
11411197 if len (list ) > maxPodsPerNode {
11421198 list = list [:maxPodsPerNode ]
1199+ debugLog (
1200+ s .config .Debug ,
1201+ "[topology] truncated pods for node=%s from %d to %d by maxPodsPerNode\n " ,
1202+ node .Name ,
1203+ originalLen ,
1204+ len (list ),
1205+ )
11431206 }
11441207
11451208 topPods := make ([]TopologyPod , 0 , len (list ))
1146- for _ , p := range list {
1147- req := topologyRequestsFromPod (p )
1209+ for _ , entry := range list {
11481210 topPods = append (topPods , TopologyPod {
1149- Name : p .Name ,
1150- Namespace : p .Namespace ,
1151- NodeName : p .NodeName ,
1152- WorkloadName : p .WorkloadName ,
1153- WorkloadType : p .WorkloadType ,
1154- QOSClass : p .QOSClass ,
1155- Requests : req ,
1211+ Name : entry . pod .Name ,
1212+ Namespace : entry . pod .Namespace ,
1213+ NodeName : entry . pod .NodeName ,
1214+ WorkloadName : entry . pod .WorkloadName ,
1215+ WorkloadType : entry . pod .WorkloadType ,
1216+ QOSClass : entry . pod .QOSClass ,
1217+ Requests : entry . req ,
11561218 })
11571219 }
11581220
@@ -1170,6 +1232,7 @@ func (s *Server) getTopology(c *gin.Context) {
11701232 CreationTime : node .CreationTime ,
11711233 })
11721234 }
1235+ debugLog (s .config .Debug , "[topology] returning topology response with %d nodes\n " , len (out ))
11731236
11741237 c .JSON (200 , gin.H {
11751238 "nodes" : out ,
0 commit comments