braedon / prometheus-kafka-consumer-group-exporter

Prometheus Kafka Consumer Group Exporter
MIT License
73 stars 39 forks source link

Memory Leak in Python 3.7 with Collectors. #36

Closed Cellebyte closed 4 years ago

Cellebyte commented 4 years ago

Hey All,

I have an interesting memory leak inside prometheus_client. I am using the CollectorRegistry and added Collectors to it for getting metrics of devices which do not support the OpenMetrics Endpoint.

Using the current version 0.7.1 with python 3.7.3 on a debian buster I am running into constantly increasing memory on my host.

The offending line is eg.:

https://github.com/prometheus/client_python/blob/3ab0374d1548769748932b9316d86b088dc7712e/prometheus_client/metrics_core.py#L77-L83

I don't know why the samples are always referenced.

Trace information:

Top 15 lines
#1: prometheus_client/metrics_core.py:145: 30714.0 KiB                             
    self.samples.append(Sample(self.name, dict(zip(self._labelnames, labels)), value, timestamp))
#2: <string>:1: 17087.0 KiB
#3: prometheus_client/metrics_core.py:117: 6763.6 KiB                              
    self.samples.append(Sample(self.name + '_total', dict(zip(self._labelnames, labe
ls)), value, timestamp))
#4: prometheus_client/exposition.py:87: 4034.4 KiB                                 
    line.name, labelstr, floatToGoString(line.value), timestamp)                   
#5: factory/view.py:275: 3070.4 KiB
    as_str = x if isinstance(x, str) else x.text                                   
#6: prometheus_client/exposition.py:113: 2571.0 KiB                                
    om_samples = {}
#7: prometheus_client/exposition.py:129: 2426.3 KiB                                
    return ''.join(output).encode('utf-8')                                         
#8: python3.7/threading.py:238: 2218.6 KiB                                         
    self._waiters = _deque()
#9: logging/__init__.py:1724: 2127.1 KiB
    self.log(DEBUG, msg, *args, **kwargs)
#10: config/configuration.py:37: 2118.1 KiB                                        
    return str(data.get(self.json_key))
#11: prometheus_client/metrics_core.py:28: 1758.8 KiB                              
    self.name = name
#12: config/configuration.py:77: 1698.4 KiB                                        
    self.config['type']
#13: config/configuration.py:88: 1528.1 KiB                                        
    labels=[label.label for label in self.labels]                                  
#14: python3.7/linecache.py:137: 1238.5 KiB                                        
    lines = fp.readlines()
#15: ncclient/xml_.py:133: 998.9 KiB
    for event, element in etree.iterparse(fp, events=('start',)):
Cellebyte commented 4 years ago

Find a solution to remove the memory issue.

from prometheus_client.core import CounterMetricFamily
c = CounterMetricFamily('my_counter_total', 'Help text', labels=['foo'])
c.add_metric(['bar'], 1.7)
c.add_metric(['baz'], 3.8)
yield c
# this is important if you reuse the *MetricFamily
c.samples.clear()