001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.log4j.pattern;
019
020import org.apache.log4j.spi.LoggingEvent;
021
022
023/**
024 * Return the relative time in milliseconds since loading of the LoggingEvent
025 * class.
026 *
027 * @author Ceki Gülcü
028 */
029public class RelativeTimePatternConverter extends LoggingEventPatternConverter {
030  /**
031   * Cached formatted timestamp.
032   */
033  private CachedTimestamp lastTimestamp = new CachedTimestamp(0, "");
034
035  /**
036   * Private constructor.
037   */
038  public RelativeTimePatternConverter() {
039    super("Time", "time");
040  }
041
042  /**
043   * Obtains an instance of RelativeTimePatternConverter.
044   * @param options options, currently ignored, may be null.
045   * @return instance of RelativeTimePatternConverter.
046   */
047  public static RelativeTimePatternConverter newInstance(
048    final String[] options) {
049    return new RelativeTimePatternConverter();
050  }
051
052  /**
053   * {@inheritDoc}
054   */
055  public void format(final LoggingEvent event, final StringBuffer toAppendTo) {
056    long timestamp = event.timeStamp;
057
058    if (!lastTimestamp.format(timestamp, toAppendTo)) {
059      final String formatted =
060        Long.toString(timestamp - LoggingEvent.getStartTime());
061      toAppendTo.append(formatted);
062      lastTimestamp = new CachedTimestamp(timestamp, formatted);
063    }
064  }
065
066  /**
067   * Cached timestamp and formatted value.
068   */
069  private static final class CachedTimestamp {
070    /**
071     * Cached timestamp.
072     */
073    private final long timestamp;
074
075    /**
076     * Cached formatted timestamp.
077     */
078    private final String formatted;
079
080    /**
081     * Creates a new instance.
082     * @param timestamp timestamp.
083     * @param formatted formatted timestamp.
084     */
085    public CachedTimestamp(long timestamp, final String formatted) {
086      this.timestamp = timestamp;
087      this.formatted = formatted;
088    }
089
090    /**
091     * Appends the cached formatted timestamp to the buffer if timestamps match.
092     * @param newTimestamp requested timestamp.
093     * @param toAppendTo buffer to append formatted timestamp.
094     * @return true if requested timestamp matched cached timestamp.
095     */
096    public boolean format(long newTimestamp, final StringBuffer toAppendTo) {
097      if (newTimestamp == timestamp) {
098        toAppendTo.append(formatted);
099
100        return true;
101      }
102
103      return false;
104    }
105  }
106}