Documentation ¶
Overview ¶
Package client contains generic representations of clients connecting to different receivers. Components, such as processors or exporters, can make use of this information to make decisions related to grouping of batches, tenancy, load balancing, tagging, among others.
The structs defined here are typically used within the context that is propagated down the pipeline, with the values being produced by authenticators and/or receivers, and consumed by processors and exporters.
Producers ¶
Receivers are responsible for obtaining a client.Info from the current context and enhancing the client.Info with the net.Addr from the peer, storing a new client.Info into the context that it passes down. For HTTP requests, the net.Addr is typically the IP address of the client.
Typically, however, receivers would delegate this processing to helpers such as the confighttp or configgrpc packages: both contain interceptors that will enhance the context with the client.Info, such that no actions are needed by receivers that are built using confighttp.HTTPServerSettings or configgrpc.GRPCServerSettings.
Authenticators are responsible for obtaining a client.Info from the current context, enhancing the client.Info with an implementation of client.AuthData, and storing a new client.Info into the context that it passes down. The attribute names should be documented with their return types and considered part of the public API for the authenticator.
Consumers ¶
Provided that the pipeline does not contain processors that would discard or rewrite the context, such as the batch processor, processors and exporters have access to the client.Info via client.FromContext. Among other usages, this data can be used to:
- annotate data points with authentication data (username, tenant, ...)
- route data points based on authentication data
- rate limit client calls based on IP addresses
Processors and exporters relying on the existence of data from the client.Info, especially client.AuthData, should clearly document this as part of the component's README file. The expected pattern for consuming data is to allow users to specify the attribute name to use in the component. The expected data type should also be communicated to users, who should then compare this with the authenticators that are part of the pipeline. For example, assuming that the OIDC authenticator pushes a "subject" string attribute and that we have a hypothetical "authprinter" processor that prints the "username" to the console, this is how an OpenTelemetry Collector configuration would look like:
extensions: oidc: issuer_url: http://localhost:8080/auth/realms/opentelemetry audience: collector receivers: otlp: protocols: grpc: auth: authenticator: oidc processors: authprinter: attribute: subject exporters: logging: service: extensions: [oidc] pipelines: traces: receivers: [otlp] processors: [authprinter] exporters: [logging]
Example (Authenticator) ¶
package main import ( "context" "go.opentelemetry.io/collector/client" ) func main() { // Your configauth.AuthenticateFunc receives a context ctx := context.Background() // Get the client from the context: if it doesn't exist, FromContext will // create one cl := client.FromContext(ctx) // After a successful authentication, place the data you want to propagate // as part of an AuthData implementation of your own cl.Auth = &exampleAuthData{ username: "jdoe", } // Your configauth.AuthenticateFunc should return this new context _ = client.NewContext(ctx, cl) } type exampleAuthData struct { username string } func (e *exampleAuthData) GetAttribute(key string) any { if key == "username" { return e.username } return nil } func (e *exampleAuthData) GetAttributeNames() []string { return []string{"username"} }
Output:
Example (Processor) ¶
package main import ( "context" "fmt" "go.opentelemetry.io/collector/client" ) func main() { // Your processor or exporter will receive a context, from which you get the // client information ctx := context.Background() cl := client.FromContext(ctx) // And use the information from the client as you need fmt.Println(cl.Addr) }
Output:
Example (Receiver) ¶
package main import ( "context" "net" "go.opentelemetry.io/collector/client" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/pdata/ptrace" ) func main() { // Your receiver get a next consumer when it's constructed var next consumer.Traces // You'll convert the incoming data into pipeline data td := ptrace.NewTraces() // You probably have a context with client metadata from your listener or // scraper ctx := context.Background() // Get the client from the context: if it doesn't exist, FromContext will // create one cl := client.FromContext(ctx) // Extract the client information based on your original context and set it // to Addr cl.Addr = &net.IPAddr{ // nolint IP: net.IPv4(1, 2, 3, 4), } // When you are done, propagate the context down the pipeline to the next // consumer next.ConsumeTraces(ctx, td) // nolint }
Output:
Index ¶
Examples ¶
Constants ¶
const MetadataHostName = "Host"
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AuthData ¶
type AuthData interface { // GetAttribute returns the value for the given attribute. Authenticator // implementations might define different data types for different // attributes. While "string" is used most of the time, a key named // "membership" might return a list of strings. GetAttribute(string) any // GetAttributes returns the names of all attributes in this authentication // data. GetAttributeNames() []string }
AuthData represents the authentication data as seen by authenticators tied to the receivers.
type Info ¶
type Info struct { // Addr for the client connecting to this collector. Available in a // best-effort basis, and generally reliable for receivers making use of // confighttp.ToServer and configgrpc.ToServerOption. Addr net.Addr // Auth information from the incoming request as provided by // configauth.ServerAuthenticator implementations tied to the receiver for // this connection. Auth AuthData // Metadata is the request metadata from the client connecting to this connector. // Experimental: *NOTE* this structure is subject to change or removal in the future. Metadata Metadata }
Info contains data related to the clients connecting to receivers.
func FromContext ¶
FromContext takes a context and returns a ClientInfo from it. When a ClientInfo isn't present, a new empty one is returned.
type Metadata ¶
type Metadata struct {
// contains filtered or unexported fields
}
Metadata is an immutable map, meant to contain request metadata.
func NewMetadata ¶
NewMetadata creates a new Metadata object to use in Info. md is used as-is.