System/local monitors written in Lua for use in Nginx rest endpoints.
Lua Shell
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
examples
Endpoint.org
Makefile
README.html
README.org
pinky
pinky-0.1-0.rockspec
pinky.lua
pinky_chef.lua
pinky_disk.lua
pinky_dpkg.lua
pinky_ec2meta.lua
pinky_hello.lua
pinky_load.lua
pinky_log.lua
pinky_md5sum.lua
pinky_memcache.lua
pinky_memfree.lua
pinky_mydb.lua
pinky_net.lua
pinky_netstat.lua
pinky_nginx.lua
pinky_passenger.lua
pinky_ping.lua
pinky_port.lua
pinky_proc.lua
pinky_process.lua
pinky_redis.lua
pinky_riak.lua
pinky_runit.lua
pinky_rvm.lua
pinky_stat.lua
pinky_unicorn.lua
pinky_vmstat.lua
reload
tests.lua

README.org

pinky - Monitoring system built on Openresty

Purpose:

How to build plugins:

Pinky rest structure

pinky -

All modules are loaded from here. There is no requirement for nginx.conf additions as a catchall for pinky.dispatch() is handled via /pinky/*

Every custom module require a preamble containing the following.
local p = require 'pinky'
local json = require 'cjson'

This covers pulling in pinky core as well as json for output formatting.

Additionally you are required to create an entry function called main that takes the truncated uri as it’s sole argument.

local empty;
local foo;
local bar;

Here we provide declarations of each function as local.

local function pinky_main(uri)
   -- This function is the entry point.
   -- We are passed the rest of the uri.
   local args = p.split(uri,"/")

   if #args == 0 then
      return json.encode("Hello controller called with no args! (e.g. http://localhost/pinky/hello)"
   elseif #args == 1 then
      return json.encode("Hello controller called with one arg, foo! (e.g. http://localhost/pinky/hello/foo)"
   elseif #args == 2 then
      return json.encode("Hello controller called with two arg, foo! (e.g. http://localhost/pinky/hello/foo)"
   end
end

We strip out all previous portions of the url including the controller name (e.g. ”hello”)

Each plugin is can enforces its own rest argument format. In this example we have three levels.

Based on each we call a different function with the arguments provided.

function empty()
   return "Hello controller called with no args! (e.g. http://localhost/pinky/hello)"
end

function foo()
   return "Hello controller called with one arg, foo! (e.g. http://localhost/pinky/hello/foo)"
end

function bar()
   return "Hello controller called with two args, foo and bar! (e.g. http://localhost/pinky/hello/foo/bar)"
end

Finally we export which functions are publicly available.

return { pinky_main = pinky_main }

For almost all cases only pinky_main should be exported. Unless there is a need to make the functions available inside other plugins.

Nginx configuration

You will need to include the following in your nginx.conf

server {
    listen 44444;
    location ~ /pinky/* {
        content_by_lua '
        local pinky = require("pinky")
        ngx.say(pinky.dispatch(ngx.var.uri))
        ';
    }
}

Pinky functions

Library

exec_command(command,fields,key_field,sep,tokenize)

This function handles executing external commands.

The arguments are:

  • command: A String containing the full path to the binary and its arguments.
  • Fields: A table of the numeric positions to return.
  • Key_field: The position to use as the hash key.
  • Sep: Regular expression to split each line of output from command.
  • Tokenize: Boolean to return output as a table, or a string.
    • true = return table
    • nil = return string
dispatch(uri)

Handler for all pinky functions.

Any calls to /pinky/foo will result in foo.lua being loaded if it exists. Then foo.pinky_main() will be called with the uri relative to pinky

file_exists(filename)

Function to verify a fully qualified path/file exists. Returns boolean.

lsdir (path)

Function to return the files in the directory passed as an argument.

print_table(in_table)

Iterate over a table and

return_fields(in_table,fields)
show_functions(module)
split(pString, pPattern)

Split a string into a table with pattern.

dispatch(uri)

Handler for all pinky functions.

Any calls to /pinky/foo will result in foo.lua being loaded if it exists. Then foo.pinky_main() will be called with the uri relative to pinky

exec_command(command,fields,key_field,sep,tokenize)

This function handles executing external commands.

The arguments are:

  • command: A String containing the full path to the binary and its arguments.
  • Fields: A table of the numeric positions to return.
  • Key_field: The position to use as the hash key.
  • Sep: Regular expression to split each line of output from command.
  • Tokenize: Boolean to return output as a table, or a string.
    • true = return table
    • nil = return string
file_exists(filename)

Function to verify a fully qualified path/file exists. Returns boolean.

find_first_file(array_of_files)

This function takes a list of files and returns the first one that exists. Given platform differences we may have several places we look for something like rvm. With this we return the first one found.

get_home

return the home directory of the current user pinky is running as.

get_ip(hostname)

resolve the hostname provided to us. We use this to avoid using user input directly in commands.

get_os

Return operating system name as seen by uname.

get_username

Return full username of the current pinky process.

lsdir(directory)

Return a table of all of the files/directories listed within.

return_fields

Used in exec_command to return only those columns requested.

split(string,delimiter)

Lua lacks a natural string#split command so this provides it.

treewalker(path,function)

This function will walk a directory tree returning all files it finds. This is used in items like /proc where we want the full ps tree.

trim(string)

Remove trailing white space.

print_table(table)

Debug method used when resolving problems.