Merge "Add support for multi-value metrics"
This commit is contained in:
commit
103d426993
@ -17,8 +17,9 @@ RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 1FA22B08 \
|
|||||||
/usr/share/luasandbox/sandboxes/heka/input/heka_tcp.lua \
|
/usr/share/luasandbox/sandboxes/heka/input/heka_tcp.lua \
|
||||||
/var/lib/hindsight/run/input/
|
/var/lib/hindsight/run/input/
|
||||||
|
|
||||||
ADD output/influxdb_tcp.lua /var/lib/hindsight/run/output/
|
ADD output/*.lua /var/lib/hindsight/run/output/
|
||||||
ADD input/kubelet_stats.lua /var/lib/hindsight/run/input/
|
ADD input/*.lua /var/lib/hindsight/run/input/
|
||||||
|
ADD modules/*.lua /opt/ccp/lua/modules/stacklight/
|
||||||
|
|
||||||
RUN useradd --user-group hindsight \
|
RUN useradd --user-group hindsight \
|
||||||
&& usermod -a -G microservices hindsight \
|
&& usermod -a -G microservices hindsight \
|
||||||
|
88
docker/hindsight/modules/message.lua
Normal file
88
docker/hindsight/modules/message.lua
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
-- Copyright 2015-2016 Mirantis, Inc.
|
||||||
|
--
|
||||||
|
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
-- you may not use this file except in compliance with the License.
|
||||||
|
-- You may obtain a copy of the License at
|
||||||
|
--
|
||||||
|
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
--
|
||||||
|
-- Unless required by applicable law or agreed to in writing, software
|
||||||
|
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
-- See the License for the specific language governing permissions and
|
||||||
|
-- limitations under the License.
|
||||||
|
|
||||||
|
local cjson = require 'cjson'
|
||||||
|
|
||||||
|
local inject_message = inject_message
|
||||||
|
local read_message = read_message
|
||||||
|
local string = string
|
||||||
|
local pcall = pcall
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
setfenv(1, M) -- Remove external access to contain everything in the module
|
||||||
|
|
||||||
|
-- Return the value and index of the last field with a given name.
|
||||||
|
function read_field(name)
|
||||||
|
local i = -1
|
||||||
|
local value = nil
|
||||||
|
local variable_name = string.format('Fields[%s]', name)
|
||||||
|
repeat
|
||||||
|
local tmp = read_message(variable_name, i + 1)
|
||||||
|
if tmp == nil then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
value = tmp
|
||||||
|
i = i + 1
|
||||||
|
until false
|
||||||
|
return value, i
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Extract value(s) from the message. The value can be either a scalar value
|
||||||
|
-- or a table for multi-value metrics.Return nil and an error message on
|
||||||
|
-- failure. The argument "tags" is optional, it's used for sanity checks.
|
||||||
|
function read_values(tags)
|
||||||
|
if not tags then
|
||||||
|
tags = {}
|
||||||
|
end
|
||||||
|
local value
|
||||||
|
local value_fields, value_fields_index = read_field('value_fields')
|
||||||
|
if value_fields ~= nil then
|
||||||
|
if tags['value_fields'] ~= nil and value_fields_index == 0 then
|
||||||
|
return nil, 'index of field "value_fields" should not be 0'
|
||||||
|
end
|
||||||
|
local i = 0
|
||||||
|
value = {}
|
||||||
|
repeat
|
||||||
|
local value_key = read_message(
|
||||||
|
'Fields[value_fields]', value_fields_index, i)
|
||||||
|
if value_key == nil then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local value_val, value_index = read_field(value_key)
|
||||||
|
if value_val == nil then
|
||||||
|
return nil, string.format('field "%s" is missing', value_key)
|
||||||
|
end
|
||||||
|
if tags[value_key] ~= nil and value_index == 0 then
|
||||||
|
return nil, string.format(
|
||||||
|
'index of field "%s" should not be 0', value_key)
|
||||||
|
end
|
||||||
|
value[value_key] = value_val
|
||||||
|
i = i + 1
|
||||||
|
until false
|
||||||
|
else
|
||||||
|
local value_index
|
||||||
|
value, value_index = read_field('value')
|
||||||
|
if value == nil then
|
||||||
|
-- "value" is a required field
|
||||||
|
return nil, 'field "value" is missing'
|
||||||
|
end
|
||||||
|
if tags['value'] ~= nil and value_index == 0 then
|
||||||
|
return nil, 'index of field "value" should not be 0'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return value, ''
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
local os = require 'os'
|
local os = require 'os'
|
||||||
local http = require 'socket.http'
|
local http = require 'socket.http'
|
||||||
|
local message = require 'stacklight.message'
|
||||||
|
|
||||||
--local write = require 'io'.write
|
--local write = require 'io'.write
|
||||||
--local flush = require 'io'.flush
|
--local flush = require 'io'.flush
|
||||||
@ -30,7 +31,7 @@ local function escape_string(str)
|
|||||||
return tostring(str):gsub("([ ,])", "\\%1")
|
return tostring(str):gsub("([ ,])", "\\%1")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function encode_value(value)
|
local function encode_scalar_value(value)
|
||||||
if type(value) == "number" then
|
if type(value) == "number" then
|
||||||
-- Always send numbers as formatted floats, so InfluxDB will accept
|
-- Always send numbers as formatted floats, so InfluxDB will accept
|
||||||
-- them if they happen to change from ints to floats between
|
-- them if they happen to change from ints to floats between
|
||||||
@ -44,6 +45,21 @@ local function encode_value(value)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function encode_value(value)
|
||||||
|
if type(value) == "table" then
|
||||||
|
local values = {}
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
table.insert(
|
||||||
|
values,
|
||||||
|
string.format("%s=%s", escape_string(k), encode_scalar_value(v))
|
||||||
|
)
|
||||||
|
end
|
||||||
|
return tablec.concat(values, ',')
|
||||||
|
else
|
||||||
|
return "value=" .. encode_scalar_value(value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function write_batch()
|
local function write_batch()
|
||||||
assert(buffer_len > 0)
|
assert(buffer_len > 0)
|
||||||
local body = table.concat(buffer, '\n')
|
local body = table.concat(buffer, '\n')
|
||||||
@ -84,29 +100,12 @@ local function create_database()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- return the value and index of the last field with a given name
|
|
||||||
local function read_field(name)
|
|
||||||
local i = -1
|
|
||||||
local value = nil
|
|
||||||
local variable_name = string.format('Fields[%s]', name)
|
|
||||||
repeat
|
|
||||||
local tmp = read_message(variable_name, i + 1)
|
|
||||||
if tmp == nil then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
value = tmp
|
|
||||||
i = i + 1
|
|
||||||
until false
|
|
||||||
return value, i
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- create a line for the current message, return nil and an error string
|
-- create a line for the current message, return nil and an error string
|
||||||
-- if the message is invalid
|
-- if the message is invalid
|
||||||
local function create_line()
|
local function create_line()
|
||||||
|
|
||||||
local tags = {}
|
local tags = {}
|
||||||
local dimensions, dimensions_index = read_field('dimensions')
|
local dimensions, dimensions_index = message.read_field('dimensions')
|
||||||
if dimensions then
|
if dimensions then
|
||||||
local i = 0
|
local i = 0
|
||||||
repeat
|
repeat
|
||||||
@ -134,7 +133,7 @@ local function create_line()
|
|||||||
return nil, 'index of field "dimensions" should not be 0'
|
return nil, 'index of field "dimensions" should not be 0'
|
||||||
end
|
end
|
||||||
|
|
||||||
local name, name_index = read_field('name')
|
local name, name_index = message.read_field('name')
|
||||||
if name == nil then
|
if name == nil then
|
||||||
-- "name" is a required field
|
-- "name" is a required field
|
||||||
return nil, 'field "name" is missing'
|
return nil, 'field "name" is missing'
|
||||||
@ -143,13 +142,9 @@ local function create_line()
|
|||||||
return nil, 'index of field "name" should not be 0'
|
return nil, 'index of field "name" should not be 0'
|
||||||
end
|
end
|
||||||
|
|
||||||
local value, value_index = read_field('value')
|
local value, err_msg = message.read_values(tags)
|
||||||
if value == nil then
|
if value == nil then
|
||||||
-- "value" is a required field
|
return nil, err_msg
|
||||||
return nil, 'field "value" is missing'
|
|
||||||
end
|
|
||||||
if tags['value'] ~= nil and value_index == 0 then
|
|
||||||
return nil, 'index of field "value" should not be 0'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local tags_array = {}
|
local tags_array = {}
|
||||||
@ -157,7 +152,7 @@ local function create_line()
|
|||||||
table.insert(tags_array, string.format('%s=%s', tag_key, tag_val))
|
table.insert(tags_array, string.format('%s=%s', tag_key, tag_val))
|
||||||
end
|
end
|
||||||
|
|
||||||
return string.format('%s,%s value=%s %d',
|
return string.format('%s,%s %s %d',
|
||||||
escape_string(name),
|
escape_string(name),
|
||||||
table.concat(tags_array, ','),
|
table.concat(tags_array, ','),
|
||||||
encode_value(value),
|
encode_value(value),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
output_path = "/var/lib/hindsight/output"
|
output_path = "/var/lib/hindsight/output"
|
||||||
sandbox_load_path = "/var/lib/hindsight/load"
|
sandbox_load_path = "/var/lib/hindsight/load"
|
||||||
sandbox_run_path = "/var/lib/hindsight/run"
|
sandbox_run_path = "/var/lib/hindsight/run"
|
||||||
analysis_lua_path = "/usr/lib/x86_64-linux-gnu/luasandbox/modules/?.lua"
|
analysis_lua_path = "/usr/lib/x86_64-linux-gnu/luasandbox/modules/?.lua;/opt/ccp/lua/modules/?.lua"
|
||||||
analysis_lua_cpath = "/usr/lib/x86_64-linux-gnu/luasandbox/modules/?.so"
|
analysis_lua_cpath = "/usr/lib/x86_64-linux-gnu/luasandbox/modules/?.so"
|
||||||
io_lua_path = analysis_lua_path .. ";/usr/lib/x86_64-linux-gnu/luasandbox/io_modules/?.lua"
|
io_lua_path = analysis_lua_path .. ";/usr/lib/x86_64-linux-gnu/luasandbox/io_modules/?.lua"
|
||||||
io_lua_cpath = analysis_lua_cpath .. ";/usr/lib/x86_64-linux-gnu/luasandbox/io_modules/?.so"
|
io_lua_cpath = analysis_lua_cpath .. ";/usr/lib/x86_64-linux-gnu/luasandbox/io_modules/?.so"
|
||||||
|
Loading…
Reference in New Issue
Block a user