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 designated PrintStream.
025 * 
026 * @author Ceki Gülcü
027 */
028abstract public class OnPrintStreamStatusListenerBase extends ContextAwareBase implements StatusListener, LifeCycle {
029
030    boolean isStarted = false;
031
032    static final long DEFAULT_RETROSPECTIVE = 300;
033    long retrospectiveThresold = DEFAULT_RETROSPECTIVE;
034
035    boolean resetResistant = false;
036
037    /**
038     * The prefix to place before each status message
039     * 
040     * @since 1.1.10
041     */
042    String prefix;
043
044    /**
045     * The PrintStream used by derived classes
046     * 
047     * @return
048     */
049    abstract protected PrintStream getPrintStream();
050
051    private void print(Status status) {
052        StringBuilder sb = new StringBuilder();
053        if (prefix != null)
054            sb.append(prefix);
055
056        StatusPrinter.buildStr(sb, "", status);
057        getPrintStream().print(sb);
058    }
059
060    public void addStatusEvent(Status status) {
061        if (!isStarted)
062            return;
063        print(status);
064    }
065
066    /**
067     * Print status messages retrospectively
068     */
069    private void retrospectivePrint() {
070        if (context == null)
071            return;
072        long now = System.currentTimeMillis();
073        StatusManager sm = context.getStatusManager();
074        List<Status> statusList = sm.getCopyOfStatusList();
075        for (Status status : statusList) {
076            long timestampOfStatusMesage = status.getTimestamp();
077            if (isElapsedTimeLongerThanThreshold(now, timestampOfStatusMesage)) {
078                print(status);
079            }
080        }
081    }
082
083    private boolean isElapsedTimeLongerThanThreshold(long now, long timestamp) {
084        long elapsedTime = now - timestamp;
085        return elapsedTime < retrospectiveThresold;
086    }
087
088    /**
089     * Invoking the start method can cause the instance to print status messages
090     * created less than value of retrospectiveThresold.
091     */
092    public void start() {
093        isStarted = true;
094        if (retrospectiveThresold > 0) {
095            retrospectivePrint();
096        }
097    }
098
099    public String getPrefix() {
100        return prefix;
101    }
102
103    public void setPrefix(String prefix) {
104        this.prefix = prefix;
105    }
106
107    public void setRetrospective(long retrospective) {
108        this.retrospectiveThresold = retrospective;
109    }
110
111    public long getRetrospective() {
112        return retrospectiveThresold;
113    }
114
115    public void stop() {
116        isStarted = false;
117    }
118
119    public boolean isStarted() {
120        return isStarted;
121    }
122
123    @Override
124    public boolean  isResetResistant() {
125        return resetResistant;
126    }
127    public void setResetResistant(boolean resetResistant) {
128        this.resetResistant = resetResistant;
129    }
130
131
132
133}