diagnostics.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package prom
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/kubecost/cost-model/pkg/env"
  6. "github.com/kubecost/cost-model/pkg/log"
  7. prometheus "github.com/prometheus/client_golang/api"
  8. )
  9. // QueuedPromRequest is a representation of a request waiting to be sent by the prometheus
  10. // client.
  11. type QueuedPromRequest struct {
  12. Context string `json:"context"`
  13. Query string `json:"query"`
  14. QueueTime int64 `json:"queueTime"`
  15. }
  16. // PrometheusQueueState contains diagnostic information concerning the state of the prometheus request
  17. // queue
  18. type PrometheusQueueState struct {
  19. QueuedRequests []*QueuedPromRequest `json:"queuedRequests"`
  20. OutboundRequests int `json:"outboundRequests"`
  21. TotalRequests int `json:"totalRequests"`
  22. MaxQueryConcurrency int `json:"maxQueryConcurrency"`
  23. }
  24. // GetPrometheusQueueState is a diagnostic function that probes the prometheus request queue and gathers
  25. // query, context, and queue statistics.
  26. func GetPrometheusQueueState(client prometheus.Client) (*PrometheusQueueState, error) {
  27. rlpc, ok := client.(*RateLimitedPrometheusClient)
  28. if !ok {
  29. return nil, fmt.Errorf("Failed to get prometheus queue state for the provided client. Must be of type RateLimitedPrometheusClient.")
  30. }
  31. outbound := rlpc.TotalOutboundRequests()
  32. requests := []*QueuedPromRequest{}
  33. rlpc.queue.Each(func(_ int, entry interface{}) {
  34. if req, ok := entry.(*workRequest); ok {
  35. requests = append(requests, &QueuedPromRequest{
  36. Context: req.contextName,
  37. Query: req.query,
  38. QueueTime: time.Since(req.start).Milliseconds(),
  39. })
  40. }
  41. })
  42. return &PrometheusQueueState{
  43. QueuedRequests: requests,
  44. OutboundRequests: outbound,
  45. TotalRequests: outbound + len(requests),
  46. MaxQueryConcurrency: env.GetMaxQueryConcurrency(),
  47. }, nil
  48. }
  49. // LogPrometheusClientState logs the current state, with respect to outbound requests, if that
  50. // information is available.
  51. func LogPrometheusClientState(client prometheus.Client) {
  52. if rc, ok := client.(requestCounter); ok {
  53. queued := rc.TotalQueuedRequests()
  54. outbound := rc.TotalOutboundRequests()
  55. total := queued + outbound
  56. log.Infof("Outbound Requests: %d, Queued Requests: %d, Total Requests: %d", outbound, queued, total)
  57. }
  58. }