config.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright The OpenTelemetry 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 prometheus // import "go.opentelemetry.io/otel/exporters/prometheus"
  15. import (
  16. "strings"
  17. "github.com/prometheus/client_golang/prometheus"
  18. "go.opentelemetry.io/otel/sdk/metric"
  19. )
  20. // config contains options for the exporter.
  21. type config struct {
  22. registerer prometheus.Registerer
  23. disableTargetInfo bool
  24. withoutUnits bool
  25. withoutCounterSuffixes bool
  26. readerOpts []metric.ManualReaderOption
  27. disableScopeInfo bool
  28. namespace string
  29. }
  30. // newConfig creates a validated config configured with options.
  31. func newConfig(opts ...Option) config {
  32. cfg := config{}
  33. for _, opt := range opts {
  34. cfg = opt.apply(cfg)
  35. }
  36. if cfg.registerer == nil {
  37. cfg.registerer = prometheus.DefaultRegisterer
  38. }
  39. return cfg
  40. }
  41. // Option sets exporter option values.
  42. type Option interface {
  43. apply(config) config
  44. }
  45. type optionFunc func(config) config
  46. func (fn optionFunc) apply(cfg config) config {
  47. return fn(cfg)
  48. }
  49. // WithRegisterer configures which prometheus Registerer the Exporter will
  50. // register with. If no registerer is used the prometheus DefaultRegisterer is
  51. // used.
  52. func WithRegisterer(reg prometheus.Registerer) Option {
  53. return optionFunc(func(cfg config) config {
  54. cfg.registerer = reg
  55. return cfg
  56. })
  57. }
  58. // WithAggregationSelector configure the Aggregation Selector the exporter will
  59. // use. If no AggregationSelector is provided the DefaultAggregationSelector is
  60. // used.
  61. func WithAggregationSelector(agg metric.AggregationSelector) Option {
  62. return optionFunc(func(cfg config) config {
  63. cfg.readerOpts = append(cfg.readerOpts, metric.WithAggregationSelector(agg))
  64. return cfg
  65. })
  66. }
  67. // WithProducer configure the metric Producer the exporter will use as a source
  68. // of external metric data.
  69. func WithProducer(producer metric.Producer) Option {
  70. return optionFunc(func(cfg config) config {
  71. cfg.readerOpts = append(cfg.readerOpts, metric.WithProducer(producer))
  72. return cfg
  73. })
  74. }
  75. // WithoutTargetInfo configures the Exporter to not export the resource target_info metric.
  76. // If not specified, the Exporter will create a target_info metric containing
  77. // the metrics' resource.Resource attributes.
  78. func WithoutTargetInfo() Option {
  79. return optionFunc(func(cfg config) config {
  80. cfg.disableTargetInfo = true
  81. return cfg
  82. })
  83. }
  84. // WithoutUnits disables exporter's addition of unit suffixes to metric names,
  85. // and will also prevent unit comments from being added in OpenMetrics once
  86. // unit comments are supported.
  87. //
  88. // By default, metric names include a unit suffix to follow Prometheus naming
  89. // conventions. For example, the counter metric request.duration, with unit
  90. // milliseconds would become request_duration_milliseconds_total.
  91. // With this option set, the name would instead be request_duration_total.
  92. func WithoutUnits() Option {
  93. return optionFunc(func(cfg config) config {
  94. cfg.withoutUnits = true
  95. return cfg
  96. })
  97. }
  98. // WithoutUnits disables exporter's addition _total suffixes on counters.
  99. //
  100. // By default, metric names include a _total suffix to follow Prometheus naming
  101. // conventions. For example, the counter metric happy.people would become
  102. // happy_people_total. With this option set, the name would instead be
  103. // happy_people.
  104. func WithoutCounterSuffixes() Option {
  105. return optionFunc(func(cfg config) config {
  106. cfg.withoutCounterSuffixes = true
  107. return cfg
  108. })
  109. }
  110. // WithoutScopeInfo configures the Exporter to not export the otel_scope_info metric.
  111. // If not specified, the Exporter will create a otel_scope_info metric containing
  112. // the metrics' Instrumentation Scope, and also add labels about Instrumentation Scope to all metric points.
  113. func WithoutScopeInfo() Option {
  114. return optionFunc(func(cfg config) config {
  115. cfg.disableScopeInfo = true
  116. return cfg
  117. })
  118. }
  119. // WithNamespace configures the Exporter to prefix metric with the given namespace.
  120. // Metadata metrics such as target_info and otel_scope_info are not prefixed since these
  121. // have special behavior based on their name.
  122. func WithNamespace(ns string) Option {
  123. return optionFunc(func(cfg config) config {
  124. ns = sanitizeName(ns)
  125. if !strings.HasSuffix(ns, "_") {
  126. // namespace and metric names should be separated with an underscore,
  127. // adds a trailing underscore if there is not one already.
  128. ns = ns + "_"
  129. }
  130. cfg.namespace = ns
  131. return cfg
  132. })
  133. }