我与framework的爱恨故事(面试篇)

我与framework的爱恨故事(面试篇)

我拿自己做实验

时间回到2022年8月, 当时为2023年4月跳槽(高级开发工程师)做准备,我是转行到程序员的行业,学历也比较的差。当时手里只有两张牌, 一是Rocketmq消息中间件源码,二是framework系统脚手架。再三思考后,我决定以自己作为实验,验证是否能用framework系统脚手架打开高级开发工程师的大门。于是用了几个月的时间, 结合公司的需求, 写了一整套framework系统框架, 并稳定在线上运行。4月份去面试时, 和面试官聊了近3小时, 这是我面试时间最长的一次, 当时就针对framework里的多个组件进行探讨, 那种感觉真的是太好了,有一种面试官是同道中人一般的错觉!

framework给了我什么

framework带给我的不仅仅是面试的成功, 薪资与职位的增长, 更多的是我收获了解决问题的思路!平常我们做业务功能开发,大家心里普遍会有一种感受:增删改查, 解决的是业务流程与逻辑的问题。在构建framework的过程中, 你会去思考,你会在心里给自己压力(这是整个系统依赖的基础框架,出不得半点问题),同时你写的代码得经得起大家的评审,设计实现得优雅(可不能被同事笑话了,哈哈)。更多的是解决一些成熟框架带来的技术问题!每次面对这样的技术问题, 从最开始的无从下手, 然后一点点debug框架源代码抓住我想要修改核心的东西,最后实现我想要的功能(一般此刻会打开手机音乐跟着哼),心里非常的爽,或许这就是作为程序员的快乐!

framework整合log4j2的一次快乐旅程

为什么最开始是日志框架, 因为我觉得, 事情都是慢慢按照线性进行的发展的, 首先把mvc简答引入到项目中, 请求已经可以进入到系统了, 那么就可以做简单的逻辑处理, 那你得打日志进行一些记录吧!这时候就灵魂三问自己了, 日志文件放在哪呢,方便以后进行统一的日志收集, 日志文件该什么样的格式呢 ,logout.log? 服务名.log? , 是不是得有一整套自己的日志模版?对对对, 都没有错, 那就开始解决这些问题!

日志文件放在哪,格式是什么? s y s : u s e r . h o m e / l o g s / a p p / {sys:user.home}/logs/app/ sys:user.home/logs/app/{FILE_NAME} , FILE_NAME是每一个服务应用的applicationName

下面是简单的日志文件配置, 主要关注sys:applicationName与sys:logLevel动态参数

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration monitorInterval="0">
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

    <!--变量配置-->
    <Properties>
        <!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
        <!-- %logger{36} 表示 Logger 名字最长36个字符 -->
        <property name="LOG_PATTERN"
                  value="%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %highlight{%p} %logger{36} - %msg%n"/>
        <property name="FILE_NAME" value="${sys:applicationName}"/>
        <!-- 定义日志存储的路径 -->
        <property name="FILE_PATH" value="${sys:user.home}/logs/app/${FILE_NAME}"/>
        <property name="LOG_LEVEL" value="${sys:logLevel}"/>

    </Properties>

    <appenders>

        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="${LOG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
        </console>

        <!-- 这个会打印出所有的info及以上级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFile" fileName="${FILE_PATH}/${FILE_NAME}.log"
                     filePattern="${FILE_PATH}/${FILE_NAME}-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="${LOG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="100MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
    </appenders>

    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <root level="${LOG_LEVEL}">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFile"/>
        </root>
    </loggers>

</configuration>

一阵引入启动, 发现效果不是自己想要的, 怎么没有加载我的日志配置文件,心里难受一秒钟, 问题不大!

发现几个问题:

  • 如何让springboot启动时 ,选择log4j2作为系统的日志文件(√)
  • 如何让springboot启动时, 加载我们自己的配置文件, 而不是默认的配置文件(√)
  • 加载配置文件的时候, 如果将sys:applicationName与sys:logLevel参数读取(√)

这时候, 就是一阵捣鼓,gpt ,google, 百度, 发现都不是我想要的, 但也有一点收获!这个时候脑瓜子里不觉间有一个想法, 既然springboot在启动时, 可以选择logback作为默认的日志框架,那肯定是有一个配置项的, 嘿嘿,顺着这个思路,果然被我发现了!告诉springboot在初始化时,LoggingSystem用Log4J2LoggingSystem就行了

java 复制代码
    private static final String LOGGING_SYSTEM_NAME = "org.springframework.boot.logging.LoggingSystem";
    private static final String LOG4J2_SYSTEM_NAME = "org.springframework.boot.logging.log4j2.Log4J2LoggingSystem";

    @Override
    public void onApplicationEvent(ApplicationStartingEvent event) {
        System.setProperty(LOGGING_SYSTEM_NAME, LOG4J2_SYSTEM_NAME);
    }

同理可得, 既然你可以加载默认的配置文件, 那么是否有一个配置, 同样的效果, 果然,又找到了,都是一样的套路!

java 复制代码
    private static final String LOG_CONFIG = "logging.config";
    private static final String CONFIG_LOCATION = "classpath:fd-log4j2.xml";
    System.setProperty(LOG_CONFIG, CONFIG_LOCATION);

对于动态的参数获取就比较的简单了,springboot在启动时, 通过ApplicationListener监听获取环境变量, 将对应的值复制到系统环境变量中即可, 心里非常舒服!

很自然打开了手机放起了音乐, 跟着哼起来!

最后

现在是2023年12月26日 0:23:40秒, 写这篇文章的时候总是不觉的嘴角上扬, 也希望读到文章的你也能获得一丢丢的乐趣! 献上整个框架代码地址:fd-framework: 企业级脚手架 (gitee.com),目前正在重写整个代码,一点点来, 很快就写完的!

相关推荐
骄马之死6 小时前
SpringMVC + SpringBoot 核心知识点总结
java·spring boot·后端
刀法如飞7 小时前
一文搞懂DDD 领域驱动设计思想原理
设计模式·架构·代码规范
郑洁文7 小时前
基于Spring Boot的流浪动物救助网站
java·spring boot·后端·毕设·流浪动物救助
螺丝钉code8 小时前
JAVA项目 Claude code CLAUDE.md 到底应该怎么写
java·人工智能·claude code
Cosolar8 小时前
LlamaIndex 文档解析与分块策略深度解析
人工智能·面试·架构
摇滚侠9 小时前
Maven 入门+高深 单一架构案例 54-59
java·架构·maven·intellij-idea
caimouse9 小时前
Reactos 第 4 章 对象管理 — 4.5 几个常用的内核函数
c语言·windows·架构
VidDown9 小时前
Webhook 调试器:让第三方回调“原形毕露”
java·开发语言·javascript·编辑器·postman
折哥的程序人生 · 物流技术专研10 小时前
Java 23 种设计模式:从踩坑到精通 | 原型模式 —— 克隆对象,深拷贝与浅拷贝的坑你踩过吗?
java·设计模式·架构·原型模式·单一职责原则
装不满的克莱因瓶10 小时前
基于 OpenResty 扩展开发实现动态服务注册与发现能力
java·开发语言·架构·openresty