Cogito, ergo sum
Legacy:FileLog
FileLog lets you write to an independant log file (rather than the normal UT2003.log). From what I gather, its usage is simple:
- Create an instance of FileLog.
- Call OpenLog() on the instance to open the log file with a filename (minus extension) you specify - the file will be placed in the "User Logs" folder with a .log extension
- Write to the log using Logf(String)
- Close the log using CloseLog()
Properties[edit]
- pointer LogAr
- Internal pointer to the file archive. You can't do anything with this.
- string LogFileName
- The filename used, this will be set after the call to OpenLog().
Methods[edit]
Native Functions[edit]
- CloseLog ( )
- Close the log file.
- Logf (string LogString)
- Write the string LogString to the opened file.
- OpenLog (string FName)
- Open a log file with the filename as defined by FName. Note: the filename can only contain alphanumeric characters and a few symbols. The following symbols will be converted to an '_': ':', '\', '/', '.'
The extention '.log' will always be appended to the filename, and the files will be saved in the ../UserLogs directory.
Events[edit]
- Destroyed ( )
- This will automatically close the log file.
Notes[edit]
The output is buffered, that means nothing will be flushed to the actual log file until the buffer is full. So when the server shuts down without the FileLog being closed the log file will not contain the last few log lines.
The event Destroyed(); is actually never called. So you have to do your own checking to close the file, a good method is to enable the Tick() event and check if Level.NextURL != ""
and then close the file. This does ofcourse not work when you shut down the server.
Important: files can only be opened once, if you try to open a file that is already opened the server will crash. So be sure to make the log file name unique per server. The following code is a usefull addition to your mod, it will allow users to configure the name of the log file with the aid of a couple place holders
function string GetServerPort() { local string S; local int i; // Figure out the server's port. S = Level.GetAddressURL(); i = InStr( S, ":" ); assert(i>=0); return Mid(S,i+1); } function string LogFilename() { local string result; result = sFileFormat; ReplaceText(result, "%P", GetServerPort()); ReplaceText(result, "%N", Level.Game.GameReplicationInfo.ServerName); ReplaceText(result, "%Y", Right("0000"$string(Level.Year), 4)); ReplaceText(result, "%M", Right("00"$string(Level.Month), 2)); ReplaceText(result, "%D", Right("00"$string(Level.Day), 2)); ReplaceText(result, "%H", Right("00"$string(Level.Hour), 2)); ReplaceText(result, "%I", Right("00"$string(Level.Minute), 2)); ReplaceText(result, "%W", Right("0"$string(Level.DayOfWeek), 1)); ReplaceText(result, "%S", Right("00"$string(Level.Second), 2)); return result; }
Discussion[edit]
Foxpaw: A less hacky way of having the FileLog destroy itself would be to have it destroyed, by whatever actor is using it to write stuff, in that actors destroyed function.
EricBlade: My FileLog crashes the engine if you don't immediatly close it after writing (Land of the Dead, engine 2226).. had to subclass GameStats to make that work right, and have it open and close the log after each write. However, this leads to a bunch of "Opened user log" lines in the main log, can I use Suppress= in the INI to suppress those messages?
El Muerte: No you need to close it before the game switches to a new map. Pre UE2.5 the log file wasn't properly closed.
EricBlade: If I do
file.OpenLog("test"); file.logf("test");
without a file.CloseLog(); after, I get a GPF. :(
El Muerte: When do you get the GPF? Also note, that only one filelog instance can write to a file, if an other files opens it it will also crash
EricBlade: The crash message says that it crashes in the logf() call, but since it only does it if i don't close the file, it doesn't make any sense. The actual code that I was using was:
var FileLog AdminLog; function alog(string x, optional name tag) { if(AdminLog == None) { AdminLog = spawn(class'FileLog'); if(AdminLog != None) { AdminLog.OpenLog("admin"); AdminLog.Logf(tag@x); } else { log(x, tag); } } else { AdminLog.Logf(tag@x); } }
I also got the same GPF if I enabled StatsLogging on the server, until I subclassed GameStats to close the log immediatly after writing.