prom_to_otlp_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package internal
  4. import (
  5. "testing"
  6. "github.com/prometheus/prometheus/model/labels"
  7. "github.com/stretchr/testify/require"
  8. "go.opentelemetry.io/collector/pdata/pcommon"
  9. conventions "go.opentelemetry.io/collector/semconv/v1.6.1"
  10. )
  11. type jobInstanceDefinition struct {
  12. job, instance, host, scheme, port string
  13. }
  14. type k8sResourceDefinition struct {
  15. podName, podUID, container, node, rs, ds, ss, job, cronjob, ns string
  16. }
  17. func makeK8sResource(jobInstance *jobInstanceDefinition, def *k8sResourceDefinition) pcommon.Resource {
  18. resource := makeResourceWithJobInstanceScheme(jobInstance, true)
  19. attrs := resource.Attributes()
  20. if def.podName != "" {
  21. attrs.PutStr(conventions.AttributeK8SPodName, def.podName)
  22. }
  23. if def.podUID != "" {
  24. attrs.PutStr(conventions.AttributeK8SPodUID, def.podUID)
  25. }
  26. if def.container != "" {
  27. attrs.PutStr(conventions.AttributeK8SContainerName, def.container)
  28. }
  29. if def.node != "" {
  30. attrs.PutStr(conventions.AttributeK8SNodeName, def.node)
  31. }
  32. if def.rs != "" {
  33. attrs.PutStr(conventions.AttributeK8SReplicaSetName, def.rs)
  34. }
  35. if def.ds != "" {
  36. attrs.PutStr(conventions.AttributeK8SDaemonSetName, def.ds)
  37. }
  38. if def.ss != "" {
  39. attrs.PutStr(conventions.AttributeK8SStatefulSetName, def.ss)
  40. }
  41. if def.job != "" {
  42. attrs.PutStr(conventions.AttributeK8SJobName, def.job)
  43. }
  44. if def.cronjob != "" {
  45. attrs.PutStr(conventions.AttributeK8SCronJobName, def.cronjob)
  46. }
  47. if def.ns != "" {
  48. attrs.PutStr(conventions.AttributeK8SNamespaceName, def.ns)
  49. }
  50. return resource
  51. }
  52. func makeResourceWithJobInstanceScheme(def *jobInstanceDefinition, hasHost bool) pcommon.Resource {
  53. resource := pcommon.NewResource()
  54. attrs := resource.Attributes()
  55. // Using hardcoded values to assert on outward expectations so that
  56. // when variables change, these tests will fail and we'll have reports.
  57. attrs.PutStr("service.name", def.job)
  58. if hasHost {
  59. attrs.PutStr("net.host.name", def.host)
  60. }
  61. attrs.PutStr("service.instance.id", def.instance)
  62. attrs.PutStr("net.host.port", def.port)
  63. attrs.PutStr("http.scheme", def.scheme)
  64. return resource
  65. }
  66. func TestCreateNodeAndResourcePromToOTLP(t *testing.T) {
  67. tests := []struct {
  68. name, job string
  69. instance string
  70. sdLabels labels.Labels
  71. want pcommon.Resource
  72. }{
  73. {
  74. name: "all attributes proper",
  75. job: "job", instance: "hostname:8888", sdLabels: labels.New(labels.Label{Name: "__scheme__", Value: "http"}),
  76. want: makeResourceWithJobInstanceScheme(&jobInstanceDefinition{
  77. "job", "hostname:8888", "hostname", "http", "8888",
  78. }, true),
  79. },
  80. {
  81. name: "missing port",
  82. job: "job", instance: "myinstance", sdLabels: labels.New(labels.Label{Name: "__scheme__", Value: "https"}),
  83. want: makeResourceWithJobInstanceScheme(&jobInstanceDefinition{
  84. "job", "myinstance", "myinstance", "https", "",
  85. }, true),
  86. },
  87. {
  88. name: "blank scheme",
  89. job: "job", instance: "myinstance:443", sdLabels: labels.New(labels.Label{Name: "__scheme__", Value: ""}),
  90. want: makeResourceWithJobInstanceScheme(&jobInstanceDefinition{
  91. "job", "myinstance:443", "myinstance", "", "443",
  92. }, true),
  93. },
  94. {
  95. name: "blank instance, blank scheme",
  96. job: "job", instance: "", sdLabels: labels.New(labels.Label{Name: "__scheme__", Value: ""}),
  97. want: makeResourceWithJobInstanceScheme(&jobInstanceDefinition{
  98. "job", "", "", "", "",
  99. }, true),
  100. },
  101. {
  102. name: "blank instance, non-blank scheme",
  103. job: "job", instance: "", sdLabels: labels.New(labels.Label{Name: "__scheme__", Value: "http"}),
  104. want: makeResourceWithJobInstanceScheme(&jobInstanceDefinition{
  105. "job", "", "", "http", "",
  106. }, true),
  107. },
  108. {
  109. name: "0.0.0.0 address",
  110. job: "job", instance: "0.0.0.0:8888", sdLabels: labels.New(labels.Label{Name: "__scheme__", Value: "http"}),
  111. want: makeResourceWithJobInstanceScheme(&jobInstanceDefinition{
  112. "job", "0.0.0.0:8888", "", "http", "8888",
  113. }, false),
  114. },
  115. {
  116. name: "localhost",
  117. job: "job", instance: "localhost:8888", sdLabels: labels.New(labels.Label{Name: "__scheme__", Value: "http"}),
  118. want: makeResourceWithJobInstanceScheme(&jobInstanceDefinition{
  119. "job", "localhost:8888", "", "http", "8888",
  120. }, false),
  121. },
  122. {
  123. name: "kubernetes daemonset pod",
  124. job: "job", instance: "hostname:8888", sdLabels: labels.New(
  125. labels.Label{Name: "__scheme__", Value: "http"},
  126. labels.Label{Name: "__meta_kubernetes_pod_name", Value: "my-pod-23491"},
  127. labels.Label{Name: "__meta_kubernetes_pod_uid", Value: "84279wretgu89dg489q2"},
  128. labels.Label{Name: "__meta_kubernetes_pod_container_name", Value: "my-container"},
  129. labels.Label{Name: "__meta_kubernetes_pod_node_name", Value: "k8s-node-123"},
  130. labels.Label{Name: "__meta_kubernetes_pod_controller_name", Value: "my-pod"},
  131. labels.Label{Name: "__meta_kubernetes_pod_controller_kind", Value: "DaemonSet"},
  132. labels.Label{Name: "__meta_kubernetes_namespace", Value: "kube-system"},
  133. ),
  134. want: makeK8sResource(&jobInstanceDefinition{
  135. "job", "hostname:8888", "hostname", "http", "8888",
  136. }, &k8sResourceDefinition{
  137. podName: "my-pod-23491",
  138. podUID: "84279wretgu89dg489q2",
  139. container: "my-container",
  140. node: "k8s-node-123",
  141. ds: "my-pod",
  142. ns: "kube-system",
  143. }),
  144. },
  145. {
  146. name: "kubernetes replicaset pod",
  147. job: "job", instance: "hostname:8888", sdLabels: labels.New(
  148. labels.Label{Name: "__scheme__", Value: "http"},
  149. labels.Label{Name: "__meta_kubernetes_pod_name", Value: "my-pod-23491"},
  150. labels.Label{Name: "__meta_kubernetes_pod_uid", Value: "84279wretgu89dg489q2"},
  151. labels.Label{Name: "__meta_kubernetes_pod_container_name", Value: "my-container"},
  152. labels.Label{Name: "__meta_kubernetes_pod_node_name", Value: "k8s-node-123"},
  153. labels.Label{Name: "__meta_kubernetes_pod_controller_name", Value: "my-pod"},
  154. labels.Label{Name: "__meta_kubernetes_pod_controller_kind", Value: "ReplicaSet"},
  155. labels.Label{Name: "__meta_kubernetes_namespace", Value: "kube-system"},
  156. ),
  157. want: makeK8sResource(&jobInstanceDefinition{
  158. "job", "hostname:8888", "hostname", "http", "8888",
  159. }, &k8sResourceDefinition{
  160. podName: "my-pod-23491",
  161. podUID: "84279wretgu89dg489q2",
  162. container: "my-container",
  163. node: "k8s-node-123",
  164. rs: "my-pod",
  165. ns: "kube-system",
  166. }),
  167. },
  168. {
  169. name: "kubernetes statefulset pod",
  170. job: "job", instance: "hostname:8888", sdLabels: labels.New(
  171. labels.Label{Name: "__scheme__", Value: "http"},
  172. labels.Label{Name: "__meta_kubernetes_pod_name", Value: "my-pod-23491"},
  173. labels.Label{Name: "__meta_kubernetes_pod_uid", Value: "84279wretgu89dg489q2"},
  174. labels.Label{Name: "__meta_kubernetes_pod_container_name", Value: "my-container"},
  175. labels.Label{Name: "__meta_kubernetes_pod_node_name", Value: "k8s-node-123"},
  176. labels.Label{Name: "__meta_kubernetes_pod_controller_name", Value: "my-pod"},
  177. labels.Label{Name: "__meta_kubernetes_pod_controller_kind", Value: "StatefulSet"},
  178. labels.Label{Name: "__meta_kubernetes_namespace", Value: "kube-system"},
  179. ),
  180. want: makeK8sResource(&jobInstanceDefinition{
  181. "job", "hostname:8888", "hostname", "http", "8888",
  182. }, &k8sResourceDefinition{
  183. podName: "my-pod-23491",
  184. podUID: "84279wretgu89dg489q2",
  185. container: "my-container",
  186. node: "k8s-node-123",
  187. ss: "my-pod",
  188. ns: "kube-system",
  189. }),
  190. },
  191. {
  192. name: "kubernetes job pod",
  193. job: "job", instance: "hostname:8888", sdLabels: labels.New(
  194. labels.Label{Name: "__scheme__", Value: "http"},
  195. labels.Label{Name: "__meta_kubernetes_pod_name", Value: "my-pod-23491"},
  196. labels.Label{Name: "__meta_kubernetes_pod_uid", Value: "84279wretgu89dg489q2"},
  197. labels.Label{Name: "__meta_kubernetes_pod_container_name", Value: "my-container"},
  198. labels.Label{Name: "__meta_kubernetes_pod_node_name", Value: "k8s-node-123"},
  199. labels.Label{Name: "__meta_kubernetes_pod_controller_name", Value: "my-pod"},
  200. labels.Label{Name: "__meta_kubernetes_pod_controller_kind", Value: "Job"},
  201. labels.Label{Name: "__meta_kubernetes_namespace", Value: "kube-system"},
  202. ),
  203. want: makeK8sResource(&jobInstanceDefinition{
  204. "job", "hostname:8888", "hostname", "http", "8888",
  205. }, &k8sResourceDefinition{
  206. podName: "my-pod-23491",
  207. podUID: "84279wretgu89dg489q2",
  208. container: "my-container",
  209. node: "k8s-node-123",
  210. job: "my-pod",
  211. ns: "kube-system",
  212. }),
  213. },
  214. {
  215. name: "kubernetes cronjob pod",
  216. job: "job", instance: "hostname:8888", sdLabels: labels.New(
  217. labels.Label{Name: "__scheme__", Value: "http"},
  218. labels.Label{Name: "__meta_kubernetes_pod_name", Value: "my-pod-23491"},
  219. labels.Label{Name: "__meta_kubernetes_pod_uid", Value: "84279wretgu89dg489q2"},
  220. labels.Label{Name: "__meta_kubernetes_pod_container_name", Value: "my-container"},
  221. labels.Label{Name: "__meta_kubernetes_pod_node_name", Value: "k8s-node-123"},
  222. labels.Label{Name: "__meta_kubernetes_pod_controller_name", Value: "my-pod"},
  223. labels.Label{Name: "__meta_kubernetes_pod_controller_kind", Value: "CronJob"},
  224. labels.Label{Name: "__meta_kubernetes_namespace", Value: "kube-system"},
  225. ),
  226. want: makeK8sResource(&jobInstanceDefinition{
  227. "job", "hostname:8888", "hostname", "http", "8888",
  228. }, &k8sResourceDefinition{
  229. podName: "my-pod-23491",
  230. podUID: "84279wretgu89dg489q2",
  231. container: "my-container",
  232. node: "k8s-node-123",
  233. cronjob: "my-pod",
  234. ns: "kube-system",
  235. }),
  236. },
  237. {
  238. name: "kubernetes node (e.g. kubelet)",
  239. job: "job", instance: "hostname:8888", sdLabels: labels.New(
  240. labels.Label{Name: "__scheme__", Value: "http"},
  241. labels.Label{Name: "__meta_kubernetes_node_name", Value: "k8s-node-123"},
  242. ),
  243. want: makeK8sResource(&jobInstanceDefinition{
  244. "job", "hostname:8888", "hostname", "http", "8888",
  245. }, &k8sResourceDefinition{
  246. node: "k8s-node-123",
  247. }),
  248. },
  249. {
  250. name: "kubernetes service endpoint",
  251. job: "job", instance: "hostname:8888", sdLabels: labels.New(
  252. labels.Label{Name: "__scheme__", Value: "http"},
  253. labels.Label{Name: "__meta_kubernetes_endpoint_node_name", Value: "k8s-node-123"},
  254. ),
  255. want: makeK8sResource(&jobInstanceDefinition{
  256. "job", "hostname:8888", "hostname", "http", "8888",
  257. }, &k8sResourceDefinition{
  258. node: "k8s-node-123",
  259. }),
  260. },
  261. }
  262. for _, tt := range tests {
  263. tt := tt
  264. t.Run(tt.name, func(t *testing.T) {
  265. got := CreateResource(tt.job, tt.instance, tt.sdLabels)
  266. require.Equal(t, tt.want.Attributes().AsRaw(), got.Attributes().AsRaw())
  267. })
  268. }
  269. }