Saving debugging output to a file

ZeroBrane Studio is often used for remote debugging, when the application being debugged is running on a different computer or a device, and it is very convenient to be able to "redirect" its printed output to the IDE. The IDE supports this functionality and not only allows "redirecting" of the printed output, but also pretty prints the results such that local t = {a = 1, b = 2} print(t) will print {a = 1, b = 2}. This option is turned on by default for some interpreters and can be explicitly enabled using debugger.redirect configuration option.

This is all good, but what if you have a long running process and want to be able to use this "remote" printing as a log file. The plugin below allows you to do just that: it will dump all the "remote" output to a file (output.log by default) in the current project folder. It also limits the number of records in the Output window (100 by default) to allow you to generate a large number of records without taking more memory.

You can save the plugin to packages/outputtofile.lua and after restarting the IDE all the remote output will be dumped to a local log file.

local filter, fname
local function append(fname, s)
  if not fname then return end
  local f = io.open(fname, "a")
    or error(("Can't open file '%s' for writing"):format(fname))
  f:write(s)
  f:close()
end

return {
  name = "Output to file",
  description = "Redirects debugging output to a file.",
  author = "Paul Kulchenko",
  version = 0.1,

  onRegister = function(self)
    local config = ide:GetConfig()
    local output = ide:GetOutput()
    local maxlines = self:GetConfig().maxlines or 100

    filter = config.debugger.outputfilter
    config.debugger.outputfilter = function(s)
      local start  = output:GetLineCount() - maxlines
      if start >= 0 then -- trim the output to the right number of lines
        local readonly = output:GetReadOnly()
        output:SetReadOnly(false)
        output:SetTargetStart(0)
        output:SetTargetEnd(output:PositionFromLine(start+1))
        output:ReplaceTarget("")
        output:SetReadOnly(readonly)
      end
      append(fname, s)
      return s
    end
  end,

  onUnRegister = function(self)
    ide:GetConfig().debugger.outputfilter = filter
  end,
  onProjectLoad = function(self, project)
    fname = MergeFullPath(project, self:GetConfig().fname or "output.log")
  end,
}
You should get a copy of my slick ZeroBrane Studio IDE and follow me on twitter here.

Leave a comment

what will you say?
(required)
(required)

About

I am Paul Kulchenko.
I live in Kirkland, WA with my wife and three kids.
I do consulting as a software developer.
I study robotics and artificial intelligence.
I write books and open-source software.
I teach introductory computer science.
I develop a slick Lua IDE and debugger.

Recommended

Close