001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.core.status;
015
016import ch.qos.logback.core.spi.ContextAwareBase;
017import ch.qos.logback.core.spi.LifeCycle;
018import ch.qos.logback.core.util.StatusPrinter;
019
020import java.io.PrintStream;
021import java.util.List;
022
023/**
024 *  Print all new incoming status messages on the on the designated PrintStream.
025 * @author Ceki Gülcü
026 */
027abstract public class OnPrintStreamStatusListenerBase extends ContextAwareBase implements StatusListener, LifeCycle {
028
029    boolean isStarted = false;
030
031    static final long DEFAULT_RETROSPECTIVE = 300;
032    long retrospectiveThresold = DEFAULT_RETROSPECTIVE;
033    
034    /**
035     * The prefix to place before each status message
036     * @since 1.1.10
037     */
038    String prefix;
039    
040    /**
041     * The PrintStream used by derived classes
042     * @return
043     */
044    abstract protected PrintStream getPrintStream();
045
046    private void print(Status status) {
047        StringBuilder sb = new StringBuilder();
048        if(prefix != null)
049            sb.append(prefix);
050        
051        StatusPrinter.buildStr(sb, "", status);
052        getPrintStream().print(sb);
053    }
054
055    public void addStatusEvent(Status status) {
056        if (!isStarted)
057            return;
058        print(status);
059    }
060
061    /**
062     * Print status messages retrospectively
063     */
064    private void retrospectivePrint() {
065        if (context == null)
066            return;
067        long now = System.currentTimeMillis();
068        StatusManager sm = context.getStatusManager();
069        List<Status> statusList = sm.getCopyOfStatusList();
070        for (Status status : statusList) {
071            long timestampOfStatusMesage = status.getDate();
072            if (isElapsedTimeLongerThanThreshold(now, timestampOfStatusMesage)) {
073                print(status);
074            }
075        }
076    }
077
078    private boolean isElapsedTimeLongerThanThreshold(long now, long timestamp) {
079        long elapsedTime = now - timestamp;
080        return elapsedTime < retrospectiveThresold;
081    }
082
083    /**
084     * Invoking the start method can cause the instance to print status messages created less than 
085     * value of retrospectiveThresold. 
086     */
087    public void start() {
088        isStarted = true;
089        if (retrospectiveThresold > 0) {
090            retrospectivePrint();
091        }
092    }
093
094    public String getPrefix() {
095        return prefix;
096    }
097
098    public void setPrefix(String prefix) {
099        this.prefix = prefix;
100    }
101    
102    public void setRetrospective(long retrospective) {
103        this.retrospectiveThresold = retrospective;
104    }
105
106    public long getRetrospective() {
107        return retrospectiveThresold;
108    }
109
110    public void stop() {
111        isStarted = false;
112    }
113
114    public boolean isStarted() {
115        return isStarted;
116    }
117
118}