指标属性用于在更上层的指标使用中进行过滤、汇总、统计等高纬度操作。在GoFrame框架的监控告警组件中,提供了3种属性注入方式:常量属性变量属性全局属性

OpenTelemetry中叫做指标属性(attributes),但在Prometheus中叫做指标标签(labels),两者是一个含义。

常量属性

常量属性是固定的一系列属性键值对,可以绑定到Meter中,也可以直接绑定到指标对象上。如果绑定到Meter上,那么Meter下所有创建的指标对象均带有该属性键值对,如果绑定到指标对象上,那么仅会在当前指标上生效。我们来看一个示例:

  1. package main
  2. import (
  3. "context"
  4. "go.opentelemetry.io/otel/exporters/prometheus"
  5. "github.com/gogf/gf/contrib/metric/otelmetric/v2"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. "github.com/gogf/gf/v2/os/gmetric"
  9. )
  10. const (
  11. instrument = "github.com/gogf/gf/example/metric/basic"
  12. instrumentVersion = "v1.0"
  13. )
  14. var (
  15. meter = gmetric.GetGlobalProvider().Meter(gmetric.MeterOption{
  16. Instrument: instrument,
  17. InstrumentVersion: instrumentVersion,
  18. Attributes: gmetric.Attributes{
  19. gmetric.NewAttribute("meter_const_attr_1", 1),
  20. },
  21. })
  22. counter = meter.MustCounter(
  23. "goframe.metric.demo.counter",
  24. gmetric.MetricOption{
  25. Help: "This is a simple demo for Counter usage",
  26. Unit: "bytes",
  27. Attributes: gmetric.Attributes{
  28. gmetric.NewAttribute("metric_const_attr_1", 1),
  29. },
  30. },
  31. )
  32. observableCounter = meter.MustObservableCounter(
  33. "goframe.metric.demo.observable_counter",
  34. gmetric.MetricOption{
  35. Help: "This is a simple demo for ObservableCounter usage",
  36. Unit: "%",
  37. Attributes: gmetric.Attributes{
  38. gmetric.NewAttribute("metric_const_attr_2", 2),
  39. },
  40. },
  41. )
  42. )
  43. func main() {
  44. var ctx = gctx.New()
  45. // Callback for observable metrics.
  46. meter.MustRegisterCallback(func(ctx context.Context, obs gmetric.Observer) error {
  47. obs.Observe(observableCounter, 10)
  48. return nil
  49. }, observableCounter)
  50. // Prometheus exporter to export metrics as Prometheus format.
  51. exporter, err := prometheus.New(
  52. prometheus.WithoutCounterSuffixes(),
  53. prometheus.WithoutUnits(),
  54. )
  55. if err != nil {
  56. g.Log().Fatal(ctx, err)
  57. }
  58. // OpenTelemetry provider.
  59. provider := otelmetric.MustProvider(
  60. otelmetric.WithReader(exporter),
  61. )
  62. provider.SetAsGlobal()
  63. defer provider.Shutdown(ctx)
  64. // Counter.
  65. counter.Inc(ctx)
  66. counter.Add(ctx, 10)
  67. // HTTP Server for metrics exporting.
  68. otelmetric.StartPrometheusMetricsServer(8000, "/metrics")
  69. }

可以看到,我们通过创建Meter对象或者Metric对象时的MeterOptionMetricOption参数中的Attributes属性字段来指定常量属性。

执行后,我们访问 http://127.0.0.1:8000/metrics 看看结果。可以看到绑定到Meter上的常量属性在两个指标上生效了,但是在各个指标上绑定的常量属性仅在对应的指标上生效了。

监控告警-指标属性 - 图1

变量属性

变量属性是在指标运行时指定的属性键值对,通常只能在运行时才能确定属性的键值对信息,并且键值对可能根据不同的执行场景而发生变化,因此叫做变量属性。

我们来看一个示例:

  1. package main
  2. import (
  3. "context"
  4. "go.opentelemetry.io/otel/exporters/prometheus"
  5. "github.com/gogf/gf/contrib/metric/otelmetric/v2"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. "github.com/gogf/gf/v2/os/gmetric"
  9. )
  10. const (
  11. instrument = "github.com/gogf/gf/example/metric/basic"
  12. instrumentVersion = "v1.0"
  13. )
  14. var (
  15. meter = gmetric.GetGlobalProvider().Meter(gmetric.MeterOption{
  16. Instrument: instrument,
  17. InstrumentVersion: instrumentVersion,
  18. Attributes: gmetric.Attributes{
  19. gmetric.NewAttribute("meter_const_attr_1", 1),
  20. },
  21. })
  22. counter = meter.MustCounter(
  23. "goframe.metric.demo.counter",
  24. gmetric.MetricOption{
  25. Help: "This is a simple demo for Counter usage",
  26. Unit: "bytes",
  27. Attributes: gmetric.Attributes{
  28. gmetric.NewAttribute("metric_const_attr_1", 1),
  29. },
  30. },
  31. )
  32. observableCounter = meter.MustObservableCounter(
  33. "goframe.metric.demo.observable_counter",
  34. gmetric.MetricOption{
  35. Help: "This is a simple demo for ObservableCounter usage",
  36. Unit: "%",
  37. Attributes: gmetric.Attributes{
  38. gmetric.NewAttribute("metric_const_attr_2", 2),
  39. },
  40. },
  41. )
  42. )
  43. func main() {
  44. var ctx = gctx.New()
  45. // Callback for observable metrics.
  46. meter.MustRegisterCallback(func(ctx context.Context, obs gmetric.Observer) error {
  47. obs.Observe(observableCounter, 10, gmetric.Option{
  48. Attributes: gmetric.Attributes{
  49. gmetric.NewAttribute("dynamic_attr_1", 1),
  50. },
  51. })
  52. return nil
  53. }, observableCounter)
  54. // Prometheus exporter to export metrics as Prometheus format.
  55. exporter, err := prometheus.New(
  56. prometheus.WithoutCounterSuffixes(),
  57. prometheus.WithoutUnits(),
  58. )
  59. if err != nil {
  60. g.Log().Fatal(ctx, err)
  61. }
  62. // OpenTelemetry provider.
  63. provider := otelmetric.MustProvider(
  64. otelmetric.WithReader(exporter),
  65. )
  66. provider.SetAsGlobal()
  67. defer provider.Shutdown(ctx)
  68. // Counter.
  69. counter.Inc(ctx, gmetric.Option{
  70. Attributes: gmetric.Attributes{
  71. gmetric.NewAttribute("dynamic_attr_2", 2),
  72. },
  73. })
  74. counter.Add(ctx, 10, gmetric.Option{
  75. Attributes: gmetric.Attributes{
  76. gmetric.NewAttribute("dynamic_attr_3", 3),
  77. },
  78. })
  79. // HTTP Server for metrics exporting.
  80. otelmetric.StartPrometheusMetricsServer(8000, "/metrics")
  81. }

可以看到,我们在运行通过Option参数中的Attributes属性字段来指定指标变量属性,变量属性比较灵活,相同的指标也可以使用不同的变量属性。

同样的,执行后,我们访问 http://127.0.0.1:8000/metrics 看看结果。

监控告警-指标属性 - 图2

全局属性

全局属性是一种更加灵活的指标属性注入方式,可以根据Instrument信息进行属性自动注入,并且可以根据Instrument名称的正则匹配来判断是否往该Instrument下所有的指标注入指标属性信息。

我们来看一个示例:

  1. package main
  2. import (
  3. "context"
  4. "go.opentelemetry.io/otel/exporters/prometheus"
  5. "github.com/gogf/gf/contrib/metric/otelmetric/v2"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. "github.com/gogf/gf/v2/os/gmetric"
  9. )
  10. const (
  11. instrument = "github.com/gogf/gf/example/metric/basic"
  12. instrumentVersion = "v1.0"
  13. )
  14. var (
  15. meter = gmetric.GetGlobalProvider().Meter(gmetric.MeterOption{
  16. Instrument: instrument,
  17. InstrumentVersion: instrumentVersion,
  18. Attributes: gmetric.Attributes{
  19. gmetric.NewAttribute("meter_const_attr_1", 1),
  20. },
  21. })
  22. counter = meter.MustCounter(
  23. "goframe.metric.demo.counter",
  24. gmetric.MetricOption{
  25. Help: "This is a simple demo for Counter usage",
  26. Unit: "bytes",
  27. Attributes: gmetric.Attributes{
  28. gmetric.NewAttribute("metric_const_attr_1", 1),
  29. },
  30. },
  31. )
  32. observableCounter = meter.MustObservableCounter(
  33. "goframe.metric.demo.observable_counter",
  34. gmetric.MetricOption{
  35. Help: "This is a simple demo for ObservableCounter usage",
  36. Unit: "%",
  37. Attributes: gmetric.Attributes{
  38. gmetric.NewAttribute("metric_const_attr_2", 2),
  39. },
  40. },
  41. )
  42. )
  43. func main() {
  44. var ctx = gctx.New()
  45. gmetric.SetGlobalAttributes(gmetric.Attributes{
  46. gmetric.NewAttribute("global_attr_1", 1),
  47. }, gmetric.SetGlobalAttributesOption{
  48. Instrument: instrument,
  49. InstrumentVersion: instrumentVersion,
  50. InstrumentPattern: "",
  51. })
  52. // Callback for observable metrics.
  53. meter.MustRegisterCallback(func(ctx context.Context, obs gmetric.Observer) error {
  54. obs.Observe(observableCounter, 10, gmetric.Option{
  55. Attributes: gmetric.Attributes{
  56. gmetric.NewAttribute("dynamic_attr_1", 1),
  57. },
  58. })
  59. return nil
  60. }, observableCounter)
  61. // Prometheus exporter to export metrics as Prometheus format.
  62. exporter, err := prometheus.New(
  63. prometheus.WithoutCounterSuffixes(),
  64. prometheus.WithoutUnits(),
  65. )
  66. if err != nil {
  67. g.Log().Fatal(ctx, err)
  68. }
  69. // OpenTelemetry provider.
  70. provider := otelmetric.MustProvider(
  71. otelmetric.WithReader(exporter),
  72. )
  73. provider.SetAsGlobal()
  74. defer provider.Shutdown(ctx)
  75. // Counter.
  76. counter.Inc(ctx, gmetric.Option{
  77. Attributes: gmetric.Attributes{
  78. gmetric.NewAttribute("dynamic_attr_2", 2),
  79. },
  80. })
  81. counter.Add(ctx, 10, gmetric.Option{
  82. Attributes: gmetric.Attributes{
  83. gmetric.NewAttribute("dynamic_attr_3", 3),
  84. },
  85. })
  86. // HTTP Server for metrics exporting.
  87. otelmetric.StartPrometheusMetricsServer(8000, "/metrics")
  88. }

通过gmetric.SetGlobalAttributes方法设置全局属性,并且根据参数gmetric.SetGlobalAttributesOption限制影响的指标范围。

同样的,执行后,我们访问 http://127.0.0.1:8000/metrics 看看结果。可以看到,全局属性已经自动添加到了指标中。

监控告警-指标属性 - 图3