<p>I'm writing custom k8s metrics collector for purpose of monitoring application's versions in two various clusters. How to expose specific location for metrics like &quot;/metrics&quot; and collect metrics in infinity cycle?</p>
<p>That's my custom metrics collector example:</p>
<pre><code>import time
from prometheus_client import start_http_server
from prometheus_client.core import REGISTRY, CounterMetricFamily
from kubernetes import client, config, watch

class CustomCollector(object):
    def __init__(self):
        pass
    def collect(self):
        g = CounterMetricFamily(&quot;retail_pods_info&quot;, 'info about pods', labels=['secret','namespace','deployment_name','image','helm'])
        config.load_kube_config('config')
        v1 = client.CoreV1Api()
        group = &quot;argoproj.io&quot;
        version = &quot;v1alpha1&quot;
        plural = &quot;applications&quot;
        #kind = &quot;Application&quot;
        namespace = &quot;argo-cd&quot;
        pod_list: client.V1PodList = v1.list_pod_for_all_namespaces(watch=False)
        pods: list[client.V1Pod] = pod_list.items
        metrics_list = []
        for pod in pods:
            metadata: client.V1ObjectMeta = pod.metadata
            spec: client.V1PodSpec = pod.spec
            volumes: list[client.V1Volume] = spec.volumes
            if volumes is not None:
                for volume in volumes:
                    if volume.projected:
                        projected: client.V1ProjectedVolumeSource = volume.projected
                        sources: list[client.V1VolumeProjection] = projected.sources
                        for source in sources:
                            if source.secret:
                                secret: client.V1SecretProjection = source.secret
                                s = secret.name + &quot; &quot; + metadata.namespace.lower() + &quot; &quot; + metadata.name.lower().rsplit('-',2)[0] + &quot; &quot; + pod.spec.containers[0].image
                                metrics_list.append(s.split())
        api_client = client.ApiClient()
        argocd_api = client.CustomObjectsApi(api_client)
        argocd_apps = argocd_api.list_namespaced_custom_object(group, version, namespace, plural, watch=False)
        for metric in metrics_list:
            for app in argocd_apps[&quot;items&quot;]:
                if metric[2] == app[&quot;metadata&quot;][&quot;name&quot;]:
                    helm_version=app[&quot;spec&quot;][&quot;source&quot;][&quot;repoURL&quot;]+&quot;-&quot;+app[&quot;spec&quot;][&quot;source&quot;][&quot;targetRevision&quot;]
                    metric.append(helm_version)
                    g.add_metric([metric[0], metric[1], metric[2], metric[3], metric[4]], 1)
                    yield g
        #
        # for k in metrics_list:
        #     g.add_metric([k[0],k[1],k[2],k[3]], 1)
        #     yield g

if __name__ == '__main__':
    start_http_server(8000)
    REGISTRY.register(CustomCollector())
    while True:
        time.sleep(60)
</code></pre>

Garamoff
<p>Regarding endpoint <code>/metrics</code>:<br />
Method <code>start_http_server</code> starts a server on the specified port, that responds to any query with metrics. So request to path <code>/metrics</code> will be responded to with generated metric by default.</p>
<p>Regarding &quot;collect metrics in infinity cycle&quot;:<br />
Your app is already doing it (kinda). Since you registered your custom collector every request will invoke the <code>collect</code> method. And since Prometheus while gathering metrics basically does it in an infinite cycle - your collector does it too.</p>
