聊聊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…...
AI Agent在智能风控中的实战:多智能体欺诈检测与预警
AI Agent在智能风控中的实战:多智能体欺诈检测与预警 你有没有过明明是正常交易却被银行冻结账户的糟糕体验?或是听说过某电商平台上线新活动首日就被黑产团伙薅走数千万补贴的新闻?随着黑产欺诈向团伙化、专业化、动态化演进,传统依赖规则引擎、单模型机器学习的风控体系已…...
tools.simonwillison.net图像处理工具集:从裁剪到优化的完整指南
tools.simonwillison.net图像处理工具集:从裁剪到优化的完整指南 【免费下载链接】tools Assorted useful tools, almost entirely generated using LLMs 项目地址: https://gitcode.com/gh_mirrors/tools23/tools tools.simonwillison.net图像处理工具集是一…...
MBTI性格测试
简介 MBTI(Myers‑Briggs Type Indicator,迈尔斯‑布里格斯类型指标)是基于荣格心理类型理论发展出的性格类型工具,由凯瑟琳库克布里格斯及其女儿伊莎贝尔布里格斯迈尔斯创建。它通过四对偏好维度将个体的认知与行为倾向归纳为 16…...
别再只测accuracy!DeepSeek集成测试必须监控的5个隐性指标(P99首token延迟、context bleed率、tool-call schema漂移)
更多请点击: https://intelliparadigm.com 第一章:DeepSeek集成测试的核心范式演进 DeepSeek大模型的工程化落地对集成测试提出了全新挑战:传统基于接口响应码与字段校验的测试范式已难以覆盖语义一致性、推理链鲁棒性、上下文敏感度等高阶质…...
2026年LLM推理加速全景:量化、投机解码与KV Cache工程实战
大语言模型推理速度慢、成本高,是阻碍AI大规模落地的核心障碍之一。一个7B参数的模型,在标准配置下每秒只能生成约30个token,对于需要实时响应的应用来说几乎无法接受。但2026年,一系列推理加速技术的成熟,让这一局面发…...
基于MAX78000的离线鸟类声音识别:边缘AI从数据到部署全流程解析
1. 项目概述:当边缘AI“听懂”鸟鸣在野外生态监测或自家后院观鸟时,你是否有过这样的经历:听到一阵清脆或婉转的鸟鸣,却完全不知道是哪位“歌唱家”在表演?传统的鸟类识别依赖专家经验和图鉴比对,不仅门槛高…...
口碑最好的AI论文写作工具推荐(从文献整理到论文成稿全流程)适合全体毕业生
还在为选题方向纠结、文献资料翻找耗时、开题报告无从下手、论文框架反复修改、查重率居高不下、降重过程痛苦不堪,甚至答辩PPT还要临时抱佛脚?作为学术新手、应届生或本科硕士毕业生,面对论文写作的重重关卡,流程复杂、操作门槛高…...
别再死磕USB HID了!用ESP32的Arduino框架手把手教你实现蓝牙鼠标键盘(附完整代码)
ESP32蓝牙HID实战:零基础打造自定义键盘鼠标 手里那块吃灰的ESP32开发板终于能派上用场了!上周我用它做了个无线演示控制器,在会议室里走着就能翻PPT,同事们都问是怎么实现的。其实秘诀就在于ESP32的蓝牙HID功能——不需要任何USB…...
ComfyUI-WD14-Tagger:3分钟实现AI智能图像标签提取,效率提升10倍
ComfyUI-WD14-Tagger:3分钟实现AI智能图像标签提取,效率提升10倍 【免费下载链接】ComfyUI-WD14-Tagger A ComfyUI extension allowing for the interrogation of booru tags from images. 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-WD14-…...
基于TESS光变曲线与深度学习的O型星物理参数预测研究
1. 项目概述与核心挑战在恒星天体物理研究中,大质量O型星扮演着至关重要的角色。它们不仅是宇宙中光度最高的天体之一,其强烈的辐射、恒星风和最终的超新星爆发,更是驱动星系化学演化和能量注入星际介质的关键引擎。然而,深入理解…...
