Documentation ¶
Overview ¶
Package dyngo is the Go implementation of Datadog's Instrumentation Gateway which provides an event-based instrumentation API based on a stack representation of instrumented functions along with nested event listeners. It allows to both correlate passed and future function calls in order to react and monitor specific function call scenarios, while keeping the monitoring state local to the monitoring logic thanks to nested Go function closures. dyngo is not intended to be directly used and should be instead wrapped behind statically and strongly typed wrapper types. Indeed, dyngo is a generic implementation relying on empty interface values (values of type `interface{}`) and using it directly can be error-prone due to the lack of compile-time type-checking. For example, AppSec provides the package `httpsec`, built on top of dyngo, as its HTTP instrumentation API and which defines the abstract HTTP operation representation expected by the AppSec monitoring.
Index ¶
- Variables
- func EmitData[T any](op Operation, data T)
- func FinishOperation[O Operation, E ResultOf[O]](op O, results E)
- func On[O Operation, E ArgOf[O]](op Operation, l EventListener[O, E])
- func OnData[T any](op Operation, l DataListener[T])
- func OnFinish[O Operation, E ResultOf[O]](op Operation, l EventListener[O, E])
- func RegisterOperation(ctx context.Context, op Operation) context.Context
- func StartAndRegisterOperation[O Operation, E ArgOf[O]](ctx context.Context, op O, args E) context.Context
- func StartOperation[O Operation, E ArgOf[O]](op O, args E)
- func SwapRootOperation(new Operation)
- type ArgOf
- type DataListener
- type EventListener
- type Operation
- type ResultOf
Constants ¶
This section is empty.
Variables ¶
var LogError = func(string, ...any) {}
LogError is the function used to log errors in the dyngo package. This is required because we really want to be able to log errors from dyngo but the log package depend on too much packages that we want to instrument. So we need to do this to avoid dependency cycles.
Functions ¶
func EmitData ¶
EmitData sends a data event up the operation stack. Listeners will be matched based on `T`. Callers may need to manually specify T when the static type of the value is more specific that the intended data event type.
func FinishOperation ¶
FinishOperation finishes the operation along with its results and emits a finish event with the operation results. The operation is then disabled and its event listeners removed.
func On ¶
func On[O Operation, E ArgOf[O]](op Operation, l EventListener[O, E])
On registers and event listener that will be called when the operation begins.
func OnFinish ¶
func OnFinish[O Operation, E ResultOf[O]](op Operation, l EventListener[O, E])
OnFinish registers an event listener that will be called when the operation finishes.
func RegisterOperation ¶
RegisterOperation registers the operation in the context tree. All operations that plan to have children operations should call this function to ensure the operation is properly linked in the context tree.
func StartAndRegisterOperation ¶
func StartAndRegisterOperation[O Operation, E ArgOf[O]](ctx context.Context, op O, args E) context.Context
StartAndRegisterOperation calls StartOperation and returns RegisterOperation result
func StartOperation ¶
StartOperation starts a new operation along with its arguments and emits a start event with the operation arguments.
func SwapRootOperation ¶
func SwapRootOperation(new Operation)
SwapRootOperation allows to atomically swap the current root operation with the given new one. Concurrent uses of the old root operation on already existing and running operation are still valid.
Types ¶
type ArgOf ¶
type ArgOf[O Operation] interface { IsArgOf(O) }
ArgOf marks a particular type as being the argument type of a given operation type. This allows this type to be listened to by an operation start listener. This removes the possibility of incorrectly pairing an operation and payload when setting up listeners, as it allows compiler-assisted coherence checks.
type DataListener ¶
type DataListener[T any] func(T)
type EventListener ¶
EventListener interface allowing to identify the Go type listened to and dispatch calls to the underlying event listener function.
type Operation ¶
type Operation interface { // Parent returns the parent operation, or nil for the root operation. Parent() Operation // contains filtered or unexported methods }
Operation interface type allowing to register event listeners to the operation. The event listeners will be automatically removed from the operation once it finishes so that it no longer can be called on finished operations.
func FromContext ¶
FromContext looks into the given context (or the GLS if orchestrion is enabled) for a parent Operation and returns it.
func NewOperation ¶
NewOperation creates and returns a new operation. It must be started by calling StartOperation, and finished by calling Finish. The returned operation should be used in wrapper types to provide statically typed start and finish functions. The following example shows how to wrap an operation so that its functions are statically typed (instead of dyngo's interface{} values):
package mypackage import "dyngo" type ( MyOperation struct { dyngo.Operation } MyOperationArgs { /* ... */ } MyOperationRes { /* ... */ } ) func StartOperation(args MyOperationArgs, parent dyngo.Operation) MyOperation { op := MyOperation{Operation: dyngo.NewOperation(parent)} dyngo.StartOperation(op, args) return op } func (op MyOperation) Finish(res MyOperationRes) { dyngo.FinishOperation(op, res) }
func NewRootOperation ¶
func NewRootOperation() Operation
NewRootOperation creates and returns a new root operation, with no parent operation. Root operations are meant to be the top-level operation of an operation stack, therefore receiving all the operation events. It allows to prepare a new set of event listeners, to then atomically swap it with the current one.
type ResultOf ¶
type ResultOf[O Operation] interface { IsResultOf(O) }
ResultOf marks a particular type as being the result type of a given operation. This allows this type to be listened to by an operation finish listener. This removes the possibility of incorrectly pairing an operation and payload when setting up listeners, as it allows compiler-assisted coherence checks.