Okay, so while working on the syslog target for NLog, I of course studied the syslog RFC to properly be able to send messages in the correct format.

A syslog message always starts of with a PRI field which is a composite of a Facility number and a Severity number. Facility numbers range from 0 to 23 and Severity numbers from 0 to 7:

enum SyslogFacility
    Kernel = 0,
    User = 1,
    Mail = 2,
    Daemons = 3,
    Authorization = 4,
    Syslog = 5,
    Printer = 6,
    News = 7,
    Uucp = 8,
    Clock = 9,
    Authorization2 = 10,
    Ftp = 11,
    Ntp = 12,
    Audit = 13,
    Alert = 14,
    Clock2 = 15,
    Local0 = 16,
    Local1 = 17,
    Local2 = 18,
    Local3 = 19,
    Local4 = 20,
    Local5 = 21,
    Local6 = 22,
    Local7 = 23
enum SyslogSeverity
    Emergency = 0,
    Alert = 1,
    Critical = 2,
    Error = 3,
    Warning = 4,
    Notice = 5,
    Informational = 6,
    Debug = 7

Okay, so to generate the PRI field, we first multiply the Facility by 8 and then add the Severity.
A message with Facility Local3and Severity Error gives the following:


So the PRI field in this syslog message would contain the value 155, letting the syslog server identify how to categorize the message.

Now, when the syslog server receives the message, a relatively simple operation allows the server to identify the Facility and Severity of the message.

To find the Facility, the PRI value is run through a bitwise right-shift three times, which leaves us the correct value (19)

int intFacility = intPri >> 3;

To find the Severity, the PRI value is run through an AND 0x7. This again leaves us with the correct Severity (3)

int intSeverity = intPri & 0x7;

My question is not so much how this works (I’ve done the maths on paper and yes it works) but WHY. I just don’t get the mechanics of it.

Why exactly right shift 3 times and why exactly AND 0x7 – how are these two numbers established?

Could I use a similar method to build my own little system containing two parameters with an arbitrary number of values in each? If so, is there a simple way of telling how to first combine the two into a single value for transmitting over the wire, and then how do I figure out how to get back to the two original values, knowing only the combined value and the number of possible values in the two lists?

If someone can explain this to me in relatively simple terms, I’d be really happy (I might even buy you a beer!)