【入侵iOS源码】【php广告任务网源码】【易语言 密码管理源码】logback 源码

来源:cornersubpix源码

1.如何配置 logback?30分钟让你彻底学会
2.RocketMQ第五讲
3.笑小枫的SpringBoot系列六SpringBoot日志打印Logback详解
4.在SpringBoot中使用logback优化异常堆栈的输出
5.log4j2(一) 获取 ILoggerFactory

logback 源码

如何配置 logback?30分钟让你彻底学会

       如何配置logback?分钟让你彻底掌握

       logback,由log4j创始人设计的开源日志组件,由logback-core、logback-classic和logback-access组成。logback-classic改进了log4j,兼容SLF4J,入侵iOS源码便于更换其他日志系统。访问模块logback-access则支持通过Http访问日志。

       配置文件结构详解:

       - 配置文件包含根logger、appender、filter等元素,如root logger的level属性和appender-ref引用。

       配置细节:

       - contextName:用于区分不同应用程序的日志上下文,默认为"default",可通过标签设置。

       - property:定义变量并可在logger上下文中使用。

       - logger:指定特定包或类的日志级别及appender。

       - root:根logger,具有唯一的level属性。

       - appender:负责日志记录,包括定义过滤条件、输出方式等。

       - filter:作为appender内部的过滤器,决定日志的php广告任务网源码接受、中立或拒绝。

       案例分析:

       - 通过配置控制台打印和文件输出,以及使用logger来区分包或类的输出。

       - logger和appender关系:logger决定哪些日志打印,appender定义输出方式,两者结合确定日志流向。

       进一步配置:

       - 详细讲解appender配置,包括名称、class、文件名、滚动策略、过滤器和编码等。

       - logger配置示例,通过appender-ref指定打印的appender和级别。

       总结:

       - 本文总结了logback的基本配置和案例,介绍了logger、appender和filter的交互,以及如何根据需要定制日志输出。

       - 学习日志框架源码有助于理解性能、缓冲和同步等问题,未来会分享更多相关技术文章,如SOFABoot和SpringBoot。

       原链接:[原文链接](juejin.cn/post/...)

RocketMQ第五讲

       broker是易语言 密码管理源码RocketMQ的核心,核心工作就是接收生成这的消息,进行存储。同时,收到消费者的请求后,从磁盘读取内容,把结果返回给消费者。

        消息主体以及元数据的存储主体,存储Producer端写入的消息主体内容,消息内容不是定长的。单个文件大小默认1G ,文件名长度为位,左边补零,剩余为起始偏移量,比如代表了第一个文件,起始偏移量为0,文件大小为1G=;当第一个文件写满了,第二个文件为,起始偏移量为,以此类推。消息主要是顺序写入日志文件,当文件满了,写入下一个文件;

        CommitLog文件中保存了消息的全量内容。不同的Topic的消息,在CommitLog都是java 编译器源码顺序存放的。就是来一个消息,不管Topic是什么,直接追加的CommitLog中。

        broker启动了一个专门的线程来构建索引,把CommitLog中的消息,构建了两种类型的索引。ConsumerQueue和Index。正常消费的时候,是根据Topic来消费,会用到ConsumerQueue索引。

        也可根据返回的offsetMsgId,解析出ip,端口和CommitLog中的物理消息偏移量,直接去CommitLog中取数据。

        引入的目的主要是提高消息消费的性能,由于RocketMQ是基于主题topic的订阅模式,消息消费是针对主题进行的,如果要遍历commitlog文件中根据topic检索消息是非常低效的。Consumer即可根据ConsumeQueue来查找待消费的消息。

        其中,ConsumeQueue(逻辑消费队列)作为消费消息的索引,保存了指定Topic下的队列消息在CommitLog中的起始物理偏移量offset,消息大小size和消息Tag的易语言账号源码HashCode值。consumequeue文件可以看成是基于topic的commitlog索引文件,故consumequeue文件夹的组织方式如下:topic/queue/file三层组织结构,具体存储路径为:$HOME/store/consumequeue/{ topic}/{ queueId}/{ fileName}。同样consumequeue文件采取定长设计,每一个条目共个字节,分别为8字节的commitlog物理偏移量、4字节的消息长度、8字节tag hashcode,单个文件由W个条目组成,可以像数组一样随机访问每一个条目,每个ConsumeQueue文件大小约5.M。

        IndexFile(索引文件)提供了一种可以通过key或时间区间来查询消息的方法。Index文件的存储位置是: { fileName},文件名fileName是以创建时的时间戳命名的,固定的单个IndexFile文件大小约为M,一个IndexFile可以保存 W个索引,IndexFile的底层存储设计为在文件系统中实现HashMap结构,故rocketmq的索引文件其底层实现为hash索引。

        按照Message Key查询消息的时候,会用到这个索引文件。

        IndexFile索引文件为用户提供通过“按照Message Key查询消息”的消息索引查询服务,IndexFile文件的存储位置是: { fileName},文件名fileName是以创建时的时间戳命名的,文件大小是固定的,等于+W 4+W = 个字节大小。如果消息的properties中设置了UNIQ_KEY这个属性,就用 topic + “#” + UNIQ_KEY的value作为 key 来做写入操作。如果消息设置了KEYS属性(多个KEY以空格分隔),也会用 topic + “#” + KEY 来做索引。

        其中的索引数据包含了Key Hash/CommitLog Offset/Timestamp/NextIndex offset 这四个字段,一共 Byte。NextIndex offset 即前面读出来的 slotValue,如果有 hash冲突,就可以用这个字段将所有冲突的索引用链表的方式串起来了。Timestamp记录的是消息storeTimestamp之间的差,并不是一个绝对的时间。整个Index File的结构如图, Byte 的Header用于保存一些总的统计信息,4 W的 Slot Table并不保存真正的索引数据,而是保存每个槽位对应的单向链表的头。 W 是真正的索引数据,即一个 Index File 可以保存 W个索引。

        “按照Message Key查询消息”的方式,RocketMQ的具体做法是,主要通过Broker端的QueryMessageProcessor业务处理器来查询,读取消息的过程就是用topic和key找到IndexFile索引文件中的一条记录,根据其中的commitLog offset从CommitLog文件中读取消息的实体内容。

        RocketMQ中有两个核心模块,remoting模块和store模块。remoting模块在NameServer,Produce,Consumer和Broker都用到。store只在Broker中用到,包含了存储文件操作的API,对消息实体的操作是通过DefaultMessageStore进行操作。

        属性和方法很多,就不往这里放了。

        文件存储实现类,包括多个内部类

        · 对于文件夹下的一个文件

        上面介绍了broker的核心业务流程和架构,关键接口和类,启动流程。最后介绍一下broker的线程模型,只有知道了线程模型,才能大概知道前面介绍的那些事如何协同工作的,对broker才能有一个立体的认识。

        RocketMQ的RPC通信采用Netty组件作为底层通信库,同样也遵循了Reactor多线程模型,同时又在这之上做了一些扩展和优化。关于Reactor线程模型,可以看看我之前写的这篇文档: Reactor线程模型

        上面的框图中可以大致了解RocketMQ中NettyRemotingServer的Reactor 多线程模型。一个 Reactor 主线程(eventLoopGroupBoss,即为上面的1)负责监听 TCP网络连接请求,建立好连接,创建SocketChannel,并注册到selector上。RocketMQ的源码中会自动根据OS的类型选择NIO和Epoll,也可以通过参数配置),然后监听真正的网络数据。拿到网络数据后,再丢给Worker线程池(eventLoopGroupSelector,即为上面的“N”,源码中默认设置为3),在真正执行业务逻辑之前需要进行SSL验证、编解码、空闲检查、网络连接管理,这些工作交给defaultEventExecutorGroup(即为上面的“M1”,源码中默认设置为8)去做。而处理业务操作放在业务线程池中执行,根据 RomotingCommand 的业务请求码code去processorTable这个本地缓存变量中找到对应的 processor,然后封装成task任务后,提交给对应的业务processor处理线程池来执行(sendMessageExecutor,以发送消息为例,即为上面的 “M2”)。

        上面的图和这段画是从官方文档抄过来的,但是文字和图对应的不是很好,画的也不够详细,但是主要流程是这个样子。以后有时间了,我重新安装自己的理解,画一张更详细的图。

        AsyncAppender-Worker-Thread-0:异步打印日志,logback使用,应该是守护线程

        FileWatchService:

        NettyEventExecutor:

        NettyNIOBoss_:一个

        NettyServerNIOSelector_:默认为三个

        NSScheduledThread:定时任务线程

        ServerHouseKeepingService:守护线程

        ThreadDeathWatch-2-1:守护线程,Netty用,已经废弃

        RemotingExecutorThread(1-8):工作线程池,没有共用NettyServerNIOSelector_,直接初始化8个线程

        AsyncAppender-Worker-Thread-0:异步打印日志,logback使用,共九个:

        RocketmqBrokerAppender_inner

        RocketmqFilterAppender_inner

        RocketmqProtectionAppender_inner

        RocketmqRemotingAppender_inner

        RocketmqRebalanceLockAppender_inner

        RocketmqStoreAppender_inner

        RocketmqStoreErrorAppender_inner

        RocketmqWaterMarkAppender_inner

        RocketmqTransactionAppender_inner

        SendMessageThread_:remotingServer.registerProcessor(RequestCode.SEND_MESSAGE

        PullMessageThread_:remotingServer.registerProcessor(RequestCode.PULL_MESSAGE

        ProcessReplyMessageThread_:remotingServer.registerProcessor(RequestCode.SEND_REPLY_MESSAGE

        QueryMessageThread_:remotingServer.registerProcessor(RequestCode.QUERY_MESSAGE

        AdminBrokerThread_:remotingServer.registerDefaultProcessor

        ClientManageThread_:remotingServer.registerProcessor(RequestCode.UNREGISTER_CLIENT

        HeartbeatThread_:remotingServer.registerProcessor(RequestCode.HEART_BEAT

        EndTransactionThread_:remotingServer.registerProcessor(RequestCode.END_TRANSACTION

        ConsumerManageThread_:remotingServer.registerProcessor(RequestCode.GET_CONSUMER_LIST_BY_GROUP,RequestCode.UPDATE_CONSUMER_OFFSET,RequestCode.QUERY_CONSUMER_OFFSET

        brokerOutApi_thread_:BrokerController.registerBrokerAll(true, false, true);

        ==================================================================

        BrokerControllerScheduledThread:=>

        BrokerController.this.getBrokerStats().record();

        BrokerController.this.consumerOffsetManager.persist();

        BrokerController.this.consumerFilterManager.persist();

        BrokerController.this.protectBroker();

        BrokerController.this.printWaterMark();

        log.info("dispatch behind commit log { } bytes", BrokerController.this.getMessageStore().dispatchBehindBytes());

        BrokerController.this.brokerOuterAPI.fetchNameServerAddr();

        BrokerController.this.printMasterAndSlaveDiff();

        BrokerController.this.registerBrokerAll(true, false, brokerConfig.isForceRegister());

        BrokerFastFailureScheduledThread:=>

        FilterServerManagerScheduledThread:=>

        FilterServerManager.this.createFilterServer();

        ClientHousekeepingScheduledThread:=>

        ClientHousekeepingService.this.scanExceptionChannel();

        PullRequestHoldService

        FileWatchService

        AllocateMappedFileService

        AcceptSocketService

        BrokerStatsThread1

笑小枫的SpringBoot系列六SpringBoot日志打印Logback详解

       SpringBoot默认采用Logback作为日志处理框架,无需显式配置即可在控制台看到启动日志,这是因为其内置了默认的base.xml配置,root输出级别设为INFO。要自定义配置,只需在resources目录下创建logback-spring.xml文件。接下来,我们详细解读Logback的配置属性,包括根节点的子节点用于定义变量,用于设置输出策略,如控制台和文件输出,用于指定类的日志级别和输出appender,而则是设置全局日志级别。多环境配置可以通过标签结合Profile功能来实现。最后,Logback还支持使用filter来筛选日志级别,以及rollingPolicy和相关归档设置。通过这篇文章,我们了解到如何灵活定制SpringBoot的Logback配置以满足不同业务需求。

       关于笑小枫:感谢关注我的SpringBoot日志详解系列,如果您喜欢本文,别忘了点赞收藏,有任何疑问,随时留言,我将保持在线回复。我的其他资源可关注微信公众号:笑小枫,个人博客:/post/

log4j2(一) 获取 ILoggerFactory

       å…³äºŽlog4j2的初始化流程,现在项目基本都是springboot项目,就需要结合 springboot 源码来解析,这块可以参考 Springboot - Log4J2LoggingSystem源码解析

        因为spring-boot-starter依赖中日志使用的是spring-boot-starter-logging,这里面是用的是logback,所以需要先剔除此依赖

        再添加log4j2依赖

        如果我们想使用 yml 后缀的配置文件还需要再加一个依赖

        然后相关依赖版本如下

        以下源码基于 log4j 2.7。

        先看一张log4j官方提供的类图

        先简单了解一下这些类

        过滤器的种类也很多,比如根据日志级别。Filter会返回一个枚举值Filter.Result,有三种:

        详细参见 log4j - Filters

        log4j的初始化流程实在有点饶,这里简要讲讲。

        LoggerFactory#getLogger(String)

        在只有一个log4j2的依赖时,加载流程大致如下:

        在 getILoggerFactory() 方法中做了这么几件事

        再看下 log4j2 的 StaticLoggerBinder 源码

        下一篇看看后续Logger的获取。

        添加 logback 依赖(直接放开 spring-boot-starter-logging 也行),这样我们项目就有两个 org/slf4j/impl/StaticLoggerBinder.class 了

        然后启动,提示

        我的疑问就是为啥不用log4j2而用logback,就打开这个网址查了下,里面最后有一段

        告诉我们

        好吧,随机的我也是醉了。。

        参考

       http://logging.apache.org/log4j/2.x/log4j-users-guide.pdf

       http://www.slf4j.org/codes.html#multiple_bindings

        回家,风雨兼程。

文章所属分类:时尚频道,点击进入>>