config_env.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Copyright (c) 2018 The Jaeger Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package config
  15. import (
  16. "fmt"
  17. "net/url"
  18. "os"
  19. "strconv"
  20. "strings"
  21. "time"
  22. "github.com/opentracing/opentracing-go"
  23. "github.com/pkg/errors"
  24. "github.com/uber/jaeger-client-go"
  25. )
  26. const (
  27. // environment variable names
  28. envServiceName = "JAEGER_SERVICE_NAME"
  29. envDisabled = "JAEGER_DISABLED"
  30. envRPCMetrics = "JAEGER_RPC_METRICS"
  31. envTags = "JAEGER_TAGS"
  32. envSamplerType = "JAEGER_SAMPLER_TYPE"
  33. envSamplerParam = "JAEGER_SAMPLER_PARAM"
  34. envSamplerManagerHostPort = "JAEGER_SAMPLER_MANAGER_HOST_PORT"
  35. envSamplerMaxOperations = "JAEGER_SAMPLER_MAX_OPERATIONS"
  36. envSamplerRefreshInterval = "JAEGER_SAMPLER_REFRESH_INTERVAL"
  37. envReporterMaxQueueSize = "JAEGER_REPORTER_MAX_QUEUE_SIZE"
  38. envReporterFlushInterval = "JAEGER_REPORTER_FLUSH_INTERVAL"
  39. envReporterLogSpans = "JAEGER_REPORTER_LOG_SPANS"
  40. envEndpoint = "JAEGER_ENDPOINT"
  41. envUser = "JAEGER_USER"
  42. envPassword = "JAEGER_PASSWORD"
  43. envAgentHost = "JAEGER_AGENT_HOST"
  44. envAgentPort = "JAEGER_AGENT_PORT"
  45. )
  46. // FromEnv uses environment variables to set the tracer's Configuration
  47. func FromEnv() (*Configuration, error) {
  48. c := &Configuration{}
  49. if e := os.Getenv(envServiceName); e != "" {
  50. c.ServiceName = e
  51. }
  52. if e := os.Getenv(envRPCMetrics); e != "" {
  53. if value, err := strconv.ParseBool(e); err == nil {
  54. c.RPCMetrics = value
  55. } else {
  56. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envRPCMetrics, e)
  57. }
  58. }
  59. if e := os.Getenv(envDisabled); e != "" {
  60. if value, err := strconv.ParseBool(e); err == nil {
  61. c.Disabled = value
  62. } else {
  63. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envDisabled, e)
  64. }
  65. }
  66. if e := os.Getenv(envTags); e != "" {
  67. c.Tags = parseTags(e)
  68. }
  69. if s, err := samplerConfigFromEnv(); err == nil {
  70. c.Sampler = s
  71. } else {
  72. return nil, errors.Wrap(err, "cannot obtain sampler config from env")
  73. }
  74. if r, err := reporterConfigFromEnv(); err == nil {
  75. c.Reporter = r
  76. } else {
  77. return nil, errors.Wrap(err, "cannot obtain reporter config from env")
  78. }
  79. return c, nil
  80. }
  81. // samplerConfigFromEnv creates a new SamplerConfig based on the environment variables
  82. func samplerConfigFromEnv() (*SamplerConfig, error) {
  83. sc := &SamplerConfig{}
  84. if e := os.Getenv(envSamplerType); e != "" {
  85. sc.Type = e
  86. }
  87. if e := os.Getenv(envSamplerParam); e != "" {
  88. if value, err := strconv.ParseFloat(e, 64); err == nil {
  89. sc.Param = value
  90. } else {
  91. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envSamplerParam, e)
  92. }
  93. }
  94. if e := os.Getenv(envSamplerManagerHostPort); e != "" {
  95. sc.SamplingServerURL = e
  96. }
  97. if e := os.Getenv(envSamplerMaxOperations); e != "" {
  98. if value, err := strconv.ParseInt(e, 10, 0); err == nil {
  99. sc.MaxOperations = int(value)
  100. } else {
  101. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envSamplerMaxOperations, e)
  102. }
  103. }
  104. if e := os.Getenv(envSamplerRefreshInterval); e != "" {
  105. if value, err := time.ParseDuration(e); err == nil {
  106. sc.SamplingRefreshInterval = value
  107. } else {
  108. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envSamplerRefreshInterval, e)
  109. }
  110. }
  111. return sc, nil
  112. }
  113. // reporterConfigFromEnv creates a new ReporterConfig based on the environment variables
  114. func reporterConfigFromEnv() (*ReporterConfig, error) {
  115. rc := &ReporterConfig{}
  116. if e := os.Getenv(envReporterMaxQueueSize); e != "" {
  117. if value, err := strconv.ParseInt(e, 10, 0); err == nil {
  118. rc.QueueSize = int(value)
  119. } else {
  120. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envReporterMaxQueueSize, e)
  121. }
  122. }
  123. if e := os.Getenv(envReporterFlushInterval); e != "" {
  124. if value, err := time.ParseDuration(e); err == nil {
  125. rc.BufferFlushInterval = value
  126. } else {
  127. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envReporterFlushInterval, e)
  128. }
  129. }
  130. if e := os.Getenv(envReporterLogSpans); e != "" {
  131. if value, err := strconv.ParseBool(e); err == nil {
  132. rc.LogSpans = value
  133. } else {
  134. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envReporterLogSpans, e)
  135. }
  136. }
  137. if e := os.Getenv(envEndpoint); e != "" {
  138. u, err := url.ParseRequestURI(e)
  139. if err != nil {
  140. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envEndpoint, e)
  141. }
  142. rc.CollectorEndpoint = u.String()
  143. user := os.Getenv(envUser)
  144. pswd := os.Getenv(envPassword)
  145. if user != "" && pswd == "" || user == "" && pswd != "" {
  146. return nil, errors.Errorf("you must set %s and %s env vars together", envUser, envPassword)
  147. }
  148. rc.User = user
  149. rc.Password = pswd
  150. } else {
  151. host := jaeger.DefaultUDPSpanServerHost
  152. if e := os.Getenv(envAgentHost); e != "" {
  153. host = e
  154. }
  155. port := jaeger.DefaultUDPSpanServerPort
  156. if e := os.Getenv(envAgentPort); e != "" {
  157. if value, err := strconv.ParseInt(e, 10, 0); err == nil {
  158. port = int(value)
  159. } else {
  160. return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envAgentPort, e)
  161. }
  162. }
  163. rc.LocalAgentHostPort = fmt.Sprintf("%s:%d", host, port)
  164. }
  165. return rc, nil
  166. }
  167. // parseTags parses the given string into a collection of Tags.
  168. // Spec for this value:
  169. // - comma separated list of key=value
  170. // - value can be specified using the notation ${envVar:defaultValue}, where `envVar`
  171. // is an environment variable and `defaultValue` is the value to use in case the env var is not set
  172. func parseTags(sTags string) []opentracing.Tag {
  173. pairs := strings.Split(sTags, ",")
  174. tags := make([]opentracing.Tag, 0)
  175. for _, p := range pairs {
  176. kv := strings.SplitN(p, "=", 2)
  177. k, v := strings.TrimSpace(kv[0]), strings.TrimSpace(kv[1])
  178. if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
  179. ed := strings.SplitN(v[2:len(v)-1], ":", 2)
  180. e, d := ed[0], ed[1]
  181. v = os.Getenv(e)
  182. if v == "" && d != "" {
  183. v = d
  184. }
  185. }
  186. tag := opentracing.Tag{Key: k, Value: v}
  187. tags = append(tags, tag)
  188. }
  189. return tags
  190. }