<div><p class="p1">Hello,</p>
<p class="p1">I'm james.</p>
<p class="p1">Thank you for releasing the collectd.</p>
<p class="p1">I developed a python plugin for collected.</p>
<p class="p1">and experiencing memory consumption growth.</p>
<p class="p1">as time goes, memory size of collected process keeps growing.</p>
<p class="p2"><br></p><p class="p2">I've searched similar cases with my case(<a href="http://www.mail-archive.com/collectd@verplant.org/msg01688.html"><span class="s2">http://www.mail-archive.com/collectd@verplant.org/msg01688.html</span></a>)</p>

<p class="p1">but not good for me with patched version.</p>
<p class="p2"><br></p>
<p class="p1">this is my environment.</p>
<p class="p1">os: linux centos 5.5 Linux  2.6.18-128.1.6.el5xen x86_64 </p>
<p class="p3"><span class="s1">collectd: collectd-5.0 branch. in git (<a href="https://github.com/octo/collectd/tree/collectd-5.0"><span class="s2">https://github.com/octo/collectd/tree/collectd-5.0</span></a>)</span></p>

<p class="p1">python: 2.6.2, 2.7.3</p>
<p class="p2"><br></p>
<p class="p1">my plugin is simple, just creates a collectd packet and dispatch to collected server.(at the bottom of this mail)</p>
<p class="p1">and attached more complex plugin for zookeeper monitoring</p>
<p class="p1">my collectd collects every 5second.</p>
<p class="p1">and memory grows 4k~ 20kbytes every  5~ 60sec(random)  in both case( simple and complex plugin.)</p>
<p class="p2"><br></p>
<p class="p2"><br></p>
<p class="p1">I've experimented several cases.</p>
<p class="p1">1. without python plugin, memory usage keeps steady ( 1.5M )</p>
<p class="p1">2. if python plugin is enabled, memory usage begins grow</p>
<p class="p1">    with my plugin, 5064KB(initial)-> 5456(after 3hour)</p>
<p class="p1">3. strange thing is that just putting empty python configuration, </p>
<p class="p1">   it still grows.</p>
<p class="p2"><br></p>
<p class="p1"><span style="background-color:rgb(204,204,204)"> LoadPlugin <span class="s2">python</span></span></p>
<p class="p4"><span style="background-color:rgb(204,204,204)"> <Plugin <span class="s2">python</span>]></span></p>
<p class="p4"><span style="background-color:rgb(204,204,204)">  ModulePath "/path/to/collectd_agent/share/<span class="s2">python</span>/"</span></p>
<p class="p4"><span style="background-color:rgb(204,204,204)">  LogTraces true</span></p>
<p class="p4"><span style="background-color:rgb(204,204,204)">  Interactive false</span></p>
<p class="p2"><span style="background-color:rgb(204,204,204)"> </Plugin></span></p>
<p class="p2"><br></p>
<p class="p1">4.  it is not related to collected debug mode.(--enable-debug with recompile)</p>
<p class="p1">     => no change. </p>
<p class="p2"><br></p>
<p class="p1">5. the more python plugins are enabled, the more memory grows.    </p>
<p class="p1">     with 4 python plugins( with more complex plugins attached), it will grow 17Mbytes after 5hours. </p>
<p class="p1">6. if python plugin raises some exceptions, memory grows even faster.</p>
<p class="p1">     with 4 python plugins( with more complex plugins), it will grow 72Mbytes after 5hours. </p>
<p class="p2"><br></p>
<p class="p1">I've tried guppy(<a href="http://pypi.python.org/pypi/guppy/"><span class="s3">http://pypi.python.org/pypi/guppy/</span></a>) to track python memory leak.</p>
<p class="p1">but there is no symptom in python plugin itself.</p>
<p class="p2"><br></p>
<p class="p1">Finally. I've used a valgrind(<a href="http://www.cprogramming.com/debugging/valgrind.html"><span class="s3">http://www.cprogramming.com/debugging/valgrind.html</span></a>) to spot problems using following command.</p>

<p class="p5">valgrind --tool=memcheck --suppressions=/python/path/valgrind-python.supp --leak-check=full <span class="s4">--error-limit=no  </span><span class="s5">--log-file=valog ./sbin/collectd </span></p>
<p class="p1">if  python plugin is disabled in configuration, there is no lost memory in report.</p>
<p class="p1">but if enabled python plugin ,it reports some following reports.</p>
<p class="p4"><span class="s6">   ( </span><span class="s2">to suppress warning, I've </span><span class="s6">recompiled python ( </span>--without-<span class="s2">pymalloc) and reinstalled collected )</span></p>
<p class="p1">I think that valgrind only reports  about initial step of collected and unable to track the multi thread workers.</p>
<p class="p1">   </p>
<p class="p2"><br></p>
<p class="p1">Do you have any idea, what cause this problem?</p><p class="p1"> thanks you for reading.</p>
<p class="p2"><br></p>
<p class="p2"><br></p>
<p class="p1">------------valgrind reports -----------------------------------------------------------------</p>
<p class="p1"> 370 bytes in 1 blocks are possibly lost in loss record 2,847 of 3,541</p>
<p class="p1">==30213==    at 0x4C2210C: malloc (vg_replace_malloc.c:195)</p>
<p class="p1">==30213==    by 0x7CED83C: PyString_FromString (stringobject.c:143)</p>
<p class="p1">==30213==    by 0x7D00A8F: PyType_Ready (typeobject.c:4059)</p>
<p class="p1">==30213==    by 0x7CE3277: _Py_ReadyTypes (object.c:2132)</p>
<p class="p1">==30213==    by 0x7D673C0: Py_InitializeEx (pythonrun.c:179)</p>
<p class="p1">==30213==    by 0x7A4CE70: cpy_config (python.c:989)</p>
<p class="p1">==30213==    by 0x4099C4: cf_read (configfile.c:361)</p>
<p class="p1">==30213==    by 0x4062C8: main (collectd.c:477)</p>
<p class="p2"><br></p>
<p class="p6"><br></p>
<p class="p4">==7443== 44 bytes in 1 blocks are possibly lost in loss record 833 of 3,469</p>
<p class="p4">==7443==    at 0x4C2276F: malloc (vg_replace_malloc.c:263)</p>
<p class="p4">==7443==    by 0x7CEEB3E: PyString_FromStringAndSize (stringobject.c:88)</p>
<p class="p4">==7443==    by 0x7D630CA: do_mkvalue (modsupport.c:427)</p>
<p class="p4">==7443==    by 0x7D6382C: do_mktuple (modsupport.c:268)</p>
<p class="p4">==7443==    by 0x7D6321B: do_mkvalue (modsupport.c:298)</p>
<p class="p4">==7443==    by 0x7D639EB: va_build_value (modsupport.c:537)</p>
<p class="p4">==7443==    by 0x7D63D6E: Py_BuildValue (modsupport.c:485)</p>
<p class="p4">==7443==    by 0x7D6F0B2: _PySys_Init (sysmodule.c:1405)</p>
<p class="p4">==7443==    by 0x7D6845F: Py_InitializeEx (pythonrun.c:215)</p>
<p class="p4">==7443==    by 0x7A4DEC0: cpy_config (python.c:996)</p>
<p class="p4">==7443==    by 0x4099C4: cf_read (configfile.c:361)</p>
<p class="p4">==7443==    by 0x4062C8: main (collectd.c:477)<span class="s6">  </span></p>
<p class="p2"><br></p>
<p class="p4">==22090== 44 bytes in 1 blocks are possibly lost in loss record 843 of 3,581</p>
<p class="p4">==22090==    at 0x4C2276F: malloc (vg_replace_malloc.c:263)</p>
<p class="p4">==22090==    by 0x7CE57C8: PyObject_Malloc (obmalloc.c:943)</p>
<p class="p4">==22090==    by 0x7CED87E: PyString_FromStringAndSize (stringobject.c:88)</p>
<p class="p4">==22090==    by 0x7D620FA: do_mkvalue (modsupport.c:427)</p>
<p class="p4">==22090==    by 0x7D6285C: do_mktuple (modsupport.c:268)</p>
<p class="p4">==22090==    by 0x7D6224B: do_mkvalue (modsupport.c:298)</p>
<p class="p4">==22090==    by 0x7D62A1B: va_build_value (modsupport.c:537)</p>
<p class="p4">==22090==    by 0x7D62D9E: Py_BuildValue (modsupport.c:485)</p>
<p class="p4">==22090==    by 0x7D6E4D2: _PySys_Init (sysmodule.c:1408)</p>
<p class="p4">==22090==    by 0x7D6742F: Py_InitializeEx (pythonrun.c:222)</p>
<p class="p4">==22090==    by 0x7A4BEA0: cpy_config (python.c:999)</p>
<p class="p4">==22090==    by 0x409924: cf_read (configfile.c:361)</p>
<p class="p6"><br></p>
<p class="p2"><br></p>
<p class="p1">---------------- following is a simple python plugin ----------------------</p>
<p class="p2"><br></p>
<p class="p7"># Simple <span class="s2">Python</span> module </p>
<p class="p8">"""</p>
<p class="p8">  Import python_plugin_test</p>
<p class="p8">  <Module python_plugin_test></p>
<p class="p8">  </p>
<p class="p8">  </Module></p>
<p class="p6"><br></p>
<p class="p8">"""</p>
<p class="p4"><span class="s7">import</span> socket</p>
<p class="p4"><span class="s7">import</span> collectd</p>
<p class="p9">import<span class="s1"> gc</span></p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p4"><span class="s7">def</span> configer(ObjConfiguration):</p>
<p class="p4">   collectd.debug(<span class="s8">'Configuring Stuff'</span>) </p>
<p class="p4">  </p>
<p class="p6"><br></p>
<p class="p4"><span class="s7">def</span> initiator():</p>
<p class="p4">    collectd.debug(<span class="s8">'</span><span class="s9">initing</span><span class="s8"> stuff'</span>)</p>
<p class="p4">    gc.set_debug(gc.DEBUG_LEAK)</p>
<p class="p4">    </p>
<p class="p6"><br></p>
<p class="p4"><span class="s7">def</span> dispatcher(data=<span class="s7">None</span>):</p>
<p class="p4">    metric = collectd.Values();</p>
<p class="p8"><span class="s1">    metric.plugin = </span>'python_plugin_test_counter'</p>
<p class="p4">    metric.type = <span class="s8">'mysql_threads'</span></p>
<p class="p4">    metric.values = [<span class="s10">5</span>,<span class="s10">10</span>,<span class="s10">15</span>,<span class="s10">10</span>]</p>
<p class="p4">    metric.dispatch()</p>
<p class="p7"><span class="s1">    </span>#<span class="s2">gcresult</span>=gc.collect()</p>
<p class="p7"><span class="s1">    </span>#<a href="http://collectd.info">collectd.info</a>("python_plugin_test:gc:%s"%<span class="s2">gcresult</span>) </p>
<p class="p4">   </p>
<p class="p4">    </p>
<p class="p4">    </p>
<p class="p7">#== Hook <span class="s2">Callbacks</span>, Order is important! ==#</p>
<p class="p4">collectd.register_config(configer)</p>
<p class="p4">collectd.register_init(initiator)</p>
<p class="p4">collectd.register_read(dispatcher)</p>
<p class="p2"><br></p>
<p class="p1">---------------------------</p></div>-- <br><div>James.kim(μ)</div><div>010 3266 8040</div><div><br></div><br>