TF - ansi colored logging!

by Unknown

Back to Mechanic's Corner.

Unknown2005-05-01 01:38:40
For those who are unfamiliar with Tinyfugue, it DOES NOT do color logging. The /log command that's built-in only outputs plain-text logs. This makes it almost impossible to review combat logs and make adjustments to your system based on the logs after you logout of Lusternia. It's my biggest complaint with Tinyfugue.

After a few hours of hacking and slamming my head into the wall, I finally figured out how to get TF to log in color! biggrin.gif laugh.gif cool.gif

Here's the code, a brief explanation of how it works and how to use it will follow:
CODE
/def start_logging = \\
   /eval /set globallog_filename ~/.tf/logs/$.$.globallog %; \\
   /eval /set worldlog_filename ~/.tf/logs/$.$.worldlog %; \\
   /eval /set combatlog_filename ~/.tf/logs/$.$.combatlog %; \\
   /log -g %{globallog_filename} %; \\
   /log -i %{globallog_filename} %; \\
   /log -w %{worldlog_filename} %; \\
   /eval /set globallog $ %; \\
   /eval /set worldlog $ %; \\
   /eval /set combatlog $ %; \\
   /def -mregexp -n0 -p50 -q -t".*" catch_all_combatlog = \\
       /test tfwrite({combatlog},encode_ansi({P0})) %; \\
   /def -mregexp -n0 -p50 -q -h"SEND .*" catch_all_send = \\
       /test tfwrite({worldlog},strcat("SENT: ",{P0})) %%; \\
       /test tfwrite({combatlog},strcat("SENT: ",{P0})) %; \\
   /def -mregexp -n0 -p50 -q -h"PROMPT (\\\\d+)h, (\\\\d+)m, (\\\\d+)e, (\\\\d+)p, (\\\\d+)en, (\\\\d+)w (.*)\\\\-" catch_all_prompt =  \\
       /test tfwrite({globallog},{P0}) %%; \\
       /test tfwrite({worldlog},{P0}) %%; \\
       /test tfwrite({combatlog},encode_ansi({P0})) %; \\

/def echol = \\
   /test echo({-1},{1},1) %; \\
   /let texttolog $(/test echo\\({-1},{1},1\\)) %; \\
   /test tfwrite({combatlog},encode_ansi({texttolog}))


This code produces 3 logs. The globallog will contain all output (both mud and TF), as well as all keyboard input (both commands sent to the mud and TF commands). The worldlog will contain all mud output, and the input sent to the mud. The combatlog will contain all non-gagged mud output, anything extra I log (via the /echol command), as well as input went to the mud...and the combat log will be in color.

Why 3 logs?

Well, when I'm going through a combat log I don't really care about the random TF output, things I gagged, etc. However, I'd still like that information in case an admin needs a log or something like that. I'd also like to have a log of EVERYTHING that came through TF so my lifes a bit easier when I debug things, however I don't want that extra junk messing up my nice pretty log for the admins. So there's a combat log, a nice pretty plain-text log of all mud output/input, and copy of that nice log with all of the TF junk thrown in (combatlog, worldlog, globallog).

Next I'll break down the code from /def start_logging, explaining what it does and what adjustments you'll need to make.

CODE
/def start_logging = \\
   /eval /set globallog_filename ~/.tf/logs/$.$.globallog %; \\
   /eval /set worldlog_filename ~/.tf/logs/$.$.worldlog %; \\
   /eval /set combatlog_filename ~/.tf/logs/$.$.combatlog %; \\

These three lines create variables to hold the filenames for the three logs. All that "ftime" business is a function that generates the text for todays date. The file formats end up being year-month-day.hour-minute-second.logtype. You'll want to adjust the directories where these files are located, and the names if you wish.

CODE
   /log -g %{globallog_filename} %; \\
   /log -i %{globallog_filename} %; \\
   /log -w %{worldlog_filename} %; \\

These three lines use some of the built-in logging features TF has for the non color logs. The first lines sends all mud and local output the to globallog. The second sends all keyboard input (both mud and tf commands) to the globallog. The last line sends only mud output to the worldlog.

CODE
   /eval /set globallog $ %; \\
   /eval /set worldlog $ %; \\
   /eval /set combatlog $ %; \\

The logging features of TF leave a lot to be desired. They don't include the prompts or color. These three lines open up the three log files for appending, so we can add stuff to them.

CODE
   /def -mregexp -n0 -p50 -q -t".*" catch_all_combatlog = \\
       /test tfwrite({combatlog},encode_ansi({P0})) %; \\

This line is the one that handles all of the coloring for the combatlog. What it does is grab EVERY line of text, encode that line with the ansi codes terminals understand, then writes it to the log file. You'll need to adjust the priority (-p50) of this line to fit in your system. You want this trigger's priority to be the lowest, that way any lines you have other triggers color or adjust will be reflected in your log.

All of your triggers which grab text you want in this log MUST be have their fallthrough property (-F) set, otherwise the text won't make it down to this logging trigger. Any triggers you have set to gag text, should probably NOT have their fallthrough property (-F) set, that way the text WON'T appear in this log. If you're a bit confused on how priority works in TF have a look at /help priority, it gives a good description. If you still have questions on it, you can always contact me.

Here's the priority scheme I'm using for the rest of my system:

Prompt Triggers: (300 <= p < 400)
- primary = p375
- secondary = p350

Highlights: (200 <= p < 300)
- afflictions = p290
- cures = p280
- actions = p250
- players = p220
- target = p210

All other Trigs: (100 <= p < 200)
- standard = p150

Logging: (0 < p < 100)
- standard = p50

CODE
   /def -mregexp -n0 -p50 -q -h"SEND .*" catch_all_send = \\
       /test tfwrite({worldlog},strcat("SENT: ",{P0})) %%; \\
       /test tfwrite({combatlog},strcat("SENT: ",{P0})) %; \\

This trigger catches everything that is sent to the mud, and NOT tinyfugue, and logs it to the world and combat logs. I wanted to signify text I sent in some uniform way, making it easier to identify. So it logs "SENT: " instead of just the command.

CODE
   /def -mregexp -n0 -p50 -q -h"PROMPT (\\\\d+)h, (\\\\d+)m, (\\\\d+)e, (\\\\d+)p, (\\\\d+)en, (\\\\d+)w (.*)\\\\-" catch_all_prompt =  \\
       /test tfwrite({globallog},{P0}) %%; \\
       /test tfwrite({worldlog},{P0}) %%; \\
       /test tfwrite({combatlog},encode_ansi({P0})) %; \\

TF's built-in logging never seems to log the prompt. This is a huge pain for logs in general, especially combat logs. This trigger logs every prompt to all three logs, and logs the prompt in color for the combatlog. You'll want to adjust the regexp for the prompt trigger to match your prompt. I use CONFIG PROMPT ALL in Lusternia.


You probably noticed there's another function, /def echol, that's what we're discussing next.

I use the /echo command quite often in my system. Primarily to replace text (have a trigger that gags some text, then echos the replacement with whatever color attributes I want), but also to notify myself of things I do and whatnot. The /echo command's output, since it doesn't come from the mud, does NOT get captured by our combatlog's trigger. It took me a while to figure out how to approach this. It's something that HAD to be done, since I wanted my balance trigger rewrites (herb, arm, sip, etc) to appear as I see them in my client and not as they appear from the mud.

My solution was to write a replacement for the /echo command. /echol is that replacement. The syntax for /echol is pretty similar to /echo, but it also logs what you're echoing to your combatlog. To echo some text in bright red you might do the following:
CODE
/echo -aBCred blah blah blah

Instead of that, I'll now use:
CODE
/echol BCred blah blah blah


The first argument to /echol must be some "attribute", the rest of the command is echoed.


Enough already, how the heck do I use this thing?

If you just simply load the code I pasted above while you're connected to TF, just type /start_logging, and everything will start being logged. I set mine up to start logging as soon as I connect to Lusternia. The way to do this is with a CONNECT hook. You can add the following code to your .tfrc file to have it log yourself in automatically and start logging (just remember to remove your username/password if you send your file to someone). Three seconds after you're logged in, it creates the logs and starts logging everything.

CODE
/def -mregexp -n1 -h"CONNECT .*" initialization = \\
   /send %; \\
   /send %; \\
   /repeat -3 1 /start_logging


To view the combatlog in color I use the less command in my terminal:

CODE
less -R 2005-04-30.21-37-32.combatlog


You could use just about any other file displaying program in the terminal. I believe there are many ansi-to-html converter programs available, and other such things, if you'd prefer the log files to be in another file format.
Unknown2005-05-01 02:46:56
You're bloody brilliant!