Unable to read/write to file from Lua script running from HAPRoxy

I was using Lua with HAProxy to write logs into custom log file. Although my script is running totally fine. But I don’t see anything written in my text file.

Here is my lua script which I am loading from HAProxy.cfg.

local function foo(value)
    -- MY CODE --
    file = io.open("test.lua", "a")
    io.output(file)
    io.write("The value of member variable archiver is " .. o_archiver)
    io.close(file)

end

core.register_converters("foo_conv", foo)

>Solution :

Short answer is no, you cannot do I/O operations using LUA when the method in Lua script is called by HAProxy.

From docs :

HAProxy is an event driven software, so blocking system calls are absolutely
forbidden. However, the Lua allows to do blocking actions. When an action
blocks, HAProxy is waiting and do nothing, so the basic functionalities like
accepting connections or forwarding data are blocked while the end of the system
call. In this case HAProxy will be less responsive.

This is very insidious because when the developer tries to execute its Lua code
with only one stream, HAProxy seems to run fine. When the code is used with
production stream, HAProxy encounters some slow processing, and it cannot
hold the load.

However, during the initialisation state, you can obviously using blocking
functions. There are typically used for loading files.

The list of prohibited standard Lua functions during the runtime contains all
that do filesystem access:

  • os.remove()
  • os.rename()
  • os.tmpname()
  • package.*()
  • io.*()
  • file.*()

Some other functions are prohibited:

  • os.execute(), waits for the end of the required execution blocking HAProxy.

  • os.exit(), is not really dangerous for the process, but it’s not the good way
    for exiting the HAProxy process.

  • print(), writes data on stdout. In some cases these writes are blocking, the
    best practice is reserving this call for debugging. We must prefer
    to use core.log() or TXN.log() for sending messages.

Some HAProxy functions have a blocking behaviour pattern in the Lua code, but
there are compatible with the non blocking design. These functions are:

  • All the socket class
  • core.sleep()

Use the core log function to do logging in your case.

core.log(loglevel, msg)

This function sends a log. The log is sent, according with the HAProxy configuration file, on the default syslog server if it is configured.

Arguments:

  • loglevel (integer) – Is the log level asociated with the message. It is a number between 0 and 7.
  • msg (string) – The log content.

Based on the severity of log you can use the following log levels.

log level definitions

  • core.emerg
  • core.alert
  • core.crit
  • core.err
  • core.warning
  • core.notice
  • core.info
  • core.debug

Based on the logfile you have configured in your haproxy.cfg the log goes to the respective file.

eg

log /dev/log local6 debug

In this example, it sends all messages to the log device and to use the local6 setup to handle the logs.

The rsyslog.conf would have a line in it to handle local6:

local6.* /var/log/haproxy.log

Reference :

Leave a Reply