Showing posts with label jetty. Show all posts
Showing posts with label jetty. Show all posts

Request logs rolling with suffixes from Jetty

It seemed simple enough. The goal: get jetty to log requests to a file such as request.log and rotate that file on a daily basis to something with a suffix.

By default Jetty wants to rename request logs something like mm_dd_yy_request.log, this is all well and good, but it complicates the logic of any tool you might use to sync and remove log files. For example log4j's RollingFileAppender will append numeric suffixes like .1 to the end of logs it has closed and rotated out, but with Jetty's default configuration, one has to get a little tricky to figure out what request log is still open. It's not as easy as grabbing request.log.* to grab the out-of-rotation logs.

I discovered the solution in the code of RolloverFileOutputStream, the class in jetty-util that Jetty's NCSARequestLog class uses internally to write the log files. When logfile appending is turned off and RolloverFileOutputStream attempts to open a new log where a file with the same name already exists, RolloverFileOuputStream will rename the existing file by appending the date, format specified by the system property ROLLOVERFILE_BACKUP_FORMAT, to the existing logfile name. This means that the request.log is the live, open log and files named like request.log.yyyyMMdd-HHmmss are the logs that are out of rotation.

So to achieve this, modify the RequestLog entry in jetty.xml to look like this:

    <Ref id="RequestLog">
      <Set name="requestLog">
        <New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
          <Arg><SystemProperty name="jetty.logs" default="./logs"/>/request.log</Arg>
          <Set name="retainDays">31</Set>
          <Set name="append">false</Set>
          <Set name="extended">false</Set>
          <Set name="LogTimeZone">GMT</Set>
          <Set name="ignorePaths">
            <Array type="java.lang.String">
              <Item>/solr/ping</Item>
            </Array>
          </Set>
        </New>
      </Set>
    </Ref>

And at starup of your jetty instance, do something like:
java -DROLLOVERFILE_BACKUP_FORMAT=yyyyMMdd-HHmmss -jar start.jar
And Viola! New log messages are written to request.log and logs are rolled out to request.log.somenicesuffixhere.

As for the ignorePaths stanze in the configuration above, you probably don't need it in your configuration. It's handy for me to skip logging health checks.

Also as for syncing the logs off the individual machines they're written to, rsync's --remove-sent-files option is pretty handy.

Serving content with Solr's Jetty instance.

When prototyping with Solr 1.4.x, I've found it useful to serve webpages, javascript and images using the Jetty server used by Solr's example instance. Doing so is straightforward:

Create a directory named contexts in the Solr examples directory which contains the etc and start.jar files. Create a context definition file inside this directory. It can be named anything, I commonly call it root-context.xml

The file contains the following:
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
  <Set name="contextPath">/</Set>
  <Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/contexts/root</Set>
  <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
</Configure>
In the contexts directory, create a directory named root and place your content there. Voila -- once you launch the solr instance with java -jar start.jar, everything placed in the root directory is available under http://yourhostname:8983, while solr is availble at http://yourhostname:8983/solr
top