-->
Previous Table of Contents Next


For example, if you want to capture in your log just the remote host name, the object requested, and the timestamp, you would use the following:


LogFormat "%h \"%r\" %t"

And that would log things that looked like


host.outsider.com "GET / HTTP/1.0" [06/Mar/1996:10:15:17]

You Can Quote Me on This

You really have to use quotation marks around the request variable. The configurable logging module will automatically interpret the values of the variables, rather than just read the variable name. Use a slash-quote, \”, to indicate that you want an actual quote character rather than the end of the string. For example, if you want to add logging of the User-Agent string, your log format would become


  LogFormat "%h \"%r\" %t \"%{User-Agent}i\""

Because the User-Agent field typically has spaces in it, it too should be quoted. Suppose that you want to capture the Referer field:


  LogFormat "%h \"%r\" %t %{Referer}i"

You don’t need the escaping quotation marks because Referer headers, as URLs, don’t have spaces in them. However, if you’re building a mission-critical application, you may as well quote it also, because the Referer header is supplied by the client and, thus, there are no guarantees about its format.

The default logfile format is the Common Logfile Format (CLF), which is expressed as


LogFormat "%h %l %u %t \"%r\" %s %b"

In fact, most existing logfile analysis tools for CLF will ignore extra fields tacked onto the end. To capture the most important extra information and yet still be parsable by those tools, you might want to use this format:


LogFormat "%h %l %u %t \"%r\" %s %b %{Referer}i \"%{User-Agent}i\""


TIP:  If you want even more control over what gets logged, you can use the configurable logging module to implement a simple conditional test for variables. This way, you can configure it to log variables only when a particular status code is—or isn’t—returned. The format for trapping a status code is to insert a comma-separated list of those codes between the % and the letter of the variable:

   %404,403{Referer}i

This example means that the Referer header will be logged only if the status returned by the server is a 404 Not Found or a 403 Access Denied. All other times just a - is logged. Having only 403 or 404 errors logged would be useful if all you cared about using Referer for was to find old links that point to resources no longer available.


The negation of the Referer status code is to put an exclamation point (!) at the beginning of the list of status codes. For example,


%!401u

logs the user in any user authentication transaction, unless the authentication failed, in which case you probably don’t want to see the name of the bogus user anyway.

Remember that, like many functions, logging functions can be configured per virtual host. Thus, if you want all logs from all virtual hosts on the same server to go to the same log, you might want to do something like


LogFormat "hosta ...."

in the <VirtualHost> sections for hosta and


LogFormat "hostb ...."

in the <VirtualHost> sections for hostb. More details about virtual hosts appear later in the section “Virtual Hosts.”


NOTE:  You have to compile in mod_log_config in order to configure logging on a “per-virtual-host” basis. You must also make sure that the default logging module, mod_log_common, isn’t compiled in; otherwise, the server will get confused.

Content Negotiation

Content negotiation is the mechanism by which a Web client can express to the server what data types it knows how to render and, based on that information, the server can give the client the “optimal” version of the resource requested. Content negotiation can happen on a number of different characteristics—the content type of the data (also called the media type), the human language the data is in (such as English or French), the character set of the document, and its encodings.

Content-Type Negotiation

If you want to use JPEG images inline on your pages but don’t want to alienate users with browsers that can’t handle inline JPEG images, you also can make a GIF version of that image. Although the GIF file might be larger or only 8-bit, that’s still better than giving the browser something it can’t handle, causing a broken link. So, the browser and the server negotiate for which data format the server sends to the client.

The specifications for content negotiation have been a part of HTTP since the beginning. Unfortunately, it can’t be relied on as extensively as you’d like. For example, current browsers that implement plug-ins by and large don’t express in the connection headers which media types they have plug-ins for. Thus, content negotiation currently can’t be used to decide whether to send someone a ShockWave file or its Java equivalent. The only safe place to use content negotiation now is to distinguish between inline JPEG or GIF images on a page. Enough browsers in use today implement content negotiation closely enough to get this functionality.

The mod_negotiation.c file in Apache 1.0 implements the content-negotiation specifications in an older version of the HTTP/1.0 IETF draft, which at this writing is on its way to RFC status. Content negotiation was removed because the specification wasn’t entirely complete. Content negotiation is getting significantly enhanced for HTTP/1.1. However, this doesn’t mean it can’t be safely used now for inline image selection.

To activate content negotiation, you must include the mod_negotiation.c module into the server. There are actually two ways to configure content negotiation:

  Using a type-map file describing all the variants of a negotiable resource with specific preference values and content characteristics
  Setting an Options value called MultiViews

Because your focus is pragmatic, you’ll go only into the MultiViews functionality. If you’re interested in the type-map functionality, the Apache Web site has documentation on it.


Previous Table of Contents Next