Click here to Skip to main content
Click here to Skip to main content

Tail for Win32 - A Windows version of the Unix 'tail -f'

By , 26 Nov 2003
 

Introduction

Ever wanted to just type 'tail -f error_log' on Windows?

Envious of your Unix friends who can track changes to a file, in real time, as they happen?

Well, now with the Objektiv Tail for Win32, you'll be happily monitoring your log files like you've never done before.

What's even better, you can track several files all at the same time with the patented "Multiple Document Interface"TM technology, with each file having its own, fabulous window.

What is it?

Tail for Win32 is a Windows version of the Unix 'tail' utility. It can be used to monitor changes to a text file in real time - ideal for watching error logs.

The program was written in C++ using MFC, and uses Win32 file change notifications to monitor when a file changes.

The application uses a 'plug-in' architecture, under which all changes are passed through external DLLs that can perform various functionality.

The first plug-in is an SMTP filter. This DLL sends emails via SMTP when a keyword is found in the file being monitored.

And?...

As well as monitoring files in real time, you can also specify a set of 'keywords' that tail looks out for. When a keyword is encountered, it can be 'syntax' highlighted in a number of optional colors, and can also fire external plug-ins. This is all configurable on the fly.

The program can also be told to ignore any lines that do not contain the keywords specified; only showing 'hot' lines.

So How Does it Work?

At the core of the application is the Win32 file notification API. This API fires an event whenever a file changes in a directory. Using this event, we can track whenever changes are made to a particular file.

For each file that is monitored, a thread is set up that blocks on the firing of the file notification. This makes the application extremely efficient - it only ever does anything when a file actually changes.

This is all written in MFC under Visual Studio 6. But compiles quite happily under .NET and .NET 2003.

The following controls are used to a greater or lesser degree:

  • RichText control -version 2.0 to allow background shading
  • ListView control - with checkboxes and combo controls
  • Tree control - subclassed to handle double-clicks and right-clicks

Can I Help?

Yes, please!

The project is hosted on SourceForge, so CVS access is all part of the deal. If you think you'd like to help and can contribute even a few minutes of your time, please do get in touch!

The project homepage is: here and the CVS repository is updated at least daily, so please do check back on a regular basis.

License

Tail is released under the GPL. In a nutshell, you can do whatever you like with the source, so long as if you pass on the application for free or for profit, you must also pass on the source.

Updates

  • 4.2.7: Tally window fix. Added background and highlight colour dialogs. Slight re-jig of the object model.
  • 4.2.6: Fixed a couple of bugs with the Tally window and the Keyword configuration window.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Paul Perkins
Web Developer
United Kingdom United Kingdom
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalserious bugsmemberehaerim18 Nov '08 - 20:48 
Tail program is very nice small utility I've been using for long time.
 
However it seems to have a few serious bugs.
 
From time to time, dwBufferSize gets negative value in line 848 from ReaderThread.
 
Tail.log below was created when monitoring a single file.
 
Tali.log shows:
 
[20081119 13:21:01] (000005e8) Debug: Allocating 468 bytes for buffer
[20081119 13:21:01] (000005e8) Debug: FindNextChangeNotification returned 1
[20081119 13:21:01] (000005e8) Debug: Waiting for file change...
[20081119 13:21:01] (000005e8) Debug: WaitForMultipleObjects triggered from file wait event
[20081119 13:21:01] (000005e8) Debug: Received change event (or polled).
[20081119 13:21:01] (000005e8) Debug: File has changed size (was 708580, now 709047)
[20081119 13:21:01] (000005e8) Debug: Allocating 468 bytes for buffer
[20081119 13:21:01] (000005e8) Debug: FindNextChangeNotification returned 1
[20081119 13:21:01] (000005e8) Debug: Waiting for file change...
[20081119 13:21:01] (000005e8) Debug: WaitForMultipleObjects triggered from file wait event
[20081119 13:21:01] (00000a10) Debug: WaitForMultipleObjects triggered from file wait event
[20081119 13:21:01] (000005e8) Debug: Received change event (or polled).
[20081119 13:21:01] (00000a10) Debug: Received change event (or polled).
[20081119 13:21:01] (000005e8) Debug: File has changed size (was 709047, now 709681)
[20081119 13:21:01] (00000a10) Debug: File has changed size (was 9608, now 10008)
[20081119 13:21:01] (000005e8) Debug: Allocating 635 bytes for buffer
[20081119 13:21:01] (00000a10) Debug: Allocating 401 bytes for buffer
[20081119 13:21:01] (000005e8) Debug: FindNextChangeNotification returned 1
[20081119 13:21:01] (000005e8) Debug: Waiting for file change...
 
Bold lines show something is wrong with the file size change and it seems that two threads (5e8 and a10) are involved in this issue.
 
[20081119 13:40:03] (00000b9c) Debug: WaitForMultipleObjects triggered from file wait event
[20081119 13:40:03] (00000b9c) Debug: Received change event (or polled).
[20081119 13:40:03] (00000b9c) Debug: File has changed size (was 26803, now 27054)
[20081119 13:40:03] (00000b9c) Debug: Waiting for file change...
[20081119 13:40:03] (00000b9c) Debug: WaitForMultipleObjects triggered from file wait event
[20081119 13:40:03] (00000b9c) Debug: Received change event (or polled).
[20081119 13:40:03] (00000b9c) Debug: File has changed size (was 27054, now -1
[20081119 13:40:03] (00000b9c) Debug: Allocating -27054 bytes for buffer
[20081119 14:54:01] (00000ca4) Terminating...)

 
Here the bold line shows the -1 all of a sudden while continuously displaying the logs.
 
Can anyone fix this bugs?
 
I hope the author of this program can solve these issues.
GeneralRe: serious bugs [modified] Pinmemberehaerim18 Jun '09 - 3:15 
Finally found the fix:
 
Add the following lines after line 776 from FileReaderThread.cpp.
 
// Open the file we're interested in to see if it has changed size.
dwNewFileSize = GetFileSizeBytes (szFileName); // line 776
if (dwNewFileSize == -1)
{
continue;
}

 

And modify GetFileSizeBytes function like:
 
static DWORD GetFileSizeBytes (
  const char* pszFilename)
{
  HANDLE  hFile = NULL;
  DWORD   dwFileSize = 0;
	DWORD dwError = 0;
 
  hFile = CreateFile (pszFilename, 
                      GENERIC_READ, 
                      FILE_SHARE_READ | FILE_SHARE_WRITE, 
                      NULL, 
                      OPEN_EXISTING, 
                      FILE_ATTRIBUTE_NORMAL, 
                      NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
    // Obtain the error code. 
    dwError = GetLastError();
		LogDebugMessage("GetFileSizeBytes/CreateFile => dwError=%d, hFile=0x%p, pszFilename=%s.", dwError, hFile, pszFilename);
		return -1;
	}
  dwFileSize = GetFileSize (hFile, NULL);
	if (dwFileSize == 0xFFFFFFFF)
	{
    // Obtain the error code. 
    dwError = GetLastError();
		LogDebugMessage("GetFileSizeBytes/GetFileSize => dwError=%d, hFile=0x%p, pszFilename=%s.", dwError, hFile, pszFilename);
	}
 
  CloseHandle (hFile);
 
  return dwFileSize;
}

 
modified on Thursday, June 18, 2009 10:06 PM

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 27 Nov 2003
Article Copyright 2003 by Paul Perkins
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid