156 lines
3.6 KiB
Go
156 lines
3.6 KiB
Go
|
// Licensed to Elasticsearch B.V. under one or more contributor
|
||
|
// license agreements. See the NOTICE file distributed with
|
||
|
// this work for additional information regarding copyright
|
||
|
// ownership. Elasticsearch B.V. licenses this file to you under
|
||
|
// the Apache License, Version 2.0 (the "License"); you may
|
||
|
// not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing,
|
||
|
// software distributed under the License is distributed on an
|
||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
// KIND, either express or implied. See the License for the
|
||
|
// specific language governing permissions and limitations
|
||
|
// under the License.
|
||
|
|
||
|
// +build windows
|
||
|
|
||
|
package eventlog
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"flag"
|
||
|
"math/rand"
|
||
|
"os/exec"
|
||
|
"strconv"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
elog "github.com/andrewkroh/sys/windows/svc/eventlog"
|
||
|
"github.com/dustin/go-humanize"
|
||
|
)
|
||
|
|
||
|
// Benchmark tests with customized output. (`go test -v -benchtime 10s -benchtest .`)
|
||
|
|
||
|
var (
|
||
|
benchTest = flag.Bool("benchtest", false, "Run benchmarks for the eventlog package")
|
||
|
injectAmount = flag.Int("inject", 50000, "Number of events to inject before running benchmarks")
|
||
|
)
|
||
|
|
||
|
// TestBenchmarkBatchReadSize tests the performance of different
|
||
|
// batch_read_size values.
|
||
|
func TestBenchmarkBatchReadSize(t *testing.T) {
|
||
|
if !*benchTest {
|
||
|
t.Skip("-benchtest not enabled")
|
||
|
}
|
||
|
|
||
|
log, err := initLog(providerName, sourceName, eventCreateMsgFile)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer func() {
|
||
|
err := uninstallLog(providerName, sourceName, log)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
// Increase the log size so that it can hold these large events.
|
||
|
output, err := exec.Command("wevtutil.exe", "sl", "/ms:1073741824", providerName).CombinedOutput()
|
||
|
if err != nil {
|
||
|
t.Fatal(err, string(output))
|
||
|
}
|
||
|
|
||
|
// Publish test messages:
|
||
|
for i := 0; i < *injectAmount; i++ {
|
||
|
err = log.Report(elog.Info, uint32(rand.Int63()%1000), []string{strconv.Itoa(i) + " " + randomSentence(256)})
|
||
|
if err != nil {
|
||
|
t.Fatal("ReportEvent error", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
benchTest := func(batchSize int) {
|
||
|
var err error
|
||
|
result := testing.Benchmark(func(b *testing.B) {
|
||
|
eventlog, tearDown := setupWinEventLog(t, 0, map[string]interface{}{
|
||
|
"name": providerName,
|
||
|
"batch_read_size": batchSize,
|
||
|
})
|
||
|
defer tearDown()
|
||
|
b.ResetTimer()
|
||
|
|
||
|
// Each iteration reads one batch.
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
_, err = eventlog.Read()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
t.Logf("batch_size=%v, total_events=%v, batch_time=%v, events_per_sec=%v, bytes_alloced_per_event=%v, total_allocs=%v",
|
||
|
batchSize,
|
||
|
result.N*batchSize,
|
||
|
time.Duration(result.NsPerOp()),
|
||
|
float64(batchSize)/time.Duration(result.NsPerOp()).Seconds(),
|
||
|
humanize.Bytes(result.MemBytes/(uint64(result.N)*uint64(batchSize))),
|
||
|
result.MemAllocs)
|
||
|
}
|
||
|
|
||
|
benchTest(10)
|
||
|
benchTest(100)
|
||
|
benchTest(500)
|
||
|
benchTest(1000)
|
||
|
}
|
||
|
|
||
|
// Utility Functions
|
||
|
|
||
|
var randomWords = []string{
|
||
|
"recover",
|
||
|
"article",
|
||
|
"highway",
|
||
|
"bargain",
|
||
|
"trolley",
|
||
|
"college",
|
||
|
"attract",
|
||
|
"wriggle",
|
||
|
"feather",
|
||
|
"neutral",
|
||
|
"percent",
|
||
|
"quality",
|
||
|
"manager",
|
||
|
"hunting",
|
||
|
"arrange",
|
||
|
}
|
||
|
|
||
|
func randomSentence(n uint) string {
|
||
|
buf := bytes.NewBuffer(make([]byte, n))
|
||
|
buf.Reset()
|
||
|
|
||
|
for {
|
||
|
idx := rand.Uint32() % uint32(len(randomWords))
|
||
|
word := randomWords[idx]
|
||
|
|
||
|
if buf.Len()+len(word) <= buf.Cap() {
|
||
|
buf.WriteString(randomWords[idx])
|
||
|
} else {
|
||
|
break
|
||
|
}
|
||
|
|
||
|
if buf.Len()+1 <= buf.Cap() {
|
||
|
buf.WriteByte(' ')
|
||
|
} else {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return buf.String()
|
||
|
}
|