All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.infobip.kafkistry.metric.ClusterStatusesMetricsCollector.kt Maven / Gradle / Ivy

The newest version!
package com.infobip.kafkistry.metric

import com.infobip.kafkistry.kafkastate.StateType
import com.infobip.kafkistry.metric.config.PrometheusMetricsProperties
import com.infobip.kafkistry.service.StatusLevel
import com.infobip.kafkistry.utils.ClusterFilter
import com.infobip.kafkistry.utils.ClusterFilterProperties
import io.prometheus.client.Collector.MetricFamilySamples
import io.prometheus.client.Collector.Type
import org.springframework.beans.factory.ObjectProvider
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.NestedConfigurationProperty
import org.springframework.stereotype.Component

@Component
@ConfigurationProperties("app.metrics.cluster-statuses")
class ClusterStatusesMetricsProperties {
    var enabled = true
    var includeDisabledClusters = false
    var omitStatusNames = mutableSetOf()

    @NestedConfigurationProperty
    var enabledOn = ClusterFilterProperties()
}

@Component
@ConditionalOnProperty("app.metrics.cluster-statuses.enabled", matchIfMissing = true)
class ClusterStatusesMetricsCollector(
    promProperties: PrometheusMetricsProperties,
    private val properties: ClusterStatusesMetricsProperties,
    clusterLabelProvider: ObjectProvider,
) : KafkistryMetricsCollector {

    //default: kafkistry_cluster_status
    private val statusMetricName = promProperties.prefix + "cluster_status"

    private val filter = ClusterFilter(properties.enabledOn)

    private val clusterLabelProvider = clusterLabelProvider.getIfAvailable {
        DefaultClusterMetricLabelProvider()
    }

    private val labelNames = listOf(
        this.clusterLabelProvider.labelName(), "status", "valid", "level"
    )

    private data class ClusterStatusEntry(
        val clusterLabel: String,
        val statusName: String,
        val valid: Boolean,
        val level: StatusLevel,
    )

    override fun expose(context: MetricsDataContext): List {
        val statusSamplesSeq = context.clusterStatuses.asSequence()
            .filter { filter(it.clusterRef) }
            .filter { it.stateType != StateType.DISABLED || properties.includeDisabledClusters }
            .flatMap { cluster ->
                val state = cluster.stateType
                val clusterLabel = clusterLabelProvider.labelValue(cluster.clusterRef.identifier)
                listOf(
                    ClusterStatusEntry(clusterLabel, state.name, state.valid, state.level)
                ) + cluster.issues.map { issue ->
                    ClusterStatusEntry(clusterLabel, issue.name, issue.valid, issue.level)
                }
            }
            .filter { it.statusName !in properties.omitStatusNames }
        val statusSamples = statusSamplesSeq.map {
            MetricFamilySamples.Sample(
                statusMetricName, labelNames,
                listOf(it.clusterLabel, it.statusName, it.valid.toString(), it.level.name),
                1.0,
            )
        }.toList()
        return mutableListOf(
            MetricFamilySamples(
                statusMetricName,
                Type.STATE_SET,
                "Individual state type per cluster",
                statusSamples,
            )
        )
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy