A number of utility scripts and programs are supplied with Exim. Most of them are built as part of the normal building process, but the log file analyser is entirely free-standing.
The shell script called `exiwhat' first of all empties the process log file in Exim's log directory. It then uses the `ps' command to find all processes running exim, and sends each one the SIGUSR1 signal. This causes each process to write a single line describing its current activity to the process log. The script then waits for one second to allow the Exim processes to react, then copies the file to the standard output.
Unfortunately, the `ps' command varies between different versions of Unix. Not only are different options used, but the format of the output is different. For this reason, there are some system configuration options that configure exactly how `exiwhat' works. If it doesn't seem to be working for you, check the following compile-time options:
EXIWHAT_PS_CMD the command for running `ps' EXIWHAT_PS_ARG the argument for `ps' EXIWHAT_EGREP_ARG the argument for `egrep' to select from `ps' output EXIWHAT_KILL_ARG the argument for the `kill' command
This facility is available only in operating systems where a signal handler can be set up such that an interrupted system call is resumed when the signal handler has finished. An example of typical output from `exiwhat' is
164 1.82 daemon: -q1h, listening on port 25 10483 1.90 running queue: waiting for 0tAycK-0002ij-00 (10492) 10492 1.90 delivering 0tAycK-0002ij-00 to mail.ref.book [42.42.42.42] (editor@ref.book) 10592 1.82 handling incoming call from [245.211.243.242] 10628 1.90 accepting a local non-SMTP message
The first number in the output line is the process number; the second is the Exim version number. The third line has been split here, in order to fit it on the page. Because Exim processes run under a variety of uids, it is necessary to run `exiwhat' as root in order to be able to send the signal to all Exim processes.
The `exiqsumm' utility is a Perl script, provided in the `util' directory, which reads the output of "exim -bp" and produces a summary of the messages by outputting a line like the following for each domain:
3 2322 74m 66m msn.com
This contains the number of messages for that domain, their total volume, and the length of time the oldest and the newest have been waiting. By default the output is sorted on the domain name, but `exiqsumm' has the options `-a' and `-c', which cause it to be sorted by oldest message and by count of messages, respectively.
The output of "exim -bp" is based on the original addresses in the message, so no addresses generated by aliasing or forwarding are included. Consequently this applies also to the output from `exiqsumm'.
The `exigrep' utility is a Perl script, provided in the `util' directory, that extracts from one or more log files all entries relevant to any message whose log entries contain at least one that matches a given pattern. The pattern match is case-insensitive. Thus one can search for all mail for a given user or a given host, for example. The usage is:
exigrep [-l] <pattern> [<log file>] ...
where the `-l' flag means `literal', that is, treat all characters in the pattern as standing for themselves. Otherwise the pattern must be a Perl regular expression. If no file names are given on the command line, the standard input is read.
The `exicyclog' script cycles the main and reject log files. Each time it is run the files get `shuffled down' by one. If the main log file name is `mainlog' (the default) then when `exicyclog' is run `mainlog' becomes `mainlog.01', the previous `mainlog.01' becomes `mainlog.02' and so on, up to a limit which is set in the script, and which defaults to 10.
In versions of Exim prior to 1.90, `exicyclog' used single-digits for numbers less than ten. This was changed to make the files list in a more natural order. The script contains conversion code. If it finds a file called `mainlog.1' it attempts to rename all files in the old form to the new form.
If no `mainlog' file exists, the script does nothing. Reject logs are handled similarly. Files that `drop off' the end are deleted. All files with numbers greater than 01 are compressed, using a compression command which is configured in the script.
It is usual to run `exicyclog' daily from a `crontab' entry of the form
1 0 * * * /opt/exim/bin/exicyclog
In this way, each day's log is (mostly) in a separate file. There will be some overlap from processes that have the log open at the time of renaming.
The `exicyclog' script can be run as the Exim user when one is defined, as the log files will be owned by that user in that case. Otherwise it has to be run as root.
The `exim_dbmbuild' program reads an input file in the format of an alias file (see chapter "The aliasfile director") and writes a DBM database using the lower-cased alias names as keys and the remainder of the information as data. The lower-casing can be prevented by calling it with the `-nolc' option. Two arguments are required: the name of the input file (which can be a single hyphen to indicate the standard input), and the base name of the output database. For example:
exim_dbmbuild /etc/aliases /etc/aliases
reads the system alias file and creates a DBM database using `/etc/aliases' as the base name. In systems that use the `ndbm' routines, the database consists of two files called (in this case) `/etc/aliases.dir' and `/etc/aliases.pag', while in systems using the `ndbm' interface to the `db' routines a single file called `/etc/aliases.db' is created. If the native `db' interface is in use (USE_DB is set in a compile-time configuration file) then a single file with no added prefix is created. In this case the two file names on the command line must be different. The utility in fact creates the database under a temporary name, and then renames the file(s).
A utility called `exinext' (mostly a Perl script) provides the ability to fish specific information out of the retry database. Given a mail domain (or a complete address), it looks up the hosts for that domain, and outputs any retry information. At present, the retry information is obtained by running `exim_dumpdb' (see below) and post-processing the output. For example:
exinext piglet@milne.fict.book kanga.milne.fict.book:100.100.8.1 error 146: Connection refused first failed: 21-Feb-1996 14:57:34 last tried: 21-Feb-1996 14:57:34 next try at: 21-Feb-1996 15:02:34 roo.milne.fict.book:100.100.8.3 error 146: Connection refused first failed: 20-Jan-1996 13:12:08 last tried: 21-Feb-1996 11:42:03 next try at: 21-Feb-1996 19:42:03 past final cutoff time
You can also give `exinext' a local `local_part', without a domain, and it will give any retry information for it. `Exinext' is not particularly efficient, but then it isn't expected to be run very often.
Three utility programs are provided for maintaining the DBM files that Exim uses to contain its delivery hint information. Each program requires two arguments. The first specifies the name of Exim's spool directory, and the second is the name of the database it is to operate on. These are as follows:
The entire contents of a database are written to the standard output by the `exim_dumpdb' program, which has no options or arguments other than the spool and database names. For example, to dump the retry database:
exim_dumpdb /var/spool/exim retry
Two lines of output are produced for each entry:
T:mail.ref.book:242.242.242.242 146 77 Connection refused 31-Oct-1995 12:00:12 02-Nov-1995 12:21:39 02-Nov-1995 20:21:39 *
The first item on the first line is the key of the record. It starts with one of the letters D, R, or T, depending on whether it refers to a directing, routing, or transport retry. For a local delivery, the next part is the local address; for a remote delivery it is the name of the remote host, followed by its failing IP address. Then there follows an error code, an additional error code, and a textual description of the error.
The three times on the second line are the time of first failure, the time of the last delivery attempt, and the computed time for the next attempt. The line ends with an asterisk if the cutoff time for the last retry rule has been exceeded.
Each output line from `exim_dumpdb' for the reject database consists of a date and time, followed by the letter T or F, followed by the address that was rejected, followed by the name of the host that sent the bad address (as given in the SMTP HELO command). The letter is F if only one previous rejection of this address has been done recently, and T if a second has occurred, causing rejection of the MAIL FROM command, and subsequently rejection of the RCPT TO commands.
Each output line from `exim_dumpdb' for the `wait-smtp' database consists of a host name followed by a list of ids for messages that are or were waiting to be delivered to that host. If there are a very large number for any one host, continuation records, with a sequence number added to the host name, may be seen. The data in these records is often out of date, because a message may be routed to several alternative hosts, and Exim makes no effort to keep cross-references.
Each output line from `exim_dumpdb' for the `serialize-smtp' database consists of a host name preceded by the time that Exim made a connection to that host. Exim keeps track of connections only for those hosts or networks that have been configured for serialization.
The `exim_tidydb' utility program is used to tidy up the contents of the databases. If run with no options, it removes all records from a database that are more than 30 days old. The cutoff date can be altered by means of the `-t' option, which must be followed by a time. For example, to remove all records older than a week from the retry database:
exim_tidydb -t 7d /var/spool/exim retry
For the `wait-xxx' databases, the `-f' option can also be used (it has no effect for other databases). This causes a check to be made to ensure that message ids in database records are those of messages that are still on the queue. Other message ids are removed, and if this leaves records empty, they are also removed.
The `exim_tidydb' utility outputs comments on the standard output whenever it removes information from the database. It is suggested that it be run periodically on all three databases, but at a quiet time of day, since it requires a database to be locked (and therefore inaccessible to Exim) while it does its work.
The `exim_fixdb' program is a utility for interactively modifying databases. Its main use is for testing Exim, but it might also be occasionally useful for getting round problems in a live system. It has no options, and its interface is somewhat crude. On entry, it prompts for input with a right angle-bracket. A key of a database record can then be entered, and the data for that record is displayed.
If `d' is typed at the next prompt, the entire record is deleted. For all except the `retry' database, that is the only operation that can be carried out. For the `retry' database, each field is output preceded by a number, and data for individual fields can be changed by typing the field number followed by new data, for example:
> 4 951102:1000
resets the time of the next delivery attempt. Time values are given as a sequence of digit pairs for year, month, day, hour, and minute. Colons can be used as optional separators.
A Perl script called `eximstats' is supplied in the `util' directory. This has been hacked about quite a bit over time. It now gives quite a lot of information by default, but there are options for suppressing various parts of it. Following any options, the arguments to the script are a list of files, which should be main log files.
`Eximstats' extracts information about the number and volume of messages received from or delivered to various hosts. The information is sorted both by message count and by volume, and the top fifty hosts in each category are listed on the standard output. For messages delivered and received locally, similar statistics are produced per user.
The output also includes total counts and statistics about delivery errors, and histograms showing the number of messages received and deliveries made in each hour of the day. A delivery with more than one address in its `envelope' (for example, an SMTP transaction with more than one RCPT TO command) is counted as a single delivery by `eximstats'.
Though normally more deliveries than receipts are reported (as messages may have multiple recipients), it is possible for `eximstats' to report more messages received than delivered, even though the spool is empty at the start and end of the period in question. If an incoming message contains no valid recipients, no deliveries are recorded for it. An error report is handled as an entirely separate message.
`Eximstats' always outputs a grand total summary giving the volume and number of messages received and deliveries made, and the number of hosts involved in each case. It also outputs the number of messages that were delayed (that is, not completely delivered at the first attempt), and the number that had at least one address that failed.
The remainder of the output is in sections that can be independently disabled or modified by various options. It consists of a summary of deliveries by transport, histograms of messages received and delivered per time interval (default per hour), information about the time messages spent on the queue, a list of relayed messages, lists of the top fifty sending hosts, local senders, destination hosts, and destination local users by count and by volume, and a list of delivery errors that occurred.
The relay information lists messages that were actually relayed, that is, they came from a remote host and were directly delivered to some other remote host. A delivery that is considered as a relay by the checking features described in section "Control of relaying" in chapter "Other policy controls on incoming mail", because its domain is not in `local_domains', might still end up being delivered locally under some configurations, and if this happens it doesn't show up as a relay in the `eximstats' output.
The options for `eximstats' are as follows:
Suppress the statistics about delivery by transport.
This option controls the histograms of messages received and deliveries per time interval. By default the time interval is one hour. If `-h0' is given, the histograms are suppressed; otherwise the value of <n> gives the number of divisions per hour, so `-h2' sets an interval of 30 minutes, and the default is equivalent to `-h1'.
Suppress information about times messages spend on the queue.
This option sets an alternative list of time intervals for the queueing information. The values are separated by commas and are in seconds, but can involve arithmetic multipliers, so for example you can set 3*60 to specify 3 minutes. A setting such as
-q60,5*60,10*60
causes `eximstats' to give counts of messages that stayed on the queue for less than one minute, less than five minutes, less than ten minutes, and over ten minutes.
Suppress information about messages relayed through this host.
Suppress information about relayed messages that match the pattern, which is matched against a string of the following form (split over two lines here in order to fit it on the page):
H=<host> [<ip address>] A=<sender address> => H=<host> A=<recipient address>
for example
H=in.host [1.2.3.4] A=from@some.where => H=out.host A=to@else.where
The sending host name appears in parentheses if it has not been verified as matching the IP address. The mail addresses are taken from the envelope, not the headers. This option allows you to screen out hosts whom you are happy to have using your host as a relay.
Sets the `top' count to <n>. This controls the listings of the `top <n>' hosts and users by count and volume. The default is 50, and setting 0 suppresses the output altogether.
Omit local information from the `top' listings.
Suppress the list of delivery errors.
Go to the first, previous, next, last section, table of contents.