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

Optionally disable Process and Platform collectors #414

Closed
glasswalk3r opened this issue May 22, 2019 · 18 comments
Closed

Optionally disable Process and Platform collectors #414

glasswalk3r opened this issue May 22, 2019 · 18 comments

Comments

@glasswalk3r
Copy link

Is there any way to optionally disable those collectors during usage? I would like to be able to disable those metrics from being generated except if they will actually be used.

A quick check on the code shows me that they are loaded from prometheus_client/__init__.py but there aren't (that I see) many options on that except by doing a PR with code modified.

I was able to see that trying to import resource on Microsoft Windows used to cause an exception, but the current version only ignores and generate constant values for those metrics:

Thanks!

@brian-brazil
Copy link
Contributor

brian-brazil commented May 22, 2019 via email

@glasswalk3r
Copy link
Author

Thanks @brian-brazil !
What would be the impacts of unregistering both of them, besides not having the information available?

@brian-brazil
Copy link
Contributor

No impact, they're there for this reason.

@iMartyn
Copy link

iMartyn commented Jun 25, 2019

Can they at least be able to use a namespace? As per https://prometheus.io/docs/practices/naming/ there should be a

single-word application prefix relevant to the domain

python is not actually relevant to the application domain that is being queried in prometheus, myapp_python_info actually is.

@brian-brazil
Copy link
Contributor

python is an appropriate namespace. They're metrics from the Python runtime, not you application's code.

@iMartyn
Copy link

iMartyn commented Jun 25, 2019

Sorry, I disagree. The specific python runtime for my app is what is being monitored here. The idea that an {ops-type person}* would be interested in all python runtime garbage collection across a cluster is let's say far-fetched. The metrics are labelled enough to drill down to a pod level, but not even a process/container level. Remember that it is perfectly possible to run two containers in one pod. I would say that allowing an optional namespace here gives that choice to the developer rather than enforcing your opinion on them.
*I say ops-type person to include devops, SREs, sysadmins etc.

@brian-brazil
Copy link
Contributor

python runtime garbage collection across a cluster is let's say far-fetched

That's what it's designed for.

I would say that allowing an optional namespace here gives that choice to the developer rather than enforcing your opinion on them.

This is not the Prometheus way, you're looking for target labels on the Prometheus side.

@skymal4ik
Copy link

Agree with topic starter, could be nice to have something like:

start_http_server(8000, enable_internal_metrics=False)

Also, please advice how can I un-register those internal python metrics?
I want to see my metrics only for testing purpose.

My code is

from prometheus_client import start_http_server, Gauge

# Create gauge
g = Gauge('current value', 'Current value')

def process_request():
    g.set(api.get_total_avg_val())
    time.sleep(60)

if __name__ == '__main__':
    # Start up the server to expose the metrics.
    start_http_server(8000)
    # Generate some requests.
    while True:
        process_request()

Thanks!

@lhw
Copy link

lhw commented Aug 5, 2019

There is probably a better way to do this but for now this will remove all metrics that are initially registered:

from prometheus_client import REGISTRY, PROCESS_COLLECTOR, PLATFORM_COLLECTOR

REGISTRY.unregister(PROCESS_COLLECTOR)
REGISTRY.unregister(PLATFORM_COLLECTOR)
# Unlike process and platform_collector gc_collector registers itself as three different collectors that have no corresponding public named variable. 
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_duration_seconds_sum'])
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_uncollectable_objects_sum'])
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_collected_objects_sum'])

# Or as throw-away line
[REGISTRY.unregister(c) for c in [PROCESS_COLLECTOR, PLATFORM_COLLECTOR, REGISTRY._names_to_collectors['python_gc_duration_seconds_sum'], REGISTRY._names_to_collectors['python_gc_uncollectable_objects_sum'], REGISTRY._names_to_collectors['python_gc_collected_objects_sum']]]

@brian-brazil
Copy link
Contributor

The original issue that was reported was fixed long ago, so closing this.

@valdemarpavesi
Copy link

valdemarpavesi commented Aug 17, 2019

very good! unregister default metrics.

there are thousands of exporter and with default metrics it could be 1000*100 it will create a big problem to time series database.


$ curl localhost:9202/metrics

# HELP request_processing_seconds Time spent processing request
# TYPE request_processing_seconds summary
request_processing_seconds_count 49.0
request_processing_seconds_sum 28.376933447027113
# TYPE request_processing_seconds_created gauge
request_processing_seconds_created 1.5660669884441628e+09
$ 

export only defined metrics:

from prometheus_client import start_http_server, Summary,REGISTRY, PROCESS_COLLECTOR, PLATFORM_COLLECTOR

import random
import time


# Unregister default metrics
REGISTRY.unregister(PROCESS_COLLECTOR)
REGISTRY.unregister(PLATFORM_COLLECTOR)
# Unlike process and platform_collector gc_collector registers itself as three different collectors that have no corresponding public named variable. 
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_duration_seconds_sum'])
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_uncollectable_objects_sum'])
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_collected_objects_sum'])


# Create a metric to track time spent and requests made.
REQUEST_TIME = Summary('request_processing_seconds', 'Time spent processing request')

# Decorate function with metric.
@REQUEST_TIME.time()
def process_request(t):
    """A dummy function that takes some time."""
    time.sleep(t)

if __name__ == '__main__':
    # Start up the server to expose the metrics.
    start_http_server(9202)
    # Generate some requests.
    while True:
        process_request(random.random())

@pcgeek86
Copy link

Thanks for the help @valdemarpavesi. This is the code I ended up with, to clean up all the built-in metrics.

    REGISTRY.unregister(PROCESS_COLLECTOR)
    REGISTRY.unregister(PLATFORM_COLLECTOR)
    REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_objects_collected_total'])

@luto
Copy link

luto commented Jun 29, 2020

for name in list(REGISTRY._names_to_collectors.values()):
    with suppress(KeyError):
        REGISTRY.unregister(name)

I ended up with this, which should also work even if the default generators ever change.

@andy-maier
Copy link
Contributor

I would prefer this similar approach instead:

for coll in list(REGISTRY._collector_to_names.keys()):
    REGISTRY.unregister(coll)

@adithyaamara
Copy link

There is probably a better way to do this but for now this will remove all metrics that are initially registered:

from prometheus_client import REGISTRY, PROCESS_COLLECTOR, PLATFORM_COLLECTOR

REGISTRY.unregister(PROCESS_COLLECTOR)
REGISTRY.unregister(PLATFORM_COLLECTOR)
# Unlike process and platform_collector gc_collector registers itself as three different collectors that have no corresponding public named variable. 
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_duration_seconds_sum'])
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_uncollectable_objects_sum'])
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_collected_objects_sum'])

# Or as throw-away line
[REGISTRY.unregister(c) for c in [PROCESS_COLLECTOR, PLATFORM_COLLECTOR, REGISTRY._names_to_collectors['python_gc_duration_seconds_sum'], REGISTRY._names_to_collectors['python_gc_uncollectable_objects_sum'], REGISTRY._names_to_collectors['python_gc_collected_objects_sum']]]

@lhw , Thank you so much for the hack, Using the REGISTRY.unregister method, I tried to remove out the requests_per_second_created auto generated metric, but surprisingly instead of just the _created metric, whole metric 'requests_per_second_total' itself vanished.
Is there any way to only remove out _created metric only and keep the original _total metric? Your help is greatly appreciated. Thank you in advance.

@csmarchbanks
Copy link
Member

For the _created metric there is an open issue to allow not exporting _created metrics: #672.

@adithyaamara
Copy link

For the _created metric there is an open issue to allow not exporting _created metrics: #672.

@csmarchbanks , I also saw your open PR #774 to fix the same issue. Eagerly waiting for your PR to get merged.
Thank you so much.

@ahaw2024
Copy link

Tested this on python 3.12

Updated config

REGISTRY.unregister(PROCESS_COLLECTOR)
REGISTRY.unregister(PLATFORM_COLLECTOR)
REGISTRY.unregister(REGISTRY._names_to_collectors['python_gc_objects_collected_total'])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests