Skip to content

Commit

Permalink
feat(operator)!: Provide default OTLP attribute configuration (#14410)
Browse files Browse the repository at this point in the history
  • Loading branch information
xperimental authored Oct 23, 2024
1 parent 673ede1 commit 1b52387
Show file tree
Hide file tree
Showing 24 changed files with 3,294 additions and 2,424 deletions.
193 changes: 72 additions & 121 deletions operator/api/loki/v1/lokistack_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,34 @@ type OpenshiftTenantSpec struct {
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Admin Groups"
AdminGroups []string `json:"adminGroups"`

// OTLP contains settings for ingesting data using OTLP in the OpenShift tenancy mode.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="OpenTelemetry Protocol"
OTLP *OpenshiftOTLPConfig `json:"otlp,omitempty"`
}

// OpenshiftOTLPConfig defines configuration specific to users using OTLP together with an OpenShift tenancy mode.
type OpenshiftOTLPConfig struct {
// DisableRecommendedAttributes can be used to reduce the number of attributes used for stream labels and structured
// metadata.
//
// Enabling this setting removes the "recommended attributes" from the generated Loki configuration. This will cause
// meta information to not be available as stream labels or structured metadata, potentially making queries more
// expensive and less performant.
//
// Note that there is a set of "required attributes", needed for OpenShift Logging to work properly. Those will be
// added to the configuration, even if this field is set to true.
//
// This option is supposed to be combined with a custom label configuration customizing the labels for the specific
// usecase.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable recommended OTLP attributes"
DisableRecommendedAttributes bool `json:"disableRecommendedAttributes,omitempty"`
}

// LokiComponentSpec defines the requirements to configure scheduling
Expand Down Expand Up @@ -791,138 +819,70 @@ type IngestionLimitSpec struct {
PerStreamRateLimitBurst int32 `json:"perStreamRateLimitBurst,omitempty"`
}

// OTLPAttributeAction defines the action to executed when indexing
// OTLP resource attributes. Resource attributes can be either added
// to the index, the chunk structured metadata or entirely dropped.
type OTLPAttributeAction string

const (
// OTLPAttributeActionIndexLabel stores a resource attribute as a label, which is part of the index identifying streams.
OTLPAttributeActionIndexLabel OTLPAttributeAction = "indexLabel"
// OTLPAttributeActionStructuredMetadata stores an attribute as structured metadata with each log entry.
OTLPAttributeActionStructuredMetadata OTLPAttributeAction = "structuredMetadata"
// OTLPAttributeActionDrop removes the matching attributes from the log entry.
OTLPAttributeActionDrop OTLPAttributeAction = "drop"
)

// OTLPAttributesSpec contains the configuration for a set of attributes
// to store them as index labels or structured metadata or drop them altogether.
type OTLPAttributesSpec struct {
// Action defines the indexing action for the selected attributes. They
// can be either added to structured metadata or drop altogether.
//
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=structured_metadata;drop
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Action"
Action OTLPAttributeAction `json:"action"`

// Attributes allows choosing the attributes by listing their names.
// OTLPSpec defines which resource, scope and log attributes should be used as stream labels or
// stored as structured metadata.
type OTLPSpec struct {
// StreamLabels configures which resource attributes are converted to Loki stream labels.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Attribute Names"
Attributes []string `json:"attributes,omitempty"`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Stream Labels"
StreamLabels *OTLPStreamLabelSpec `json:"streamLabels,omitempty"`

// Regex allows choosing the attributes by matching a regular expression.
// StructuredMetadata configures which attributes are saved in structured metadata.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Regular Expression"
Regex string `json:"regex,omitempty"`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Structured Metadata"
StructuredMetadata *OTLPMetadataSpec `json:"structuredMetadata,omitempty"`
}

// OTLPResourceAttributesConfigSpec contains the configuration for a set of resource attributes
// to store them as index labels or structured metadata or drop them altogether.
type OTLPResourceAttributesConfigSpec struct {
// Action defines the indexing action for the selected resoure attributes. They
// can be either indexed as labels, added to structured metadata or drop altogether.
//
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=index_label;structured_metadata;drop
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Action"
Action OTLPAttributeAction `json:"action"`

// Attributes is the list of attributes to configure indexing or drop them
// altogether.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Attribute Names"
Attributes []string `json:"attributes,omitempty"`

// Regex allows choosing the attributes by matching a regular expression.
type OTLPStreamLabelSpec struct {
// ResourceAttributes lists the names of the resource attributes that should be converted into Loki stream labels.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Regular Expression"
Regex string `json:"regex,omitempty"`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Attributes"
ResourceAttributes []OTLPAttributeReference `json:"resourceAttributes,omitempty"`
}

// OTLPResourceAttributesSpec contains the configuration for resource attributes
// to store them as index labels or structured metadata or drop them altogether.
type OTLPResourceAttributesSpec struct {
// IgnoreDefaults controls whether to ignore the global configuration for resource attributes
// indexed as labels.
//
// If IgnoreDefaults is true, then this spec needs to contain at least one mapping to a index label.
type OTLPMetadataSpec struct {
// ResourceAttributes lists the names of resource attributes that should be included in structured metadata.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch",displayName="Ignore Global Defaults"
IgnoreDefaults bool `json:"ignoreDefaults,omitempty"`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Attributes"
ResourceAttributes []OTLPAttributeReference `json:"resourceAttributes,omitempty"`

// Attributes contains the configuration for resource attributes
// to store them as index labels or structured metadata or drop them altogether.
// ScopeAttributes lists the names of scope attributes that should be included in structured metadata.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Attributes"
Attributes []OTLPResourceAttributesConfigSpec `json:"attributes,omitempty"`
}
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Scope Attributes"
ScopeAttributes []OTLPAttributeReference `json:"scopeAttributes,omitempty"`

// GlobalOTLPSpec defines which resource, scope and log attributes to
// be stored as index or structured metadata or drop altogether for all
// tenants.
type GlobalOTLPSpec struct {
// IndexedResourceAttributes contains the global configuration for resource attributes
// to store them as index labels.
// LogAttributes lists the names of log attributes that should be included in structured metadata.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Indexed Resource Attributes"
IndexedResourceAttributes []string `json:"indexedResourceAttributes,omitempty"`

OTLPSpec `json:",omitempty"`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Log Attributes"
LogAttributes []OTLPAttributeReference `json:"logAttributes,omitempty"`
}

// OTLPSpec defines which resource, scope and log attributes to
// be stored as index or structured metadata or drop altogether
type OTLPSpec struct {
// ResourceAttributes contains the configuration for resource attributes
// to store them as index labels or structured metadata or drop them altogether.
type OTLPAttributeReference struct {
// Name contains either a verbatim name of an attribute or a regular expression matching many attributes.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Attributes"
ResourceAttributes *OTLPResourceAttributesSpec `json:"resourceAttributes,omitempty"`

// ScopeAttributes contains the configuration for scope attributes
// to store them as structured metadata or drop them altogether.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Scope Attributes"
ScopeAttributes []OTLPAttributesSpec `json:"scopeAttributes,omitempty"`
// +required
// +kubebuilder:validation:Required
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Name"
Name string `json:"name"`

// LogAttributes contains the configuration for log attributes
// to store them as structured metadata or drop them altogether.
// If Regex is true, then Name is treated as a regular expression instead of as a verbatim attribute name.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Log Attributes"
LogAttributes []OTLPAttributesSpec `json:"logAttributes,omitempty"`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Treat name as regular expression"
Regex bool `json:"regex,omitempty"`
}

// RetentionStreamSpec defines a log stream with separate retention time.
Expand Down Expand Up @@ -978,13 +938,14 @@ type LimitsTemplateSpec struct {
// +kubebuilder:validation:Optional
QueryLimits *QueryLimitSpec `json:"queries,omitempty"`

// OTLP to configure which resource, scope and log attributes
// to store as labels or structured metadata or drop them altogether
// for all tenants.
// OTLP to configure which resource, scope and log attributes are stored as stream labels or structured metadata.
//
// Tenancy modes can provide a default OTLP configuration, when no custom OTLP configuration is set or even
// enforce the use of some required attributes.
//
// +optional
// +kubebuilder:validation:Optional
OTLP *GlobalOTLPSpec `json:"otlp,omitempty"`
OTLP *OTLPSpec `json:"otlp,omitempty"`

// Retention defines how long logs are kept in storage.
//
Expand All @@ -993,7 +954,7 @@ type LimitsTemplateSpec struct {
Retention *RetentionLimitSpec `json:"retention,omitempty"`
}

// LimitsTemplateSpec defines the limits applied at ingestion or query path.
// PerTenantLimitsTemplateSpec defines the limits applied at ingestion or query path.
type PerTenantLimitsTemplateSpec struct {
// IngestionLimits defines the limits applied on ingested log streams.
//
Expand All @@ -1007,9 +968,12 @@ type PerTenantLimitsTemplateSpec struct {
// +kubebuilder:validation:Optional
QueryLimits *PerTenantQueryLimitSpec `json:"queries,omitempty"`

// OTLP to configure which resource, scope and log attributes
// to store as labels or structured metadata or drop them altogether
// for a single tenants.
// OTLP to configure which resource, scope and log attributes are stored as stream labels or structured metadata.
//
// Tenancy modes can provide a default OTLP configuration, when no custom OTLP configuration is set or even
// enforce the use of some required attributes.
//
// The per-tenant configuration for OTLP attributes will be merged with the global configuration.
//
// +optional
// +kubebuilder:validation:Optional
Expand Down Expand Up @@ -1463,16 +1427,3 @@ func (t BlockedQueryTypes) String() string {

return strings.Join(res, ",")
}

func (a OTLPAttributeAction) Value() string {
switch a {
case OTLPAttributeActionIndexLabel:
return "index_label"
case OTLPAttributeActionStructuredMetadata:
return "structured_metadata"
case OTLPAttributeActionDrop:
return "drop"
default:
return string(a)
}
}
12 changes: 6 additions & 6 deletions operator/api/loki/v1/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ var (
// ErrIPv6InstanceAddrTypeNotAllowed when the default InstanceAddrType is used with enableIPv6.
ErrIPv6InstanceAddrTypeNotAllowed = errors.New(`instanceAddrType "default" cannot be used with enableIPv6 at the same time`)

// ErrOTLPResourceAttributesEmptyNotAllowed when the OTLP ResourceAttributes are empty even though ignoreDefaults is enabled.
ErrOTLPResourceAttributesEmptyNotAllowed = errors.New(`resourceAttributes cannot be empty when ignoreDefaults is true`)
// ErrOTLPResourceAttributesIndexLabelActionMissing when OTLP ResourceAttributes does not contain at least one index label when ignoreDefaults is enabled.
ErrOTLPResourceAttributesIndexLabelActionMissing = errors.New(`resourceAttributes does not contain at least one attributed mapped to "index_label"`)
// ErrOTLPAttributesSpecInvalid when the OTLPAttributesSpec attibutes and regex fields are both empty.
ErrOTLPAttributesSpecInvalid = errors.New(`attributes and regex cannot be empty at the same time`)
// ErrOTLPGlobalNoStreamLabel when the global OTLP configuration does not define at least one stream label.
ErrOTLPGlobalNoStreamLabel = errors.New("global OTLP configuration needs to define at least one stream label")
// ErrOTLPTenantMissing when a tenant is missing from the OTLP configuration although it has been defined in the tenancy.
ErrOTLPTenantMissing = errors.New("if no global OTLP configuration is present which defines at least one stream label, every tenant must have an OTLP configuration")
// ErrOTLPTenantNoStreamLabel when a tenant is defined but has no stream labels and there also no global stream labels.
ErrOTLPTenantNoStreamLabel = errors.New("if no global OTLP configuration is present which defines at least one stream label, every tenant must define at least one stream label")

// ErrRuleMustMatchNamespace indicates that an expression used in an alerting or recording rule is missing
// matchers for a namespace.
Expand Down
Loading

0 comments on commit 1b52387

Please sign in to comment.