forked from sstoiana/collectd-to-graphite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcollectd-graphite-proxy.js
146 lines (124 loc) · 4.18 KB
/
collectd-graphite-proxy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* TODO(sissel): make connections retry/etc
* TODO(sissel): make graphite target configurable via command line
*
* This code is a work in progress.
*
* To use this, put the following in your collectd config:
*
* LoadPlugin write_http
* <Plugin write_http>
* <URL "http://monitor:3012/post-collectd">
* </URL>
* </Plugin>
*
* This will make collectd write 'PUTVAL' statements over HTTP to the above URL.
* This code below will then convert the PUTVAL statements to graphite metrics
* and ship them to 'monitor:2003'
*/
var http = require("http");
var net = require("net");
var assert = require("assert");
var fs = require('fs');
var types = fs.readFileSync('/usr/share/collectd/types.db', encoding='utf8').split("\n");
var typesObj = new Object;
var type_comments_re = /^#/;
var type_cut_re = /^([^\s]+)\s+(.*)/;
for (var i in types) {
if (!type_comments_re.exec(types[i])) {
typeSet = type_cut_re.exec(types[i])
if (!typeSet) { continue; }
for (var t=0;t < typeSet.length;t++) {
var name = typeSet[1];
typesObj[name] = new Array();
var eachType = typeSet[2].split(", ")
for (var u=0; u < eachType.length; u++){
var theName = eachType[u].split(":")[0];
typesObj[name].push(theName);
}
}
}
}
try {
var graphite_connection = net.createConnection(2003, host=process.argv[2]);
} catch (error) {
throw error;
}
graphite_connection.on("close", function() {
throw new Error("Connection closed");
});
graphite_connection.on("error", function() {
throw new Error("Connection error");
});
var request_handler = function(request, response) {
merge = require('url').parse(request.url, true);
var putval_re = /^PUTVAL ([^ ]+)(?: ([^ ]+=[^ ]+)?) ([0-9.]+)(:.*)/;
request.addListener("data", function(chunk) {
metrics = chunk.toString().split("\n");
for (var i in metrics) {
var m = putval_re.exec(metrics[i]);
if (!m) {
continue;
}
var values = m[4].split(":");
for (var v in values) {
var name = m[1];
var options = m[2];
var time = m[3];
if ( v == 0 ) {
continue;
}
// Replace some chars for graphite, split into parts
var name_parts = name.replace(/\./g, "_").replace(/\//g, ".").split(".");
// Start to construct the new name
var rebuild = ["agents"]
var host = name_parts[0].split(/_/)[0]
if(merge.query.host) host=merge.query.host;
rebuild = rebuild.concat(host)
// Pluigin names can contain an "instance" which is set apart by a dash
var plugin = name_parts[1].split("-")
rebuild = rebuild.concat(plugin[0])
if (plugin.length > 1) {
var plugin_instance = plugin.slice(1).join("-")
rebuild = rebuild.concat(plugin_instance)
}
plugin = plugin[0]
// Type names can also contain an "instance"
var type = name_parts[2].split("-")
if (type[0] != plugin) {
// If type and plugin are equal, delete one to clean up a bit
rebuild = rebuild.concat(type[0])
}
if (type.length > 1) {
var type_instance = type.slice(1).join("-")
rebuild = rebuild.concat(type_instance)
}
type = type[0]
// Put the name back together
name = rebuild.join(".")
if ( values.length > 2 ) {
var metric = name_parts[2];
// If the metric contains a '-' (after removing the instance name)
// then we want to remove it before looking up in the types.db
index = metric.search(/-/)
if (index > -1) {
metric = /^([\w]+)-(.*)$/.exec(metric);
} else {
// Kinda a hack
metric = [ "", metric]
}
name = name + "." + typesObj[metric[1]][v - 1];
}
message = [name, values[v], time].join(" ");
graphite_connection.write(message + "\n");
}
}
});
request.addListener("end", function() {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("OK");
response.end();
});
}
var server = http.createServer()
server.addListener("request", request_handler)
server.listen(3012);