Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Enable resource status for telemetry resources #1453

Merged
Merged
9 changes: 0 additions & 9 deletions config/development/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,6 @@ labels:
app.kubernetes.io/instance: telemetry-manager
app.kubernetes.io/managed-by: kustomize

patches:
- patch: |-
- op: add
path: /spec/template/spec/containers/0/args/-
value: --kyma-input-allowed=true
target:
kind: Deployment
name: manager

resources:
- crd
- ../rbac
Expand Down
3 changes: 2 additions & 1 deletion controllers/telemetry/metricpipeline_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ func NewMetricPipelineController(client client.Client, reconcileTriggerChan <-ch
}

agentRBAC := otelcollector.MakeMetricAgentRBAC(types.NamespacedName{Name: config.Agent.BaseName, Namespace: config.Agent.Namespace})
gatewayRBAC := otelcollector.MakeMetricGatewayRBAC(types.NamespacedName{Name: config.Gateway.BaseName, Namespace: config.Gateway.Namespace}, config.KymaInputAllowed)
gatewayRBAC := otelcollector.MakeMetricGatewayRBAC(types.NamespacedName{Name: config.Gateway.BaseName, Namespace: config.Gateway.Namespace})

discoveryClient, err := discovery.NewDiscoveryClientForConfig(config.RestConfig)
if err != nil {
return nil, err
Expand Down
24 changes: 24 additions & 0 deletions docs/user/04-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,30 @@ spec:
> [!NOTE]
> The Metric agent can scrape endpoints even if the workload is a part of the Istio service mesh and accepts mTLS communication. However, there's a constraint: For scraping through HTTPS, Istio must configure the workload using 'STRICT' mTLS mode. Without 'STRICT' mTLS mode, you can set up scraping through HTTP by applying the annotation `prometheus.io/scheme=http`. For related troubleshooting, see [Log entry: Failed to scrape Prometheus endpoint](#log-entry-failed-to-scrape-prometheus-endpoint).


### 4. Default Metrics for Telemetry Health
By default, a MetricPipeline emits metrics about the health of all pipelines managed by the Telemetry module. Based on these metrics, you can track the status of every individual pipeline and set up alerting for it. The following metrics are emitted for every pipeline and the Telemetry module itself:

| Metric | Description | Availability |
|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|
| kyma.resource.status.conditions | Value represents status of different conditions reported by the resource. Possible values are 'True' => 1, 'False' => 0, and -1 for other status values | Available for both, the pipeline and the telemetry resource |
| kyma.resource.status.state | Value represents the state of the resource (if present) | Available for the telemetry resource |

The following metric attributes are available for monitoring:

| Name | Description |
|--------------------------|----------------------------------------------------------------------------------------------|
| metric.attributes.Type | Type of the condition |
| metric.attributes.status | Status of the condition |
| metric.attributes.reason | Contains a programmatic identifier indicating the reason for the condition's last transition |


A typical alert rule looks like the following example. The alert is triggered if metrics are not delivered to the backend:
```promql
min by (k8s_resource_name) ((kyma_resource_status_conditions{type="TelemetryFlowHealthy",k8s_resource_kind="metricpipelines"})) == 0
```


### 5. Activate Runtime Metrics

To enable collection of runtime metrics, define a MetricPipeline that has the `runtime` section enabled as input:
Expand Down
25 changes: 8 additions & 17 deletions internal/otelcollector/config/metric/gateway/config_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@ import (
"github.com/kyma-project/telemetry-manager/internal/otelcollector/config/otlpexporter"
)

const KymaInputAnnotation = "telemetry.kyma-project.io/experimental-kyma-input"

type Builder struct {
Reader client.Reader
}

type BuildOptions struct {
GatewayNamespace string
InstrumentationScopeVersion string
KymaInputAllowed bool
}

func (b *Builder) Build(ctx context.Context, pipelines []telemetryv1alpha1.MetricPipeline, opts BuildOptions) (*Config, otlpexporter.EnvVars, error) {
Expand Down Expand Up @@ -60,9 +57,9 @@ func (b *Builder) Build(ctx context.Context, pipelines []telemetryv1alpha1.Metri
inputPipelineID := formatInputPipelineID(pipeline.Name)
attributesEnrichmentPipelineID := formatAttributesEnrichmentPipelineID(pipeline.Name)
outputPipelineID := formatOutputPipelineID(pipeline.Name)
cfg.Service.Pipelines[inputPipelineID] = makeInputPipelineServiceConfig(&pipeline, opts)
cfg.Service.Pipelines[inputPipelineID] = makeInputPipelineServiceConfig(&pipeline)
cfg.Service.Pipelines[attributesEnrichmentPipelineID] = makeAttributesEnrichmentPipelineServiceConfig(pipeline.Name)
cfg.Service.Pipelines[outputPipelineID] = makeOutputPipelineServiceConfig(&pipeline, opts)
cfg.Service.Pipelines[outputPipelineID] = makeOutputPipelineServiceConfig(&pipeline)
}

return cfg, envVars, nil
Expand All @@ -77,7 +74,7 @@ func declareComponentsForMetricPipeline(
envVars otlpexporter.EnvVars,
opts BuildOptions,
) error {
declareSingletonKymaStatsReceiverCreator(pipeline, cfg, opts)
declareSingletonKymaStatsReceiverCreator(cfg, opts)
declareSingletonK8sClusterReceiverCreator(pipeline, cfg, opts)
declareDiagnosticMetricsDropFilters(pipeline, cfg)
declareInputSourceFilters(pipeline, cfg)
Expand All @@ -94,10 +91,9 @@ func declareSingletonK8sClusterReceiverCreator(pipeline *telemetryv1alpha1.Metri
}
}

func declareSingletonKymaStatsReceiverCreator(pipeline *telemetryv1alpha1.MetricPipeline, cfg *Config, opts BuildOptions) {
if isKymaInputEnabled(pipeline.Annotations, opts.KymaInputAllowed) {
cfg.Receivers.SingletonKymaStatsReceiverCreator = makeSingletonKymaStatsReceiverCreatorConfig(opts.GatewayNamespace)
}
func declareSingletonKymaStatsReceiverCreator(cfg *Config, opts BuildOptions) {
cfg.Receivers.SingletonKymaStatsReceiverCreator = makeSingletonKymaStatsReceiverCreatorConfig(opts.GatewayNamespace)

}

func declareDiagnosticMetricsDropFilters(pipeline *telemetryv1alpha1.MetricPipeline, cfg *Config) {
Expand Down Expand Up @@ -168,9 +164,8 @@ func declareNamespaceFilters(pipeline *telemetryv1alpha1.MetricPipeline, cfg *Co
}

func declareInstrumentationScopeTransform(pipeline *telemetryv1alpha1.MetricPipeline, cfg *Config, opts BuildOptions) {
if isKymaInputEnabled(pipeline.Annotations, opts.KymaInputAllowed) {
cfg.Processors.SetInstrumentationScopeKyma = metric.MakeInstrumentationScopeProcessor(metric.InputSourceKyma, opts.InstrumentationScopeVersion)
}
cfg.Processors.SetInstrumentationScopeKyma = metric.MakeInstrumentationScopeProcessor(metric.InputSourceKyma, opts.InstrumentationScopeVersion)

if isRuntimeInputEnabled(pipeline.Spec.Input) {
cfg.Processors.SetInstrumentationScopeRuntime = metric.MakeInstrumentationScopeProcessor(metric.InputSourceK8sCluster, opts.InstrumentationScopeVersion)
}
Expand Down Expand Up @@ -271,7 +266,3 @@ func isRuntimeContainerMetricsEnabled(input telemetryv1alpha1.MetricPipelineInpu

return !isRuntimeContainerMetricsDisabled
}

func isKymaInputEnabled(annotations map[string]string, kymaInputAllowed bool) bool {
return kymaInputAllowed && annotations[KymaInputAnnotation] == "true"
}
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,10 @@ func TestProcessors(t *testing.T) {
collectorConfig, _, err := sut.Build(
ctx,
[]telemetryv1alpha1.MetricPipeline{
testutils.NewMetricPipelineBuilder().WithName("test").WithAnnotations(map[string]string{KymaInputAnnotation: "true"}).Build(),
testutils.NewMetricPipelineBuilder().WithName("test").Build(),
},
BuildOptions{
InstrumentationScopeVersion: "main",
KymaInputAllowed: true,
},
)
require.NoError(t, err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ func TestReceivers(t *testing.T) {
collectorConfig, _, err := sut.Build(
ctx,
[]telemetryv1alpha1.MetricPipeline{
testutils.NewMetricPipelineBuilder().WithName("test").WithAnnotations(map[string]string{KymaInputAnnotation: "true"}).Build(),
testutils.NewMetricPipelineBuilder().WithName("test").Build(),
},
BuildOptions{
GatewayNamespace: gatewayNamespace,
KymaInputAllowed: true,
},
)
require.NoError(t, err)
Expand Down
16 changes: 6 additions & 10 deletions internal/otelcollector/config/metric/gateway/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"github.com/kyma-project/telemetry-manager/internal/otelcollector/config/otlpexporter"
)

func makeInputPipelineServiceConfig(pipeline *telemetryv1alpha1.MetricPipeline, opts BuildOptions) config.Pipeline {
func makeInputPipelineServiceConfig(pipeline *telemetryv1alpha1.MetricPipeline) config.Pipeline {
return config.Pipeline{
Receivers: makeReceiversIDs(pipeline, opts),
Receivers: makeReceiversIDs(pipeline),
Processors: []string{"memory_limiter"},
Exporters: []string{formatRoutingConnectorID(pipeline.Name)},
}
Expand All @@ -23,7 +23,7 @@ func makeAttributesEnrichmentPipelineServiceConfig(pipelineName string) config.P
}
}

func makeOutputPipelineServiceConfig(pipeline *telemetryv1alpha1.MetricPipeline, opts BuildOptions) config.Pipeline {
func makeOutputPipelineServiceConfig(pipeline *telemetryv1alpha1.MetricPipeline) config.Pipeline {
var processors []string

input := pipeline.Spec.Input
Expand All @@ -38,9 +38,7 @@ func makeOutputPipelineServiceConfig(pipeline *telemetryv1alpha1.MetricPipeline,
processors = append(processors, makeRuntimeResourcesFiltersIDs(input)...)
processors = append(processors, makeDiagnosticMetricFiltersIDs(input)...)

if isKymaInputEnabled(pipeline.Annotations, opts.KymaInputAllowed) {
processors = append(processors, "transform/set-instrumentation-scope-kyma")
}
processors = append(processors, "transform/set-instrumentation-scope-kyma")

processors = append(processors, "resource/insert-cluster-name", "resource/delete-skip-enrichment-attribute", "batch")

Expand All @@ -51,14 +49,12 @@ func makeOutputPipelineServiceConfig(pipeline *telemetryv1alpha1.MetricPipeline,
}
}

func makeReceiversIDs(pipeline *telemetryv1alpha1.MetricPipeline, opts BuildOptions) []string {
func makeReceiversIDs(pipeline *telemetryv1alpha1.MetricPipeline) []string {
var receivers []string

receivers = append(receivers, "otlp")

if isKymaInputEnabled(pipeline.Annotations, opts.KymaInputAllowed) {
receivers = append(receivers, "singleton_receiver_creator/kymastats")
}
receivers = append(receivers, "singleton_receiver_creator/kymastats")

if isRuntimeInputEnabled(pipeline.Spec.Input) {
receivers = append(receivers, "singleton_receiver_creator/k8s_cluster")
Expand Down
Loading
Loading