Documentation ¶
Index ¶
- func AsTraceMapCarrier[C TraceMapCarrierBase](carrier C) propagation.TextMapCarrier
- func EmbedInCtx(ctx context.Context, dn *Node) context.Context
- func GetCaller(depth int) string
- func GetDirAndFile(depth int) (dir, fileAndLine, parentAndFileAndLine string)
- type Agent
- type Annotation
- type Annotationer
- type CluesCtxKey
- type Comment
- type CommentHistory
- type Node
- func (dn *Node) AddAgent(name string) *Node
- func (dn *Node) AddComment(depth int, msg string, vs ...any) *Node
- func (dn *Node) AddSpan(ctx context.Context, name string) (context.Context, *Node)
- func (dn *Node) AddSpanAttributes(values map[string]any)
- func (dn *Node) AddValues(m map[string]any) *Node
- func (dn *Node) AppendToTree(name string) *Node
- func (dn *Node) Bytes() ([]byte, error)
- func (dn *Node) CloseSpan(ctx context.Context) *Node
- func (dn *Node) Comments() CommentHistory
- func (dn *Node) InitOTEL(ctx context.Context, name string, config OTELConfig) error
- func (dn *Node) InjectTrace(ctx context.Context, carrier propagation.TextMapCarrier)
- func (dn *Node) Map() map[string]any
- func (dn *Node) OTELLogger() log.Logger
- func (dn *Node) OTELMeter() metric.Meter
- func (dn *Node) ReceiveTrace(ctx context.Context, carrier propagation.TextMapCarrier) context.Context
- func (dn *Node) RunLineage(fn func(id string, vs map[string]any))
- func (dn *Node) SetValues(m map[string]any)
- func (dn *Node) Slice() []any
- func (dn *Node) SpawnDescendant() *Node
- type Noder
- type OTELClient
- type OTELConfig
- type TraceMapCarrierBase
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AsTraceMapCarrier ¶
func AsTraceMapCarrier[C TraceMapCarrierBase]( carrier C, ) propagation.TextMapCarrier
AsTraceMapCarrier converts a traceMapCarrier interface to its propagation package implementation for that structure. ie: map becomes a MapCarrier, headers become HeaderCarriers.
func EmbedInCtx ¶
EmbedInCtx adds the node in the context, and returns the updated context.
func GetCaller ¶
GetCaller retrieves the func name of the caller. Depth is the skip-caller count. Clues funcs that call this one should provide either `1` (if they do not already have a depth value), or `depth+1` otherwise.`
func GetDirAndFile ¶
GetDirAndFile retrieves the file and line number of the caller. Depth is the skip-caller count. Clues funcs that call this one should provide either `1` (if they do not already have a depth value), or `depth+1` otherwise`.
formats: dir `absolute/os/path/to/parent/folder` fileAndLine `<file>:<line>` parentAndFileAndLine `<parent>/<file>:<line>`
Types ¶
type Annotation ¶
type Annotation struct {
// contains filtered or unexported fields
}
func NewAttribute ¶
func NewAttribute(k string, v any) Annotation
func (Annotation) IsAttribute ¶
func (a Annotation) IsAttribute() bool
func (Annotation) KV ¶
func (a Annotation) KV() log.KeyValue
type Annotationer ¶
type Comment ¶
type Comment struct { // the func name in which the comment was created. Caller string // the name of the file owning the caller. File string // the comment message itself. Message string }
func NewComment ¶
NewComment formats the provided values, and grabs the caller and trace info according to the depth. Depth is a skip-caller count, and any func calling this one should provide either `1` (for itself) or `depth+1` (if it was already given a depth value).
type CommentHistory ¶
type CommentHistory []Comment
CommentHistory allows us to put a stringer on a slice of CommentHistory.
func (CommentHistory) String ¶
func (cs CommentHistory) String() string
String formats the slice of comments as a stack, much like you'd see with an error stacktrace. Comments are listed top-to-bottom from first- to-last.
The format for each comment in the stack is:
<caller> - <file>:<line> <message>
type Node ¶
type Node struct { Parent *Node // OTEL contains the client instance for the in memory OTEL runtime. It is only // present if the end user calls the clues initialization step. OTEL *OTELClient // Span is the current otel Span. // Spans are kept separately from the otelClient because we want the client to // maintain a consistent reference to otel initialization, while the Span can // get replaced at arbitrary points. Span trace.Span // ids are optional and are used primarily as tracing markers. // if empty, the trace for that node will get skipped when building the // full trace along the node's ancestry path in the tree. ID string // Values are they arbitrary key:value pairs that appear in clues when callers // use the Add(ctx, k, v) or err.With(k, v) adders. Each key-value pair added // to the node is used to produce the final set of Values() in the node, // with lower nodes in the tree taking priority over higher nodes for any // collision resolution. Values map[string]any // each node can hold a single commment. The history of comments produced // by the ancestry path through the tree will get concatenated from oldest // ancestor to the current node to produce the Comment history. Comment Comment // Agents act as proxy node that can relay specific, intentional data // additions. They're namespaced so that additions to the Agents don't accidentally // clobber other values in the node. This also allows Agents to protect // variations of data from each other, in case users need to compare differences // on the same keys. That's not the goal for Agents, exactly, but it is capable. Agents map[string]*Agent }
Node contains the data tracked by both clues in contexts and in errors.
These nodes compose a tree, such that nodes can walk their ancestry path from leaf (the current node) to root (the highest ancestor), but not from root to child. This allows clues to establish sets of common ancestor data with unique branches for individual descendants, making the addition of new data inherently theadsafe.
For collisions during aggregation, distance from the root denotes priority, with the root having the lowest priority. IE: if a child overwrites a key declared by an ancestor, the child's entry takes priority.
func FromBytes ¶
FromBytes deserializes the bytes to a new Node. No clients, agents, or hooks are initialized in this process.
func (*Node) AddComment ¶
AddComment creates a new nodewith a comment but no other properties.
func (*Node) AddSpan ¶
AddSpan adds a new otel span. If the otel client is nil, no-ops. Attrs can be added to the span with addSpanAttrs. This span will continue to be used for that purpose until replaced with another span, which will appear in a separate context (and thus a separate, node).
func (*Node) AddSpanAttributes ¶
AddSpanAttributes adds the values to the current span. If the span is nil (such as if otel wasn't initialized or no span has been generated), this call no-ops.
func (*Node) AddValues ¶
AddValues adds all entries in the map to the node's values. automatically propagates values onto the current span.
func (*Node) AppendToTree ¶
AppendToTree adds a new leaf with the provided name.
func (*Node) Bytes ¶
Bytes serializes the Node to a slice of bytes. Only attributes and comments are maintained. All values are stringified in the process.
Node hierarchy, clients (such as otel), agents, and hooks (such as labelCounter) are all sliced from the result.
func (*Node) CloseSpan ¶
CloseSpan closes the otel span and removes it span from the data node. If no span is present, no ops.
func (*Node) Comments ¶
func (dn *Node) Comments() CommentHistory
Comments retrieves the full ancestor comment chain. The return value is ordered from the first added comment (closest to the root) to the most recent one (closest to the leaf).
func (*Node) InitOTEL ¶
Init sets up persistent clients in the clues ecosystem such as otel. Initialization is NOT required. It is an optional step that end users can take if and when they want those clients running in their clues instance.
Multiple initializations will no-op.
func (*Node) InjectTrace ¶
func (dn *Node) InjectTrace( ctx context.Context, carrier propagation.TextMapCarrier, )
injectTrace adds the current trace details to the provided carrier. If otel is not initialized, no-ops.
The carrier data is mutated by this call.
func (*Node) Map ¶
Map flattens the tree of node.values into a map. Descendant nodes take priority over ancestors in cases of collision.
func (*Node) OTELLogger ¶
logger gets the otel logger instance from the otel client. Returns nil if otel wasn't initialized.
func (*Node) OTELMeter ¶
OTELMeter gets the otel logger instance from the otel client. Returns nil if otel wasn't initialized.
func (*Node) ReceiveTrace ¶
func (dn *Node) ReceiveTrace( ctx context.Context, carrier propagation.TextMapCarrier, ) context.Context
receiveTrace extracts the current trace details from the carrier and adds them to the context. If otel is not initialized, no-ops.
The carrier data is mutated by this call.
func (*Node) RunLineage ¶
RunLineage runs the fn on every valueNode in the ancestry tree, starting at the root and ending at the node.
func (*Node) SetValues ¶
SetValues is generally a helper called by addValues. In certain corner cases (like agents) it may get called directly.
func (*Node) Slice ¶
Slice flattens the tree of node.values into a Slice where all even indices contain the keys, and all odd indices contain values. Descendant nodes take priority over ancestors in cases of collision.
func (*Node) SpawnDescendant ¶
SpawnDescendant generates a new node that is a descendant of the current node. A descendant maintains a pointer to its parent, and carries any genetic necessities (ie, copies of fields) that must be present for continued functionality.
type OTELClient ¶
type OTELClient struct { ServiceName string LoggerProvider *sdkLog.LoggerProvider Logger log.Logger MeterProvider *sdkMetric.MeterProvider Meter metric.Meter TracerProvider *sdkTrace.TracerProvider Tracer trace.Tracer // contains filtered or unexported fields }
func NewOTELClient ¶
func NewOTELClient( ctx context.Context, serviceName string, config OTELConfig, ) (*OTELClient, error)
NewOTELClient bootstraps the OpenTelemetry pipeline to run against a local server instance. If it does not return an error, make sure to call the client.Close() method for proper cleanup. The service name is used to match traces across backends.
type OTELConfig ¶
type OTELConfig struct { // specify the endpoint location to use for grpc communication. // If empty, no telemetry exporter will be generated. // ex: localhost:4317 // ex: 0.0.0.0:4317 GRPCEndpoint string }