opentsdb_test.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /*
  2. Copyright 2019 The Vitess Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package opentsdb
  14. import (
  15. "encoding/json"
  16. "expvar"
  17. "reflect"
  18. "sort"
  19. "testing"
  20. "time"
  21. "git.nspix.com/golang/micro/stats"
  22. )
  23. func TestOpenTsdbCounter(t *testing.T) {
  24. name := "counter_name"
  25. c := stats.NewCounter(name, "counter description")
  26. c.Add(1)
  27. checkOutput(t, name, `
  28. [
  29. {
  30. "metric": "vtgate.counter_name",
  31. "timestamp": 1234,
  32. "value": 1,
  33. "tags": {
  34. "host": "localhost"
  35. }
  36. }
  37. ]`)
  38. }
  39. func TestOpenTsdbCounterFunc(t *testing.T) {
  40. name := "counter_fn_name"
  41. stats.NewCounterFunc(name, "help", func() int64 {
  42. return 2
  43. })
  44. checkOutput(t, name, `
  45. [
  46. {
  47. "metric": "vtgate.counter_fn_name",
  48. "timestamp": 1234,
  49. "value": 2,
  50. "tags": {
  51. "host": "localhost"
  52. }
  53. }
  54. ]`)
  55. }
  56. func TestGaugesWithMultiLabels(t *testing.T) {
  57. name := "gauges_with_multi_labels_name"
  58. gauges := stats.NewGaugesWithMultiLabels(name, "help", []string{"flavor", "texture"})
  59. gauges.Add([]string{"sour", "brittle"}, 3)
  60. checkOutput(t, name, `
  61. [
  62. {
  63. "metric": "vtgate.gauges_with_multi_labels_name",
  64. "timestamp": 1234,
  65. "value": 3,
  66. "tags": {
  67. "flavor": "sour",
  68. "host": "localhost",
  69. "texture": "brittle"
  70. }
  71. }
  72. ]`)
  73. }
  74. type myVar bool
  75. func (mv *myVar) String() string {
  76. return `{"myKey": 1.2}`
  77. }
  78. func TestExpvar(t *testing.T) {
  79. name := "blah_expvar"
  80. expvar.Publish(name, new(myVar))
  81. checkOutput(t, name, `
  82. [
  83. {
  84. "metric": "vtgate.expvar.blah_expvar.mykey",
  85. "timestamp": 1234,
  86. "value": 1.2,
  87. "tags": {
  88. "host": "localhost"
  89. }
  90. }
  91. ]`)
  92. }
  93. func TestOpenTsdbTimings(t *testing.T) {
  94. name := "blah_timings"
  95. cats := []string{"cat1", "cat2"}
  96. timing := stats.NewTimings(name, "help", "category", cats...)
  97. timing.Add("cat1", time.Duration(1000000000))
  98. timing.Add("cat1", time.Duration(1))
  99. checkOutput(t, name, `
  100. [
  101. {
  102. "metric": "vtgate.blah_timings.1000000",
  103. "timestamp": 1234,
  104. "value": 0,
  105. "tags": {
  106. "category": "cat1",
  107. "host": "localhost"
  108. }
  109. },
  110. {
  111. "metric": "vtgate.blah_timings.1000000",
  112. "timestamp": 1234,
  113. "value": 0,
  114. "tags": {
  115. "category": "cat2",
  116. "host": "localhost"
  117. }
  118. },
  119. {
  120. "metric": "vtgate.blah_timings.10000000",
  121. "timestamp": 1234,
  122. "value": 0,
  123. "tags": {
  124. "category": "cat1",
  125. "host": "localhost"
  126. }
  127. },
  128. {
  129. "metric": "vtgate.blah_timings.10000000",
  130. "timestamp": 1234,
  131. "value": 0,
  132. "tags": {
  133. "category": "cat2",
  134. "host": "localhost"
  135. }
  136. },
  137. {
  138. "metric": "vtgate.blah_timings.100000000",
  139. "timestamp": 1234,
  140. "value": 0,
  141. "tags": {
  142. "category": "cat1",
  143. "host": "localhost"
  144. }
  145. },
  146. {
  147. "metric": "vtgate.blah_timings.100000000",
  148. "timestamp": 1234,
  149. "value": 0,
  150. "tags": {
  151. "category": "cat2",
  152. "host": "localhost"
  153. }
  154. },
  155. {
  156. "metric": "vtgate.blah_timings.1000000000",
  157. "timestamp": 1234,
  158. "value": 1,
  159. "tags": {
  160. "category": "cat1",
  161. "host": "localhost"
  162. }
  163. },
  164. {
  165. "metric": "vtgate.blah_timings.1000000000",
  166. "timestamp": 1234,
  167. "value": 0,
  168. "tags": {
  169. "category": "cat2",
  170. "host": "localhost"
  171. }
  172. },
  173. {
  174. "metric": "vtgate.blah_timings.10000000000",
  175. "timestamp": 1234,
  176. "value": 0,
  177. "tags": {
  178. "category": "cat1",
  179. "host": "localhost"
  180. }
  181. },
  182. {
  183. "metric": "vtgate.blah_timings.10000000000",
  184. "timestamp": 1234,
  185. "value": 0,
  186. "tags": {
  187. "category": "cat2",
  188. "host": "localhost"
  189. }
  190. },
  191. {
  192. "metric": "vtgate.blah_timings.500000",
  193. "timestamp": 1234,
  194. "value": 1,
  195. "tags": {
  196. "category": "cat1",
  197. "host": "localhost"
  198. }
  199. },
  200. {
  201. "metric": "vtgate.blah_timings.500000",
  202. "timestamp": 1234,
  203. "value": 0,
  204. "tags": {
  205. "category": "cat2",
  206. "host": "localhost"
  207. }
  208. },
  209. {
  210. "metric": "vtgate.blah_timings.5000000",
  211. "timestamp": 1234,
  212. "value": 0,
  213. "tags": {
  214. "category": "cat1",
  215. "host": "localhost"
  216. }
  217. },
  218. {
  219. "metric": "vtgate.blah_timings.5000000",
  220. "timestamp": 1234,
  221. "value": 0,
  222. "tags": {
  223. "category": "cat2",
  224. "host": "localhost"
  225. }
  226. },
  227. {
  228. "metric": "vtgate.blah_timings.50000000",
  229. "timestamp": 1234,
  230. "value": 0,
  231. "tags": {
  232. "category": "cat1",
  233. "host": "localhost"
  234. }
  235. },
  236. {
  237. "metric": "vtgate.blah_timings.50000000",
  238. "timestamp": 1234,
  239. "value": 0,
  240. "tags": {
  241. "category": "cat2",
  242. "host": "localhost"
  243. }
  244. },
  245. {
  246. "metric": "vtgate.blah_timings.500000000",
  247. "timestamp": 1234,
  248. "value": 0,
  249. "tags": {
  250. "category": "cat1",
  251. "host": "localhost"
  252. }
  253. },
  254. {
  255. "metric": "vtgate.blah_timings.500000000",
  256. "timestamp": 1234,
  257. "value": 0,
  258. "tags": {
  259. "category": "cat2",
  260. "host": "localhost"
  261. }
  262. },
  263. {
  264. "metric": "vtgate.blah_timings.5000000000",
  265. "timestamp": 1234,
  266. "value": 0,
  267. "tags": {
  268. "category": "cat1",
  269. "host": "localhost"
  270. }
  271. },
  272. {
  273. "metric": "vtgate.blah_timings.5000000000",
  274. "timestamp": 1234,
  275. "value": 0,
  276. "tags": {
  277. "category": "cat2",
  278. "host": "localhost"
  279. }
  280. },
  281. {
  282. "metric": "vtgate.blah_timings.count",
  283. "timestamp": 1234,
  284. "value": 2,
  285. "tags": {
  286. "category": "cat1",
  287. "host": "localhost"
  288. }
  289. },
  290. {
  291. "metric": "vtgate.blah_timings.count",
  292. "timestamp": 1234,
  293. "value": 0,
  294. "tags": {
  295. "category": "cat2",
  296. "host": "localhost"
  297. }
  298. },
  299. {
  300. "metric": "vtgate.blah_timings.inf",
  301. "timestamp": 1234,
  302. "value": 0,
  303. "tags": {
  304. "category": "cat1",
  305. "host": "localhost"
  306. }
  307. },
  308. {
  309. "metric": "vtgate.blah_timings.inf",
  310. "timestamp": 1234,
  311. "value": 0,
  312. "tags": {
  313. "category": "cat2",
  314. "host": "localhost"
  315. }
  316. },
  317. {
  318. "metric": "vtgate.blah_timings.time",
  319. "timestamp": 1234,
  320. "value": 1000000001,
  321. "tags": {
  322. "category": "cat1",
  323. "host": "localhost"
  324. }
  325. },
  326. {
  327. "metric": "vtgate.blah_timings.time",
  328. "timestamp": 1234,
  329. "value": 0,
  330. "tags": {
  331. "category": "cat2",
  332. "host": "localhost"
  333. }
  334. }
  335. ]`)
  336. }
  337. func checkOutput(t *testing.T, statName string, wantJSON string) {
  338. backend := &openTSDBBackend{
  339. prefix: "vtgate",
  340. commonTags: map[string]string{"host": "localhost"},
  341. }
  342. timestamp := int64(1234)
  343. dc := &dataCollector{
  344. settings: backend,
  345. timestamp: timestamp,
  346. }
  347. found := false
  348. expvar.Do(func(kv expvar.KeyValue) {
  349. if kv.Key == statName {
  350. found = true
  351. dc.addExpVar(kv)
  352. sort.Sort(byMetric(dc.dataPoints))
  353. gotBytes, err := json.MarshalIndent(dc.dataPoints, "", " ")
  354. if err != nil {
  355. t.Errorf("Failed to marshal json: %v", err)
  356. return
  357. }
  358. var got interface{}
  359. err = json.Unmarshal(gotBytes, &got)
  360. if err != nil {
  361. t.Errorf("Failed to marshal json: %v", err)
  362. return
  363. }
  364. var want interface{}
  365. err = json.Unmarshal([]byte(wantJSON), &want)
  366. if err != nil {
  367. t.Errorf("Failed to marshal json: %v", err)
  368. return
  369. }
  370. if !reflect.DeepEqual(got, want) {
  371. t.Errorf("addExpVar(%#v) = %s, want %s", kv, string(gotBytes), wantJSON)
  372. }
  373. }
  374. })
  375. if !found {
  376. t.Errorf("Stat %s not found?...", statName)
  377. }
  378. }