chore: release 0.29.0.rc0 (#1600)

This commit is contained in:
Jan-Otto Kröpke
2024-09-11 00:34:10 +02:00
committed by GitHub
parent 83b0aa8f62
commit f712c07c38
119 changed files with 5113 additions and 2255 deletions

View File

@@ -31,11 +31,13 @@ type NameTable struct {
func (t *NameTable) LookupString(index uint32) string {
t.initialize()
return t.table.index[index]
}
func (t *NameTable) LookupIndex(str string) uint32 {
t.initialize()
return t.table.string[str]
}
@@ -56,7 +58,9 @@ func (t *NameTable) initialize() {
if err != nil {
panic(err)
}
r := bytes.NewReader(buffer)
for {
index, err := readUTF16String(r)
if err != nil {

View File

@@ -119,6 +119,8 @@ import (
"strings"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// TODO: There's a LittleEndian field in the PERF header - we ought to check it.
@@ -204,7 +206,7 @@ func queryRawData(query string) ([]byte, error) {
buffer = make([]byte, bufLen)
name, err := syscall.UTF16PtrFromString(query)
name, err := windows.UTF16PtrFromString(query)
if err != nil {
return nil, fmt.Errorf("failed to encode query string: %w", err)
}
@@ -212,21 +214,23 @@ func queryRawData(query string) ([]byte, error) {
for {
bufLen := uint32(len(buffer))
//nolint:forbidigo // Legacy Code
err := syscall.RegQueryValueEx(
syscall.HKEY_PERFORMANCE_DATA,
windows.HKEY_PERFORMANCE_DATA,
name,
nil,
&valType,
(*byte)(unsafe.Pointer(&buffer[0])),
&bufLen)
if errors.Is(err, error(syscall.ERROR_MORE_DATA)) {
if errors.Is(err, error(syscall.ERROR_MORE_DATA)) { //nolint:forbidigo // Legacy Code
newBuffer := make([]byte, len(buffer)+16384)
copy(newBuffer, buffer)
buffer = newBuffer
continue
} else if err != nil {
var errNo syscall.Errno
var errNo syscall.Errno //nolint:forbidigo // Legacy Code
if errors.As(err, &errNo) {
return nil, fmt.Errorf("ReqQueryValueEx failed: %w errno %d", err, uint(errNo))
}
@@ -276,6 +280,7 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
// Read global header
header := new(perfDataBlock)
err = header.BinaryReadFrom(r)
if err != nil {
return nil, fmt.Errorf("failed to read performance data block for %q with: %w", query, err)
@@ -300,6 +305,7 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
}
obj := new(perfObjectType)
err = obj.BinaryReadFrom(r)
if err != nil {
return nil, err
@@ -329,6 +335,7 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
for i := range numCounterDefs {
def := new(perfCounterDefinition)
err := def.BinaryReadFrom(r)
if err != nil {
return nil, err
@@ -410,7 +417,9 @@ func parseCounterBlock(b []byte, r io.ReadSeeker, pos int64, defs []*PerfCounter
if err != nil {
return 0, nil, err
}
block := new(perfCounterBlock)
err = block.BinaryReadFrom(r)
if err != nil {
return 0, nil, err
@@ -453,7 +462,6 @@ func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, value
272696576 64bit rate
*/
switch counterDef.CounterSize {
case 4:
value = int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)]))

View File

@@ -3,7 +3,8 @@ package perflib
import (
"encoding/binary"
"io"
"syscall"
"golang.org/x/sys/windows"
)
/*
@@ -36,7 +37,7 @@ type perfDataBlock struct {
HeaderLength uint32
NumObjectTypes uint32
DefaultObject int32
SystemTime syscall.Systemtime
SystemTime windows.Systemtime
_ uint32 // TODO
PerfTime int64
PerfFreq int64

View File

@@ -3,11 +3,9 @@ package perflib
import (
"errors"
"fmt"
"log/slog"
"reflect"
"strings"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
)
// Conversion factors.
@@ -16,14 +14,16 @@ const (
WindowsEpoch = 116444736000000000
)
func UnmarshalObject(obj *PerfObject, vs interface{}, logger log.Logger) error {
func UnmarshalObject(obj *PerfObject, vs interface{}, logger *slog.Logger) error {
if obj == nil {
return errors.New("counter not found")
}
rv := reflect.ValueOf(vs)
if rv.Kind() != reflect.Ptr || rv.IsNil() {
return fmt.Errorf("%v is nil or not a pointer to slice", reflect.TypeOf(vs))
}
ev := rv.Elem()
if ev.Kind() != reflect.Slice {
return fmt.Errorf("%v is not slice", reflect.TypeOf(vs))
@@ -40,6 +40,7 @@ func UnmarshalObject(obj *PerfObject, vs interface{}, logger log.Logger) error {
rt := target.Type()
counters := make(map[string]*PerfCounter, len(instance.Counters))
for _, ctr := range instance.Counters {
if ctr.Def.IsBaseValue && !ctr.Def.IsNanosecondCounter {
counters[ctr.Def.Name+"_Base"] = ctr
@@ -50,10 +51,12 @@ func UnmarshalObject(obj *PerfObject, vs interface{}, logger log.Logger) error {
for i := range target.NumField() {
f := rt.Field(i)
tag := f.Tag.Get("perflib")
if tag == "" {
continue
}
secondValue := false
st := strings.Split(tag, ",")
@@ -67,12 +70,15 @@ func UnmarshalObject(obj *PerfObject, vs interface{}, logger log.Logger) error {
ctr, found := counters[tag]
if !found {
_ = level.Debug(logger).Log("msg", fmt.Sprintf("missing counter %q, have %v", tag, counterMapKeys(counters)))
logger.Debug(fmt.Sprintf("missing counter %q, have %v", tag, counterMapKeys(counters)))
continue
}
if !target.Field(i).CanSet() {
return fmt.Errorf("tagged field %v cannot be written to", f.Name)
}
if fieldType := target.Field(i).Type(); fieldType != reflect.TypeOf((*float64)(nil)).Elem() {
return fmt.Errorf("tagged field %v has wrong type %v, must be float64", f.Name, fieldType)
}
@@ -81,7 +87,9 @@ func UnmarshalObject(obj *PerfObject, vs interface{}, logger log.Logger) error {
if !ctr.Def.HasSecondValue {
return fmt.Errorf("tagged field %v expected a SecondValue, which was not present", f.Name)
}
target.Field(i).SetFloat(float64(ctr.SecondValue))
continue
}
@@ -108,5 +116,6 @@ func counterMapKeys(m map[string]*PerfCounter) []string {
for k := range m {
keys = append(keys, k)
}
return keys
}

View File

@@ -3,12 +3,14 @@ package perflib
import (
"encoding/binary"
"io"
"syscall"
"golang.org/x/sys/windows"
)
// readUTF16StringAtPos Read an unterminated UTF16 string at a given position, specifying its length.
func readUTF16StringAtPos(r io.ReadSeeker, absPos int64, length uint32) (string, error) {
value := make([]uint16, length/2)
_, err := r.Seek(absPos, io.SeekStart)
if err != nil {
return "", err
@@ -19,7 +21,7 @@ func readUTF16StringAtPos(r io.ReadSeeker, absPos int64, length uint32) (string,
return "", err
}
return syscall.UTF16ToString(value), nil
return windows.UTF16ToString(value), nil
}
// readUTF16String Reads a null-terminated UTF16 string at the current offset.
@@ -43,5 +45,5 @@ func readUTF16String(r io.Reader) (string, error) {
return "", err
}
return syscall.UTF16ToString(out), nil
return windows.UTF16ToString(out), nil
}

View File

@@ -18,5 +18,6 @@ func GetPerflibSnapshot(objNames string) (map[string]*PerfObject, error) {
for _, obj := range objects {
indexed[obj.Name] = obj
}
return indexed, nil
}

View File

@@ -1,10 +1,10 @@
package perflib
import (
"io"
"log/slog"
"reflect"
"testing"
"github.com/go-kit/log"
)
type simple struct {
@@ -114,11 +114,14 @@ func TestUnmarshalPerflib(t *testing.T) {
t.Run(c.name, func(t *testing.T) {
t.Parallel()
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
output := make([]simple, 0)
err := UnmarshalObject(c.obj, &output, log.NewNopLogger())
err := UnmarshalObject(c.obj, &output, logger)
if err != nil && !c.expectError {
t.Errorf("Did not expect error, got %q", err)
}
if err == nil && c.expectError {
t.Errorf("Expected an error, but got ok")
}