Fix InfluxDB line protocol encoder
In particular, it didn't properly escape tag values with double quotes.
Change-Id: I8328f8cf23e49a3aa63a86e1c6866df36f8fe08d
diff --git a/heka/files/lua/common/influxdb.lua b/heka/files/lua/common/influxdb.lua
index d9c359d..9341399 100644
--- a/heka/files/lua/common/influxdb.lua
+++ b/heka/files/lua/common/influxdb.lua
@@ -26,8 +26,14 @@
setfenv(1, InfluxEncoder) -- Remove external access to contain everything in the module
-local function escape_string(str)
- return tostring(str):gsub("([ ,])", "\\%1")
+local function escape_string(str, preserve_quotes)
+ v = tostring(str)
+ -- single quotes are always forbidden
+ v = v:gsub("'", "")
+ if not preserve_quotes then
+ v = v:gsub('"', "")
+ end
+ return v:gsub("([ ,=])", "\\%1")
end
local function encode_scalar_value(value)
@@ -40,7 +46,7 @@
-- string values need to be double quoted
return '"' .. value:gsub('"', '\\"') .. '"'
elseif type(value) == "boolean" then
- return '"' .. tostring(value) .. '"'
+ return tostring(value)
end
end
@@ -50,7 +56,7 @@
for k,v in pairs(value) do
table.insert(
values,
- string.format("%s=%s", escape_string(k), encode_scalar_value(v))
+ string.format("%s=%s", escape_string(k, true), encode_scalar_value(v))
)
end
return table.concat(values, ',')
diff --git a/tests/lua/test_afd.lua b/tests/lua/test_afd.lua
index 478a36c..1016984 100644
--- a/tests/lua/test_afd.lua
+++ b/tests/lua/test_afd.lua
@@ -54,7 +54,7 @@
assertEquals(last_injected_msg.Type, 'afd_metric')
assertEquals(last_injected_msg.Fields.value, consts.OKAY)
assertEquals(last_injected_msg.Fields.hostname, 'node-1')
- assertEquals(last_injected_msg.Fields.notification_handler, 'mail')
+ assertEquals(last_injected_msg.Fields.notification_handler, nil)
assertEquals(last_injected_msg.Payload, '{"alarms":[]}')
end
diff --git a/tests/lua/test_influxdb.lua b/tests/lua/test_influxdb.lua
index 160c6b5..73d650d 100644
--- a/tests/lua/test_influxdb.lua
+++ b/tests/lua/test_influxdb.lua
@@ -21,11 +21,18 @@
TestInfluxDB = {}
+ function TestInfluxDB:test_escaping_characters()
+ local encoder = influxdb.new("s")
+ assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 2, {tag1='"tag1"'}), 'foo,tag1=tag1 value=2.000000 1000')
+ assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 2, {tag1=",tag 1="}), 'foo,tag1=\\,tag\\ 1\\= value=2.000000 1000')
+ assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 'b"ar'), 'foo value="b\\"ar" 1000')
+ assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', true), 'foo value=true 1000')
+ end
+
function TestInfluxDB:test_ms_precision_encoder()
local encoder = influxdb.new("ms")
assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 1), 'foo value=1.000000 1000000')
assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 'bar'), 'foo value="bar" 1000000')
- assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 'b"ar'), 'foo value="b\\"ar" 1000000')
assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', 1, {tag2="t2",tag1="t1"}), 'foo,tag1=t1,tag2=t2 value=1.000000 1000000')
assertEquals(encoder:encode_datapoint(1e9 * 1000, 'foo', {a=1, b=2}), 'foo a=1.000000,b=2.000000 1000000')
end