2023-05-08 22:29:52 +00:00
|
|
|
// Copyright 2023 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package trace
|
|
|
|
|
|
internal/trace: interpret string ID arguments for experimental events
Currently one of the reasons experimental events are tricky to use is
because:
- There's no way to take advantage of the existing infrastructure, like
strings and stacks, and
- There's no way to attach arbitrary data to an event (except through
strings, possibly).
Fix this by abstracting away the raw arguments in an ExperimentalEvent
and requiring access to the arguments via a new method, ArgValue. This
returns a Value, which gives us an opportunity to construct a typed
value for the raw argument dynamically, and a way to access existing
tables. The type of the argument is deduced from conventions for the
argument's name. This seems more than sufficient for experimental
events.
To make this work, we also need to add a "string" variant to the Value
type. This may be a little confusing since they're primarily used for
metrics, but one could imagine other scenarios in which this is useful,
such as including build information in the trace as a metric, so I think
this is fine.
This change also updates the Value API to accomodate a String method for
use with things that expect a fmt.Stringer, which means renaming the
value assertion methods to have a "To" prefix.
Change-Id: I43a2334f6cd306122c5b94641a6252ca4258b39f
Reviewed-on: https://go-review.googlesource.com/c/go/+/645135
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-28 20:54:34 +00:00
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"unsafe"
|
|
|
|
|
)
|
2023-05-08 22:29:52 +00:00
|
|
|
|
|
|
|
|
// Value is a dynamically-typed value obtained from a trace.
|
|
|
|
|
type Value struct {
|
internal/trace: interpret string ID arguments for experimental events
Currently one of the reasons experimental events are tricky to use is
because:
- There's no way to take advantage of the existing infrastructure, like
strings and stacks, and
- There's no way to attach arbitrary data to an event (except through
strings, possibly).
Fix this by abstracting away the raw arguments in an ExperimentalEvent
and requiring access to the arguments via a new method, ArgValue. This
returns a Value, which gives us an opportunity to construct a typed
value for the raw argument dynamically, and a way to access existing
tables. The type of the argument is deduced from conventions for the
argument's name. This seems more than sufficient for experimental
events.
To make this work, we also need to add a "string" variant to the Value
type. This may be a little confusing since they're primarily used for
metrics, but one could imagine other scenarios in which this is useful,
such as including build information in the trace as a metric, so I think
this is fine.
This change also updates the Value API to accomodate a String method for
use with things that expect a fmt.Stringer, which means renaming the
value assertion methods to have a "To" prefix.
Change-Id: I43a2334f6cd306122c5b94641a6252ca4258b39f
Reviewed-on: https://go-review.googlesource.com/c/go/+/645135
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-28 20:54:34 +00:00
|
|
|
kind ValueKind
|
|
|
|
|
pointer unsafe.Pointer
|
|
|
|
|
scalar uint64
|
2023-05-08 22:29:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ValueKind is the type of a dynamically-typed value from a trace.
|
|
|
|
|
type ValueKind uint8
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
ValueBad ValueKind = iota
|
|
|
|
|
ValueUint64
|
internal/trace: interpret string ID arguments for experimental events
Currently one of the reasons experimental events are tricky to use is
because:
- There's no way to take advantage of the existing infrastructure, like
strings and stacks, and
- There's no way to attach arbitrary data to an event (except through
strings, possibly).
Fix this by abstracting away the raw arguments in an ExperimentalEvent
and requiring access to the arguments via a new method, ArgValue. This
returns a Value, which gives us an opportunity to construct a typed
value for the raw argument dynamically, and a way to access existing
tables. The type of the argument is deduced from conventions for the
argument's name. This seems more than sufficient for experimental
events.
To make this work, we also need to add a "string" variant to the Value
type. This may be a little confusing since they're primarily used for
metrics, but one could imagine other scenarios in which this is useful,
such as including build information in the trace as a metric, so I think
this is fine.
This change also updates the Value API to accomodate a String method for
use with things that expect a fmt.Stringer, which means renaming the
value assertion methods to have a "To" prefix.
Change-Id: I43a2334f6cd306122c5b94641a6252ca4258b39f
Reviewed-on: https://go-review.googlesource.com/c/go/+/645135
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-28 20:54:34 +00:00
|
|
|
ValueString
|
2023-05-08 22:29:52 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Kind returns the ValueKind of the value.
|
|
|
|
|
//
|
|
|
|
|
// It represents the underlying structure of the value.
|
|
|
|
|
//
|
|
|
|
|
// New ValueKinds may be added in the future. Users of this type must be robust
|
|
|
|
|
// to that possibility.
|
|
|
|
|
func (v Value) Kind() ValueKind {
|
|
|
|
|
return v.kind
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 21:35:29 +00:00
|
|
|
// Uint64 returns the uint64 value for a ValueUint64.
|
2023-05-08 22:29:52 +00:00
|
|
|
//
|
internal/trace: interpret string ID arguments for experimental events
Currently one of the reasons experimental events are tricky to use is
because:
- There's no way to take advantage of the existing infrastructure, like
strings and stacks, and
- There's no way to attach arbitrary data to an event (except through
strings, possibly).
Fix this by abstracting away the raw arguments in an ExperimentalEvent
and requiring access to the arguments via a new method, ArgValue. This
returns a Value, which gives us an opportunity to construct a typed
value for the raw argument dynamically, and a way to access existing
tables. The type of the argument is deduced from conventions for the
argument's name. This seems more than sufficient for experimental
events.
To make this work, we also need to add a "string" variant to the Value
type. This may be a little confusing since they're primarily used for
metrics, but one could imagine other scenarios in which this is useful,
such as including build information in the trace as a metric, so I think
this is fine.
This change also updates the Value API to accomodate a String method for
use with things that expect a fmt.Stringer, which means renaming the
value assertion methods to have a "To" prefix.
Change-Id: I43a2334f6cd306122c5b94641a6252ca4258b39f
Reviewed-on: https://go-review.googlesource.com/c/go/+/645135
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-28 20:54:34 +00:00
|
|
|
// Panics if this Value's Kind is not ValueUint64.
|
2025-06-11 21:35:29 +00:00
|
|
|
func (v Value) Uint64() uint64 {
|
2023-05-08 22:29:52 +00:00
|
|
|
if v.kind != ValueUint64 {
|
2025-06-11 21:35:29 +00:00
|
|
|
panic("Uint64 called on Value of a different Kind")
|
2023-05-08 22:29:52 +00:00
|
|
|
}
|
|
|
|
|
return v.scalar
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 21:35:29 +00:00
|
|
|
// String returns the string value for a ValueString, and otherwise
|
|
|
|
|
// a string representation of the value for other kinds of values.
|
|
|
|
|
func (v Value) String() string {
|
|
|
|
|
if v.kind == ValueString {
|
|
|
|
|
return unsafe.String((*byte)(v.pointer), int(v.scalar))
|
|
|
|
|
}
|
|
|
|
|
switch v.kind {
|
|
|
|
|
case ValueUint64:
|
|
|
|
|
return fmt.Sprintf("Value{Uint64(%d)}", v.Uint64())
|
internal/trace: interpret string ID arguments for experimental events
Currently one of the reasons experimental events are tricky to use is
because:
- There's no way to take advantage of the existing infrastructure, like
strings and stacks, and
- There's no way to attach arbitrary data to an event (except through
strings, possibly).
Fix this by abstracting away the raw arguments in an ExperimentalEvent
and requiring access to the arguments via a new method, ArgValue. This
returns a Value, which gives us an opportunity to construct a typed
value for the raw argument dynamically, and a way to access existing
tables. The type of the argument is deduced from conventions for the
argument's name. This seems more than sufficient for experimental
events.
To make this work, we also need to add a "string" variant to the Value
type. This may be a little confusing since they're primarily used for
metrics, but one could imagine other scenarios in which this is useful,
such as including build information in the trace as a metric, so I think
this is fine.
This change also updates the Value API to accomodate a String method for
use with things that expect a fmt.Stringer, which means renaming the
value assertion methods to have a "To" prefix.
Change-Id: I43a2334f6cd306122c5b94641a6252ca4258b39f
Reviewed-on: https://go-review.googlesource.com/c/go/+/645135
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-28 20:54:34 +00:00
|
|
|
}
|
2025-06-11 21:35:29 +00:00
|
|
|
return "Value{Bad}"
|
internal/trace: interpret string ID arguments for experimental events
Currently one of the reasons experimental events are tricky to use is
because:
- There's no way to take advantage of the existing infrastructure, like
strings and stacks, and
- There's no way to attach arbitrary data to an event (except through
strings, possibly).
Fix this by abstracting away the raw arguments in an ExperimentalEvent
and requiring access to the arguments via a new method, ArgValue. This
returns a Value, which gives us an opportunity to construct a typed
value for the raw argument dynamically, and a way to access existing
tables. The type of the argument is deduced from conventions for the
argument's name. This seems more than sufficient for experimental
events.
To make this work, we also need to add a "string" variant to the Value
type. This may be a little confusing since they're primarily used for
metrics, but one could imagine other scenarios in which this is useful,
such as including build information in the trace as a metric, so I think
this is fine.
This change also updates the Value API to accomodate a String method for
use with things that expect a fmt.Stringer, which means renaming the
value assertion methods to have a "To" prefix.
Change-Id: I43a2334f6cd306122c5b94641a6252ca4258b39f
Reviewed-on: https://go-review.googlesource.com/c/go/+/645135
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-28 20:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func uint64Value(x uint64) Value {
|
|
|
|
|
return Value{kind: ValueUint64, scalar: x}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func stringValue(s string) Value {
|
|
|
|
|
return Value{kind: ValueString, scalar: uint64(len(s)), pointer: unsafe.Pointer(unsafe.StringData(s))}
|
|
|
|
|
}
|