Previous Section  < Day Day Up >  Next Section

Hack 70 Tail Log Files

figs/expert.gif figs/hack70.gif

Keeping track of your log file activity is even easier when you can view real-time logs over IRC.

Many programs generate log files. If you have direct access to the filesystem, you can tail these files in real time using tail -f filename. This allows you to see the latest lines being appended to the log file every second. Most IRC bots generate log files so you can keep track of what they've been up to and to see any errors that may have occurred.

If you don't have direct access to the filesystem or if you want to let other people tail your log files, you can create an IRC bot that offers to tail files on the local machine. The bot described in this hack allows multiple users to tail the same log file over separate DCC CHAT connections.

Because log files may grow at a fast rate, you can't just send each new line via a private message to the recipient. Most IRC servers restrict the rate at which messages can be sent and will even disconnect you if you try to send too much too fast. This is why this bot will make use of DCC CHAT—it allows lines to be sent to a recipient over a direct TCP connection, bypassing the servers that make up the IRC network. This lets you send as much data as you want, without having to worry about being disconnected.

11.4.1 The Code

To restrict access to the log file, a password will be stored as plain text in the bot's source code. If you want to tail the log file, simply send this password to the bot in a private message and it will start a new thread to handle your request.

Save the main bot code as TailBot.java:

import org.jibble.pircbot.*;



public class TailBot extends PircBot {

    

    // The top-secret access password.

    private String password = "password";

    // The log file to tail.

    private String filename = "c:/temp/log.txt";

    

    public TailBot(String name) {

        setName(name);

    }

    

    public void onPrivateMessage(String sender, String login,

            String hostname, String message) {

        

        if (message.trim( ).equals(password)) {

            Thread thread = new TailThread(this, sender, filename);

            thread.start( );

        }

    }

    

}

The TailThread class will be responsible for requesting and accepting the DCC CHAT connection. This is done in a separate thread to the main bot, as it could take a long time for this to happen and it would otherwise block the normal operation of the bot.

Once the DCC CHAT connection has been established, the TailThread class will perform the tailing by checking the size of the file every second. If the file has grown since the last time it was checked, the new content will be sent directly to the connected client. If the file size remains the same, no action needs to be taken. If the file size shrinks, then the log file may have been rotated or truncated. When this happens, the user is notified and the tailing continues from the end of the file.

Save the following as TailThread.java:

import org.jibble.pircbot.*;

import java.io.*;



public class TailThread extends Thread {

    

    public static final long delay = 1000;

    private PircBot bot;

    private String nick;

    private File file;

    

    public TailThread(PircBot bot, String nick, String filename) {

        this.bot = bot;

        this.nick = nick;

        file = new File(filename);

    }

    

    public void run( ) {

        

        try {

            DccChat chat = bot.dccSendChatRequest(nick, 120000);

            if (chat != null) {

                

                long lastLength = file.length( );

                boolean running = true;

                while (running) {

                    long length = file.length( );

                    if (length > lastLength) {

                        // Open the file to get the new contents.

                        RandomAccessFile raf = new RandomAccessFile(file, "r");

                        raf.seek(lastLength);

                        String line = null;

                        // Send each new line to the connected client.

                        while ((line = raf.readLine( )) != null) {

                            chat.sendLine(line);

                        }

                        raf.close( );

                    }

                    else if (length < lastLength) {

                        chat.sendLine(Colors.RED + Colors.BOLD +

                                "[Log file truncated. Restarting at end.]");

                    }

                    lastLength = length;

                    

                    // Wait a second before the next check.

                    try {

                        Thread.sleep(delay);

                    }

                    catch (InterruptedException e) {

                        // Do nothing.

                    }

                }

                

            }

        }

        catch (IOException e) {

            // Chat session ended unexpectedly.

        }

    }

    

}

Because this bot responds only to private messages, it's not essential to place it in a channel, but doing so helps to make other people realize its presence. Save the following as TailBotMain.java:

public class TailBotMain {

    

    public static void main(String[] args) throws Exception {

        TailBot bot = new TailBot("TailBot");

        bot.setVerbose(true);

        bot.connect("irc.freenode.net");

        bot.joinChannel("#irchacks");

    }

    

}

11.4.2 Running the Hack

Compile the bot like so:

C:\java\TailBot> javac -classpath .;pircbot.jar *.java

Run TailBotMain with the following:

C:\java\TailBot> java -classpath .;pircbot.jar TailBotMain

TailBot will then start up and be ready to receive commands.

11.4.3 The Results

You will need to send your chosen password to TailBot in order to view the log activity:

/msg TailBot  password 

The bot will then send a DCC CHAT request. As soon as you accept this request, you will be connected directly to the bot and will start seeing the output from the tailing. Figure 11-3 shows a simple web server log file being tailed. The timestamps provided by the IRC client provide a useful piece of information that is missing from the log file itself.

Figure 11-3. Tailing a simple web server log file with TailBot
figs/irch_1103.gif


If you have a log file that is appended to very rarely, it may be possible to implement such a tailing system via private messages. This removes any firewall problems, as you no longer have to connect directly to the bot, but at the expense of risking disconnection if the log file updates too rapidly.

    Previous Section  < Day Day Up >  Next Section