ぐるっとぐりっど

日曜プログラマがいろいろ試してみたことを、後の自分のためにまとめておく場所

hubotでinfluxdbの収集データをグラフ化してSlackにアップロードする

自鯖の性能値管理に、InfluxdbをはじめとするTICKスタックを使ってるのだけど、なんか閾値設定がうまくいかなくて、閾値をまたぐたびにKapacitorがアラートを投げてきてうっとうしくなってきた。

そこで、hubotで定期的に収集したデータをグラフにして、slackにアップロードするようにしてみた。

ソースコードはこちら

github.com


グラフ化には、chartjs-nodeを使っている。canvasだったりchartjs、d3のNode.js用ライブラリがいろいろとあって、とくに最近実はスパイウェア混入してた事件とかもあって心配なんだけど、多分大丈夫のはず。

また、Hubotは一般的にはcoffee-scriptを使って書くようだけど、いまさらcoffee-scriptは微妙だと思って、pure javascriptで書いてる。

    var chartNode = new ChartjsNode(400, 300);

    request.get({url:'http://localhost:8086/query?pretty=true&db=monitoring&q='+encodeURIComponent('select mean(' + key +') from ' + name + ' where time > now() - 24h GROUP BY TIME(10m)')},
                function(error, response, body) {
                    if (error) {
                        console.log(error);
                        console.log(response);
                        return;
                    }
                    var parsedJson = JSON.parse(body);
                    var label = [];
                    var data = [];
                    for (let value of parsedJson['results'][0]['series'][0]['values']) {
                        var d = new Date(value[0]);
                        label.push(("0" + d.getHours()).slice(-2) + ":" + ("0" + d.getMinutes()).slice(-2) + ":" + ("0" + d.getSeconds()).slice(-2));
                        data.push(value[1]);
                    }
                    
                    chartNode.drawChart( {
                        type: 'line',
                        data: {
                            labels: label,
                            datasets: [{
                                label: parsedJson['results'][0]['series'][0]['name'],
                                data: data,
                                backgroundColor: "rgba(255, 0, 0, 0.5)"
                            }]
                        },
                        options: {
                            scales: {
                                yAxes: [{
                                    ticks: {
                                        beginAtZero: false
                                    }
                                }]
                            }
                        }})
                        .then(() => {
                            return chartNode.getImageStream('image/png');
                        })
                        .then(streamResult => {
                            return chartNode.writeImageToFile('image/png', '/tmp/testimage.png');
                        })

                        });
                    
                });
};

request使って、json型のデータをinfluxdbから取得して、最終的に/tmp/testimage.pngを作る。

そんなに複雑なことしてないつもり。

request.post({url:'https://slack.com/api/files.upload',
              formData: {
               token: process.env.HUBOT_SLACK_TOKEN,
               filename: 'testimage.png',
               file: fs.createReadStream('/tmp/testimage.png'),
               channels: 'develop'
              }},
             function(error, response, body) {
             });

作った/tmp/testimage.pngをslackにアップロードする。


アップロードされるグラフがこんな感じ

f:id:grugrut:20170805193356p:plain

いいかんじですね。