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