My two oldest sons are both aspiring musicians: One plays the piano, and one plays the guitar. Their teachers have asked them to practice daily, and they're usually pretty good about doing so—but they often forget to write down their practice times. This has led to a new family saying: "If you didn't write it down, it didn't happen."

The reverse of this statement is true for Exchange Server: "If it's written down, it happened." For that reason, Exchange keeps a variety of logs in different places. For example, the application event log is the first place you should look when you need to know why a service didn't start or why some other component is misbehaving. There are lots of tools for aggregating and searching the log entries that Exchange generates. For example, Microsoft's Log Parser can ingest Microsoft IIS logs so you can create SQL queries against your log data. There are also several commercial products for gathering and scanning event logs across multiple computers; Microsoft System Center Operations Manager and GFI LANguard are the first two that come to mind.

The spam-filtering logs generated on an Exchange 2007 Edge Transport server role are a bit different. These logs are technically known as agent logs because they're generated by the Content Filter agent. Agent logs normally live in \Exchange Server\TransportRoles\Logs\AgentLog; logs can reach a maximum size of 10MB, and the directory can hold 30 days worth of logs or 250MB, whichever comes first. If you want to inspect these logs, you can use the Get-AgentLog cmdlet in Exchange Management Shell. Check Microsoft's online documentation to see the parameters you can use with Get-AgentLog; you'll need these parameters to constrain the log retrieval to a particular date range or cause. In addition, check the Microsoft article "How to Manage Agent Log Output" to see how to modify the keys that control the number and size of log files in Exchange 2007 SP1 Edge Transport servers.

Here's what a log file entry for a filtered message looks like:

Timestamp       : 1/2/2008 4:09:13 AM  <br>SessionId       : 08CA0AB1F361124E  <br>IPAddress       : 121.168.107.174  <br>MessageId       :  <br>P1FromAddress   : jraine68@avantages.net  <br>P2FromAddresses : \{\}  <br>Recipients      : \{info@robichaux.net\}  <br>Agent           : Connection Filtering Agent  <br>Event           : OnRcptCommand  <br>Action          : RejectCommand  <br>SmtpResponse    : 550 5.7.1 Recipient not authorized, your IP has been found on a block list  <br>Reason          : BlockListProvider  <br>ReasonData      : sbl-xbl.spamhaus.org

This information makes it fairly easy to figure out why a particular message was rejected—provided that you know the approximate time frame in which it was sent or the message ID. Of course, there won't be a message ID if the message was rejected before its contents were accepted, so keep that in mind when you consider how you'll search for messages.

There are lots of neat tricks you can do with Get-AgentLog. For example, if you want to see the list of messages blocked by a particular IP blacklist, you could enter

get-AgentLog | where \{$_.ReasonData -eq "<i>blacklistName</i>"\}

where blacklistName is the actual name of the blacklist. If you're not satisfied with the command-line approach to inspecting the agent logs, fear not: Exchange MVP Glen Scales has written a GUI tool (in PowerShell, of course) that provides a simple GUI for inspecting the contents of these logs. Grab it from Glen's Exchange Dev Blog.