sampler_bench_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. // Copyright (c) 2016 Uber Technologies, Inc.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. package zapcore_test
  21. import (
  22. "fmt"
  23. "testing"
  24. "time"
  25. "github.com/stretchr/testify/assert"
  26. "go.uber.org/atomic"
  27. "go.uber.org/zap/internal/ztest"
  28. . "go.uber.org/zap/zapcore"
  29. )
  30. var counterTestCases = [][]string{
  31. // some stuff I made up
  32. {
  33. "foo",
  34. "bar",
  35. "baz",
  36. "alpha",
  37. "bravo",
  38. "charlie",
  39. "delta",
  40. },
  41. // shuf -n50 /usr/share/dict/words
  42. {
  43. "unbracing",
  44. "stereotomy",
  45. "supranervian",
  46. "moaning",
  47. "exchangeability",
  48. "gunyang",
  49. "sulcation",
  50. "dariole",
  51. "archheresy",
  52. "synchronistically",
  53. "clips",
  54. "unsanctioned",
  55. "Argoan",
  56. "liparomphalus",
  57. "layship",
  58. "Fregatae",
  59. "microzoology",
  60. "glaciaria",
  61. "Frugivora",
  62. "patterist",
  63. "Grossulariaceae",
  64. "lithotint",
  65. "bargander",
  66. "opisthographical",
  67. "cacography",
  68. "chalkstone",
  69. "nonsubstantialism",
  70. "sardonicism",
  71. "calamiform",
  72. "lodginghouse",
  73. "predisposedly",
  74. "topotypic",
  75. "broideress",
  76. "outrange",
  77. "gingivolabial",
  78. "monoazo",
  79. "sparlike",
  80. "concameration",
  81. "untoothed",
  82. "Camorrism",
  83. "reissuer",
  84. "soap",
  85. "palaiotype",
  86. "countercharm",
  87. "yellowbird",
  88. "palterly",
  89. "writinger",
  90. "boatfalls",
  91. "tuglike",
  92. "underbitten",
  93. },
  94. // shuf -n100 /usr/share/dict/words
  95. {
  96. "rooty",
  97. "malcultivation",
  98. "degrade",
  99. "pseudoindependent",
  100. "stillatory",
  101. "antiseptize",
  102. "protoamphibian",
  103. "antiar",
  104. "Esther",
  105. "pseudelminth",
  106. "superfluitance",
  107. "teallite",
  108. "disunity",
  109. "spirignathous",
  110. "vergency",
  111. "myliobatid",
  112. "inosic",
  113. "overabstemious",
  114. "patriarchally",
  115. "foreimagine",
  116. "coetaneity",
  117. "hemimellitene",
  118. "hyperspatial",
  119. "aulophyte",
  120. "electropoion",
  121. "antitrope",
  122. "Amarantus",
  123. "smaltine",
  124. "lighthead",
  125. "syntonically",
  126. "incubous",
  127. "versation",
  128. "cirsophthalmia",
  129. "Ulidian",
  130. "homoeography",
  131. "Velella",
  132. "Hecatean",
  133. "serfage",
  134. "Spermaphyta",
  135. "palatoplasty",
  136. "electroextraction",
  137. "aconite",
  138. "avirulence",
  139. "initiator",
  140. "besmear",
  141. "unrecognizably",
  142. "euphoniousness",
  143. "balbuties",
  144. "pascuage",
  145. "quebracho",
  146. "Yakala",
  147. "auriform",
  148. "sevenbark",
  149. "superorganism",
  150. "telesterion",
  151. "ensand",
  152. "nagaika",
  153. "anisuria",
  154. "etching",
  155. "soundingly",
  156. "grumpish",
  157. "drillmaster",
  158. "perfumed",
  159. "dealkylate",
  160. "anthracitiferous",
  161. "predefiance",
  162. "sulphoxylate",
  163. "freeness",
  164. "untucking",
  165. "misworshiper",
  166. "Nestorianize",
  167. "nonegoistical",
  168. "construe",
  169. "upstroke",
  170. "teated",
  171. "nasolachrymal",
  172. "Mastodontidae",
  173. "gallows",
  174. "radioluminescent",
  175. "uncourtierlike",
  176. "phasmatrope",
  177. "Clunisian",
  178. "drainage",
  179. "sootless",
  180. "brachyfacial",
  181. "antiheroism",
  182. "irreligionize",
  183. "ked",
  184. "unfact",
  185. "nonprofessed",
  186. "milady",
  187. "conjecture",
  188. "Arctomys",
  189. "guapilla",
  190. "Sassenach",
  191. "emmetrope",
  192. "rosewort",
  193. "raphidiferous",
  194. "pooh",
  195. "Tyndallize",
  196. },
  197. }
  198. func BenchmarkSampler_Check(b *testing.B) {
  199. for _, keys := range counterTestCases {
  200. b.Run(fmt.Sprintf("%v keys", len(keys)), func(b *testing.B) {
  201. fac := NewSamplerWithOptions(
  202. NewCore(
  203. NewJSONEncoder(testEncoderConfig()),
  204. &ztest.Discarder{},
  205. DebugLevel,
  206. ),
  207. time.Millisecond, 1, 1000)
  208. b.ResetTimer()
  209. b.RunParallel(func(pb *testing.PB) {
  210. i := 0
  211. for pb.Next() {
  212. ent := Entry{
  213. Level: DebugLevel + Level(i%4),
  214. Message: keys[i],
  215. }
  216. _ = fac.Check(ent, nil)
  217. i++
  218. if n := len(keys); i >= n {
  219. i -= n
  220. }
  221. }
  222. })
  223. })
  224. }
  225. }
  226. func makeSamplerCountingHook() (func(_ Entry, dec SamplingDecision), *atomic.Int64, *atomic.Int64) {
  227. droppedCount := new(atomic.Int64)
  228. sampledCount := new(atomic.Int64)
  229. h := func(_ Entry, dec SamplingDecision) {
  230. if dec&LogDropped > 0 {
  231. droppedCount.Inc()
  232. } else if dec&LogSampled > 0 {
  233. sampledCount.Inc()
  234. }
  235. }
  236. return h, droppedCount, sampledCount
  237. }
  238. func BenchmarkSampler_CheckWithHook(b *testing.B) {
  239. hook, dropped, sampled := makeSamplerCountingHook()
  240. for _, keys := range counterTestCases {
  241. b.Run(fmt.Sprintf("%v keys", len(keys)), func(b *testing.B) {
  242. fac := NewSamplerWithOptions(
  243. NewCore(
  244. NewJSONEncoder(testEncoderConfig()),
  245. &ztest.Discarder{},
  246. DebugLevel,
  247. ),
  248. time.Millisecond,
  249. 1,
  250. 1000,
  251. SamplerHook(hook),
  252. )
  253. b.ResetTimer()
  254. b.RunParallel(func(pb *testing.PB) {
  255. i := 0
  256. for pb.Next() {
  257. ent := Entry{
  258. Level: DebugLevel + Level(i%4),
  259. Message: keys[i],
  260. }
  261. _ = fac.Check(ent, nil)
  262. i++
  263. if n := len(keys); i >= n {
  264. i -= n
  265. }
  266. }
  267. })
  268. })
  269. }
  270. // We expect to see 1000 dropped messages for every sampled per settings,
  271. // with a delta due to less 1000 messages getting dropped after initial one
  272. // is sampled.
  273. assert.Greater(b, dropped.Load()/1000, sampled.Load()-1000)
  274. }