metrics.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright 2016 Circonus, Inc. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package checkmgr
  5. import (
  6. "github.com/circonus-labs/circonus-gometrics/api"
  7. )
  8. // IsMetricActive checks whether a given metric name is currently active(enabled)
  9. func (cm *CheckManager) IsMetricActive(name string) bool {
  10. cm.availableMetricsmu.Lock()
  11. defer cm.availableMetricsmu.Unlock()
  12. return cm.availableMetrics[name]
  13. }
  14. // ActivateMetric determines if a given metric should be activated
  15. func (cm *CheckManager) ActivateMetric(name string) bool {
  16. cm.availableMetricsmu.Lock()
  17. defer cm.availableMetricsmu.Unlock()
  18. active, exists := cm.availableMetrics[name]
  19. if !exists {
  20. return true
  21. }
  22. if !active && cm.forceMetricActivation {
  23. return true
  24. }
  25. return false
  26. }
  27. // AddMetricTags updates check bundle metrics with tags
  28. func (cm *CheckManager) AddMetricTags(metricName string, tags []string, appendTags bool) bool {
  29. tagsUpdated := false
  30. if appendTags && len(tags) == 0 {
  31. return tagsUpdated
  32. }
  33. currentTags, exists := cm.metricTags[metricName]
  34. if !exists {
  35. foundMetric := false
  36. if cm.checkBundle != nil {
  37. for _, metric := range cm.checkBundle.Metrics {
  38. if metric.Name == metricName {
  39. foundMetric = true
  40. currentTags = metric.Tags
  41. break
  42. }
  43. }
  44. }
  45. if !foundMetric {
  46. currentTags = []string{}
  47. }
  48. }
  49. action := ""
  50. if appendTags {
  51. numNewTags := countNewTags(currentTags, tags)
  52. if numNewTags > 0 {
  53. action = "Added"
  54. currentTags = append(currentTags, tags...)
  55. tagsUpdated = true
  56. }
  57. } else {
  58. if len(tags) != len(currentTags) {
  59. action = "Set"
  60. currentTags = tags
  61. tagsUpdated = true
  62. } else {
  63. numNewTags := countNewTags(currentTags, tags)
  64. if numNewTags > 0 {
  65. action = "Set"
  66. currentTags = tags
  67. tagsUpdated = true
  68. }
  69. }
  70. }
  71. if tagsUpdated {
  72. cm.metricTags[metricName] = currentTags
  73. }
  74. if cm.Debug && action != "" {
  75. cm.Log.Printf("[DEBUG] %s metric tag(s) %s %v\n", action, metricName, tags)
  76. }
  77. return tagsUpdated
  78. }
  79. // addNewMetrics updates a check bundle with new metrics
  80. func (cm *CheckManager) addNewMetrics(newMetrics map[string]*api.CheckBundleMetric) bool {
  81. updatedCheckBundle := false
  82. if cm.checkBundle == nil || len(newMetrics) == 0 {
  83. return updatedCheckBundle
  84. }
  85. cm.cbmu.Lock()
  86. defer cm.cbmu.Unlock()
  87. numCurrMetrics := len(cm.checkBundle.Metrics)
  88. numNewMetrics := len(newMetrics)
  89. if numCurrMetrics+numNewMetrics >= cap(cm.checkBundle.Metrics) {
  90. nm := make([]api.CheckBundleMetric, numCurrMetrics+numNewMetrics)
  91. copy(nm, cm.checkBundle.Metrics)
  92. cm.checkBundle.Metrics = nm
  93. }
  94. cm.checkBundle.Metrics = cm.checkBundle.Metrics[0 : numCurrMetrics+numNewMetrics]
  95. i := 0
  96. for _, metric := range newMetrics {
  97. cm.checkBundle.Metrics[numCurrMetrics+i] = *metric
  98. i++
  99. updatedCheckBundle = true
  100. }
  101. if updatedCheckBundle {
  102. cm.forceCheckUpdate = true
  103. }
  104. return updatedCheckBundle
  105. }
  106. // inventoryMetrics creates list of active metrics in check bundle
  107. func (cm *CheckManager) inventoryMetrics() {
  108. availableMetrics := make(map[string]bool)
  109. for _, metric := range cm.checkBundle.Metrics {
  110. availableMetrics[metric.Name] = metric.Status == "active"
  111. }
  112. cm.availableMetricsmu.Lock()
  113. cm.availableMetrics = availableMetrics
  114. cm.availableMetricsmu.Unlock()
  115. }
  116. // countNewTags returns a count of new tags which do not exist in the current list of tags
  117. func countNewTags(currTags []string, newTags []string) int {
  118. if len(newTags) == 0 {
  119. return 0
  120. }
  121. if len(currTags) == 0 {
  122. return len(newTags)
  123. }
  124. newTagCount := 0
  125. for _, newTag := range newTags {
  126. found := false
  127. for _, currTag := range currTags {
  128. if newTag == currTag {
  129. found = true
  130. break
  131. }
  132. }
  133. if !found {
  134. newTagCount++
  135. }
  136. }
  137. return newTagCount
  138. }