JSON logging

UnrealIRCd 6 introduces optional JSON logging in log files and in server notices sent to snomasks. This makes it easy to parse and process log messages by programs and bots.

The JSON log also contains a lot more detail than the text log because it includes, for each user, things like realname, account, operlogin, geoip information, tls information, channels, etc.

JSON Example output
This is an example of the JSON output when someone types :



Enabling in disk logging
Usually you will want to keep your ircd.log logging as plaintext (non-JSON) because it is easy to read by humans.

So just add another NEW log block with JSON logging enabled, like this: log { source { all; !debug; }       destination { file "ircd.json.log" { maxsize 100M; type json; } } } As you can see, you simply set the log::destination::file::type to json.

And then /REHASH.

Colorized JSON
The JSON logged to the file is not nicely formatted and does not contain color. The colorized JSON log as shown in the screenshot on this page is generated with the tool 'jq'. So this is all completely optional, just mentioning it for anyone interested in seeing it colorized:
 * 1) Install jq, eg through:
 * 2) Then tail (or cat) the log through it, eg:

Enabling on IRC
IRCOps receive server notices through snomasks. It is possible to receive the associated JSON logging data on IRC as well.

Since this is very new, no client supports this natively, so here is a technical explanation:
 * 1) Send   to indicate that you want to receive JSON logging, eg
 * 2) Become IRCOp using   (if you are not one already)
 * 3) Open up a debug window in your client so you can see raw IRC traffic. Eg:   in mIRC. Other clients typically have something similar.
 * 4) Now when you receive a server notice via snomasks (for example a new user connecting), then the JSON data will be sent in the   message tag.

In mIRC scripting the JSON data in the server notice will be in

Your bot/program can then parse this as JSON data and process it. The format is much more consistent than regular text messages and typically shows a lot more details about the objects involved (client, channel, etc)

Example on IRC
First, request the capability, oper up, and for this example we will also set the join snomask (+s +j): CAP REQ :unrealircd.org/json-log OPER ........... MODE Yournick +s +j

Then when another client types  we will receive the following raw server traffic: @unrealircd.org/json-log={"timestamp":"2022-05-23T11:02:13.519Z","level":"info","subsystem":"join","event_id":"LOCAL_CLIENT_JOIN","log_source":"maintest.test.net","msg":"User\sSyzop\sjoined\s#five","client":{"name":"Syzop","id":"001F9RV02","hostname":"xyz.example.org","ip":"198.51.100.1","server_port":6697,"client_port":37030,"details":"Syzop!~x@xyz.example.org","connected_since":"2022-05-23T11:02:06.000Z","idle_since":"2022-05-23T11:02:06.000Z","user":{"username":"~x","realname":"IRC\sUser","vhost":"oper/netadmin.test.net","cloakedhost":"Mask-8608861.example.net","servername":"maintest.test.net","reputation":12,"security-groups":["unknown-users","tls-and-known-users","tls-users"],"modes":"iotxz","geoip":{"country_code":"NL"}},"snomasks":"bcdfkoqsBOS","operlogin":"Syzop","operclass":"netadmin-with-override","channels":["#five","#four","#three","#two","#one"]},"tls":{"certfp":"aafe66a7d808e1fca077805c54b1274a92d30c3023e35ec130f358d238218296","cipher":"TLSv1.3-TLS_CHACHA20_POLY1305_SHA256"},"channel":{"name":"#five","creation_time":"2022-05-23T11:02:13.000Z","num_users":1,"modes":"ntf\s[4j#R1,5m#M1,3n#N1,3t#b1]:2"},"modes":"o","source":{"file":"join.c","line":292,"function":"_join_channel"}}
 * maintest.test.net NOTICE oper :join.LOCAL_CLIENT_JOIN [info] User Syzop joined #five

UnrealIRCd JSON data
Every JSON log message contains at least the following data:

In addition to that there are a couple of fields that are often included (but not always):

client object
This can be a user, a server or a freshly accepted connection that is still in the handshake and we don't know yet what it will be.

client.user
For users there is a user object within the client object:

TODO: Document. See example at the beginning of this page for now.

channel object
TODO: Document. See example at the beginning of this page for now.