Remove loglite files and references (extracted to separate package).

This commit is contained in:
Wouter R 2016-06-05 23:35:47 +02:00
parent 29599f2da2
commit 68099330b0
6 changed files with 2 additions and 434 deletions

View File

@ -116,9 +116,6 @@ define Package/wifibox/install
$(INSTALL_BIN) $(WIFIBOX_BASE_DIR)/script/d3d-updater.lua $(1)/$(TGT_LUA_DIR_SUFFIX)/script
$(LN) -s /$(TGT_LUA_DIR_SUFFIX)/script/d3d-updater.lua $(1)/bin/d3d-updater
$(CP) $(WIFIBOX_BASE_DIR)/script/loglite-filters.lua $(1)/root/
$(INSTALL_BIN) $(WIFIBOX_BASE_DIR)/script/loglite.lua $(1)/$(TGT_LUA_DIR_SUFFIX)/script
$(LN) -s /$(TGT_LUA_DIR_SUFFIX)/script/loglite.lua $(1)/bin/loglite
$(INSTALL_BIN) $(WIFIBOX_BASE_DIR)/script/wifibox_init $(1)/etc/init.d/wifibox
$(INSTALL_BIN) $(WIFIBOX_BASE_DIR)/script/dhcpcheck_init $(1)/etc/init.d/dhcpcheck
$(INSTALL_BIN) $(WIFIBOX_BASE_DIR)/script/d3dapi $(1)/$(TGT_LUA_DIR_SUFFIX)/script

View File

@ -1,6 +1,6 @@
local M = {
BASE_PATH = 'src',
EXCLUDE_FILES = { 'src/util/JSON.lua', 'src/util/urlcode.lua', 'src/script/loglite%-filters.lua' },
EXCLUDE_FILES = { 'src/util/JSON.lua', 'src/util/urlcode.lua' },
PROCESS_FILES = {
['src/[^/]*%.lua'] = 'lua',
['src/network/[^/]*%.lua'] = 'lua',

View File

@ -61,6 +61,7 @@ if [ $? -gt 0 ]; then
alias encore='ulimit -c unlimited'
alias wopkg='opkg -f /usr/share/lua/wifibox/opkg.conf'
# Convenience aliases for the loglite script (separate package)
alias tailfw='loglite /tmp/wifibox.log firmware'
tailp3d() {
logfile=/tmp/print3d-ttyACM0.log

View File

@ -1,92 +0,0 @@
## Loglite
The loglite script allows coloring and filtering of log files by specifying certain patterns and associating directives to them. These mainly specify colors but additionally, (non-)matched lines can be deleted from output and also all output lines can be numbered.
### Usage
The script can follow an existing log file (comparable to `tail -f`), or it can follow its standard input. A file to follow is always specified as the first argument and a filter set name as the second (use '-' as file name to read from standard input). Details on filter sets can be found below. If no filter set is mentioned on the command-line, the script will attempt to use one named 'default'.
* Example following an existing log file using a filter set named 'example':
`./loglite.lua print3d.log example`.
* Example using standard input, to filter/view a whole log file, with a filter set named 'serial' (note the '-' as file name):
`cat print3d-ttyACM0.log | ./loglite.lua - serial`
* Example using standard input, to capture both output streams from `print3d`, with a filter set named 'example' (note the '-' as file name):
`./print3d -V 2>&1 | ./loglite.lua - example`.
#### On WiFi-Box
Loglite is already installed since version 0.10.10 as `loglite`.
Check `/root/.profile` for handy aliases like `tailfw` and `tailp3d`.
### Filter sets
The script looks for filter sets in the file '$HOME/loglite-filters.lua'. It looks like this:
``` lua
local M = {}
M.default = {
['options'] = { mode = 'keep', count = 'none' },
['patterns'] = {
['%(error%)'] = 'red',
['%(warning%)'] = 'yellow',
['%(bulk%)'] = 'bold,black'
}
}
M.specialization = {
['parent'] = 'default',
['options'] = { mode = 'delete' }
['patterns'] = {
['setState%(%)'] = 'bblue,_nodelete'
}
}
return M
```
Here, the declaration and returning of `M` is required for the loglite script to be able to cleanly import the file. In `M.default`, 'default' is the name of a filter set being defined (similar for 'specialization'). Definitions can contain three so-called keys: 'parent' specifies a filter set to inherit from in order to reduce code duplication, 'options' and 'patterns' are described below.
Inheritance can be used to set new keys or to override keys from the parent set. Previously set keys cannot be removed, but they can be set to a non-existing directive (e.g., Lua's 'false' keyword) to achieve the same effect. Note that directives in inheriting sets are currently not combined with previous ones, so for instance overriding `['test'] = 'red, _delete'` with `['test'] = 'blue'` will result in only the directive 'blue' to be applied.
#### Options
Two options are currently available:
* `mode`, which specifies whether to keep log lines (`keep`, the default) or to drop them (`delete`). For specific lines this can then be overridden, see 'Patterns' below.
* `count`, which can be set to `all` to prefix log lines with a counter, or `none` (default) to leave them as is.
#### Patterns
Pattern specifications are patterns as used in Lua: [Lua documentation on patterns](http://www.lua.org/pil/20.2.html).
The following directives can be associated with a pattern:
* A foreground color, one of: black, red, green, yellow, blue, magenta, cyan or white.
* A background color, like foreground colors but prefixed with 'b'.
* `bold`, which usually has the effect of rendering a bright variant of the foreground color (note that `bold,black` renders as dark gray).
* `reverse` will reverse fore- and background colors.
* Also available are `blink` and `underscore` but they do currently not work in all terminal programs or might need to be enabled in the preferences.
* `_delete` or `_nodelete` to override the active mode specified in the 'options' above.
Directives can be combined with ',' (e.g.: `'red,_nodelete'`). Finally, in any filter set, pattern rules are matched from top to bottom, the last one encountered overriding any previous conflicting directive.
### Installation
Note: Loglite is already installed on the WiFi-Box since version 0.10.10.
Install Lua. See:
http://lua-users.org/wiki/LuaBinaries
It's tested in Lua 5.1 and Lua 5.2.
Loglite will check for a `loglite-filters.lua` file in your home directory. It's recommended to create a symbolic link to the latest version.
On OS X / Linux:
```
cd
ln -s [absolute path to file]/loglite-filters.lua loglite-filters.lua
```
It's recommended to create a symbolic link in one of your PATH directories (`echo $PATH`) to the loglite.lua file. This allows you to run `loglite` from any directory.
On OS X / Linux:
```
cd /usr/local/bin
ln -s [absolute path to file]/loglite.lua loglite.lua
```

View File

@ -1,63 +0,0 @@
local M = {}
M.default = {
['options'] = { mode = 'keep', count = 'none' },
['patterns'] = {
['%(error%)'] = 'red',
['%(warning%)'] = 'yellow',
['%(bulk%)'] = 'gray',
['setState%(%)'] = 'bblue'
}
}
-- filter rules for firmware log (/tmp/wifibox.log)
M.firmware = {
['parent'] = 'default',
['patterns'] = {
['START%-RQ'] = 'bblue',
['END%-RQ'] = 'blue'
}
}
-- filter rules for print3d log (/tmp/print3d-*.log)
M.print3d = {
['parent'] = 'default',
['patterns'] = {
['Print 3D server'] = 'byellow',
['sendCode%(%)'] = 'green',
['readCode%(%)'] = 'blue',
['readResponseCode%(%)'] = 'blue'
}
}
-- filter rules for serial communcation of print3d
M.serial = {
['options'] = { mode = 'delete', count = 'none' },
['patterns'] = {
['Print 3D server'] = 'byellow,_nodelete',
['sendCode%(%)'] = 'green,_nodelete',
['readCode%(%)'] = 'blue,_nodelete',
['readResponseCode%(%)'] = 'blue,_nodelete',
['setState%(%)'] = 'bblue,_nodelete',
['%[ABSD%]'] = 'gray,_nodelete', -- 0.10.10
['%[ABD%]'] = 'gray,_nodelete', -- 0.10.9
['%(info%)'] = 'gray,_nodelete' -- 0.10.10
}
}
M.test = { -- TEST set
['options'] = { mode = 'keep', count = 'all' },
['patterns'] = {
['%(info%)'] = 'yellow'
}
}
M.printstart = {
['options'] = { mode = 'delete' },
['patterns'] = {
['print started'] = '_uppercase,bwhite'
}
}
return M

View File

@ -1,275 +0,0 @@
#!/usr/bin/env lua
--[[
For documentation on this script, see README-loglite.md.
Ideas for improvement:
* add more directives like uppercase, prefix/suffix?
* create separate package for this script: a) since it is useful for any log file, b) this file is getting somewhat long
* for broader terminal support: detect `tput` and use it if available (http://wiki.bash-hackers.org/scripting/terminalcodes)
* pre-split keyword lists for efficiency instead of redoing this at every new line?
FIXME:
* with deleteMode enabled, multiple matches and _nodelete in a later match, previous directives are ignored
]]--
--[[========================================================================]]--
--Note: overview of ANSI escape codes: http://ascii-table.com/ansi-escape-sequences.php (support varies per terminal/termtype)
local ANSI_COLORS = {
['bold'] = 1,
['underscore'] = 4,
['blink'] = 5, -- on osx/iterm2, this has to be enabled in preferences
['reverse'] = 7,
['black'] = 30,
['red'] = 31,
['green'] = 32,
['yellow'] = 33,
['blue'] = 34,
['magenta'] = 35,
['cyan'] = 36,
['white'] = 37,
['bblack'] = 40,
['bred'] = 41,
['bgreen'] = 42,
['byellow'] = 43,
['bblue'] = 44,
['bmagenta'] = 45,
['bcyan'] = 46,
['bwhite'] = 47
}
local ESCAPE_STR = string.char(27) .. "["
local RESET_CODE = ESCAPE_STR .. "m"
local DFL_FILTERSET_FILE = "loglite-filters.lua"
--[[========================================================================]]--
--- Stringifies the given object.
-- From util/utils.lua
-- Note that self-referencing objects will cause an endless loop with the current implementation.
-- @param o The object to convert.
-- @treturn string Stringified version of o.
local function dump(o)
if type(o) == 'table' then
local s = '{ '
for k,v in pairs(o) do
if type(k) ~= 'number' then k = '"'..k..'"' end
s = s .. '['..k..'] = ' .. dump(v) .. ','
end
return s .. '} '
else
return tostring(o)
end
end
--- Splits a string on a given divider character.
-- From util/utils.lua
-- @string[opt=':'] div The divider character to use.
-- @return An array containing the resultant substrings.
-- @usage local str = "a,b,c"; local parts = str:split(',')
function string:split(div)
local div, pos, arr = div or ':', 0, {}
for st,sp in function() return self:find(div, pos, true) end do
table.insert(arr, self:sub(pos, st - 1))
pos = sp + 1
end
table.insert(arr, self:sub(pos))
return arr
end
--- Determines if filename exists and can be opened for reading.
-- From http://stackoverflow.com/a/4991602
-- @string filename The file to test.
-- @return True if the file exists and is readable, false otherwise.
function fileExists(filename)
local f = io.open(filename, "r")
if f ~= nil then io.close(f) return true else return false end
end
--- Converts keys of a table into a string.
-- Adapted from http://stackoverflow.com/a/12674376.
-- @string tbl A key/value table.
-- @string[opt=','] sep Separator to use between items.
-- @boolean[opt=false] sort Whether or not to sort the resulting list.
-- @return A string with all keys from the given table.
local function keysToString(tbl, sep, sort)
local sep, sort = sep or ',', sort or false
local keyset, n = {}, 0
for k,_ in pairs(tbl) do
n = n + 1
keyset[n] = k
end
if sort then table.sort(keyset) end
return table.concat(keyset, sep)
end
--- Merge two tables recursively (i.e., subtables also get merged).
-- from: http://stackoverflow.com/a/1283608
-- @table t1 Table to merge into.
-- @table t2 Table to merge into t1.
-- @return The combined table (actually t1).
function mergeTables(t1, t2)
for k,v in pairs(t2) do
if type(v) == "table" then
if type(t1[k] or false) == "table" then
mergeTables(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
t1[k] = v
end
end
return t1
end
local function hasValue(t, needle)
for k,v in pairs(t) do
if needle == v then return k end
end
return nil
end
local function makeAnsiCode(key)
if not ANSI_COLORS[key] then return nil end
return ESCAPE_STR .. ANSI_COLORS[key] .. 'm'
end
--[[========================================================================]]--
local function tailStream(stream, filterSet)
patterns = filterSet and filterSet.patterns or {}
options = filterSet and filterSet.options or { ['mode'] = 'keep' }
local c = 0
for line in stream:lines() do
--c = c + 1 -- Note: this would also count deleted lines
local embellished = line
local keepLine = (options.mode == 'keep')
local keepLineOverridden = false
-- look for a pattern matching this line
for p,c in pairs(patterns) do
if line:match(p) then
-- print("[DEBUG] +matched rule '" .. p .. "'/'" .. c .. "' against '" .. line .. "'")
local kws = c:split(',')
if hasValue(kws, '_delete') then keepLine = false; keepLineOverridden = true
elseif hasValue(kws, '_nodelete') then keepLine = true; keepLineOverridden = true
end
if keepLine then
-- first collect formatting sequences
local fmt = ''
for _,kw in ipairs(kws) do
local code = makeAnsiCode(kw)
if code then fmt = fmt .. code end
end
-- then wrap the line in formatting, if any
if fmt:len() > 0 then embellished = fmt .. embellished .. RESET_CODE end
else
-- Note: break out of loop and stop processing when line should be deleted _if_ the default has been overridden to do so
if keepLineOverridden then
embellished = nil
break
end
end
--break -- Note: don't break, allow multiple matches per line, e.g. to mix and match fg and bg colors
end
end
if embellished and keepLine then
c = c + 1
if options.count == 'all' then print(c, embellished)
else print(embellished) end
else
-- print("[DEBUG] -skipped '"..line.."'")
end
--c = line:match 'truncated' and 0 or c -- from tail on stderr apparently
end
end
--TODO: could be extended to look for multiple filenames in multiple paths
local function readConfigFile(filename, searchPath)
fullPath = searchPath .. '/' .. filename
if not fileExists(fullPath) then
--print("[DEBUG] config file '" .. fullPath .. "' not found")
return nil
end
--print("[DEBUG] using config file '" .. fullPath .. "'")
-- require does not accept full paths? also, pcall does not help with dofile
return dofile(fullPath)
end
--- Load filter set with given name from configSets, with inheritance as specified.
local function readFilterSet(configSets, setName)
local result = {}
for k,_ in pairs(configSets) do
if k == setName then
parent = configSets[setName]['parent']
if parent ~= nil then
--print("[DEBUG] recursing for filter set '" .. parent .. "' from config")
result = mergeTables(result, readFilterSet(configSets, parent))
end
--print("[DEBUG] using/merging filter set '" .. setName .. "' from config")
result = mergeTables(result, configSets[setName])
break
end
end
return result
end
--NOTE: if command-line options get any more complex, switch to a lightweight
-- getopt like this one? https://attractivechaos.wordpress.com/2011/04/07/getopt-for-lua/
local function main()
-- handle command-line arguments
local showHelp, followFile, filterSetName = false, nil, 'default'
if #arg > 0 and arg[1] == "-h" or arg[1] == "--help" then
showHelp = true
else
if #arg > 0 and arg[1] ~= '-' then followFile = arg[1] end
if #arg > 1 then filterSetName = arg[2] end
end
-- read filter set file if available
local configSets = readConfigFile(DFL_FILTERSET_FILE, os.getenv('HOME')) or {}
local filterSet = readFilterSet(configSets, filterSetName)
-- print("[DEBUG] final filter set for '" .. filterSetName .. "' from config: " .. dump(filterSet))
-- if requested, display help and exit
if showHelp and showHelp == true then
print("Usage: loglite.lua [file-to-tail] [filter-set]")
print(" If no arguments are supplied, or if the first one is `-', stdin is used as input.")
print(" If no filter set is supplied, a set named `default' will be looked for.")
print(" Filter sets can be defined in a file `loglite-filters.lua' in your home directory.")
print()
print(" Available filter sets in " .. os.getenv('HOME') .. "/" .. DFL_FILTERSET_FILE .. ": " .. keysToString(configSets, ', ', true))
os.exit(0)
end
-------------------------
--print("[DEBUG] following file: '" .. (followFile and followFile or "<stdin>") .. "', with filter set '" .. filterSetName .. "'.")
--Info on tailing a file: https://stackoverflow.com/questions/17363973/how-can-i-tail-f-a-log-filetruncate-aware-in-lua
--local tailin = io.popen('tail -F '..(...)..' 2>&1', 'r')
local tailin = followFile and io.popen('tail -f ' .. followFile, 'r') or io.stdin
pcall(tailStream, tailin, filterSet) -- Note: protected call to suppress interrupt error thrown by lines iterator
end
main()
os.exit(0)