promenv.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package env
  2. import (
  3. "fmt"
  4. "runtime"
  5. "time"
  6. "github.com/opencost/opencost/core/pkg/env"
  7. )
  8. const (
  9. PrometheusServerEndpointEnvVar = "PROMETHEUS_SERVER_ENDPOINT"
  10. PrometheusRetryOnRateLimitResponseEnvVar = "PROMETHEUS_RETRY_ON_RATE_LIMIT"
  11. PrometheusRetryOnRateLimitMaxRetriesEnvVar = "PROMETHEUS_RETRY_ON_RATE_LIMIT_MAX_RETRIES"
  12. PrometheusRetryOnRateLimitDefaultWaitEnvVar = "PROMETHEUS_RETRY_ON_RATE_LIMIT_DEFAULT_WAIT"
  13. PrometheusQueryTimeoutEnvVar = "PROMETHEUS_QUERY_TIMEOUT"
  14. PrometheusKeepAliveEnvVar = "PROMETHEUS_KEEP_ALIVE"
  15. PrometheusTLSHandshakeTimeoutEnvVar = "PROMETHEUS_TLS_HANDSHAKE_TIMEOUT"
  16. ScrapeIntervalEnvVar = "KUBECOST_SCRAPE_INTERVAL"
  17. PrometheusMaxQueryDurationMinutesEnvVar = "PROMETHEUS_MAX_QUERY_DURATION_MINUTES"
  18. PrometheusQueryResolutionSecondsEnvVar = "PROMETHEUS_QUERY_RESOLUTION_SECONDS"
  19. MaxQueryConcurrencyEnvVar = "MAX_QUERY_CONCURRENCY"
  20. PromClusterIDLabelEnvVar = "PROM_CLUSTER_ID_LABEL"
  21. PrometheusHeaderXScopeOrgIdEnvVar = "PROMETHEUS_HEADER_X_SCOPE_ORGID"
  22. InsecureSkipVerifyEnvVar = "INSECURE_SKIP_VERIFY"
  23. KubeRbacProxyEnabledEnvVar = "KUBE_RBAC_PROXY_ENABLED"
  24. DBBasicAuthUsername = "DB_BASIC_AUTH_USERNAME"
  25. DBBasicAuthPassword = "DB_BASIC_AUTH_PW"
  26. DBBearerToken = "DB_BEARER_TOKEN"
  27. PromMtlsAuthCAFile = "PROM_MTLS_AUTH_CA_FILE"
  28. PromMtlsAuthCrtFile = "PROM_MTLS_AUTH_CRT_FILE"
  29. PromMtlsAuthKeyFile = "PROM_MTLS_AUTH_KEY_FILE"
  30. CurrentClusterIdFilterEnabledVar = "CURRENT_CLUSTER_ID_FILTER_ENABLED"
  31. KubecostJobNameEnvVar = "KUBECOST_JOB_NAME"
  32. )
  33. // In sharded Prometheus setups, PROMETHEUS_SERVER_ENDPOINT should point to a global query endpoint (e.g., Thanos Query, Cortex, or Mimir)
  34. // to ensure OpenCost receives complete data. Pointing to a single Prometheus pod may result in incomplete or intermittent export results.
  35. // IsPrometheusRetryOnRateLimitResponse will attempt to retry if a 429 response is received OR a 400 with a body containing
  36. // ThrottleException (common in AWS services like AMP)
  37. func IsPrometheusRetryOnRateLimitResponse() bool {
  38. return env.GetBool(PrometheusRetryOnRateLimitResponseEnvVar, true)
  39. }
  40. // GetPrometheusRetryOnRateLimitMaxRetries returns the maximum number of retries that should be attempted prior to failing.
  41. // Only used if IsPrometheusRetryOnRateLimitResponse() is true.
  42. func GetPrometheusRetryOnRateLimitMaxRetries() int {
  43. return env.GetInt(PrometheusRetryOnRateLimitMaxRetriesEnvVar, 5)
  44. }
  45. // GetPrometheusRetryOnRateLimitDefaultWait returns the default wait time for a retriable rate limit response without a
  46. // Retry-After header.
  47. func GetPrometheusRetryOnRateLimitDefaultWait() time.Duration {
  48. return env.GetDuration(PrometheusRetryOnRateLimitDefaultWaitEnvVar, 100*time.Millisecond)
  49. }
  50. // GetPrometheusHeaderXScopeOrgId returns the default value for X-Scope-OrgID header used for requests in Mimir/Cortex-Tenant API.
  51. // To use Mimir(or Cortex-Tenant) instead of Prometheus add variable from cluster settings:
  52. // "PROMETHEUS_HEADER_X_SCOPE_ORGID": "my-cluster-name"
  53. // Then set Prometheus URL to prometheus API endpoint:
  54. // "PROMETHEUS_SERVER_ENDPOINT": "http://mimir-url/prometheus/"
  55. func GetPrometheusHeaderXScopeOrgId() string {
  56. return env.Get(PrometheusHeaderXScopeOrgIdEnvVar, "")
  57. }
  58. // GetPrometheusServerEndpoint returns the environment variable value for PrometheusServerEndpointEnvVar which
  59. // represents the prometheus server endpoint used to execute prometheus queries.
  60. func GetPrometheusServerEndpoint() string {
  61. return env.Get(PrometheusServerEndpointEnvVar, "")
  62. }
  63. func GetScrapeInterval() time.Duration {
  64. return env.GetDuration(ScrapeIntervalEnvVar, 0)
  65. }
  66. func GetPrometheusQueryTimeout() time.Duration {
  67. return env.GetDuration(PrometheusQueryTimeoutEnvVar, 120*time.Second)
  68. }
  69. func GetPrometheusKeepAlive() time.Duration {
  70. return env.GetDuration(PrometheusKeepAliveEnvVar, 120*time.Second)
  71. }
  72. func GetPrometheusTLSHandshakeTimeout() time.Duration {
  73. return env.GetDuration(PrometheusTLSHandshakeTimeoutEnvVar, 10*time.Second)
  74. }
  75. // GetJobName returns the environment variable value for JobNameEnvVar, specifying which job name
  76. // is used for prometheus to scrape the provided metrics.
  77. func GetJobName() string {
  78. return env.Get(KubecostJobNameEnvVar, "kubecost")
  79. }
  80. func IsInsecureSkipVerify() bool {
  81. return env.GetBool(InsecureSkipVerifyEnvVar, false)
  82. }
  83. func IsKubeRbacProxyEnabled() bool {
  84. return env.GetBool(KubeRbacProxyEnabledEnvVar, false)
  85. }
  86. // GetPrometheusQueryResolution determines the resolution of prom queries. The smaller the
  87. // duration, the higher the resolution; the higher the resolution, the more
  88. // accurate the query results, but the more computationally expensive.
  89. func GetPrometheusQueryResolution() time.Duration {
  90. // Use the configured query resolution, or default to
  91. // 5m (i.e. 300s)
  92. secs := time.Duration(env.GetInt64(PrometheusQueryResolutionSecondsEnvVar, 300))
  93. return secs * time.Second
  94. }
  95. // GetMaxQueryConcurrency returns the environment variable value for MaxQueryConcurrencyEnvVar
  96. func GetMaxQueryConcurrency() int {
  97. maxQueryConcurrency := env.GetInt(MaxQueryConcurrencyEnvVar, 5)
  98. if maxQueryConcurrency <= 0 {
  99. return runtime.GOMAXPROCS(0)
  100. }
  101. return maxQueryConcurrency
  102. }
  103. func GetDBBasicAuthUsername() string {
  104. return env.Get(DBBasicAuthUsername, "")
  105. }
  106. func GetDBBasicAuthUserPassword() string {
  107. return env.Get(DBBasicAuthPassword, "")
  108. }
  109. func GetDBBearerToken() string {
  110. return env.Get(DBBearerToken, "")
  111. }
  112. func IsPromMtlsAuthEnabled() bool {
  113. if GetPromMtlsAuthCAFile() == "" {
  114. return false
  115. }
  116. if GetPromMtlsAuthCrtFile() == "" {
  117. return false
  118. }
  119. if GetPromMtlsAuthKeyFile() == "" {
  120. return false
  121. }
  122. return true
  123. }
  124. func GetPromMtlsAuthCAFile() string {
  125. return env.Get(PromMtlsAuthCAFile, "")
  126. }
  127. func GetPromMtlsAuthCrtFile() string {
  128. return env.Get(PromMtlsAuthCrtFile, "")
  129. }
  130. func GetPromMtlsAuthKeyFile() string {
  131. return env.Get(PromMtlsAuthKeyFile, "")
  132. }
  133. func GetPrometheusMaxQueryDuration() time.Duration {
  134. dayMins := 60 * 24
  135. mins := time.Duration(env.GetInt64(PrometheusMaxQueryDurationMinutesEnvVar, int64(dayMins)))
  136. return mins * time.Minute
  137. }
  138. // GetPromClusterLabel returns the environment variable value for PromClusterIDLabel
  139. func GetPromClusterLabel() string {
  140. return env.Get(PromClusterIDLabelEnvVar, "cluster_id")
  141. }
  142. // GetPromClusterFilter returns environment variable value CurrentClusterIdFilterEnabledVar which
  143. // represents additional prometheus filter for all metrics for current cluster id
  144. func GetPromClusterFilter() string {
  145. if env.GetBool(CurrentClusterIdFilterEnabledVar, false) {
  146. return fmt.Sprintf("%s=\"%s\"", GetPromClusterLabel(), env.GetClusterID())
  147. }
  148. return ""
  149. }