其实不太想用opentsdb,一直以来用influxdb+grafana挺方便的,而且tsdb依赖hbase,虽说容量和速度有保证,但是分布式系统对于一个监控平台来说,终归还是有些重了,出问题定位更繁琐,但领导说用那就用吧。

在这里必须吐一下OpenTSDB和Tcollector的文档更新,太落后,看官方文档根本找不到配置文件的位置。最后还得看源码,尤其是TCollector,这个tsdb官方推出的数据采集器。不光文档落后,除了核心,周边辅助的代码也落后。而且插件方式设计的各种数据收集器太奇葩了,运行不了就狂报错。

安装tsdb还是比较方便的,找一台hbase的regionserver直接rpm就可以。主要是搞了tcollector以后排错,不过问题主要是在tcollector上,不赖tsdb。

不过tsdb装完以后,需要自己运行一个脚本叫create_table.sh来在hbase里创建tsdb需要的表。这块坑了我几分钟,安装官方文档的说法,创建表格时采用何种压缩方式并不重要,然后运行脚本,半个小时表都没创建起来,脚本默认会采用LZO方式选择压缩,就是建不起来,必须在命令行写env COMPRESSION='NONE' ... 才可以。不过我这集群是支持lzo的啊。不过跟tcollector相比,这就不算事。

tsdb的配置也算简单,就不细说了。


tcollector是opentsdb官方推出的数据采集器,符合个人开源风格,文档长期不更新。参看官方文档硬是找不到在哪配置能访问opentsdb,文档写的文件根本在代码里不存在,只能翻源码。

tcollector安装也不复杂,自带一个rpm的打包Makefile,直接make rpm就可以打包成rpm,然后放到repo里面yum安装即可,主要问题是安装以后跑起来没数据。

那就开始排错吧,首先确定opentsdb能不能接收到数据。停掉tsdb,用 nc -l 4242 启动一个TCP Server,监听在原tsdb的端口上,然后启动tcollector,nc接收到一个version,然后就没了。好吧,去看tcollector的源码。

        # we use the version command as it is very low effort for the TSD
        # to respond
        LOG.debug('verifying our TSD connection is alive')
        try:
            self.tsd.sendall('version\n')
        except socket.error, msg:
            self.tsd = None
            self.blacklist_connection()
            return False

嗯,version其实是相当于发送一个ping命令,如果没有响应,就把服务器放到黑名单里。我不明白,往单一服务器发送的程序,要黑名单干什么。

继续nc -l,收到version给个响应。

收到version以后,直接在nc控制台里打2,随便给个响应就行,立刻数据就上来了。好吧,tcollector发送数据其实没问题,那问题一定是在tsdb这边了。

打开tsdb的日志,没有任何报错。

打开 /etc/opentsdb/logback.xml 将日志等级从INFO提升为DEBUG,opentsdb采用slf4j作为日志记录。

  <root level="DEBUG">
    <!-- <appender-ref ref="STDOUT"/> -->
    <appender-ref ref="CYCLIC"/>
    <appender-ref ref="FILE"/>
  </root>

重启tsdb,再去看日志,来了。


16:58:27.470 DEBUG [PutDataPointRpc.execute] - put: unknown metric: No such name for 'metrics': 'tcollector.reader.lines_collected'


说hbase的tsdb表里没有metrics这个列名,翻看官方文档,有个配置叫


tsd.core.auto_create_metrics = true


默认是false,设置成true以后重启tsdb,数据进入hbase,没有问题了。


不过数据进到hbase里面又出现一个问题,没有cpu的度量信息,看源码得知cpu信息在collector里面的sysload.py里面,不过翻看Makefile打包出来的rpm,里面不包含这个文件。没办法,接着回去看tcollector的Makefile和rpm的spec文件,顺手修复了一下centos6下的bug。

Makefile倒是没看出什么问题,几个选项,all, rpm, clean, distclean, swix,分别对应 make all, make rpm, make clean等,那应该就是在spec文件里面了。

果然,spec文件的第一个问题是rpm调用的python被硬指向了python 2.7,而centos6里面是没有2.7的,顺手改之。

%global py2_sitelib   /usr/lib/python2.6/site-packages

第二个问题,安装的插件指向的是具体文件。

%files collectors    
%{tcollectordir}/collectors/0/dfstat.py    
%{tcollectordir}/collectors/0/ifstat.py    
%{tcollectordir}/collectors/0/iostat.py    
%{tcollectordir}/collectors/0/netstat.py    
%{tcollectordir}/collectors/0/procnettcp.py    
%{tcollectordir}/collectors/0/procstats.py    
%{tcollectordir}/collectors/0/smart_stats.py

所以结果是这几个文件才会被打包到rpm,这明显是主要代码更新了,而周边辅助的代码没更新导致的。

不过改成 * 是不优雅的,因为有些新增的插件因为调用依赖问题,启动后会一直报错,所以,需要根据具体需求来执行都安装哪些插件,所以,从这一点上说,这部分代码的产品化程度还远远不够,最起码要做出插件判断啊,缺少依赖就别运行了。

更新了spec,重新打包,需要的数据就都进入hbase了。


而tcollector的配置是最大的槽点,放到最后压轴来说,根据官方文档,理应有一个startstop脚本,将上报服务器配置为opentsdb的服务器,结果源码里死都找不到这个startstop脚本。然后通过阅读源码得知,他娘的核心配置文件是放在插件文件夹里的,这思路,简直是灾难啊。在 tcollector/collectors/etc/config.py里面,其实并不复杂,但是比较烦人。

    defaults = {
        'verbose': False,
        'no_tcollector_stats': False,
        'evictinterval': 6000,
        'dedupinterval': 300,
        'deduponlyzero': False,
        'allowed_inactivity_time': 600,
        'dryrun': False,
        'maxtags': 8,
        'max_bytes': 64 * 1024 * 1024,
        'http_password': False,
        'reconnectinterval': 0,
        'http_username': False,
        'port': 4242,
        'pidfile': '/var/run/tcollector.pid',
        'http': False,
        'http_api_path': "api/put",
        'tags': [],
        'remove_inactive_collectors': False,
        'host': 'to.your.opentsdb.server',
        'backup_count': 1,
        'logfile': '/var/log/tcollector.log',
        'cdir': default_cdir,
        'ssl': False,
        'stdin': False,
        'daemonize': False,
        'hosts': False
    }


嗯,这是我目前逛街发现的最坑的有公司维护的开源代码了,设计出这个代码结构的工程师应该拉出去枪毙半小时。浪费我2小时宝贵的撸码时间装这破玩意。

然后,我发现我司有一台服务器上面是有tcollector的代码的,文件创建时间是15年,那会我还没来,说明其实我司早就调研过这个,但是一直没搞起来可能,这东西没多难,但是文档确实坑人。

感觉产品设计,从来就不是互联网码农的强项,快速开发实现功能就行了,从不考虑产品化工程化代码结构优化的问题。

最后,领导愿意看用gnuplot画的图我也就不说什么了。我还是把opentsdb作为数据源接入到grafana里面,用那个看更漂亮一点。