Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@asus4
Last active November 16, 2015 06:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asus4/2142b74cd1469310891b to your computer and use it in GitHub Desktop.
Save asus4/2142b74cd1469310891b to your computer and use it in GitHub Desktop.
ofxMackerel
//
// ofxMackerel.cpp
//
// Copyright 2015 asus4
//
//
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include <Poco/Path.h>
#include <Poco/URI.h>
#include <Poco/Exception.h>
#include <Poco/JSON/Object.h>
#include <Poco/JSON/Array.h>
#include <dispatch/dispatch.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <ctime>
#include "ofxMackerel.hpp"
ofxMackerel::Mackerel() {
mackerel_origin = "https://mackerel.io";
timeout = 10; // in sec
interval = 60; // in sec
}
void ofxMackerel::setup(const std::string _apiKey, const std::string _id) {
apiKey = _apiKey;
if (_id == "") {
id = loadId();
} else {
id = _id;
}
}
void ofxMackerel::queueMetrics(const std::string metrics, const float value) {
metricsQueue[metrics] = value;
// check 60 sec
if (lastPostTime + interval < ofGetUnixTime()) {
sendAllMetrics();
}
}
void ofxMackerel::setTimeout(const int seconds) {
timeout = seconds;
}
void ofxMackerel::setInterval(const int seconds) {
interval = seconds;
}
string ofxMackerel::loadId() {
// mac
string path = (string)getenv("HOME") + "/Library/mackerel-agent/id";
if (ofFile::doesFileExist(path, false)) {
return ofBufferFromFile(path).getText();
}
ofLogError("No id file");
return "";
}
string ofxMackerel::postRequest(string url, string body) {
// https://gist.github.com/jefftimesten/247717dcca0669090cfa
using Poco::Net::HTTPSClientSession;
using Poco::Net::HTTPRequest;
using Poco::Net::HTTPResponse;
using Poco::Net::HTTPMessage;
using Poco::URI;
using Poco::StreamCopier;
using Poco::Exception;
try {
// prepare session
URI uri(url);
HTTPSClientSession session(uri.getHost(), uri.getPort());
session.setTimeout(Poco::Timespan(timeout, 0));
// prepare path
string path(uri.getPathAndQuery());
if (path.empty()) path = "/";
// send request
HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1);
req.setContentType("application/json");
// Add headers
req.set("X-Api-Key", apiKey);
// Set the request body
req.setContentLength(body.length());
// sends request, returns open stream
std::ostream& os = session.sendRequest(req);
os << body; // sends the body
// req.write(std::cout); // print out request
// cout << body << endl;
// get response
HTTPResponse res;
istream &is = session.receiveResponse(res);
stringstream ss;
StreamCopier::copyStream(is, ss);
ofLogVerbose() << ofToString(res.getStatus())
<< ":" << ss.str() << endl;
return ss.str();
}
catch (Exception &ex) {
cerr << ex.displayText() << endl;
return "";
}
}
void ofxMackerel::sendAllMetrics() {
using Poco::JSON::Object;
using Poco::JSON::Array;
int epoch = static_cast<int>(ofGetUnixTime());
Array params;
for (auto& metric : metricsQueue) {
Object m;
m.set("hostId", id);
m.set("name", metric.first);
m.set("time", epoch);
m.set("value", metric.second);
params.add(m);
}
metricsQueue.clear();
std::ostringstream os;
params.stringify(os);
string body = os.str();
ofLogVerbose() << "ofxMackerel post "<< body << endl;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
postRequest(mackerel_origin+"/api/v0/tsdb", body);
});
lastPostTime = epoch;
}
//
// ofxMackerel.hpp
// Wrapper for mackerel io
// https://mackerel.io/
//
// Copyright 2015 asus4
//
//
#pragma once
#include <string>
#include <map>
#include "ofMain.h"
namespace ofx {
namespace mackerel {
class Mackerel {
public:
~Mackerel() {}
Mackerel();
void setup(const std::string apiKey, const std::string id = "");
void queueMetrics(const std::string metrics, const float value);
// settings
void setTimeout(const int seconds);
void setInterval(const int seconds);
protected:
std::string apiKey;
std::string id;
std::string mackerel_origin;
std::map<std::string, float> metricsQueue;
unsigned int lastPostTime;
int timeout;
int interval;
// private
std::string loadId();
std::string postRequest(string url, string body);
void sendAllMetrics();
};
} // namespace mackerel
} // namespace ofx
using ofxMackerel = ofx::mackerel::Mackerel;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment