collector.go 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763
  1. package collector
  2. import (
  3. "github.com/opencost/opencost/core/pkg/source"
  4. "github.com/opencost/opencost/modules/collector-source/pkg/metric"
  5. "github.com/opencost/opencost/modules/collector-source/pkg/metric/aggregator"
  6. "github.com/opencost/opencost/modules/collector-source/pkg/scrape"
  7. )
  8. // NewOpenCostMetricStore creates a new MetricStore which has registered all MetricCollector instances required
  9. // for OpenCost
  10. func NewOpenCostMetricStore() metric.MetricStore {
  11. memStore := metric.NewInMemoryMetricStore()
  12. // Register all the metrics
  13. memStore.Register(NewPVPricePerGiBHourMetricCollector())
  14. memStore.Register(NewPVUsedAverageMetricCollector())
  15. memStore.Register(NewPVUsedMaxMetricCollector())
  16. memStore.Register(NewPVCInfoMetricCollector())
  17. memStore.Register(NewPVActiveMinutesMetricCollector())
  18. memStore.Register(NewLocalStorageUsedActiveMinutesMetricCollector())
  19. memStore.Register(NewLocalStorageUsedAverageMetricCollector())
  20. memStore.Register(NewLocalStorageUsedMaxMetricCollector())
  21. memStore.Register(NewLocalStorageBytesMetricCollector())
  22. memStore.Register(NewLocalStorageActiveMinutesMetricCollector())
  23. memStore.Register(NewNodeCPUCoresCapacityMetricCollector())
  24. memStore.Register(NewNodeCPUCoresAllocatableMetricCollector())
  25. memStore.Register(NewNodeRAMBytesCapacityMetricCollector())
  26. memStore.Register(NewNodeRAMBytesAllocatableMetricCollector())
  27. memStore.Register(NewNodeGPUCountMetricCollector())
  28. memStore.Register(NewNodeLabelsMetricCollector())
  29. memStore.Register(NewNodeActiveMinutesMetricCollector())
  30. memStore.Register(NewNodeCPUModeTotalMetricCollector())
  31. memStore.Register(NewNodeRAMSystemUsageAverageMetricCollector())
  32. memStore.Register(NewNodeRAMUserUsageAverageMetricCollector())
  33. memStore.Register(NewLBPricePerHourMetricCollector())
  34. memStore.Register(NewLBActiveMinutesMetricCollector())
  35. memStore.Register(NewClusterManagementDurationMetricCollector())
  36. memStore.Register(NewClusterManagementPricePerHourMetricCollector())
  37. memStore.Register(NewPodActiveMinutesMetricCollector())
  38. memStore.Register(NewRAMBytesAllocatedMetricCollector())
  39. memStore.Register(NewRAMRequestsMetricCollector())
  40. memStore.Register(NewRAMUsageAverageMetricCollector())
  41. memStore.Register(NewRAMUsageMaxMetricCollector())
  42. memStore.Register(NewCPUCoresAllocatedMetricCollector())
  43. memStore.Register(NewCPURequestsMetricCollector())
  44. memStore.Register(NewCPUUsageAverageMetricCollector())
  45. memStore.Register(NewCPUUsageMaxMetricCollector())
  46. memStore.Register(NewGPUsRequestedMetricCollector())
  47. memStore.Register(NewGPUsUsageAverageMetricCollector())
  48. memStore.Register(NewGPUsUsageMaxMetricCollector())
  49. memStore.Register(NewGPUsAllocatedMetricCollector())
  50. memStore.Register(NewIsGPUSharedMetricCollector())
  51. memStore.Register(NewGPUInfoMetricCollector())
  52. memStore.Register(NewNodeCPUPricePerHourMetricCollector())
  53. memStore.Register(NewNodeRAMPricePerGiBHourMetricCollector())
  54. memStore.Register(NewNodeGPUPricePerHourMetricCollector())
  55. memStore.Register(NewNodeIsSpotMetricCollector())
  56. memStore.Register(NewPodPVCAllocationMetricCollector())
  57. memStore.Register(NewPVCBytesRequestedMetricCollector())
  58. memStore.Register(NewPVBytesMetricCollector())
  59. memStore.Register(NewPVInfoMetricCollector())
  60. memStore.Register(NewNetZoneGiBMetricCollector())
  61. memStore.Register(NewNetZonePricePerGiBMetricCollector())
  62. memStore.Register(NewNetRegionGiBMetricCollector())
  63. memStore.Register(NewNetRegionPricePerGiBMetricCollector())
  64. memStore.Register(NewNetInternetGiBMetricCollector())
  65. memStore.Register(NewNetInternetPricePerGiBMetricCollector())
  66. memStore.Register(NewNetInternetServiceGiBMetricCollector())
  67. memStore.Register(NewNetReceiveBytesMetricCollector())
  68. memStore.Register(NewNetZoneIngressGiBMetricCollector())
  69. memStore.Register(NewNetRegionIngressGiBMetricCollector())
  70. memStore.Register(NewNetInternetIngressGiBMetricCollector())
  71. memStore.Register(NewNetInternetServiceIngressGiBMetricCollector())
  72. memStore.Register(NewNetTransferBytesMetricCollector())
  73. memStore.Register(NewNamespaceLabelsMetricCollector())
  74. memStore.Register(NewNamespaceAnnotationsMetricCollector())
  75. memStore.Register(NewPodLabelsMetricCollector())
  76. memStore.Register(NewPodAnnotationsMetricCollector())
  77. memStore.Register(NewServiceLabelsMetricCollector())
  78. memStore.Register(NewDeploymentLabelsMetricCollector())
  79. memStore.Register(NewStatefulSetLabelsMetricCollector())
  80. memStore.Register(NewDaemonSetLabelsMetricCollector())
  81. memStore.Register(NewJobLabelsMetricCollector())
  82. memStore.Register(NewPodsWithReplicaSetOwnerMetricCollector())
  83. memStore.Register(NewReplicaSetsWithoutOwnersMetricCollector())
  84. memStore.Register(NewReplicaSetsWithRolloutMetricCollector())
  85. return memStore
  86. }
  87. // avg(
  88. // avg_over_time(
  89. // pv_hourly_cost{
  90. // <some_custom_filter>
  91. // }[1h]
  92. // )
  93. // ) by (cluster_id, persistentvolume, volumename, provider_id)
  94. func NewPVPricePerGiBHourMetricCollector() *metric.MetricCollector {
  95. return metric.NewMetricCollector(
  96. metric.PVPricePerGiBHourID,
  97. scrape.PVHourlyCost,
  98. []string{
  99. source.VolumeNameLabel,
  100. source.PVLabel,
  101. source.ProviderIDLabel,
  102. },
  103. aggregator.AverageOverTime,
  104. nil,
  105. )
  106. }
  107. // avg(
  108. // avg_over_time(
  109. // kubelet_volume_stats_used_bytes{
  110. // <some_custom_filter>
  111. // }[1h]
  112. // )
  113. // ) by (cluster_id, persistentvolumeclaim, namespace)
  114. func NewPVUsedAverageMetricCollector() *metric.MetricCollector {
  115. return metric.NewMetricCollector(
  116. metric.PVUsedAverageID,
  117. scrape.KubeletVolumeStatsUsedBytes,
  118. []string{
  119. source.NamespaceLabel,
  120. source.PVCLabel,
  121. },
  122. aggregator.AverageOverTime,
  123. nil,
  124. )
  125. }
  126. // max(
  127. // max_over_time(
  128. // kubelet_volume_stats_used_bytes{
  129. // <some_custom_filter>
  130. // }[1h]
  131. // )
  132. // ) by (cluster_id, persistentvolumeclaim, namespace)
  133. func NewPVUsedMaxMetricCollector() *metric.MetricCollector {
  134. return metric.NewMetricCollector(
  135. metric.PVUsedMaxID,
  136. scrape.KubeletVolumeStatsUsedBytes,
  137. []string{
  138. source.NamespaceLabel,
  139. source.PVCLabel,
  140. },
  141. aggregator.MaxOverTime,
  142. nil,
  143. )
  144. }
  145. // avg(
  146. // kube_persistentvolumeclaim_info{
  147. // volumename != "",
  148. // <some_custom_filter>
  149. // }
  150. // ) by (persistentvolumeclaim, storageclass, volumename, namespace, cluster_id)[0:10m]
  151. func NewPVCInfoMetricCollector() *metric.MetricCollector {
  152. return metric.NewMetricCollector(
  153. metric.PVCInfoID,
  154. scrape.KubePersistentVolumeClaimInfo,
  155. []string{
  156. source.NamespaceLabel,
  157. source.VolumeNameLabel,
  158. source.PVCLabel,
  159. source.StorageClassLabel,
  160. },
  161. aggregator.Info,
  162. func(labels map[string]string) bool {
  163. return labels[source.VolumeNameLabel] != ""
  164. },
  165. )
  166. }
  167. // avg(
  168. // kube_persistentvolume_capacity_bytes{
  169. // <some_custom_filter>
  170. // }
  171. // ) by (cluster_id, persistentvolume)[0:10m]
  172. func NewPVActiveMinutesMetricCollector() *metric.MetricCollector {
  173. return metric.NewMetricCollector(
  174. metric.PVActiveMinutesID,
  175. scrape.KubePersistentVolumeCapacityBytes,
  176. []string{
  177. source.PVLabel,
  178. },
  179. aggregator.ActiveMinutes,
  180. nil,
  181. )
  182. }
  183. // sum_over_time(
  184. //
  185. // sum(
  186. // container_fs_usage_bytes{
  187. // device=~"/dev/(nvme|sda).*",
  188. // id="/",
  189. // <some_custom_filter>
  190. // }
  191. // ) by (instance, device, cluster_id)[%s:%dm]
  192. //
  193. // ) / 1024 / 1024 / 1024 * %f * %f`
  194. // NewLocalStorageUsedActiveMinutesMetricCollector does not have an associated query end point but is used in the results
  195. // of QueryLocalStorageUsedCost
  196. func NewLocalStorageUsedActiveMinutesMetricCollector() *metric.MetricCollector {
  197. return metric.NewMetricCollector(
  198. metric.LocalStorageUsedActiveMinutesID,
  199. scrape.ContainerFSUsageBytes,
  200. []string{
  201. source.InstanceLabel,
  202. source.DeviceLabel,
  203. },
  204. aggregator.ActiveMinutes,
  205. nil, // filter not required here because only container root file system is being scraped
  206. )
  207. }
  208. // avg(
  209. // sum(
  210. // avg_over_time(
  211. // container_fs_usage_bytes{
  212. // device=~"/dev/(nvme|sda).*",
  213. // id="/",
  214. // <some_custom_filter>
  215. // }[1h]
  216. // )
  217. // ) by (instance, device, cluster_id, job)
  218. // ) by (instance, device, cluster_id)
  219. func NewLocalStorageUsedAverageMetricCollector() *metric.MetricCollector {
  220. return metric.NewMetricCollector(
  221. metric.LocalStorageUsedAverageID,
  222. scrape.ContainerFSUsageBytes,
  223. []string{
  224. source.InstanceLabel,
  225. source.DeviceLabel,
  226. },
  227. aggregator.AverageOverTime,
  228. nil, // filter not required here because only container root file system is being scraped
  229. )
  230. }
  231. // max(
  232. //
  233. // sum(
  234. // max_over_time(
  235. // container_fs_usage_bytes{
  236. // device=~"/dev/(nvme|sda).*",
  237. // id="/",
  238. // <some_custom_filter>
  239. // }[1h]
  240. // )
  241. // ) by (instance, device, cluster_id, job)
  242. //
  243. // ) by (instance, device, cluster_id)
  244. func NewLocalStorageUsedMaxMetricCollector() *metric.MetricCollector {
  245. return metric.NewMetricCollector(
  246. metric.LocalStorageUsedMaxID,
  247. scrape.ContainerFSUsageBytes,
  248. []string{
  249. source.InstanceLabel,
  250. source.DeviceLabel,
  251. },
  252. aggregator.MaxOverTime,
  253. nil, // filter not required here because only container root file system is being scraped
  254. )
  255. }
  256. // avg_over_time(
  257. //
  258. // sum(
  259. // container_fs_limit_bytes{
  260. // device=~"/dev/(nvme|sda).*",
  261. // id="/",
  262. // <some_custom_filter>
  263. // }
  264. // ) by (instance, device, cluster_id)[%s:%dm]
  265. //
  266. // )
  267. func NewLocalStorageBytesMetricCollector() *metric.MetricCollector {
  268. return metric.NewMetricCollector(
  269. metric.LocalStorageBytesID,
  270. scrape.NodeFSCapacityBytes,
  271. []string{
  272. source.InstanceLabel,
  273. source.DeviceLabel,
  274. },
  275. aggregator.AverageOverTime,
  276. nil, // filter not required here because only node root file system is being scraped
  277. )
  278. }
  279. // count(
  280. //
  281. // node_total_hourly_cost{
  282. // <some_custom_filter>
  283. // }
  284. //
  285. // ) by (cluster_id, node, instance, provider_id)[%s:%dm]
  286. func NewLocalStorageActiveMinutesMetricCollector() *metric.MetricCollector {
  287. return metric.NewMetricCollector(
  288. metric.LocalStorageActiveMinutesID,
  289. scrape.NodeTotalHourlyCost,
  290. []string{
  291. source.NodeLabel,
  292. source.ProviderIDLabel,
  293. },
  294. aggregator.ActiveMinutes,
  295. nil,
  296. )
  297. }
  298. // avg(
  299. //
  300. // avg_over_time(
  301. // kube_node_status_capacity_cpu_cores{
  302. // <some_custom_filter>
  303. // }[1h]
  304. // )
  305. //
  306. // ) by (cluster_id, node)
  307. func NewNodeCPUCoresCapacityMetricCollector() *metric.MetricCollector {
  308. return metric.NewMetricCollector(
  309. metric.NodeCPUCoresCapacityID,
  310. scrape.KubeNodeStatusCapacityCPUCores,
  311. []string{
  312. source.NodeLabel,
  313. },
  314. aggregator.AverageOverTime,
  315. nil,
  316. )
  317. }
  318. // avg(
  319. // avg_over_time(
  320. // kube_node_status_allocatable_cpu_cores{
  321. // <some_custom_filter>
  322. // }[1h]
  323. // )
  324. // ) by (cluster_id, node)
  325. func NewNodeCPUCoresAllocatableMetricCollector() *metric.MetricCollector {
  326. return metric.NewMetricCollector(
  327. metric.NodeCPUCoresAllocatableID,
  328. scrape.KubeNodeStatusAllocatableCPUCores,
  329. []string{
  330. source.NodeLabel,
  331. },
  332. aggregator.AverageOverTime,
  333. nil,
  334. )
  335. }
  336. // avg(
  337. // avg_over_time(
  338. // kube_node_status_capacity_memory_bytes{
  339. // <some_custom_filter>
  340. // }[1h]
  341. // )
  342. // ) by (cluster_id, node)
  343. func NewNodeRAMBytesCapacityMetricCollector() *metric.MetricCollector {
  344. return metric.NewMetricCollector(
  345. metric.NodeRAMBytesCapacityID,
  346. scrape.KubeNodeStatusCapacityMemoryBytes,
  347. []string{
  348. source.NodeLabel,
  349. },
  350. aggregator.AverageOverTime,
  351. nil,
  352. )
  353. }
  354. // avg(
  355. // avg_over_time(
  356. // kube_node_status_allocatable_memory_bytes{
  357. // <some_custom_filter>
  358. // }[1h]
  359. // )
  360. // ) by (cluster_id, node)
  361. func NewNodeRAMBytesAllocatableMetricCollector() *metric.MetricCollector {
  362. return metric.NewMetricCollector(
  363. metric.NodeRAMBytesAllocatableID,
  364. scrape.KubeNodeStatusAllocatableMemoryBytes,
  365. []string{
  366. source.NodeLabel,
  367. },
  368. aggregator.AverageOverTime,
  369. nil,
  370. )
  371. }
  372. // avg(
  373. // avg_over_time(
  374. // node_gpu_count{
  375. // <some_custom_filter>
  376. // }[1h]
  377. // )
  378. // ) by (cluster_id, node, provider_id)
  379. func NewNodeGPUCountMetricCollector() *metric.MetricCollector {
  380. return metric.NewMetricCollector(
  381. metric.NodeGPUCountID,
  382. scrape.NodeGPUCount,
  383. []string{
  384. source.NodeLabel,
  385. source.ProviderIDLabel,
  386. },
  387. aggregator.AverageOverTime,
  388. nil,
  389. )
  390. }
  391. // avg_over_time(
  392. // kube_node_labels{
  393. // <some_custom_filter>
  394. // }[1h]
  395. // )
  396. func NewNodeLabelsMetricCollector() *metric.MetricCollector {
  397. return metric.NewMetricCollector(
  398. metric.NodeLabelsID,
  399. scrape.KubeNodeLabels,
  400. []string{
  401. source.NodeLabel,
  402. },
  403. aggregator.Info,
  404. nil,
  405. )
  406. }
  407. // avg(
  408. // node_total_hourly_cost{
  409. // <some_custom_filter>
  410. // }
  411. // ) by (node, cluster_id, provider_id)[%s:%dm]
  412. func NewNodeActiveMinutesMetricCollector() *metric.MetricCollector {
  413. return metric.NewMetricCollector(
  414. metric.NodeActiveMinutesID,
  415. scrape.NodeTotalHourlyCost,
  416. []string{
  417. source.NodeLabel,
  418. source.ProviderIDLabel,
  419. },
  420. aggregator.ActiveMinutes,
  421. nil,
  422. )
  423. }
  424. // sum(
  425. // rate(
  426. // node_cpu_seconds_total{
  427. // <some_custom_filter>
  428. // }[%s:%dm]
  429. // )
  430. // ) by (kubernetes_node, cluster_id, mode)
  431. func NewNodeCPUModeTotalMetricCollector() *metric.MetricCollector {
  432. return metric.NewMetricCollector(
  433. metric.NodeCPUModeTotalID,
  434. scrape.NodeCPUSecondsTotal,
  435. []string{
  436. source.KubernetesNodeLabel,
  437. source.ModeLabel,
  438. },
  439. aggregator.Rate,
  440. nil,
  441. )
  442. }
  443. // avg(
  444. // avg_over_time(
  445. // container_memory_working_set_bytes{
  446. // container_name!="POD",
  447. // container_name!="",
  448. // namespace="kube-system",
  449. // <some_custom_filter>
  450. // }[%s:%dm]
  451. // )
  452. // ) by (instance, cluster_id)
  453. func NewNodeRAMSystemUsageAverageMetricCollector() *metric.MetricCollector {
  454. return metric.NewMetricCollector(
  455. metric.NodeRAMSystemUsageAverageID,
  456. scrape.ContainerMemoryWorkingSetBytes,
  457. []string{
  458. source.InstanceLabel,
  459. },
  460. aggregator.AverageOverTime,
  461. func(labels map[string]string) bool {
  462. return labels[source.ContainerLabel] != "POD" && labels[source.ContainerLabel] != "" && labels[source.NamespaceLabel] == "kube-system"
  463. },
  464. )
  465. }
  466. // avg(
  467. // avg_over_time(
  468. // container_memory_working_set_bytes{
  469. // container_name!="POD",
  470. // container_name!="",
  471. // namespace!="kube-system",
  472. // <some_custom_filter>
  473. // }[%s:%dm]
  474. // )
  475. // ) by (instance, cluster_id)
  476. func NewNodeRAMUserUsageAverageMetricCollector() *metric.MetricCollector {
  477. return metric.NewMetricCollector(
  478. metric.NodeRAMUserUsageAverageID,
  479. scrape.ContainerMemoryWorkingSetBytes,
  480. []string{
  481. source.InstanceLabel,
  482. },
  483. aggregator.AverageOverTime,
  484. func(labels map[string]string) bool {
  485. return labels[source.ContainerLabel] != "POD" && labels[source.ContainerLabel] != "" && labels[source.NamespaceLabel] != "kube-system"
  486. },
  487. )
  488. }
  489. // avg(
  490. // avg_over_time(
  491. // kubecost_load_balancer_cost{
  492. // <some_custom_filter>
  493. // }[1h]
  494. // )
  495. // ) by (namespace, service_name, ingress_ip, cluster_id)
  496. func NewLBPricePerHourMetricCollector() *metric.MetricCollector {
  497. return metric.NewMetricCollector(
  498. metric.LBPricePerHourID,
  499. scrape.KubecostLoadBalancerCost,
  500. []string{
  501. source.NamespaceLabel,
  502. source.ServiceNameLabel,
  503. source.IngressIPLabel,
  504. },
  505. aggregator.AverageOverTime,
  506. nil,
  507. )
  508. }
  509. // avg(
  510. // kubecost_load_balancer_cost{
  511. // <some_custom_filter>
  512. // }
  513. // ) by (namespace, service_name, cluster_id, ingress_ip)[%s:%dm]
  514. func NewLBActiveMinutesMetricCollector() *metric.MetricCollector {
  515. return metric.NewMetricCollector(
  516. metric.LBActiveMinutesID,
  517. scrape.KubecostLoadBalancerCost,
  518. []string{
  519. source.NamespaceLabel,
  520. source.ServiceNameLabel,
  521. source.IngressIPLabel,
  522. },
  523. aggregator.ActiveMinutes,
  524. nil,
  525. )
  526. }
  527. // avg(
  528. // kubecost_cluster_management_cost{
  529. // <some_custom_filter>
  530. // }
  531. // ) by (cluster_id, provisioner_name)[%s:%dm]
  532. func NewClusterManagementDurationMetricCollector() *metric.MetricCollector {
  533. return metric.NewMetricCollector(
  534. metric.ClusterManagementDurationID,
  535. scrape.KubecostClusterManagementCost,
  536. []string{
  537. source.ProvisionerNameLabel,
  538. },
  539. aggregator.ActiveMinutes,
  540. nil,
  541. )
  542. }
  543. // avg(
  544. // avg_over_time(
  545. // kubecost_cluster_management_cost{
  546. // <some_custom_filter>
  547. // }[1h]
  548. // )
  549. // ) by (cluster_id, provisioner_name)
  550. func NewClusterManagementPricePerHourMetricCollector() *metric.MetricCollector {
  551. return metric.NewMetricCollector(
  552. metric.ClusterManagementPricePerHourID,
  553. scrape.KubecostClusterManagementCost,
  554. []string{
  555. source.ProvisionerNameLabel,
  556. },
  557. aggregator.AverageOverTime,
  558. nil,
  559. )
  560. }
  561. // avg(
  562. // kube_pod_container_status_running{
  563. // <some_custom_filter>
  564. // } != 0
  565. // ) by (pod, namespace, uid, cluster_id)[%s:%s]
  566. func NewPodActiveMinutesMetricCollector() *metric.MetricCollector {
  567. return metric.NewMetricCollector(
  568. metric.PodActiveMinutesID,
  569. scrape.KubePodContainerStatusRunning,
  570. []string{
  571. source.UIDLabel,
  572. source.NamespaceLabel,
  573. source.PodLabel,
  574. },
  575. aggregator.ActiveMinutes,
  576. nil,
  577. )
  578. }
  579. // avg(
  580. // avg_over_time(
  581. // container_memory_allocation_bytes{
  582. // container!="",
  583. // container!="POD",
  584. // node!="",
  585. // <some_custom_filter>
  586. // }[1h]
  587. // )
  588. // ) by (container, pod, namespace, node, cluster_id, provider_id)
  589. func NewRAMBytesAllocatedMetricCollector() *metric.MetricCollector {
  590. return metric.NewMetricCollector(
  591. metric.RAMBytesAllocatedID,
  592. scrape.ContainerMemoryAllocationBytes,
  593. []string{
  594. source.NodeLabel,
  595. source.InstanceLabel,
  596. source.NamespaceLabel,
  597. source.PodLabel,
  598. source.ContainerLabel,
  599. },
  600. aggregator.AverageOverTime,
  601. func(labels map[string]string) bool {
  602. return labels[source.ContainerLabel] != "POD" && labels[source.ContainerLabel] != "" && labels[source.NodeLabel] != ""
  603. },
  604. )
  605. }
  606. // avg(
  607. // avg_over_time(
  608. // kube_pod_container_resource_requests{
  609. // resource="memory",
  610. // unit="byte",
  611. // container!="",
  612. // container!="POD",
  613. // node!="",
  614. // <some_custom_filter>
  615. // }[1h]
  616. // )
  617. //) by (container, pod, namespace, node, cluster_id)
  618. func NewRAMRequestsMetricCollector() *metric.MetricCollector {
  619. return metric.NewMetricCollector(
  620. metric.RAMRequestsID,
  621. scrape.KubePodContainerResourceRequests,
  622. []string{
  623. source.NodeLabel,
  624. source.InstanceLabel,
  625. source.NamespaceLabel,
  626. source.PodLabel,
  627. source.ContainerLabel,
  628. },
  629. aggregator.AverageOverTime,
  630. func(labels map[string]string) bool {
  631. return labels[source.ResourceLabel] == "memory" && labels[source.UnitLabel] == "byte" && labels[source.ContainerLabel] != "POD" && labels[source.ContainerLabel] != "" && labels[source.NodeLabel] != ""
  632. },
  633. )
  634. }
  635. // avg(
  636. // avg_over_time(
  637. // container_memory_working_set_bytes{
  638. // container!="",
  639. // container!="POD",
  640. // <some_custom_filter>
  641. // }[1h]
  642. // )
  643. // ) by (container, pod, namespace, instance, cluster_id)
  644. func NewRAMUsageAverageMetricCollector() *metric.MetricCollector {
  645. return metric.NewMetricCollector(
  646. metric.RAMUsageAverageID,
  647. scrape.ContainerMemoryWorkingSetBytes,
  648. []string{
  649. source.NodeLabel,
  650. source.InstanceLabel,
  651. source.NamespaceLabel,
  652. source.PodLabel,
  653. source.ContainerLabel,
  654. },
  655. aggregator.AverageOverTime,
  656. func(labels map[string]string) bool {
  657. return labels[source.ContainerLabel] != "POD" && labels[source.ContainerLabel] != ""
  658. },
  659. )
  660. }
  661. // max(
  662. // max_over_time(
  663. // container_memory_working_set_bytes{
  664. // container!="",
  665. // container_name!="POD",
  666. // container!="POD",
  667. // <some_custom_filter>
  668. // }[%s]
  669. // )
  670. // ) by (container_name, container, pod_name, pod, namespace, node, instance, %s)
  671. func NewRAMUsageMaxMetricCollector() *metric.MetricCollector {
  672. return metric.NewMetricCollector(
  673. metric.RAMUsageMaxID,
  674. scrape.ContainerMemoryWorkingSetBytes,
  675. []string{
  676. source.NodeLabel,
  677. source.InstanceLabel,
  678. source.NamespaceLabel,
  679. source.PodLabel,
  680. source.ContainerLabel,
  681. },
  682. aggregator.MaxOverTime,
  683. func(labels map[string]string) bool {
  684. return labels[source.ContainerLabel] != "" && labels[source.ContainerLabel] != "POD" && labels[source.NodeLabel] != ""
  685. },
  686. )
  687. }
  688. // avg(
  689. // avg_over_time(
  690. // container_cpu_allocation{
  691. // container!="",
  692. // container!="POD",
  693. // node!="",
  694. // <some_custom_filter>
  695. // }[1h]
  696. // )
  697. // ) by (container, pod, namespace, node, cluster_id)
  698. func NewCPUCoresAllocatedMetricCollector() *metric.MetricCollector {
  699. return metric.NewMetricCollector(
  700. metric.CPUCoresAllocatedID,
  701. scrape.ContainerCPUAllocation,
  702. []string{
  703. source.NodeLabel,
  704. source.InstanceLabel,
  705. source.NamespaceLabel,
  706. source.PodLabel,
  707. source.ContainerLabel,
  708. },
  709. aggregator.AverageOverTime,
  710. func(labels map[string]string) bool {
  711. return labels[source.ContainerLabel] != "POD" && labels[source.ContainerLabel] != "" && labels[source.NodeLabel] != ""
  712. },
  713. )
  714. }
  715. // avg(
  716. // avg_over_time(
  717. // kube_pod_container_resource_requests{
  718. // resource="cpu",
  719. // unit="core",
  720. // container!="",
  721. // container!="POD",
  722. // node!="",
  723. // <some_custom_filter>
  724. // }[1h]
  725. // )
  726. // ) by (container, pod, namespace, node, cluster_id)
  727. func NewCPURequestsMetricCollector() *metric.MetricCollector {
  728. return metric.NewMetricCollector(
  729. metric.CPURequestsID,
  730. scrape.KubePodContainerResourceRequests,
  731. []string{
  732. source.NodeLabel,
  733. source.InstanceLabel,
  734. source.NamespaceLabel,
  735. source.PodLabel,
  736. source.ContainerLabel,
  737. },
  738. aggregator.AverageOverTime,
  739. func(labels map[string]string) bool {
  740. return labels[source.ResourceLabel] == "cpu" && labels[source.UnitLabel] == "core" && labels[source.ContainerLabel] != "POD" && labels[source.ContainerLabel] != "" && labels[source.NodeLabel] != ""
  741. },
  742. )
  743. }
  744. // avg(
  745. // rate(
  746. // container_cpu_usage_seconds_total{
  747. // container!="",
  748. // container_name!="POD",
  749. // container!="POD",
  750. // <some_custom_filter>
  751. // }[1h]
  752. // )
  753. // ) by (container_name, container, pod_name, pod, namespace, node, instance, cluster_id)
  754. func NewCPUUsageAverageMetricCollector() *metric.MetricCollector {
  755. return metric.NewMetricCollector(
  756. metric.CPUUsageAverageID,
  757. scrape.ContainerCPUUsageSecondsTotal,
  758. []string{
  759. source.NodeLabel,
  760. source.InstanceLabel,
  761. source.NamespaceLabel,
  762. source.PodLabel,
  763. source.ContainerLabel,
  764. },
  765. aggregator.Rate,
  766. func(labels map[string]string) bool {
  767. return labels[source.ContainerLabel] != "" && labels[source.ContainerLabel] != "POD"
  768. },
  769. )
  770. }
  771. // max(
  772. //
  773. // max_over_time(
  774. // irate(
  775. // container_cpu_usage_seconds_total{
  776. // container!="POD",
  777. // container!="",
  778. // <some_custom_filter>
  779. // }[1h]
  780. // )[%s:%s]
  781. // )
  782. //
  783. // ) by (container, pod_name, pod, namespace, node, instance, cluster_id)
  784. func NewCPUUsageMaxMetricCollector() *metric.MetricCollector {
  785. return metric.NewMetricCollector(
  786. metric.CPUUsageMaxID,
  787. scrape.ContainerCPUUsageSecondsTotal,
  788. []string{
  789. source.NodeLabel,
  790. source.InstanceLabel,
  791. source.NamespaceLabel,
  792. source.PodLabel,
  793. source.ContainerLabel,
  794. },
  795. aggregator.IRateMax,
  796. func(labels map[string]string) bool {
  797. return labels[source.ContainerLabel] != "" && labels[source.ContainerLabel] != "POD"
  798. },
  799. )
  800. }
  801. // avg(
  802. // avg_over_time(
  803. // kube_pod_container_resource_requests{
  804. // resource="nvidia_com_gpu",
  805. // container!="",
  806. // container!="POD",
  807. // node!="",
  808. // <some_custom_filter>
  809. // }[1h]
  810. // )
  811. // ) by (container, pod, namespace, node, cluster_id)
  812. func NewGPUsRequestedMetricCollector() *metric.MetricCollector {
  813. return metric.NewMetricCollector(
  814. metric.GPUsRequestedID,
  815. scrape.KubePodContainerResourceRequests,
  816. []string{
  817. source.NamespaceLabel,
  818. source.PodLabel,
  819. source.ContainerLabel,
  820. },
  821. aggregator.AverageOverTime,
  822. func(labels map[string]string) bool {
  823. return labels[source.ResourceLabel] == "nvidia_com_gpu" && labels[source.ContainerLabel] != "POD" && labels[source.ContainerLabel] != "" && labels[source.NodeLabel] != ""
  824. },
  825. )
  826. }
  827. // avg(
  828. // avg_over_time(
  829. // DCGM_FI_PROF_GR_ENGINE_ACTIVE{
  830. // container!=""
  831. // }[1h]
  832. // )
  833. // ) by (container, pod, namespace, cluster_id)
  834. func NewGPUsUsageAverageMetricCollector() *metric.MetricCollector {
  835. return metric.NewMetricCollector(
  836. metric.GPUsUsageAverageID,
  837. scrape.DCGMFIPROFGRENGINEACTIVE,
  838. []string{
  839. source.NamespaceLabel,
  840. source.PodLabel,
  841. source.ContainerLabel,
  842. },
  843. aggregator.AverageOverTime,
  844. func(labels map[string]string) bool {
  845. return labels[source.ContainerLabel] != ""
  846. },
  847. )
  848. }
  849. // max(
  850. // max_over_time(
  851. // DCGM_FI_PROF_GR_ENGINE_ACTIVE{
  852. // container!=""
  853. // }[1h]
  854. // )
  855. // ) by (container, pod, namespace, cluster_id)
  856. func NewGPUsUsageMaxMetricCollector() *metric.MetricCollector {
  857. return metric.NewMetricCollector(
  858. metric.GPUsUsageMaxID,
  859. scrape.DCGMFIPROFGRENGINEACTIVE,
  860. []string{
  861. source.NamespaceLabel,
  862. source.PodLabel,
  863. source.ContainerLabel,
  864. },
  865. aggregator.MaxOverTime,
  866. func(labels map[string]string) bool {
  867. return labels[source.ContainerLabel] != ""
  868. },
  869. )
  870. }
  871. // avg(
  872. // avg_over_time(
  873. // container_gpu_allocation{
  874. // container!="",
  875. // container!="POD",
  876. // node!="",
  877. // <some_custom_filter>
  878. // }[1h]
  879. // )
  880. // ) by (container, pod, namespace, node, cluster_id)
  881. func NewGPUsAllocatedMetricCollector() *metric.MetricCollector {
  882. return metric.NewMetricCollector(
  883. metric.GPUsAllocatedID,
  884. scrape.ContainerGPUAllocation,
  885. []string{
  886. source.NamespaceLabel,
  887. source.PodLabel,
  888. source.ContainerLabel,
  889. },
  890. aggregator.AverageOverTime,
  891. func(labels map[string]string) bool {
  892. return labels[source.ContainerLabel] != "" && labels[source.ContainerLabel] != "POD" && labels[source.NodeLabel] != ""
  893. },
  894. )
  895. }
  896. // avg(
  897. // avg_over_time(
  898. // kube_pod_container_resource_requests{
  899. // container!="",
  900. // node != "",
  901. // pod != "",
  902. // container!= "",
  903. // unit = "integer",
  904. // <some_custom_filter>
  905. // }[1h]
  906. // )
  907. // ) by (container, pod, namespace, node, resource, cluster_id)
  908. func NewIsGPUSharedMetricCollector() *metric.MetricCollector {
  909. return metric.NewMetricCollector(
  910. metric.IsGPUSharedID,
  911. scrape.KubePodContainerResourceRequests,
  912. []string{
  913. source.NamespaceLabel,
  914. source.PodLabel,
  915. source.ContainerLabel,
  916. source.ResourceLabel,
  917. },
  918. aggregator.AverageOverTime,
  919. func(labels map[string]string) bool {
  920. return labels[source.ContainerLabel] != "" && labels[source.NodeLabel] != "" && labels[source.PodLabel] != "" && labels[source.UnitLabel] == "integer"
  921. },
  922. )
  923. }
  924. // avg(
  925. // avg_over_time(
  926. // DCGM_FI_DEV_DEC_UTIL{
  927. // container!="",
  928. // <some_custom_filter>
  929. // }[1h]
  930. // )
  931. // ) by (container, pod, namespace, device, modelName, UUID, cluster_id)
  932. func NewGPUInfoMetricCollector() *metric.MetricCollector {
  933. return metric.NewMetricCollector(
  934. metric.GPUInfoID,
  935. scrape.DCGMFIDEVDECUTIL,
  936. []string{
  937. source.NamespaceLabel,
  938. source.PodLabel,
  939. source.ContainerLabel,
  940. source.DeviceLabel,
  941. source.ModelNameLabel,
  942. source.UUIDLabel,
  943. },
  944. aggregator.Info,
  945. func(labels map[string]string) bool {
  946. return labels[source.ContainerLabel] != ""
  947. },
  948. )
  949. }
  950. // avg(
  951. // avg_over_time(
  952. // node_cpu_hourly_cost{
  953. // <some_custom_filter>
  954. // }[1h]
  955. // )
  956. // ) by (node, cluster_id, instance_type, provider_id)
  957. func NewNodeCPUPricePerHourMetricCollector() *metric.MetricCollector {
  958. return metric.NewMetricCollector(
  959. metric.NodeCPUPricePerHourID,
  960. scrape.NodeCPUHourlyCost,
  961. []string{
  962. source.NodeLabel,
  963. source.InstanceTypeLabel,
  964. source.ProviderIDLabel,
  965. },
  966. aggregator.AverageOverTime,
  967. nil,
  968. )
  969. }
  970. // avg(
  971. // avg_over_time(
  972. // node_ram_hourly_cost{
  973. // <some_custom_filter>
  974. // }[1h]
  975. // )
  976. // ) by (node, cluster_id, instance_type, provider_id)
  977. func NewNodeRAMPricePerGiBHourMetricCollector() *metric.MetricCollector {
  978. return metric.NewMetricCollector(
  979. metric.NodeRAMPricePerGiBHourID,
  980. scrape.NodeRAMHourlyCost,
  981. []string{
  982. source.NodeLabel,
  983. source.InstanceTypeLabel,
  984. source.ProviderIDLabel,
  985. },
  986. aggregator.AverageOverTime,
  987. nil,
  988. )
  989. }
  990. // avg(
  991. // avg_over_time(
  992. // node_gpu_hourly_cost{
  993. // <some_custom_filter>
  994. // }[1h]
  995. // )
  996. // ) by (node, cluster_id, instance_type, provider_id)
  997. func NewNodeGPUPricePerHourMetricCollector() *metric.MetricCollector {
  998. return metric.NewMetricCollector(
  999. metric.NodeGPUPricePerHourID,
  1000. scrape.NodeGPUHourlyCost,
  1001. []string{
  1002. source.NodeLabel,
  1003. source.InstanceTypeLabel,
  1004. source.ProviderIDLabel,
  1005. },
  1006. aggregator.AverageOverTime,
  1007. nil,
  1008. )
  1009. }
  1010. // avg_over_time(
  1011. // kubecost_node_is_spot{
  1012. // <some_custom_filter>
  1013. // }[1h]
  1014. // )
  1015. func NewNodeIsSpotMetricCollector() *metric.MetricCollector {
  1016. return metric.NewMetricCollector(
  1017. metric.NodeIsSpotID,
  1018. scrape.KubecostNodeIsSpot,
  1019. []string{
  1020. source.NodeLabel,
  1021. source.ProviderIDLabel,
  1022. },
  1023. aggregator.AverageOverTime,
  1024. nil,
  1025. )
  1026. }
  1027. // avg(
  1028. // avg_over_time(
  1029. // pod_pvc_allocation{
  1030. // <some_custom_filter>
  1031. // }[1h]
  1032. // )
  1033. // ) by (persistentvolume, persistentvolumeclaim, pod, namespace, cluster_id)
  1034. func NewPodPVCAllocationMetricCollector() *metric.MetricCollector {
  1035. return metric.NewMetricCollector(
  1036. metric.PodPVCAllocationID,
  1037. scrape.PodPVCAllocation,
  1038. []string{
  1039. source.NamespaceLabel,
  1040. source.PodLabel,
  1041. source.PVLabel,
  1042. source.PVCLabel,
  1043. },
  1044. aggregator.AverageOverTime,
  1045. nil,
  1046. )
  1047. }
  1048. // avg(
  1049. // avg_over_time(
  1050. // kube_persistentvolumeclaim_resource_requests_storage_bytes{
  1051. // <some_custom_filter>
  1052. // }[1h]
  1053. // )
  1054. // ) by (persistentvolumeclaim, namespace, cluster_id)
  1055. func NewPVCBytesRequestedMetricCollector() *metric.MetricCollector {
  1056. return metric.NewMetricCollector(
  1057. metric.PVCBytesRequestedID,
  1058. scrape.KubePersistentVolumeClaimResourceRequestsStorageBytes,
  1059. []string{
  1060. source.NamespaceLabel,
  1061. source.PVCLabel,
  1062. },
  1063. aggregator.AverageOverTime,
  1064. nil,
  1065. )
  1066. }
  1067. // avg(
  1068. // avg_over_time(
  1069. // kube_persistentvolume_capacity_bytes{
  1070. // <some_custom_filter>
  1071. // }[1h]
  1072. // )
  1073. // ) by (persistentvolume, cluster_id)
  1074. func NewPVBytesMetricCollector() *metric.MetricCollector {
  1075. return metric.NewMetricCollector(
  1076. metric.PVBytesID,
  1077. scrape.KubePersistentVolumeCapacityBytes,
  1078. []string{
  1079. source.PVLabel,
  1080. },
  1081. aggregator.AverageOverTime,
  1082. nil,
  1083. )
  1084. }
  1085. // avg(
  1086. // avg_over_time(
  1087. // kubecost_pv_info{
  1088. // <some_custom_filter>
  1089. // }[1h]
  1090. // )
  1091. // ) by (cluster_id, storageclass, persistentvolume, provider_id)
  1092. func NewPVInfoMetricCollector() *metric.MetricCollector {
  1093. return metric.NewMetricCollector(
  1094. metric.PVInfoID,
  1095. scrape.KubecostPVInfo,
  1096. []string{
  1097. source.PVLabel,
  1098. source.StorageClassLabel,
  1099. source.ProviderIDLabel,
  1100. },
  1101. aggregator.AverageOverTime,
  1102. nil,
  1103. )
  1104. }
  1105. // sum(
  1106. // increase(
  1107. // kubecost_pod_network_egress_bytes_total{
  1108. // internet="false",
  1109. // same_zone="false",
  1110. // same_region="true",
  1111. // <some_custom_filter>
  1112. // }[1h]
  1113. // )
  1114. // ) by (pod_name, namespace, cluster_id) / 1024 / 1024 / 1024
  1115. //
  1116. func NewNetZoneGiBMetricCollector() *metric.MetricCollector {
  1117. return metric.NewMetricCollector(
  1118. metric.NetZoneGiBID,
  1119. scrape.KubecostPodNetworkEgressBytesTotal,
  1120. []string{
  1121. source.NamespaceLabel,
  1122. source.PodNameLabel,
  1123. },
  1124. aggregator.Increase,
  1125. func(labels map[string]string) bool {
  1126. return labels[source.InternetLabel] == "false" && labels[source.SameZoneLabel] == "false" && labels[source.SameRegionLabel] == "true"
  1127. },
  1128. )
  1129. }
  1130. // avg(
  1131. // avg_over_time(
  1132. // kubecost_network_zone_egress_cost{
  1133. // <some_custom_filter>
  1134. // }[1h]
  1135. // )
  1136. // ) by (cluster_id)
  1137. //
  1138. func NewNetZonePricePerGiBMetricCollector() *metric.MetricCollector {
  1139. return metric.NewMetricCollector(
  1140. metric.NetZonePricePerGiBID,
  1141. scrape.KubecostNetworkZoneEgressCost,
  1142. []string{},
  1143. aggregator.AverageOverTime,
  1144. nil,
  1145. )
  1146. }
  1147. // sum(
  1148. // increase(
  1149. // kubecost_pod_network_egress_bytes_total{
  1150. // internet="false",
  1151. // same_zone="false",
  1152. // same_region="false",
  1153. // <some_custom_filter>
  1154. // }[1h]
  1155. // )
  1156. // ) by (pod_name, namespace, cluster_id) / 1024 / 1024 / 1024
  1157. func NewNetRegionGiBMetricCollector() *metric.MetricCollector {
  1158. return metric.NewMetricCollector(
  1159. metric.NetRegionGiBID,
  1160. scrape.KubecostPodNetworkEgressBytesTotal,
  1161. []string{
  1162. source.NamespaceLabel,
  1163. source.PodNameLabel,
  1164. },
  1165. aggregator.Increase,
  1166. func(labels map[string]string) bool {
  1167. return labels[source.InternetLabel] == "false" && labels[source.SameZoneLabel] == "false" && labels[source.SameRegionLabel] == "false"
  1168. },
  1169. )
  1170. }
  1171. // avg(
  1172. // avg_over_time(
  1173. // kubecost_network_region_egress_cost{
  1174. // <some_custom_filter>
  1175. // }[1h]
  1176. // )
  1177. // ) by (cluster_id)
  1178. func NewNetRegionPricePerGiBMetricCollector() *metric.MetricCollector {
  1179. return metric.NewMetricCollector(
  1180. metric.NetRegionPricePerGiBID,
  1181. scrape.KubecostNetworkRegionEgressCost,
  1182. []string{},
  1183. aggregator.AverageOverTime,
  1184. nil,
  1185. )
  1186. }
  1187. // sum(
  1188. // increase(
  1189. // kubecost_pod_network_egress_bytes_total{
  1190. // internet="true",
  1191. // <some_custom_filter>
  1192. // }[1h]
  1193. // )
  1194. // ) by (pod_name, namespace, cluster_id) / 1024 / 1024 / 1024
  1195. func NewNetInternetGiBMetricCollector() *metric.MetricCollector {
  1196. return metric.NewMetricCollector(
  1197. metric.NetInternetGiBID,
  1198. scrape.KubecostPodNetworkEgressBytesTotal,
  1199. []string{
  1200. source.NamespaceLabel,
  1201. source.PodNameLabel,
  1202. },
  1203. aggregator.Increase,
  1204. func(labels map[string]string) bool {
  1205. return labels[source.InternetLabel] == "true"
  1206. },
  1207. )
  1208. }
  1209. // avg(
  1210. // avg_over_time(
  1211. // kubecost_network_internet_egress_cost{
  1212. // <some_custom_filter>
  1213. // }[1h]
  1214. // )
  1215. // ) by (cluster_id)
  1216. func NewNetInternetPricePerGiBMetricCollector() *metric.MetricCollector {
  1217. return metric.NewMetricCollector(
  1218. metric.NetInternetPricePerGiBID,
  1219. scrape.KubecostNetworkInternetEgressCost,
  1220. []string{},
  1221. aggregator.AverageOverTime,
  1222. nil,
  1223. )
  1224. }
  1225. // sum(
  1226. // increase(
  1227. // kubecost_pod_network_egress_bytes_total{
  1228. // internet="true",
  1229. // <some_custom_filter>
  1230. // }[%s]
  1231. // )
  1232. // ) by (pod_name, namespace, service, %s) / 1024 / 1024 / 1024
  1233. func NewNetInternetServiceGiBMetricCollector() *metric.MetricCollector {
  1234. return metric.NewMetricCollector(
  1235. metric.NetInternetServiceGiBID,
  1236. scrape.KubecostPodNetworkEgressBytesTotal,
  1237. []string{
  1238. source.NamespaceLabel,
  1239. source.PodNameLabel,
  1240. source.ServiceLabel,
  1241. },
  1242. aggregator.Increase,
  1243. func(labels map[string]string) bool {
  1244. return labels[source.InternetLabel] == "true"
  1245. },
  1246. )
  1247. }
  1248. // sum(
  1249. // increase(
  1250. // container_network_receive_bytes_total{
  1251. // pod!="",
  1252. // <some_custom_filter>
  1253. // }[1h]
  1254. // )
  1255. // ) by (pod_name, pod, namespace, cluster_id)
  1256. func NewNetReceiveBytesMetricCollector() *metric.MetricCollector {
  1257. return metric.NewMetricCollector(
  1258. metric.NetReceiveBytesID,
  1259. scrape.ContainerNetworkReceiveBytesTotal,
  1260. []string{
  1261. source.NamespaceLabel,
  1262. source.PodLabel,
  1263. },
  1264. aggregator.Increase,
  1265. func(labels map[string]string) bool {
  1266. return labels[source.PodLabel] != ""
  1267. },
  1268. )
  1269. }
  1270. // sum(
  1271. // increase(
  1272. // kubecost_pod_network_ingress_bytes_total{
  1273. // internet="false",
  1274. // same_zone="false",
  1275. // same_region="true",
  1276. // <some_custom_filter>
  1277. // }[1h]
  1278. // )
  1279. // ) by (pod_name, namespace, cluster_id) / 1024 / 1024 / 1024
  1280. func NewNetZoneIngressGiBMetricCollector() *metric.MetricCollector {
  1281. return metric.NewMetricCollector(
  1282. metric.NetZoneIngressGiBID,
  1283. scrape.KubecostPodNetworkIngressBytesTotal,
  1284. []string{
  1285. source.NamespaceLabel,
  1286. source.PodNameLabel,
  1287. },
  1288. aggregator.Increase,
  1289. func(labels map[string]string) bool {
  1290. return labels[source.InternetLabel] == "false" &&
  1291. labels[source.SameZoneLabel] == "false" &&
  1292. labels[source.SameRegionLabel] == "true"
  1293. },
  1294. )
  1295. }
  1296. // sum(
  1297. // increase(
  1298. // kubecost_pod_network_ingress_bytes_total{
  1299. // internet="false",
  1300. // same_zone="false",
  1301. // same_region="false",
  1302. // <some_custom_filter>
  1303. // }[1h]
  1304. // )
  1305. // ) by (pod_name, namespace, cluster_id) / 1024 / 1024 / 1024
  1306. func NewNetRegionIngressGiBMetricCollector() *metric.MetricCollector {
  1307. return metric.NewMetricCollector(
  1308. metric.NetRegionIngressGiBID,
  1309. scrape.KubecostPodNetworkIngressBytesTotal,
  1310. []string{
  1311. source.NamespaceLabel,
  1312. source.PodNameLabel,
  1313. },
  1314. aggregator.Increase,
  1315. func(labels map[string]string) bool {
  1316. return labels[source.InternetLabel] == "false" &&
  1317. labels[source.SameZoneLabel] == "false" &&
  1318. labels[source.SameRegionLabel] == "false"
  1319. },
  1320. )
  1321. }
  1322. // sum(
  1323. // increase(
  1324. // kubecost_pod_network_ingress_bytes_total{
  1325. // internet="true",
  1326. // <some_custom_filter>
  1327. // }[1h]
  1328. // )
  1329. // ) by (pod_name, namespace, cluster_id) / 1024 / 1024 / 1024
  1330. func NewNetInternetIngressGiBMetricCollector() *metric.MetricCollector {
  1331. return metric.NewMetricCollector(
  1332. metric.NetInternetIngressGiBID,
  1333. scrape.KubecostPodNetworkIngressBytesTotal,
  1334. []string{
  1335. source.NamespaceLabel,
  1336. source.PodNameLabel,
  1337. },
  1338. aggregator.Increase,
  1339. func(labels map[string]string) bool {
  1340. return labels[source.InternetLabel] == "true"
  1341. },
  1342. )
  1343. }
  1344. // `sum(
  1345. // increase(
  1346. // kubecost_pod_network_ingress_bytes_total{
  1347. // internet="true",
  1348. // <some_custom_filter>
  1349. // }[1h]
  1350. // )
  1351. // ) by (pod_name, namespace, service, cluster_id) / 1024 / 1024 / 1024
  1352. func NewNetInternetServiceIngressGiBMetricCollector() *metric.MetricCollector {
  1353. return metric.NewMetricCollector(
  1354. metric.NetInternetServiceIngressGiBID,
  1355. scrape.KubecostPodNetworkIngressBytesTotal,
  1356. []string{
  1357. source.NamespaceLabel,
  1358. source.PodNameLabel,
  1359. source.ServiceLabel,
  1360. },
  1361. aggregator.Increase,
  1362. func(labels map[string]string) bool {
  1363. return labels[source.InternetLabel] == "true"
  1364. },
  1365. )
  1366. }
  1367. // sum(
  1368. // increase(
  1369. // container_network_transmit_bytes_total{
  1370. // pod!="",
  1371. // <some_custom_filter>
  1372. // }[1h]
  1373. // )
  1374. // ) by (pod_name, pod, namespace, cluster_id)
  1375. func NewNetTransferBytesMetricCollector() *metric.MetricCollector {
  1376. return metric.NewMetricCollector(
  1377. metric.NetTransferBytesID,
  1378. scrape.ContainerNetworkTransmitBytesTotal,
  1379. []string{
  1380. source.NamespaceLabel,
  1381. source.PodLabel,
  1382. },
  1383. aggregator.Increase,
  1384. func(labels map[string]string) bool {
  1385. return labels[source.PodLabel] != ""
  1386. },
  1387. )
  1388. }
  1389. // avg_over_time(
  1390. // kube_namespace_labels{
  1391. // <some_custom_filter>
  1392. // }[1h]
  1393. // )
  1394. func NewNamespaceLabelsMetricCollector() *metric.MetricCollector {
  1395. return metric.NewMetricCollector(
  1396. metric.NamespaceLabelsID,
  1397. scrape.KubeNamespaceLabels,
  1398. []string{
  1399. source.NamespaceLabel,
  1400. },
  1401. aggregator.Info,
  1402. nil,
  1403. )
  1404. }
  1405. // avg_over_time(
  1406. // kube_namespace_annotations{
  1407. // <some_custom_filter>
  1408. // }[1h]
  1409. // )
  1410. func NewNamespaceAnnotationsMetricCollector() *metric.MetricCollector {
  1411. return metric.NewMetricCollector(
  1412. metric.NamespaceAnnotationsID,
  1413. scrape.KubeNamespaceAnnotations,
  1414. []string{
  1415. source.NamespaceLabel,
  1416. },
  1417. aggregator.Info,
  1418. nil,
  1419. )
  1420. }
  1421. // avg_over_time(
  1422. // kube_pod_labels{
  1423. // <some_custom_filter>
  1424. // }[1h]
  1425. // )
  1426. func NewPodLabelsMetricCollector() *metric.MetricCollector {
  1427. return metric.NewMetricCollector(
  1428. metric.PodLabelsID,
  1429. scrape.KubePodLabels,
  1430. []string{
  1431. source.NamespaceLabel,
  1432. source.PodLabel,
  1433. },
  1434. aggregator.Info,
  1435. nil,
  1436. )
  1437. }
  1438. // avg_over_time(
  1439. // kube_pod_annotations{
  1440. // <some_custom_filter>
  1441. // }[1h]
  1442. // )
  1443. func NewPodAnnotationsMetricCollector() *metric.MetricCollector {
  1444. return metric.NewMetricCollector(
  1445. metric.PodAnnotationsID,
  1446. scrape.KubePodAnnotations,
  1447. []string{
  1448. source.NamespaceLabel,
  1449. source.PodLabel,
  1450. },
  1451. aggregator.Info,
  1452. nil,
  1453. )
  1454. }
  1455. // avg_over_time(
  1456. // service_selector_labels{
  1457. // <some_custom_filter>
  1458. // }[1h]
  1459. // )
  1460. func NewServiceLabelsMetricCollector() *metric.MetricCollector {
  1461. return metric.NewMetricCollector(
  1462. metric.ServiceLabelsID,
  1463. scrape.ServiceSelectorLabels,
  1464. []string{
  1465. source.NamespaceLabel,
  1466. source.ServiceLabel,
  1467. },
  1468. aggregator.Info,
  1469. nil,
  1470. )
  1471. }
  1472. // avg_over_time(
  1473. // deployment_match_labels{
  1474. // <some_custom_filter>
  1475. // }[1h]
  1476. // )
  1477. func NewDeploymentLabelsMetricCollector() *metric.MetricCollector {
  1478. return metric.NewMetricCollector(
  1479. metric.DeploymentLabelsID,
  1480. scrape.DeploymentMatchLabels,
  1481. []string{
  1482. source.NamespaceLabel,
  1483. source.DeploymentLabel,
  1484. },
  1485. aggregator.Info,
  1486. nil,
  1487. )
  1488. }
  1489. // avg_over_time(
  1490. // statefulSet_match_labels{
  1491. // <some_custom_filter>
  1492. // }[1h]
  1493. // )
  1494. func NewStatefulSetLabelsMetricCollector() *metric.MetricCollector {
  1495. return metric.NewMetricCollector(
  1496. metric.StatefulSetLabelsID,
  1497. scrape.StatefulSetMatchLabels,
  1498. []string{
  1499. source.NamespaceLabel,
  1500. source.StatefulSetLabel,
  1501. },
  1502. aggregator.Info,
  1503. nil,
  1504. )
  1505. }
  1506. // sum(
  1507. // avg_over_time(
  1508. // kube_pod_owner{
  1509. // owner_kind="DaemonSet",
  1510. // <some_custom_filter>
  1511. // }[1h]
  1512. // )
  1513. // ) by (pod, owner_name, namespace, cluster_id)
  1514. func NewDaemonSetLabelsMetricCollector() *metric.MetricCollector {
  1515. return metric.NewMetricCollector(
  1516. metric.DaemonSetLabelsID,
  1517. scrape.KubePodOwner,
  1518. []string{
  1519. source.NamespaceLabel,
  1520. source.PodLabel,
  1521. source.OwnerNameLabel,
  1522. },
  1523. aggregator.Info,
  1524. func(labels map[string]string) bool {
  1525. return labels[source.OwnerKindLabel] == "DaemonSet"
  1526. },
  1527. )
  1528. }
  1529. // sum(
  1530. // avg_over_time(
  1531. // kube_pod_owner{
  1532. // owner_kind="Job",
  1533. // <some_custom_filter>
  1534. // }[1h]
  1535. // )
  1536. // ) by (pod, owner_name, namespace, cluster_id)
  1537. func NewJobLabelsMetricCollector() *metric.MetricCollector {
  1538. return metric.NewMetricCollector(
  1539. metric.JobLabelsID,
  1540. scrape.KubePodOwner,
  1541. []string{
  1542. source.NamespaceLabel,
  1543. source.PodLabel,
  1544. source.OwnerNameLabel,
  1545. },
  1546. aggregator.Info,
  1547. func(labels map[string]string) bool {
  1548. return labels[source.OwnerKindLabel] == "Job"
  1549. },
  1550. )
  1551. }
  1552. // sum(
  1553. // avg_over_time(
  1554. // kube_pod_owner{
  1555. // owner_kind="ReplicaSet",
  1556. // <some_custom_filter>
  1557. // }[1h]
  1558. // )
  1559. // ) by (pod, owner_name, namespace, cluster_id)
  1560. func NewPodsWithReplicaSetOwnerMetricCollector() *metric.MetricCollector {
  1561. return metric.NewMetricCollector(
  1562. metric.PodsWithReplicaSetOwnerID,
  1563. scrape.KubePodOwner,
  1564. []string{
  1565. source.NamespaceLabel,
  1566. source.PodLabel,
  1567. source.OwnerNameLabel,
  1568. },
  1569. aggregator.Info,
  1570. func(labels map[string]string) bool {
  1571. return labels[source.OwnerKindLabel] == "ReplicaSet"
  1572. },
  1573. )
  1574. }
  1575. // sum(
  1576. // avg_over_time(
  1577. // kube_replicaset_owner{
  1578. // owner_kind="<none>",
  1579. // owner_name="<none>",
  1580. // <some_custom_filter>
  1581. // }[1h]
  1582. // )
  1583. // ) by (replicaset, namespace, cluster_id)
  1584. func NewReplicaSetsWithoutOwnersMetricCollector() *metric.MetricCollector {
  1585. return metric.NewMetricCollector(
  1586. metric.ReplicaSetsWithoutOwnersID,
  1587. scrape.KubeReplicasetOwner,
  1588. []string{
  1589. source.NamespaceLabel,
  1590. source.ReplicaSetLabel,
  1591. },
  1592. aggregator.Info,
  1593. func(labels map[string]string) bool {
  1594. return labels[source.OwnerKindLabel] == "<none>" && labels[source.OwnerNameLabel] == "<none>"
  1595. },
  1596. )
  1597. }
  1598. // sum(
  1599. // avg_over_time(
  1600. // kube_replicaset_owner{
  1601. // owner_kind="Rollout",
  1602. // <some_custom_filter>
  1603. // }[1h]
  1604. // )
  1605. // ) by (replicaset, namespace, owner_kind, owner_name, cluster_id)
  1606. func NewReplicaSetsWithRolloutMetricCollector() *metric.MetricCollector {
  1607. return metric.NewMetricCollector(
  1608. metric.ReplicaSetsWithRolloutID,
  1609. scrape.KubeReplicasetOwner,
  1610. []string{
  1611. source.NamespaceLabel,
  1612. source.ReplicaSetLabel,
  1613. source.OwnerNameLabel,
  1614. source.OwnerKindLabel,
  1615. },
  1616. aggregator.Info,
  1617. func(labels map[string]string) bool {
  1618. return labels[source.OwnerKindLabel] == "Rollout"
  1619. },
  1620. )
  1621. }