generated from dogmatiq/template-go
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
1,241 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package telemetry | ||
|
||
import ( | ||
"fmt" | ||
"log/slog" | ||
"math" | ||
"reflect" | ||
|
||
"go.opentelemetry.io/otel/attribute" | ||
"golang.org/x/exp/constraints" | ||
) | ||
|
||
// Attr is a telemetry attribute. | ||
type Attr struct { | ||
typ attrType | ||
key string | ||
str string | ||
num uint64 | ||
sli any | ||
} | ||
|
||
// String returns a string attribute. | ||
func String[T ~string](k string, v T) Attr { | ||
return Attr{ | ||
typ: attrTypeString, | ||
key: k, | ||
str: string(v), | ||
} | ||
} | ||
|
||
// Stringer returns a string attribute. The value is the result of calling | ||
// v.String(). | ||
func Stringer(k string, v fmt.Stringer) Attr { | ||
return String(k, v.String()) | ||
} | ||
|
||
// Type returns a string attribute set to the name of T. | ||
func Type[T any](k string, v T) Attr { | ||
t := reflect.TypeOf(v) | ||
for t.Kind() == reflect.Ptr { | ||
t = t.Elem() | ||
} | ||
return String(k, t.String()) | ||
} | ||
|
||
// Bool returns a boolean attribute. | ||
func Bool[T ~bool](k string, v T) Attr { | ||
var n uint64 | ||
if v { | ||
n = 1 | ||
} | ||
|
||
return Attr{ | ||
typ: attrTypeBool, | ||
key: k, | ||
num: n, | ||
} | ||
} | ||
|
||
// Int returns an int64 attribute. | ||
func Int[T constraints.Integer](k string, v T) Attr { | ||
return Attr{ | ||
typ: attrTypeInt64, | ||
key: k, | ||
num: uint64(v), | ||
} | ||
} | ||
|
||
// If conditionally includes an attribute. | ||
func If(cond bool, attr Attr) Attr { | ||
if cond { | ||
return attr | ||
} | ||
return Attr{} | ||
} | ||
|
||
// Float returns a float64 attribute. | ||
func Float[T constraints.Float](k string, v T) Attr { | ||
return Attr{ | ||
typ: attrTypeFloat64, | ||
key: k, | ||
num: math.Float64bits(float64(v)), | ||
} | ||
} | ||
|
||
func (a Attr) otel() (attribute.KeyValue, bool) { | ||
switch a.typ { | ||
case attrTypeNone: | ||
return attribute.KeyValue{}, false | ||
case attrTypeString: | ||
return attribute.String(a.key, a.str), true | ||
case attrTypeBool: | ||
return attribute.Bool(a.key, a.num != 0), true | ||
case attrTypeInt64: | ||
return attribute.Int64(a.key, int64(a.num)), true | ||
case attrTypeFloat64: | ||
return attribute.Float64(a.key, math.Float64frombits(a.num)), true | ||
default: | ||
panic("unknown attribute type") | ||
} | ||
} | ||
|
||
func (a Attr) slog() (slog.Attr, bool) { | ||
switch a.typ { | ||
case attrTypeNone: | ||
return slog.Attr{}, false | ||
case attrTypeString: | ||
return slog.String(a.key, a.str), true | ||
case attrTypeBool: | ||
return slog.Bool(a.key, a.num != 0), true | ||
case attrTypeInt64: | ||
return slog.Int64(a.key, int64(a.num)), true | ||
case attrTypeFloat64: | ||
return slog.Float64(a.key, math.Float64frombits(a.num)), true | ||
default: | ||
panic("unknown attribute type") | ||
} | ||
} | ||
|
||
type attrType uint8 | ||
|
||
const ( | ||
attrTypeNone attrType = iota | ||
attrTypeString | ||
attrTypeBool | ||
attrTypeInt64 | ||
attrTypeFloat64 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package telemetry | ||
|
||
import ( | ||
"go.opentelemetry.io/otel/attribute" | ||
"go.opentelemetry.io/otel/metric" | ||
) | ||
|
||
var ( | ||
// ReadDirection is an attribute that indicates a read operation. | ||
ReadDirection = metric.WithAttributeSet( | ||
attribute.NewSet( | ||
attribute.String("direction", "read"), | ||
), | ||
) | ||
|
||
// WriteDirection is an attribute that indicates a write operation. | ||
WriteDirection = metric.WithAttributeSet( | ||
attribute.NewSet( | ||
attribute.String("direction", "write"), | ||
), | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Package telemetry is an internal API for observability/instrumentation. | ||
package telemetry |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package telemetry | ||
|
||
import ( | ||
"fmt" | ||
"sync/atomic" | ||
|
||
"github.com/dogmatiq/enginekit/protobuf/uuidpb" | ||
) | ||
|
||
var handleCounter atomic.Uint64 | ||
|
||
// HandleID returns a unique identifier for an open instance of a journal or | ||
// keyspace. | ||
// | ||
// It includes a counter component for easy visual identification by humans, and | ||
// a UUID component for global correlation in observability tools. | ||
func HandleID() string { | ||
return fmt.Sprintf( | ||
"#%d %s", | ||
handleCounter.Add(1), | ||
uuidpb.Generate().String(), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package telemetry | ||
|
||
import ( | ||
"log/slog" | ||
"slices" | ||
|
||
"go.opentelemetry.io/otel/metric" | ||
"go.opentelemetry.io/otel/trace" | ||
) | ||
|
||
// Provider provides Recorder instances scoped to particular subsystems. | ||
type Provider struct { | ||
TracerProvider trace.TracerProvider | ||
MeterProvider metric.MeterProvider | ||
Logger *slog.Logger | ||
Attrs []Attr | ||
} | ||
|
||
// Recorder returns a new Recorder instance. | ||
// | ||
// pkg is the path to the Go package that is performing the instrumentation. If | ||
// it is an internal package, use the package path of the public parent package | ||
// instead. | ||
// | ||
// name is the one-word name of the subsystem that the recorder is for, for | ||
// example "journal" or "aggregate". | ||
func (p *Provider) Recorder(pkg, name string, attrs ...Attr) *Recorder { | ||
r := &Recorder{ | ||
name: "io.dogmatiq.persistencekit." + name, | ||
attrs: append( | ||
slices.Clone(p.Attrs), | ||
attrs..., | ||
), | ||
tracer: p.TracerProvider.Tracer(pkg, tracerVersion), | ||
meter: p.MeterProvider.Meter(pkg, meterVersion), | ||
logger: p.Logger, | ||
} | ||
|
||
r.errors = r.Int64Counter( | ||
"errors", | ||
metric.WithDescription("The number of errors that have occurred."), | ||
metric.WithUnit("{error}"), | ||
) | ||
|
||
return r | ||
} |
Oops, something went wrong.