聊聊logback的StatusManager

2023-11-07 16:34:19 浏览数 (2)

本文主要研究一下logback的StatusManager

StatusManager

ch/qos/logback/core/status/StatusManager.java

代码语言:javascript复制
public interface StatusManager {

    /**
     * Add a new status message.
     * 
     * @param status
     */
    void add(Status status);

    /**
     * Obtain a copy of the status list maintained by this StatusManager.
     * 
     * @return
     */
    List<Status> getCopyOfStatusList();

    /**
     * Return the highest level of all the statii.
     * 
     * @return
     */
    // int getLevel();

    /**
     * Return the number of status entries.
     * 
     * @return
     */
    int getCount();

    /**
     * Add a status listener.
     * 
     * @param listener
     */

    /**
     * Add a status listener. The StatusManager may decide to skip installation if
     * an earlier instance was already installed.
     * 
     * @param listener
     * @return true if actually added, false if skipped
     */
    boolean add(StatusListener listener);

    /**
     * ); Remove a status listener.
     * 
     * @param listener
     */
    void remove(StatusListener listener);

    /**
     * Clear the list of status messages.
     */
    void clear();

    /**
     * Obtain a copy of the status listener list maintained by this StatusManager
     * 
     * @return
     */
    List<StatusListener> getCopyOfStatusListenerList();

}

StatusManager接口针对status定义了add、getCopyOfStatusList、getCount、clear方法,针对StatusListener定义了add、remove、getCopyOfStatusListenerList方法

BasicStatusManager

ch/qos/logback/core/BasicStatusManager.java

代码语言:javascript复制
public class BasicStatusManager implements StatusManager {

	final protected List<Status> statusList = new ArrayList<Status>();

	final protected CyclicBuffer<Status> tailBuffer = new CyclicBuffer<Status>(TAIL_SIZE);

	final protected LogbackLock statusListLock = new LogbackLock();

	final protected List<StatusListener> statusListenerList = new ArrayList<StatusListener>();

    final protected LogbackLock statusListenerListLock = new LogbackLock();

    //......
}

BasicStatusManager实现了StatusManager接口,它使用statusList及statusListLock来操作status,使用statusListenerList及statusListenerListLock来操作StatusListener;另外针对status还提供了tailBuffer

add status

代码语言:javascript复制
    public void add(Status newStatus) {
        // LBCORE-72: fire event before the count check
        fireStatusAddEvent(newStatus);

        count  ;
        if (newStatus.getLevel() > level) {
            level = newStatus.getLevel();
        }

        synchronized (statusListLock) {
            if (statusList.size() < MAX_HEADER_COUNT) {
                statusList.add(newStatus);
            } else {
                tailBuffer.add(newStatus);
            }
        }

    }

add方法先加锁,再判断是否超出限制,没有则添加到statusList,超出则添加到tailBuffer

getCopyOfStatusList

代码语言:javascript复制
    public List<Status> getCopyOfStatusList() {
        synchronized (statusListLock) {
            List<Status> tList = new ArrayList<Status>(statusList);
            tList.addAll(tailBuffer.asList());
            return tList;
        }
    }

getCopyOfStatusList则加锁,然后从statusList及tailBuffer获取status

clear

代码语言:javascript复制
    public void clear() {
        synchronized (statusListLock) {
            count = 0;
            statusList.clear();
            tailBuffer.clear();
        }
    }

clear则加锁,重置count,清空statusList及tailBuffer

add listener

代码语言:javascript复制
    public boolean add(StatusListener listener) {
        synchronized (statusListenerListLock) {
            if (listener instanceof OnConsoleStatusListener) {
                boolean alreadyPresent = checkForPresence(statusListenerList, listener.getClass());
                if (alreadyPresent)
                    return false;
            }
            statusListenerList.add(listener);
        }
        return true;
    }

    private boolean checkForPresence(List<StatusListener> statusListenerList, Class<?> aClass) {
        for (StatusListener e : statusListenerList) {
            if (e.getClass() == aClass)
                return true;
        }
        return false;
    }    

add listener方法先加锁,然后判断是否已经存在,不存在则添加到statusListenerList

remove

代码语言:javascript复制
    public void remove(StatusListener listener) {
        synchronized (statusListenerListLock) {
            statusListenerList.remove(listener);
        }
    }

remove则先加锁,然后从statusListenerList中移除

getCopyOfStatusListenerList

代码语言:javascript复制
    public List<StatusListener> getCopyOfStatusListenerList() {
        synchronized (statusListenerListLock) {
            return new ArrayList<StatusListener>(statusListenerList);
        }
    }

getCopyOfStatusListenerList则先加锁然后拷贝statusListenerList

Status

ch/qos/logback/core/status/Status.java

代码语言:javascript复制
public interface Status {

    int INFO = 0;
    int WARN = 1;
    int ERROR = 2;

    int getLevel();

    int getEffectiveLevel();

    Object getOrigin();

    String getMessage();

    Throwable getThrowable();

    /**
     * @eprecated. Use getTimestamp instead.
     * @return
     */
    @Deprecated
    default Long getDate() {
        return getTimestamp();
    }

    long getTimestamp();

    boolean hasChildren();

    void add(Status child);

    boolean remove(Status child);

    Iterator<Status> iterator();

}

Status接口定义了getLevel、getEffectiveLevel、getOrigin、getMessage、getThrowable、getTimestamp、hasChildren、add、remove、iterator方法

StatusBase

ch/qos/logback/core/status/StatusBase.java

代码语言:javascript复制
abstract public class StatusBase implements Status {

    static private final List<Status> EMPTY_LIST = new ArrayList<Status>(0);

    int level;
    final String message;
    final Object origin;
    List<Status> childrenList;
    Throwable throwable;
    long timestamp;

    public synchronized void add(Status child) {
        if (child == null) {
            throw new NullPointerException("Null values are not valid Status.");
        }
        if (childrenList == null) {
            childrenList = new ArrayList<Status>();
        }
        childrenList.add(child);
    }

    public synchronized boolean hasChildren() {
        return ((childrenList != null) && (childrenList.size() > 0));
    }

    public synchronized Iterator<Status> iterator() {
        if (childrenList != null) {
            return childrenList.iterator();
        } else {
            return EMPTY_LIST.iterator();
        }
    }

    public synchronized boolean remove(Status statusToRemove) {
        if (childrenList == null) {
            return false;
        }
        // TODO also search in childrens' children
        return childrenList.remove(statusToRemove);
    }

    public synchronized int getEffectiveLevel() {
        int result = level;
        int effLevel;

        Iterator<Status> it = iterator();
        Status s;
        while (it.hasNext()) {
            s = (Status) it.next();
            effLevel = s.getEffectiveLevel();
            if (effLevel > result) {
                result = effLevel;
            }
        }
        return result;
    }

    //......

}

StatusBase声明实现Status接口,它通过childrenList来存储子status

InfoStatus

ch/qos/logback/core/status/InfoStatus.java

代码语言:javascript复制
public class InfoStatus extends StatusBase {
    public InfoStatus(String msg, Object origin) {
        super(Status.INFO, msg, origin);
    }

    public InfoStatus(String msg, Object origin, Throwable t) {
        super(Status.INFO, msg, origin, t);
    }

}

InfoStatus继承了StatusBase,它的level为Status.INFO

WarnStatus

ch/qos/logback/core/status/WarnStatus.java

代码语言:javascript复制
public class WarnStatus extends StatusBase {

    public WarnStatus(String msg, Object origin) {
        super(Status.WARN, msg, origin);
    }

    public WarnStatus(String msg, Object origin, Throwable t) {
        super(Status.WARN, msg, origin, t);
    }

}

WarnStatus继承了StatusBase,它的level为Status.WARN

ErrorStatus

ch/qos/logback/core/status/ErrorStatus.java

代码语言:javascript复制
public class ErrorStatus extends StatusBase {

    public ErrorStatus(String msg, Object origin) {
        super(Status.ERROR, msg, origin);
    }

    public ErrorStatus(String msg, Object origin, Throwable t) {
        super(Status.ERROR, msg, origin, t);
    }

}

ErrorStatus继承了StatusBase,它的level为Status.ERROR

小结

logback定义了StatusManager用于管理status及其listener,其add方法会回调listener,之后加锁,再判断是否超出限制,没有则添加到statusList,超出则添加到tailBuffer;Status是个接口,它有一个抽象类为StatusBase,而InfoStatus、WarnStatus、ErrorStatus都继承了StatusBase。

0 人点赞