Tutorial - load balancing syslog messages by using protocol extensions
Syslog protocol available on the NetScaler appliance works only for the messages generated on the NetScaler appliance. It does not load balance the messages coming from external nodes. To load balance such messages, you need to use the protocol extensions feature and write the syslog message parsing logic by using the Lua 5.2 programming language.
Code for parsing syslog message
The code only has the TCP client data callback function defined - client.on_data(). For server data, it does not add a callback function and the server to client takes the fast native path. The code identifies message boundary based on the trailing character. If the TCP packet contains more than one syslog messages, then we split the packet based on the trailing character and load balance each message.
--[[
  Syslog event handler for TCP client data
    ctxt - TCP client side App processing context.
    data - TCP Data stream received.
--]]
function client.on_data(ctxt, payload)
                  local message = nil
                  local data_len
                  local data = payload.data
                  local trailing_character = "\n"
                  ::split_message::
                                    -- Get the offset of trailing character
                                    local new_line_character_offset = data:find(trailing_character)
                                    -- If trailing character is not found, then wait for more data.
                                    if (not new_line_character_offset) then
                                                      goto need_more_data
                                    end
                                    -- Get the length of the current message
                                    data_len = data:len()
                                    -- Check whether we have more than one message
                                    -- by comparing trailing character offset and
                                    -- current data length
                                    if (data_len > new_line_character_offset) then
                                                      -- If we have more than one message, then split
                                                      -- the data into two parts such that first part
                                                      -- will contain message upto trailing character
                                                      -- offset and second part will contain
                                                      -- remaining message.
                                                      message, data = data:split(new_line_character_offset)
                                    else
                                                      message = data
                                                      data = nil
                                    end
-- Send the data to the backend server.
                                    ns.send(ctxt.output, "EOM", {data = message})
                                    goto done
                                    ::need_more_data::
                                                      -- Wait for more data
                                                      ctxt:hold(data)
                                                      data = nil
                                                      goto done
                                    ::done::
                                                      -- If we have more data to parse,
                                                      -- then do parsing again.
                                                      if (data) then
                                                                        goto split_message
                                                      end
end
<!--NeedCopy-->