summaryallocation_json.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package opencost
  2. import (
  3. "time"
  4. "github.com/opencost/opencost/core/pkg/util/formatutil"
  5. )
  6. // SummaryAllocationResponse is a sanitized version of SummaryAllocation, which
  7. // formats fields and protects against issues like mashaling NaNs.
  8. type SummaryAllocationResponse struct {
  9. Name string `json:"name"`
  10. Start time.Time `json:"start"`
  11. End time.Time `json:"end"`
  12. CPUCoreRequestAverage *float64 `json:"cpuCoreRequestAverage"`
  13. CPUCoreUsageAverage *float64 `json:"cpuCoreUsageAverage"`
  14. CPUCost *float64 `json:"cpuCost"`
  15. CPUCostIdle *float64 `json:"cpuCostIdle"`
  16. GPURequestAverage *float64 `json:"gpuRequestAverage"`
  17. GPUUsageAverage *float64 `json:"gpuUsageAverage"`
  18. GPUCost *float64 `json:"gpuCost"`
  19. GPUCostIdle *float64 `json:"gpuCostIdle"`
  20. NetworkCost *float64 `json:"networkCost"`
  21. LoadBalancerCost *float64 `json:"loadBalancerCost"`
  22. PVCost *float64 `json:"pvCost"`
  23. RAMBytesRequestAverage *float64 `json:"ramByteRequestAverage"`
  24. RAMBytesUsageAverage *float64 `json:"ramByteUsageAverage"`
  25. RAMCost *float64 `json:"ramCost"`
  26. RAMCostIdle *float64 `json:"ramCostIdle"`
  27. SharedCost *float64 `json:"sharedCost"`
  28. ExternalCost *float64 `json:"externalCost"`
  29. TotalEfficiency *float64 `json:"totalEfficiency"`
  30. TotalCost *float64 `json:"totalCost"`
  31. }
  32. // ToResponse converts a SummaryAllocation to a SummaryAllocationResponse,
  33. // protecting against NaN and null values.
  34. func (sa *SummaryAllocation) ToResponse() *SummaryAllocationResponse {
  35. if sa == nil {
  36. return nil
  37. }
  38. // if the efficiency has already been set,
  39. // prefer that since it has been calculated elsewhere
  40. // and matches the sorting criteria more closely
  41. efficiency := sa.Efficiency
  42. if efficiency == 0 {
  43. // if efficiency has not been set by SQL or otherwise, calculate it
  44. // using the object method
  45. efficiency = sa.TotalEfficiency()
  46. }
  47. return &SummaryAllocationResponse{
  48. Name: sa.Name,
  49. Start: sa.Start,
  50. End: sa.End,
  51. CPUCoreRequestAverage: formatutil.Float64ToResponse(sa.CPUCoreRequestAverage),
  52. CPUCoreUsageAverage: formatutil.Float64ToResponse(sa.CPUCoreUsageAverage),
  53. CPUCost: formatutil.Float64ToResponse(sa.CPUCost),
  54. CPUCostIdle: formatutil.Float64ToResponse(sa.CPUCostIdle),
  55. GPURequestAverage: formatutil.Float64ToResponse(sa.GPURequestAverage),
  56. GPUUsageAverage: formatutil.Float64ToResponse(sa.GPUUsageAverage),
  57. GPUCost: formatutil.Float64ToResponse(sa.GPUCost),
  58. GPUCostIdle: formatutil.Float64ToResponse(sa.GPUCostIdle),
  59. NetworkCost: formatutil.Float64ToResponse(sa.NetworkCost),
  60. LoadBalancerCost: formatutil.Float64ToResponse(sa.LoadBalancerCost),
  61. PVCost: formatutil.Float64ToResponse(sa.PVCost),
  62. RAMBytesRequestAverage: formatutil.Float64ToResponse(sa.RAMBytesRequestAverage),
  63. RAMBytesUsageAverage: formatutil.Float64ToResponse(sa.RAMBytesUsageAverage),
  64. RAMCost: formatutil.Float64ToResponse(sa.RAMCost),
  65. RAMCostIdle: formatutil.Float64ToResponse(sa.RAMCostIdle),
  66. SharedCost: formatutil.Float64ToResponse(sa.SharedCost),
  67. ExternalCost: formatutil.Float64ToResponse(sa.ExternalCost),
  68. TotalEfficiency: formatutil.Float64ToResponse(efficiency),
  69. TotalCost: formatutil.Float64ToResponse(sa.TotalCost()),
  70. }
  71. }
  72. // SummaryAllocationSetResponse is a sanitized version of SummaryAllocationSet,
  73. // which formats fields and protects against issues like marshaling NaNs.
  74. type SummaryAllocationSetResponse struct {
  75. SummaryAllocations map[string]*SummaryAllocationResponse `json:"allocations"`
  76. Window Window `json:"window"`
  77. }
  78. // ToResponse converts a SummaryAllocationSet to a SummaryAllocationSetResponse,
  79. // protecting against NaN and null values.
  80. func (sas *SummaryAllocationSet) ToResponse() *SummaryAllocationSetResponse {
  81. if sas == nil {
  82. return nil
  83. }
  84. sars := make(map[string]*SummaryAllocationResponse, len(sas.SummaryAllocations))
  85. for k, v := range sas.SummaryAllocations {
  86. sars[k] = v.ToResponse()
  87. }
  88. return &SummaryAllocationSetResponse{
  89. SummaryAllocations: sars,
  90. Window: sas.Window.Clone(),
  91. }
  92. }
  93. // SummaryAllocationSetRangeResponse is a sanitized version of SummaryAllocationSetRange,
  94. // which formats fields and protects against issues like marshaling NaNs.
  95. type SummaryAllocationSetRangeResponse struct {
  96. Step time.Duration `json:"step"`
  97. SummaryAllocationSets []*SummaryAllocationSetResponse `json:"sets"`
  98. Window Window `json:"window"`
  99. }
  100. // ToResponse converts a SummaryAllocationSet to a SummaryAllocationSetResponse,
  101. // protecting against NaN and null values.
  102. func (sasr *SummaryAllocationSetRange) ToResponse() *SummaryAllocationSetRangeResponse {
  103. if sasr == nil {
  104. return nil
  105. }
  106. sasrr := make([]*SummaryAllocationSetResponse, len(sasr.SummaryAllocationSets))
  107. for i, v := range sasr.SummaryAllocationSets {
  108. sasrr[i] = v.ToResponse()
  109. }
  110. return &SummaryAllocationSetRangeResponse{
  111. Step: sasr.Step,
  112. SummaryAllocationSets: sasrr,
  113. Window: sasr.Window.Clone(),
  114. }
  115. }
  116. func EmptySummaryAllocationSetRangeResponse() *SummaryAllocationSetRangeResponse {
  117. return &SummaryAllocationSetRangeResponse{}
  118. }