promenv.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. package env
  2. import (
  3. "fmt"
  4. "runtime"
  5. "time"
  6. "github.com/opencost/opencost/core/pkg/env"
  7. "github.com/opencost/opencost/core/pkg/source"
  8. )
  9. const (
  10. PrometheusServerEndpointEnvVar = "PROMETHEUS_SERVER_ENDPOINT"
  11. PromClusterIDLabelEnvVar = "PROM_CLUSTER_ID_LABEL"
  12. PromNamespaceLabelEnvVar = "PROM_NAMESPACE_LABEL"
  13. PromNodeLabelEnvVar = "PROM_NODE_LABEL"
  14. PromInstanceLabelEnvVar = "PROM_INSTANCE_LABEL"
  15. PromInstanceTypeLabelEnvVar = "PROM_INSTANCE_TYPE_LABEL"
  16. PromContainerLabelEnvVar = "PROM_CONTAINER_LABEL"
  17. PromPodLabelEnvVar = "PROM_POD_LABEL"
  18. PromProviderIDLabelEnvVar = "PROM_PROVIDER_ID_LABEL"
  19. PromDeviceLabelEnvVar = "PROM_DEVICE_LABEL"
  20. PromPVCLabelEnvVar = "PROM_PVC_LABEL"
  21. PromPVLabelEnvVar = "PROM_PV_LABEL"
  22. PromStorageClassLabelEnvVar = "PROM_STORAGE_CLASS_LABEL"
  23. PromVolumeNameLabelEnvVar = "PROM_VOLUME_NAME_LABEL"
  24. PromServiceLabelEnvVar = "PROM_SERVICE_LABEL"
  25. PromServiceNameLabelEnvVar = "PROM_SERVICE_NAME_LABEL"
  26. PromIngressIPLabelEnvVar = "PROM_INGRESS_IP_LABEL"
  27. PromProvisionerNameLabelEnvVar = "PROM_PROVISIONER_NAME_LABEL"
  28. PromUIDLabelEnvVar = "PROM_UID_LABEL"
  29. PromKubernetesNodeLabelEnvVar = "PROM_KUBERNETES_NODE_LABEL"
  30. PromModeLabelEnvVar = "PROM_MODE_LABEL"
  31. PromModelNameLabelEnvVar = "PROM_MODEL_NAME_LABEL"
  32. PromUUIDLabelEnvVar = "PROM_UUID_LABEL"
  33. PromResourceLabelEnvVar = "PROM_RESOURCE_LABEL"
  34. PromDeploymentLabelEnvVar = "PROM_DEPLOYMENT_LABEL"
  35. PromStatefulSetLabelEnvVar = "PROM_STATEFUL_SET_LABEL"
  36. PromReplicaSetLabelEnvVar = "PROM_REPLICA_SET_LABEL"
  37. PromOwnerNameLabelEnvVar = "PROM_OWNER_NAME_LABEL"
  38. PromOwnerKindLabelEnvVar = "PROM_OWNER_KIND_LABEL"
  39. PromUnitLabelEnvVar = "PROM_UNIT_LABEL"
  40. PromInternetLabelEnvVar = "PROM_INTERNET_LABEL"
  41. PromSameZoneLabelEnvVar = "PROM_SAME_ZONE_LABEL"
  42. PromSameRegionLabelEnvVar = "PROM_SAME_REGION_LABEL"
  43. PrometheusRetryOnRateLimitResponseEnvVar = "PROMETHEUS_RETRY_ON_RATE_LIMIT"
  44. PrometheusRetryOnRateLimitMaxRetriesEnvVar = "PROMETHEUS_RETRY_ON_RATE_LIMIT_MAX_RETRIES"
  45. PrometheusRetryOnRateLimitDefaultWaitEnvVar = "PROMETHEUS_RETRY_ON_RATE_LIMIT_DEFAULT_WAIT"
  46. PrometheusQueryTimeoutEnvVar = "PROMETHEUS_QUERY_TIMEOUT"
  47. PrometheusKeepAliveEnvVar = "PROMETHEUS_KEEP_ALIVE"
  48. PrometheusTLSHandshakeTimeoutEnvVar = "PROMETHEUS_TLS_HANDSHAKE_TIMEOUT"
  49. PrometheusScrapeJobNameEnvVar = "PROMETHEUS_SCRAPE_JOB_NAME"
  50. PrometheusScrapeIntervalEnvVar = "PROMETHEUS_SCRAPE_INTERVAL"
  51. PrometheusMaxQueryDurationMinutesEnvVar = "PROMETHEUS_MAX_QUERY_DURATION_MINUTES"
  52. PrometheusQueryResolutionSecondsEnvVar = "PROMETHEUS_QUERY_RESOLUTION_SECONDS"
  53. MaxQueryConcurrencyEnvVar = "MAX_QUERY_CONCURRENCY"
  54. PrometheusHeaderXScopeOrgIdEnvVar = "PROMETHEUS_HEADER_X_SCOPE_ORGID"
  55. InsecureSkipVerifyEnvVar = "INSECURE_SKIP_VERIFY"
  56. KubeRbacProxyEnabledEnvVar = "KUBE_RBAC_PROXY_ENABLED"
  57. DBBasicAuthUsername = "DB_BASIC_AUTH_USERNAME"
  58. DBBasicAuthPassword = "DB_BASIC_AUTH_PW"
  59. DBBearerToken = "DB_BEARER_TOKEN"
  60. CurrentClusterIdFilterEnabledVar = "CURRENT_CLUSTER_ID_FILTER_ENABLED"
  61. // Deprecated env vars that we can use to fallback on temporarily
  62. DeprecatedScrapeIntervalEnvVar = "KUBECOST_SCRAPE_INTERVAL"
  63. DeprecatedJobNameEnvVar = "KUBECOST_JOB_NAME"
  64. )
  65. // GetPrometheusServerEndpoint returns the environment variable value for PrometheusServerEndpointEnvVar which
  66. // represents the prometheus server endpoint used to execute prometheus queries.
  67. //
  68. // In sharded Prometheus setups, PROMETHEUS_SERVER_ENDPOINT should point to a global query endpoint (e.g., Thanos Query, Cortex, or Mimir)
  69. // to ensure OpenCost receives complete data. Pointing to a single Prometheus pod may result in incomplete or intermittent export results.
  70. func GetPrometheusServerEndpoint() string {
  71. return env.Get(PrometheusServerEndpointEnvVar, "")
  72. }
  73. // IsPrometheusRetryOnRateLimitResponse will attempt to retry if a 429 response is received OR a 400 with a body containing
  74. // ThrottleException (common in AWS services like AMP)
  75. func IsPrometheusRetryOnRateLimitResponse() bool {
  76. return env.GetBool(PrometheusRetryOnRateLimitResponseEnvVar, true)
  77. }
  78. // GetPrometheusRetryOnRateLimitMaxRetries returns the maximum number of retries that should be attempted prior to failing.
  79. // Only used if IsPrometheusRetryOnRateLimitResponse() is true.
  80. func GetPrometheusRetryOnRateLimitMaxRetries() int {
  81. return env.GetInt(PrometheusRetryOnRateLimitMaxRetriesEnvVar, 5)
  82. }
  83. // GetPrometheusRetryOnRateLimitDefaultWait returns the default wait time for a retriable rate limit response without a
  84. // Retry-After header.
  85. func GetPrometheusRetryOnRateLimitDefaultWait() time.Duration {
  86. return env.GetDuration(PrometheusRetryOnRateLimitDefaultWaitEnvVar, 100*time.Millisecond)
  87. }
  88. // GetPrometheusHeaderXScopeOrgId returns the default value for X-Scope-OrgID header used for requests in Mimir/Cortex-Tenant API.
  89. // To use Mimir(or Cortex-Tenant) instead of Prometheus add variable from cluster settings:
  90. // "PROMETHEUS_HEADER_X_SCOPE_ORGID": "my-cluster-name"
  91. // Then set Prometheus URL to prometheus API endpoint:
  92. // "PROMETHEUS_SERVER_ENDPOINT": "http://mimir-url/prometheus/"
  93. func GetPrometheusHeaderXScopeOrgId() string {
  94. return env.Get(PrometheusHeaderXScopeOrgIdEnvVar, "")
  95. }
  96. // GetScrapeInterval returns the environment variable for PrometheusScrapeIntervalEnvVar, specifying the scrape interval for Prometheus,
  97. // should opencost not be able to deduce the configuration automatically.
  98. func GetScrapeInterval() time.Duration {
  99. // return the current scrape interval env var, fallback on deprecated env var, default to 60s
  100. // (as per the helm installation defaults)
  101. return env.GetDuration(PrometheusScrapeIntervalEnvVar, env.GetDuration(DeprecatedScrapeIntervalEnvVar, 60*time.Second))
  102. }
  103. // GetJobName returns the environment variable value for PrometheusScrapeJobNameEnvVar, specifying which job name
  104. // is used for prometheus to scrape the provided metrics.
  105. func GetJobName() string {
  106. // return the current job name env var, fallback on deprecated env var, default to "opencost"
  107. // (as per the helm installation defaults)
  108. return env.Get(PrometheusScrapeJobNameEnvVar, env.Get(DeprecatedJobNameEnvVar, "opencost"))
  109. }
  110. func GetPrometheusQueryTimeout() time.Duration {
  111. return env.GetDuration(PrometheusQueryTimeoutEnvVar, 120*time.Second)
  112. }
  113. func GetPrometheusKeepAlive() time.Duration {
  114. return env.GetDuration(PrometheusKeepAliveEnvVar, 120*time.Second)
  115. }
  116. func GetPrometheusTLSHandshakeTimeout() time.Duration {
  117. return env.GetDuration(PrometheusTLSHandshakeTimeoutEnvVar, 10*time.Second)
  118. }
  119. func IsInsecureSkipVerify() bool {
  120. return env.GetBool(InsecureSkipVerifyEnvVar, false)
  121. }
  122. func IsKubeRbacProxyEnabled() bool {
  123. return env.GetBool(KubeRbacProxyEnabledEnvVar, false)
  124. }
  125. // GetPrometheusQueryResolution determines the resolution of prom queries. The smaller the
  126. // duration, the higher the resolution; the higher the resolution, the more
  127. // accurate the query results, but the more computationally expensive.
  128. func GetPrometheusQueryResolution() time.Duration {
  129. // Use the configured query resolution, or default to
  130. // 5m (i.e. 300s)
  131. secs := time.Duration(env.GetInt64(PrometheusQueryResolutionSecondsEnvVar, 300))
  132. return secs * time.Second
  133. }
  134. // GetMaxQueryConcurrency returns the environment variable value for MaxQueryConcurrencyEnvVar
  135. func GetMaxQueryConcurrency() int {
  136. maxQueryConcurrency := env.GetInt(MaxQueryConcurrencyEnvVar, 5)
  137. if maxQueryConcurrency <= 0 {
  138. return runtime.GOMAXPROCS(0)
  139. }
  140. return maxQueryConcurrency
  141. }
  142. func GetDBBasicAuthUsername() string {
  143. return env.Get(DBBasicAuthUsername, "")
  144. }
  145. func GetDBBasicAuthUserPassword() string {
  146. return env.Get(DBBasicAuthPassword, "")
  147. }
  148. func GetDBBearerToken() string {
  149. return env.Get(DBBearerToken, "")
  150. }
  151. func GetPrometheusMaxQueryDuration() time.Duration {
  152. dayMins := 60 * 24
  153. mins := time.Duration(env.GetInt64(PrometheusMaxQueryDurationMinutesEnvVar, int64(dayMins)))
  154. return mins * time.Minute
  155. }
  156. // GetPromClusterFilter returns environment variable value CurrentClusterIdFilterEnabledVar which
  157. // represents additional prometheus filter for all metrics for current cluster id
  158. func GetPromClusterFilter() string {
  159. if env.GetBool(CurrentClusterIdFilterEnabledVar, false) {
  160. return fmt.Sprintf("%s=\"%s\"", GetPromClusterLabel(), env.GetClusterID())
  161. }
  162. return ""
  163. }
  164. // GetPromClusterLabel returns the environment variable value for PromClusterIDLabel: `PROM_CLUSTER_ID_LABEL`
  165. // Prometheus query formatting and results parsers will use this label to determine the ClusterID
  166. func GetPromClusterLabel() string {
  167. return env.Get(PromClusterIDLabelEnvVar, source.ClusterIDLabel)
  168. }
  169. // GetPromNamespaceLabel returns the value set by PromNamespaceLabelEnvVar: `PROM_NAMESPACE_LABEL`
  170. // Prometheus query formatting and results parsers will use this label to determine the Namespace.
  171. func GetPromNamespaceLabel() []string {
  172. return GetListWithDefaults(PromNamespaceLabelEnvVar, source.NamespaceLabel)
  173. }
  174. // GetPromNodeLabel returns the value set by PromNodeLabelEnvVar: `PROM_NODE_LABEL`
  175. // Prometheus query formatting and results parsers will use this label to determine the Node.
  176. func GetPromNodeLabel() []string {
  177. return GetListWithDefaults(PromNodeLabelEnvVar, source.NodeLabel)
  178. }
  179. // GetPromInstanceLabel returns the value set by PromInstanceLabelEnvVar: `PROM_INSTANCE_LABEL`
  180. // Prometheus query formatting and results parsers will use this label to determine the Instance.
  181. func GetPromInstanceLabel() []string {
  182. return GetListWithDefaults(PromInstanceLabelEnvVar, source.InstanceLabel)
  183. }
  184. // GetPromInstanceTypeLabel returns the value set by PromInstanceTypeLabelEnvVar: `PROM_INSTANCE_TYPE_LABEL`
  185. // Prometheus query formatting and results parsers will use this label to determine the InstanceType.
  186. func GetPromInstanceTypeLabel() []string {
  187. return GetListWithDefaults(PromInstanceTypeLabelEnvVar, source.InstanceTypeLabel)
  188. }
  189. // GetPromContainerLabel returns the value set by PromContainerLabelEnvVar: `PROM_CONTAINER_LABEL`
  190. // Prometheus query formatting and results parsers will use this label to determine the Container.
  191. func GetPromContainerLabel() []string {
  192. return GetListWithDefaults(PromContainerLabelEnvVar, source.ContainerLabel, source.ContainerNameLabel)
  193. }
  194. // GetPromPodLabel returns the value set by PromPodLabelEnvVar: `PROM_POD_LABEL`
  195. // Prometheus query formatting and results parsers will use this label to determine the Pod.
  196. func GetPromPodLabel() []string {
  197. return GetListWithDefaults(PromPodLabelEnvVar, source.PodLabel, source.PodNameLabel)
  198. }
  199. // GetPromProviderIDLabel returns the value set by PromProviderIDLabelEnvVar: `PROM_PROVIDER_ID_LABEL`
  200. // Prometheus query formatting and results parsers will use this label to determine the ProviderID.
  201. func GetPromProviderIDLabel() []string {
  202. return GetListWithDefaults(PromProviderIDLabelEnvVar, source.ProviderIDLabel)
  203. }
  204. // GetPromDeviceLabel returns the value set by PromDeviceLabelEnvVar: `PROM_DEVICE_LABEL`
  205. // Prometheus query formatting and results parsers will use this label to determine the Device.
  206. func GetPromDeviceLabel() []string {
  207. return GetListWithDefaults(PromDeviceLabelEnvVar, source.DeviceLabel)
  208. }
  209. // GetPromPVCLabel returns the value set by PromPVCLabelEnvVar: `PROM_PVC_LABEL`
  210. // Prometheus query formatting and results parsers will use this label to determine the PVC.
  211. func GetPromPVCLabel() []string {
  212. return GetListWithDefaults(PromPVCLabelEnvVar, source.PVCLabel)
  213. }
  214. // GetPromPVLabel returns the value set by PromPVLabelEnvVar: `PROM_PV_LABEL`
  215. // Prometheus query formatting and results parsers will use this label to determine the PV.
  216. func GetPromPVLabel() []string {
  217. return GetListWithDefaults(PromPVLabelEnvVar, source.PVLabel)
  218. }
  219. // GetPromStorageClassLabel returns the value set by PromStorageClassLabelEnvVar: `PROM_STORAGE_CLASS_LABEL`
  220. // Prometheus query formatting and results parsers will use this label to determine the StorageClass.
  221. func GetPromStorageClassLabel() []string {
  222. return GetListWithDefaults(PromStorageClassLabelEnvVar, source.StorageClassLabel)
  223. }
  224. // GetPromVolumeNameLabel returns the value set by PromVolumeNameLabelEnvVar: `PROM_VOLUME_NAME_LABEL`
  225. // Prometheus query formatting and results parsers will use this label to determine the VolumeName.
  226. func GetPromVolumeNameLabel() []string {
  227. return GetListWithDefaults(PromVolumeNameLabelEnvVar, source.VolumeNameLabel)
  228. }
  229. // GetPromServiceLabel returns the value set by PromServiceLabelEnvVar: `PROM_SERVICE_LABEL`
  230. // Prometheus query formatting and results parsers will use this label to determine the Service.
  231. func GetPromServiceLabel() []string {
  232. return GetListWithDefaults(PromServiceLabelEnvVar, source.ServiceLabel, source.ServiceNameLabel)
  233. }
  234. // GetPromIngressIPLabel returns the value set by PromIngressIPLabelEnvVar: `PROM_INGRESS_IP_LABEL`
  235. // Prometheus query formatting and results parsers will use this label to determine the IngressIP.
  236. func GetPromIngressIPLabel() []string {
  237. return GetListWithDefaults(PromIngressIPLabelEnvVar, source.IngressIPLabel)
  238. }
  239. // GetPromProvisionerNameLabel returns the value set by PromProvisionerNameLabelEnvVar: `PROM_PROVISIONER_NAME_LABEL`
  240. // Prometheus query formatting and results parsers will use this label to determine the ProvisionerName.
  241. func GetPromProvisionerNameLabel() []string {
  242. return GetListWithDefaults(PromProvisionerNameLabelEnvVar, source.ProvisionerNameLabel)
  243. }
  244. // GetPromUIDLabel returns the value set by PromUIDLabelEnvVar: `PROM_UID_LABEL`
  245. // Prometheus query formatting and results parsers will use this label to determine the UID.
  246. func GetPromUIDLabel() []string {
  247. return GetListWithDefaults(PromUIDLabelEnvVar, source.UIDLabel)
  248. }
  249. // GetPromKubernetesNodeLabel returns the value set by PromKubernetesNodeLabelEnvVar: `PROM_KUBERNETES_NODE_LABEL`
  250. // Prometheus query formatting and results parsers will use this label to determine the KubernetesNode.
  251. func GetPromKubernetesNodeLabel() []string {
  252. return GetListWithDefaults(PromKubernetesNodeLabelEnvVar, source.KubernetesNodeLabel)
  253. }
  254. // GetPromModeLabel returns the value set by PromModeLabelEnvVar: `PROM_MODE_LABEL`
  255. // Prometheus query formatting and results parsers will use this label to determine the Mode.
  256. func GetPromModeLabel() []string {
  257. return GetListWithDefaults(PromModeLabelEnvVar, source.ModeLabel)
  258. }
  259. // GetPromModelNameLabel returns the value set by PromModelNameLabelEnvVar: `PROM_MODEL_NAME_LABEL`
  260. // Prometheus query formatting and results parsers will use this label to determine the ModelName.
  261. func GetPromModelNameLabel() []string {
  262. return GetListWithDefaults(PromModelNameLabelEnvVar, source.ModelNameLabel)
  263. }
  264. // GetPromUUIDLabel returns the value set by PromUUIDLabelEnvVar: `PROM_UUID_LABEL`
  265. // Prometheus query formatting and results parsers will use this label to determine the UUID.
  266. func GetPromUUIDLabel() []string {
  267. return GetListWithDefaults(PromUUIDLabelEnvVar, source.UUIDLabel)
  268. }
  269. // GetPromResourceLabel returns the value set by PromResourceLabelEnvVar: `PROM_RESOURCE_LABEL`
  270. // Prometheus query formatting and results parsers will use this label to determine the Resource.
  271. func GetPromResourceLabel() []string {
  272. return GetListWithDefaults(PromResourceLabelEnvVar, source.ResourceLabel)
  273. }
  274. // GetPromDeploymentLabel returns the value set by PromDeploymentLabelEnvVar: `PROM_DEPLOYMENT_LABEL`
  275. // Prometheus query formatting and results parsers will use this label to determine the Deployment.
  276. func GetPromDeploymentLabel() []string {
  277. return GetListWithDefaults(PromDeploymentLabelEnvVar, source.DeploymentLabel)
  278. }
  279. // GetPromStatefulSetLabel returns the value set by PromStatefulSetLabelEnvVar: `PROM_STATEFUL_SET_LABEL`
  280. // Prometheus query formatting and results parsers will use this label to determine the StatefulSet.
  281. func GetPromStatefulSetLabel() []string {
  282. return GetListWithDefaults(PromStatefulSetLabelEnvVar, source.StatefulSetLabel)
  283. }
  284. // GetPromReplicaSetLabel returns the value set by PromReplicaSetLabelEnvVar: `PROM_REPLICA_SET_LABEL`
  285. // Prometheus query formatting and results parsers will use this label to determine the ReplicaSet.
  286. func GetPromReplicaSetLabel() []string {
  287. return GetListWithDefaults(PromReplicaSetLabelEnvVar, source.ReplicaSetLabel)
  288. }
  289. // GetPromOwnerNameLabel returns the value set by PromOwnerNameLabelEnvVar: `PROM_OWNER_NAME_LABEL`
  290. // Prometheus query formatting and results parsers will use this label to determine the OwnerName.
  291. func GetPromOwnerNameLabel() []string {
  292. return GetListWithDefaults(PromOwnerNameLabelEnvVar, source.OwnerNameLabel)
  293. }
  294. // GetPromOwnerKindLabel returns the value set by PromOwnerKindLabelEnvVar: `PROM_OWNER_KIND_LABEL`
  295. // Prometheus query formatting and results parsers will use this label to determine the OwnerKind.
  296. func GetPromOwnerKindLabel() []string {
  297. return GetListWithDefaults(PromOwnerKindLabelEnvVar, source.OwnerKindLabel)
  298. }
  299. // GetPromUnitLabel returns the value set by PromUnitLabelEnvVar: `PROM_UNIT_LABEL`
  300. // Prometheus query formatting and results parsers will use this label to determine the Unit.
  301. func GetPromUnitLabel() []string {
  302. return GetListWithDefaults(PromUnitLabelEnvVar, source.UnitLabel)
  303. }
  304. // GetPromInternetLabel returns the value set by PromInternetLabelEnvVar: `PROM_INTERNET_LABEL`
  305. // Prometheus query formatting and results parsers will use this label to determine the Internet.
  306. func GetPromInternetLabel() []string {
  307. return GetListWithDefaults(PromInternetLabelEnvVar, source.InternetLabel)
  308. }
  309. // GetPromSameZoneLabel returns the value set by PromSameZoneLabelEnvVar: `PROM_SAME_ZONE_LABEL`
  310. // Prometheus query formatting and results parsers will use this label to determine the SameZone.
  311. func GetPromSameZoneLabel() []string {
  312. return GetListWithDefaults(PromSameZoneLabelEnvVar, source.SameZoneLabel)
  313. }
  314. // GetPromSameRegionLabel returns the value set by PromSameRegionLabelEnvVar: `PROM_SAME_REGION_LABEL`
  315. // Prometheus query formatting and results parsers will use this label to determine the SameRegion.
  316. func GetPromSameRegionLabel() []string {
  317. return GetListWithDefaults(PromSameRegionLabelEnvVar, source.SameRegionLabel)
  318. }
  319. func GetListWithDefaults(key string, defaultValues ...string) []string {
  320. list := env.GetList(key, ",")
  321. if len(list) == 0 {
  322. return defaultValues
  323. }
  324. return list
  325. }