metricrecord_to_metricdata.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package skywalkingexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/skywalkingexporter"
  4. import (
  5. "strconv"
  6. "go.opentelemetry.io/collector/pdata/pcommon"
  7. "go.opentelemetry.io/collector/pdata/pmetric"
  8. conventions "go.opentelemetry.io/collector/semconv/v1.6.1"
  9. metricpb "skywalking.apache.org/repo/goapi/collect/language/agent/v3"
  10. )
  11. const (
  12. defaultServiceInstance = "otel-collector-instance"
  13. )
  14. func resourceToMetricLabels(resource pcommon.Resource) []*metricpb.Label {
  15. attrs := resource.Attributes()
  16. labels := make([]*metricpb.Label, 0, attrs.Len())
  17. attrs.Range(func(k string, v pcommon.Value) bool {
  18. labels = append(labels,
  19. &metricpb.Label{
  20. Name: k,
  21. Value: v.AsString(),
  22. })
  23. return true
  24. })
  25. return labels
  26. }
  27. func resourceToServiceInfo(resource pcommon.Resource) (service string, serviceInstance string) {
  28. attrs := resource.Attributes()
  29. if serviceName, ok := attrs.Get(conventions.AttributeServiceName); ok {
  30. service = serviceName.AsString()
  31. } else {
  32. service = defaultServiceName
  33. }
  34. if serviceInstanceID, ok := attrs.Get(conventions.AttributeServiceInstanceID); ok {
  35. serviceInstance = serviceInstanceID.AsString()
  36. } else {
  37. serviceInstance = defaultServiceInstance
  38. }
  39. return service, serviceInstance
  40. }
  41. func numberMetricsToData(name string, data pmetric.NumberDataPointSlice, defaultLabels []*metricpb.Label) (metrics []*metricpb.MeterData) {
  42. metrics = make([]*metricpb.MeterData, 0, data.Len())
  43. for i := 0; i < data.Len(); i++ {
  44. dataPoint := data.At(i)
  45. attributeMap := dataPoint.Attributes()
  46. labels := make([]*metricpb.Label, 0, attributeMap.Len()+len(defaultLabels))
  47. attributeMap.Range(func(k string, v pcommon.Value) bool {
  48. labels = append(labels, &metricpb.Label{Name: k, Value: v.AsString()})
  49. return true
  50. })
  51. for _, label := range defaultLabels {
  52. labels = append(labels, &metricpb.Label{Name: label.Name, Value: label.Value})
  53. }
  54. meterData := &metricpb.MeterData{}
  55. sv := &metricpb.MeterData_SingleValue{SingleValue: &metricpb.MeterSingleValue{}}
  56. sv.SingleValue.Labels = labels
  57. meterData.Timestamp = dataPoint.Timestamp().AsTime().UnixMilli()
  58. sv.SingleValue.Name = name
  59. switch dataPoint.ValueType() {
  60. case pmetric.NumberDataPointValueTypeInt:
  61. sv.SingleValue.Value = float64(dataPoint.IntValue())
  62. case pmetric.NumberDataPointValueTypeDouble:
  63. sv.SingleValue.Value = dataPoint.DoubleValue()
  64. }
  65. meterData.Metric = sv
  66. metrics = append(metrics, meterData)
  67. }
  68. return metrics
  69. }
  70. func doubleHistogramMetricsToData(name string, data pmetric.HistogramDataPointSlice, defaultLabels []*metricpb.Label) (metrics []*metricpb.MeterData) {
  71. metrics = make([]*metricpb.MeterData, 0, 3*data.Len())
  72. for i := 0; i < data.Len(); i++ {
  73. dataPoint := data.At(i)
  74. attributeMap := dataPoint.Attributes()
  75. labels := make([]*metricpb.Label, 0, attributeMap.Len()+len(defaultLabels))
  76. attributeMap.Range(func(k string, v pcommon.Value) bool {
  77. labels = append(labels, &metricpb.Label{Name: k, Value: v.AsString()})
  78. return true
  79. })
  80. for _, label := range defaultLabels {
  81. labels = append(labels, &metricpb.Label{Name: label.Name, Value: label.Value})
  82. }
  83. meterData := &metricpb.MeterData{}
  84. hg := &metricpb.MeterData_Histogram{Histogram: &metricpb.MeterHistogram{}}
  85. hg.Histogram.Labels = labels
  86. hg.Histogram.Name = name
  87. bounds := dataPoint.ExplicitBounds()
  88. bucketCount := dataPoint.BucketCounts().Len()
  89. if bucketCount > 0 {
  90. hg.Histogram.Values = append(hg.Histogram.Values,
  91. &metricpb.MeterBucketValue{Count: int64(dataPoint.BucketCounts().At(0)), IsNegativeInfinity: true})
  92. }
  93. for i := 1; i < bucketCount && i-1 < bounds.Len(); i++ {
  94. hg.Histogram.Values = append(hg.Histogram.Values, &metricpb.MeterBucketValue{Bucket: bounds.At(i - 1),
  95. Count: int64(dataPoint.BucketCounts().At(i))})
  96. }
  97. meterData.Metric = hg
  98. meterData.Timestamp = dataPoint.Timestamp().AsTime().UnixMilli()
  99. metrics = append(metrics, meterData)
  100. meterDataSum := &metricpb.MeterData{}
  101. svs := &metricpb.MeterData_SingleValue{SingleValue: &metricpb.MeterSingleValue{}}
  102. svs.SingleValue.Labels = labels
  103. svs.SingleValue.Name = name + "_sum"
  104. svs.SingleValue.Value = dataPoint.Sum()
  105. meterDataSum.Metric = svs
  106. meterDataSum.Timestamp = dataPoint.Timestamp().AsTime().UnixMilli()
  107. metrics = append(metrics, meterDataSum)
  108. meterDataCount := &metricpb.MeterData{}
  109. svc := &metricpb.MeterData_SingleValue{SingleValue: &metricpb.MeterSingleValue{}}
  110. svc.SingleValue.Labels = labels
  111. meterDataCount.Timestamp = dataPoint.Timestamp().AsTime().UnixMilli()
  112. svc.SingleValue.Name = name + "_count"
  113. svc.SingleValue.Value = float64(dataPoint.Count())
  114. meterDataCount.Metric = svc
  115. metrics = append(metrics, meterDataCount)
  116. }
  117. return metrics
  118. }
  119. func doubleSummaryMetricsToData(name string, data pmetric.SummaryDataPointSlice, defaultLabels []*metricpb.Label) (metrics []*metricpb.MeterData) {
  120. metrics = make([]*metricpb.MeterData, 0, 3*data.Len())
  121. for i := 0; i < data.Len(); i++ {
  122. dataPoint := data.At(i)
  123. attributeMap := dataPoint.Attributes()
  124. labels := make([]*metricpb.Label, 0, attributeMap.Len()+len(defaultLabels))
  125. attributeMap.Range(func(k string, v pcommon.Value) bool {
  126. labels = append(labels, &metricpb.Label{Name: k, Value: v.AsString()})
  127. return true
  128. })
  129. for _, label := range defaultLabels {
  130. labels = append(labels, &metricpb.Label{Name: label.Name, Value: label.Value})
  131. }
  132. values := dataPoint.QuantileValues()
  133. for i := 0; i < values.Len(); i++ {
  134. value := values.At(i)
  135. meterData := &metricpb.MeterData{}
  136. sv := &metricpb.MeterData_SingleValue{SingleValue: &metricpb.MeterSingleValue{}}
  137. svLabels := make([]*metricpb.Label, 0, len(labels)+1)
  138. svLabels = append(svLabels, labels...)
  139. svLabels = append(svLabels, &metricpb.Label{Name: "quantile", Value: strconv.FormatFloat(value.Quantile(), 'g', -1, 64)})
  140. sv.SingleValue.Labels = svLabels
  141. meterData.Timestamp = dataPoint.Timestamp().AsTime().UnixMilli()
  142. sv.SingleValue.Name = name
  143. sv.SingleValue.Value = value.Value()
  144. meterData.Metric = sv
  145. metrics = append(metrics, meterData)
  146. }
  147. meterDataSum := &metricpb.MeterData{}
  148. svs := &metricpb.MeterData_SingleValue{SingleValue: &metricpb.MeterSingleValue{}}
  149. svs.SingleValue.Labels = labels
  150. svs.SingleValue.Name = name + "_sum"
  151. svs.SingleValue.Value = dataPoint.Sum()
  152. meterDataSum.Metric = svs
  153. meterDataSum.Timestamp = dataPoint.Timestamp().AsTime().UnixMilli()
  154. metrics = append(metrics, meterDataSum)
  155. meterDataCount := &metricpb.MeterData{}
  156. svc := &metricpb.MeterData_SingleValue{SingleValue: &metricpb.MeterSingleValue{}}
  157. svc.SingleValue.Labels = labels
  158. meterDataCount.Timestamp = dataPoint.Timestamp().AsTime().UnixMilli()
  159. svc.SingleValue.Name = name + "_count"
  160. svc.SingleValue.Value = float64(dataPoint.Count())
  161. meterDataCount.Metric = svc
  162. metrics = append(metrics, meterDataCount)
  163. }
  164. return metrics
  165. }
  166. func metricDataToSwMetricData(md pmetric.Metric, defaultLabels []*metricpb.Label) (metrics []*metricpb.MeterData) {
  167. //exhaustive:enforce
  168. switch md.Type() {
  169. case pmetric.MetricTypeEmpty:
  170. break
  171. case pmetric.MetricTypeGauge:
  172. return numberMetricsToData(md.Name(), md.Gauge().DataPoints(), defaultLabels)
  173. case pmetric.MetricTypeSum:
  174. return numberMetricsToData(md.Name(), md.Sum().DataPoints(), defaultLabels)
  175. case pmetric.MetricTypeHistogram:
  176. return doubleHistogramMetricsToData(md.Name(), md.Histogram().DataPoints(), defaultLabels)
  177. case pmetric.MetricTypeSummary:
  178. return doubleSummaryMetricsToData(md.Name(), md.Summary().DataPoints(), defaultLabels)
  179. case pmetric.MetricTypeExponentialHistogram:
  180. return nil
  181. }
  182. return nil
  183. }
  184. func metricsRecordToMetricData(
  185. md pmetric.Metrics,
  186. ) (metrics *metricpb.MeterDataCollection) {
  187. resMetrics := md.ResourceMetrics()
  188. for i := 0; i < resMetrics.Len(); i++ {
  189. resMetricSlice := resMetrics.At(i)
  190. labels := resourceToMetricLabels(resMetricSlice.Resource())
  191. service, serviceInstance := resourceToServiceInfo(resMetricSlice.Resource())
  192. insMetricSlice := resMetricSlice.ScopeMetrics()
  193. metrics = &metricpb.MeterDataCollection{}
  194. for j := 0; j < insMetricSlice.Len(); j++ {
  195. insMetrics := insMetricSlice.At(j)
  196. // ignore insMetrics.Scope()
  197. metricSlice := insMetrics.Metrics()
  198. for k := 0; k < metricSlice.Len(); k++ {
  199. oneMetric := metricSlice.At(k)
  200. ms := metricDataToSwMetricData(oneMetric, labels)
  201. if ms == nil {
  202. continue
  203. }
  204. for _, m := range ms {
  205. m.Service = service
  206. m.ServiceInstance = serviceInstance
  207. }
  208. metrics.MeterData = append(metrics.MeterData, ms...)
  209. }
  210. }
  211. }
  212. return metrics
  213. }