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-->