mirror of
https://github.com/Doodle3D/doodle3d-firmware.git
synced 2024-11-18 03:27:56 +01:00
Remove loglite files and references (extracted to separate package).
This commit is contained in:
parent
29599f2da2
commit
68099330b0
3
Makefile
3
Makefile
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
```
|
@ -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
|
@ -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)
|
Loading…
Reference in New Issue
Block a user