info-beamer

Screen black all of a sudden

#1

Hello,
we are running info beamer standalone. After one day of uptime, while our customer surveyed the application, everything went black all of a sudden.

I have logged into the Raspberry and this is the log from readproctitle (set up following https://info-beamer.com/blog/running-info-beamer-in-production this guide)

readproctitleserviceerrors:.............................................................(LINE CUT FOR CLARITY)
supervise: fatal: unable to acquire info-beamer/supervise/lock: file does not exist
supervise: fatal: unable to acquire ib-input/supervise/lock: file does not exist
supervise: fatal: unable to acquire log/supervise/lock: file does not exist
python: no process found
Service start 

*************


Device type is 2 and starting pos is 0,0

But I have two services running, and this last lines seems the log from the pyhton service that listens for touch events. How can I be sure to read logs of the infobeamer service?
I have setup two services in /etc/service. One info-beamer as per Florian doc, another service to start the event listener. Maybe the log gets overwritten?

Thank you,

#2

Do your service directories look like this?

<dir>/run
<dir>/log/run

If so, daemontools, which I assume you use, will start both the top-level run executable and the log/run executable and pipe the stdout output of the former into stdin of the latter. It’s then the job of the latter for persist that log somewhere.

The log/run might look like this which forwards the log output to syslog (which then probably ends up in /var/log/syslog):

#!/bin/sh
export SERVICE=$(basename $(dirname $PWD))
exec logger -t $SERVICE

For any log to actually end up there, the run executable must output to stdout. That’s why info-beamer on the hosted OS is started like this (slightly modified to fit in one line). Not the stderr to stdout redirection using 2>&1:

#!/bin/sh
[..setting up env vars..]
exec nice -n -5 /info-beamer/info-beamer /space/root 2>&1
#3

ehm… just one directory/service has the subdir log… And yes I use daemontools as per your tutorial. But the one that I think is missing the log is the less important service (the python script). Do you suggest using log also for this one?
now my dir layout is

/service/info-beamer/run
/service/info-beamer/log/run
/service/ib-input/run


I hope the crash happens again before showtime, so to be able to look at the log files. Busybox should put them in memory and i will be able to use logread or something like this I think.
Thanks
W

#4

Unless you intend to have a read-only FS, using normal syslog based logging might be more useful as the log is then persistent in /var/log/syslog on Raspbian (I think. At least that’s how it worked last time I checked).

On the hosted OS, logger logs to /dev/log which the busybox syslogd picks up and then logs into a circular memory buffer that is readable with logread. So a reboot wipes all logs. Unless you set that up on Raspbian as well, using logger should result in messages added to /var/log/syslog.

#5

Hi,
yes I have a read only FS, to be safe from power failures and subsequent FS corruption. Moreover presentation data don’t change.

I followed a tutorial on making my raspberry SD card full R/O and it had busybox installed. I know a reboot erases everything, but due to panic (!) I didn’t spend enough time investigating and just did reboot, silly me. I was just wondering if the service setup is correct for logging even with the mess I made.
Thanks anyway

#6

If logging is setup up correctly, you should see new output being added by info-beamer at least every 10 seconds when running logread -f. Is that the case?

#7

Hi,
I will check tonight on a dev device (devices at the exhibition are a bit difficul to reach). I really hope so…

By the way, our render code is copied in structure from uour in touch Ui experiments.

function render()
   -- do some prep work
    ..... 
   while ui.loop()
      .... 
      -- do main work, animations etc   
   end
end

function node.render()

    gl.clear(0, 0, 0, 0)
    config.st()

    ui.run(render)
    -- parse input params
    ui.input_state(input_state.down, input_state.x, input_state.y, input_state.hover_x, input_state.hover_y)

end

-- coroutine based continuous UI

local _run
function ui.run(entry)
    if not _run then
        _run = coroutine.wrap(entry)
    end
    _run()
end

function ui.loop()
    coroutine.yield()
    return true
end

if our node.lua produces an error (during the render function) because I don’t know, something unexpected happens, we make a call to a lua method on an uninitialized image (for example) or we access an array out of bounds, do you suggest encapsulating the call to ui.run in a pcall could return us errors so we can take approrpiate actions, for example start everything from the beginning?

For example. a code inside our render that does this wrong call to info beamer LUA API (like this for the sake of argument)

local img = resource.load_image("file.png")
img:dispose()
local size = img:size() --throw error

will throw an error. Will it be “catched” by the pcall so we could at least go back to a known state?

I’m writing this because I am a bit afraid of users interacting for 3 full days with our touch signage and finding bugs we didn’t have time to test (overall dev was 2 weeks…)
Thanks

#8

coroutine.wrap creates a new coroutine and calls the passed function. In that case render. If that function causes an error, the coroutine enters the dead state and in case of an error _run() will also throw that error in the caller (see here).

Without testing this, something like

local ok, err = pcall(_run)
if not ok then
    print(err)
    _run = nil
end

should implement the “restart on error” logic.

1 Like
#9

Hi Florian,
I’ve discovered it by myself. So my render code is like this now.

function node.render()

    gl.clear(0, 0, 0, 0)
    config.st()

    status, error = pcall(ui.run, render)
    if status == false then
        -- reset coroutine
        ui.reset()
        -- clean up cache
        pcall(function()
            -- do house chores (ensuring they don't in turn return errors)
        end)
        -- restart from beginning
        current_page = root_page
    end

    ui.input_state(input_state.down, input_state.x, input_state.y, input_state.hover_x, input_state.hover_y)
end

I’ve testd by causing some exceptions and it seems to work as expected. Thank you for your guidance.

BTW on my reference machine, cloned from the ones in production, logread -f work as you foretold me! So it has the circular buffer of log messages (in memory) thrown by daemontools while running my service, and collected via busybox