聊聊logback的StatusManager
序
本文主要研究一下logback的StatusManager
StatusManager
ch/qos/logback/core/status/StatusManager.java
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
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
public void add(Status newStatus) {// LBCORE-72: fire event before the count checkfireStatusAddEvent(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
public List<Status> getCopyOfStatusList() {synchronized (statusListLock) {List<Status> tList = new ArrayList<Status>(statusList);tList.addAll(tailBuffer.asList());return tList;}}
getCopyOfStatusList则加锁,然后从statusList及tailBuffer获取status
clear
public void clear() {synchronized (statusListLock) {count = 0;statusList.clear();tailBuffer.clear();}}
clear则加锁,重置count,清空statusList及tailBuffer
add listener
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
public void remove(StatusListener listener) {synchronized (statusListenerListLock) {statusListenerList.remove(listener);}}
remove则先加锁,然后从statusListenerList中移除
getCopyOfStatusListenerList
public List<StatusListener> getCopyOfStatusListenerList() {synchronized (statusListenerListLock) {return new ArrayList<StatusListener>(statusListenerList);}}
getCopyOfStatusListenerList则先加锁然后拷贝statusListenerList
Status
ch/qos/logback/core/status/Status.java
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*/@Deprecateddefault 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
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' childrenreturn 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
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
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
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。
相关文章:
聊聊logback的StatusManager
序 本文主要研究一下logback的StatusManager StatusManager ch/qos/logback/core/status/StatusManager.java public interface StatusManager {/*** Add a new status message.* * param status*/void add(Status status);/*** Obtain a copy of the status list maintain…...
[PyTorch][chapter 61][强化学习-免模型学习1]
前言: 在现实的学习任务中,环境 其中的转移概率P,奖赏函数R 是未知的,或者状态X也是未知的 称为免模型学习(model-free learning) 目录: 1: 蒙特卡洛强化学习 2:同策略-蒙特卡洛强化学习 3&am…...
网络运维Day04-补充
文章目录 周期性计划任务周期性计划任务使用案例一案例二 周期性计划任务 在固定时间可以完成相同的任务,被称之为周期性计划任务由crond服务提供需要将定时任务,写到一个文件书写格式如下 分 时 日 月 周 任务(绝对路径)分:0-59时ÿ…...
前端埋点方式
前言: 想要了解用户在系统中所做的操作,从而得出用户在本系统中最常用的模块、在系统中停留的时间。对于了解用户的行为、分析用户的需求有很大的帮助,想实现这种需求可以通过前端埋点的方式。 埋点方式: 1.什么是埋点?…...
iOS导航栏返回按钮
导航栏返回按钮隐藏: override func pushViewController(_ viewController: UIViewController, animated: Bool) {if let vc self.viewControllers.last {let backItem UIBarButtonItem()backItem.title ""vc.navigationItem.backBarButtonItem backI…...
2023中国视频云市场报告:腾讯云音视频解决方案份额连续六次蝉联榜首,加速全球化布局
近日,国际数据公司(IDC)发布了《中国视频云市场跟踪(2023上半年)》报告,腾讯云音视频的解决方案份额连续六次蝉联榜首,并在视频生产创作与媒资管理市场份额中排名第一。同时,在实时音…...
jpa Repository的常用写法总结
一、前言 之前项目在xml中写sql,感觉标签有很多,比较灵活; 最近在写新项目,使用了jpa,只能在java中写sql了,感觉不太灵活,但是也得凑付用。 以下总结下常用入参出参写法。 二、Repository代…...
笔记本电脑 禁用/启用 自带键盘
现在无论办公还是生活 很多人都会选择笔记本电脑 但很多人喜欢机械键盘 或者 用一些外接键盘 但是很多时候我们想操作 会碰到笔记本原来的键盘导致错误操作 那么 我们就需要将笔记本原来的键盘禁用掉 我们先以管理员身份运行命令窗口 然后 有两个命令 禁用默认键盘 sc conf…...
基于 golang 从零到一实现时间轮算法 (三)
引言 本文参考小徐先生的相关博客整理,项目地址为: https://github.com/xiaoxuxiansheng/timewheel/blob/main/redis_time_wheel.go。主要是完善流程以及记录个人学习笔记。 分布式版实现 本章我们讨论一下,如何基于 redis 实现分布式版本的…...
k8s 1.28安装
容器运行时,containerd 按照官方的指导,需要安装runc和cni插件,提示的安装方式,有三种: 二进制安装包源码apt-get 或 dnf安装 我们这里选用第三种,找到docker官方提供的安装方式 ubuntu-containerd # A…...
安装anaconda时控制台conda-version报错
今天根据站内的一篇博客教程博客在此安装anaconda时,检查conda版本时报错如下: >>>>>>>>>>>> ERROR REPORT <<<<<<<<<<<< Traceback (most recent call last): File “D:\An…...
链表(1)
目录 单链表 主函数test.c test1 test2 test3 test4 头文件&函数声明SList.h 函数实现SList.c 打印SLPrint 创建节点CreateNode 尾插SLPushBack 头插SLPushFront 头删SLPopBck 尾删SLPopFront 易错点 本篇开始链表学习。今天主要是单链表&OJ题目。 单链…...
智慧农业:农林牧数据可视化监控平台
数字农业是一种现代农业方式,它将信息作为农业生产的重要元素,并利用现代信息技术进行农业生产过程的实时可视化、数字化设计和信息化管理。能将信息技术与农业生产的各个环节有机融合,对于改造传统农业和改变农业生产方式具有重要意义。 图扑…...
知识注入以对抗大型语言模型(LLM)的幻觉11.6
知识注入以对抗大型语言模型(LLM)的幻觉 摘要1 引言2 问题设置和实验2.1 幻觉2.2 生成响应质量 3 结果和讨论3.1 幻觉3.2 生成响应质量 4 结论和未来工作 摘要 大型语言模型(LLM)内容生成的一个缺点是产生幻觉,即在输…...
机器人物理交互场景及应用的实际意义
机器人物理交互场景是指机器人与物理世界或人类进行实际的物理互动和交互的情境。这些场景涉及机器人在不同环境和应用中使用其物理能力,以执行任务、提供服务或与人类互动。 医疗协助: 外科手术助手:机器人可以用于外科手术,提供…...
Kubernetes Dashboard 用户名密码方式登录
Author:rab 前言 为了 K8s 集群安全,默认情况下 Dashboard 以 Token 的形式登录的,那如果我们想以用户名/密码的方式登录该怎么操作呢?其实只需要我们创建用户并进行 ClusterRoleBinding 绑定即可,接下来是具体的操作…...
Redisson中的对象
Redisson - 是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象 (Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, …...
GNU ld链接器 lang_process()(二)
一、ldemul_create_output_section_statements() 位于lang_process()中11行 。 该函数用于创建与目标有关的输出段的语句。这些语句将用于描述输出段的属性和分配。 void ldemul_create_output_section_statements (void) {if (ld_emulation->create_output_section_sta…...
《国产服务器操作系统发展报告(2023)》重磅发布
11月1日,《国产服务器操作系统发展报告(2023)》(以下简称“报告”)在 2023 云栖大会上正式发布,开放原子开源基金会理事长孙文龙、中国信息通信研究院副总工程师石友康、阿里云基础软件部副总裁马涛、浪潮信…...
【PTE-day03 报错注入】
报错注入 1、报错注入 group by count2、报错注入 extractvalue3、报错注入updatexml1、报错注入 group by count http://124.222.124.9:8888/Less-5/?id=-1 union select 1,count(*),concat((select database()),ceil(rand(0)*2)) as a from information_schema.tables grou…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
