【Java日志系列实践1】系统操作日志的标准使用

1 常见日志分类

日志一般根据使用场景分为系统日志和操作日志。
系统日志:排查定位问题
操作日志:记录用户操作,业务数据回溯与统计。

2 系统日志格式

系统日志主要是为开发排查问题提供依据,日志一般打印在日志文件中,可读性要求没那么高。
SpringBoot 默认选择的是 slf4j + logback 的组合,默认会将日志打印到控制台上。

日期时间:精确到毫秒。
日志级别:打印 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 等级别日志信息。
进程 ID:当前项目进程 ID 。
分隔符:— 是分隔符,分隔符后面代表具体的日志内容。
线程名:方括号中间的内容表示线程名称。
类名:当前日志打印所属的类名称。
日志内容:开发人员设定的日志具体内容。

实际工程中规范的日志信息:

  1. 单机项目建议打印:时间(精度根据需要制定)、日志级别、线程、类名、异常堆栈、日志内容(包括方法名、关键请求参数与返回参数);
  2. 分布式项目建议额外包含:用户标识、机器ip/主机名、traceId;

在.yml文件里的配置

#单机示例
logging:
  level:
    root: debug
  pattern:
    console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) - %clr([%t]){faint} %X{userId} %X{traceId}%clr(:) {faint} %m%n%wEx"
#分布式示例
logging:
  level:
    root: info
  pattern:
    console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) -- %clr([%t]){faint} %X{hostIp} %X{userId} %X{traceId}%clr(:) %m%n%wEx"

实际工程项目中,常需要更改为其他日志系统(如 log4j2 ),则可以在配置文件里进行一些符合个人习惯的设置。
如果启动项目时觉得日志打印太多,还可以调整项目日志的记录级别为 WARN ,打印 WARN 及优先级更高的 ERROR 级别的日志。

@SpringBootTest
class LogTest {
    //LoggerFactory是slf4j的日志对象工程
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Test
    void testPrintLog() {
        logger.trace("I am trace log..");
        logger.debug("I am debug log..");
        logger.info("I am info log..");
        logger.warn("I am warn log..");
        logger.error("I am error log..");
    }
}

(2)日志级别等自定义设置
Springboot默认的打印级别是info,而trace、debug不打印,调试时若想打印debug日志,可以在配置文件中进行自定义设置,如下:

    @GetMapping("start")
    public void normalLog(){
        List<String> requestList = new ArrayList<>();
        requestList.add("入参列表1");
        requestList.add("入参列表2");
        Gson gson = new Gson();
        //获取到用户标识
        String userNo = "userId007";
        //把用户ID放到MDC上下文中
        MDC.put("userId", userNo);
        logger.info("【normalLog】menuFolderList:{}", gson.toJson(requestList));
    }

如果启动项目时觉得日志打印太多,还可以调整项目日志的记录级别为 WARN ,打印 WARN 及优先级更高的 ERROR 级别的日志。

@WebFilter(filterName = "traceIdFilter", urlPatterns = "/*")
@Component
public class TraceFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        MDC.put("traceId", UUID.randomUUID().toString());
        filterChain.doFilter(httpServletRequest,httpServletResponse);

        // 获取 pod ip
        String podIp = new InetUtils(new InetUtilsProperties()).findFirstNonLoopbackHostInfo().getIpAddress();
        MDC.put("hostIp", podIp);
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

}

(3)定制操作日志配置
通过配置 Log 的配置文件,把有关操作日志的 Log 单独放到一日志文件中。不同业务日志记录到不同的文件
在logging-logback的defaults.xml文件里,对日志进行了一些基本定义,比如CONSOLE_LOG_PATTERN和LOG_FILE【边讲解边演示】
我们一起来看看控制台、日志文件的日志显示格式的自定义方式和效果【解释日期、线程号、靠左输出日志级别、全类名字符数量、日志消息换行符】
第一步: 文件配置
logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger{50}- %msg%n
在logback的日志追加器XX-appender里,我们可以自己扩展更多的定义

1、yml配置日志文件

logging:
config: classpath:log4j2/log4j2-local.xml

2、xml进行日志具体配置

<configuration status="debug">
    <appenders>
        <!--异步磁盘appender,默认按天&按512M文件大小切分日志,默认最多保留30个日志文件,默认为noblocking写日志模式-->
        <XMDFile name="requestLog" fileName="request.log" rolloverMax="5"></XMDFile>

        <!--ERROR日志、WARN日志单独输出到一个文件-->
        <XMDFile name="errorLog" fileName="error.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
        </XMDFile>

        <!--日志远程上报-->
        <Scribe name="ScribeAppender">
            <!-- 在指定日志名方面,scribeCategory 和 appkey 两者至少存在一种,且 scribeCategory 高于 appkey。-->
            <!-- <Property name="scribeCategory">data_update_test_lc</Property> -->
            <LcLayout/>
        </Scribe>
        <Async name="ScribeAsyncAppender" blocking="false">
            <AppenderRef ref="ScribeAppender"/>
        </Async>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{DEFAULT} [%t] %-5p (%C{1}:%L) - %m%n"/>
        </Console>
    </appenders>

    <loggers>
        <logger name="com.meituan" level="info"/>

        <logger name="org.springframework" level="info"/>

        <root level="info">
            <appender-ref ref="requestLog"/>
            <appender-ref ref="warnLog"/>
            <appender-ref ref="errorLog"/>
            <appender-ref ref="ScribeAsyncAppender"/>
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
### 回答1: 学生管理系统是一个广泛应用的项目,它能够帮助学校或教育机构有效管理学生信息。下面是一个简单的Java实践学生管理系统项目源代码: ```java import java.util.ArrayList; class Student { private String name; private int id; public Student(String name, int id) { this.name = name; this.id = id; } public String getName() { return name; } public int getId() { return id; } } class StudentManagementSystem { private ArrayList<Student> students; public StudentManagementSystem() { students = new ArrayList<>(); } public void addStudent(Student student) { students.add(student); } public void removeStudent(Student student) { students.remove(student); } public void printAllStudents() { for (Student student : students) { System.out.println("Name: " + student.getName() + ", ID: " + student.getId()); } } } public class Main { public static void main(String[] args) { StudentManagementSystem sms = new StudentManagementSystem(); // 添加学生 Student student1 = new Student("张三", 1); Student student2 = new Student("李四", 2); Student student3 = new Student("王五", 3); sms.addStudent(student1); sms.addStudent(student2); sms.addStudent(student3); // 删除学生 sms.removeStudent(student2); // 打印所有学生 sms.printAllStudents(); } } ``` 这个源代码中,首先定义了一个学生类(Student),包括学生的姓名和学号属性,并提供相应的获取方法。然后,定义了一个学生管理系统类(StudentManagementSystem),包含一个学生列表,该类提供了添加学生、删除学生和打印所有学生的方法。最后,在主方法中创建了一个学生管理系统对象,并进行了相关操作:添加学生、删除学生、打印所有学生。 ### 回答2: Java实践学生管理系统项目源代码会比较复杂,不足以在这里用300字详细解释所有的源代码。但是,我可以给你一个简单的实现思路和相关功能模块。 1. 登录模块:实现用户的登录验证,包括管理员和学生用户。 2. 学生信息管理模块:包括添加学生信息、查询学生信息、修改学生信息和删除学生信息等功能。 3. 课程信息管理模块:包括添加课程信息、查询课程信息、修改课程信息和删除课程信息等功能。 4. 选课模块:学生可以根据自己的需要选择需要的课程。 5. 成绩管理模块:管理员可以录入学生的成绩,并且学生可以查询自己的成绩。 6. 教师信息管理模块:包括添加教师信息、查询教师信息、修改教师信息和删除教师信息等功能。 7. 记录日志模块:记录系统操作日志,包括用户登录日志操作记录等。 这只是一个简单的实现思路,实际项目中还需要考虑各种异常处理、权限控制、数据校验等方面的实现。总的来说,这是一个针对学生管理系统的简单应用程序,可以通过Java来实现。 ### 回答3: Java学生管理系统项目的源代码是一个用Java语言编写的完整的学生信息管理系统,用于对学生信息进行管理和操作。该项目基于面向对象的思想,采用了MVC(Model-View-Controller)的设计模式,使得代码结构清晰、易于维护和扩展。以下是一个简单的示例源代码: ``` // Student.java public class Student { private String name; private int age; private String gender; public Student(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public int getAge() { return age; } public String getGender() { return gender; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setGender(String gender) { this.gender = gender; } } // StudentManagementSystem.java import java.util.ArrayList; import java.util.List; public class StudentManagementSystem { private List<Student> students; public StudentManagementSystem() { students = new ArrayList<>(); } public void addStudent(Student student) { students.add(student); } public void removeStudent(Student student) { students.remove(student); } public void updateStudent(Student student, String name, int age, String gender) { student.setName(name); student.setAge(age); student.setGender(gender); } public List<Student> getAllStudents() { return students; } } // MainApp.java public class MainApp { public static void main(String[] args) { StudentManagementSystem sms = new StudentManagementSystem(); Student student1 = new Student("张三", 18, "男"); Student student2 = new Student("李四", 20, "女"); sms.addStudent(student1); sms.addStudent(student2); List<Student> allStudents = sms.getAllStudents(); for (Student student : allStudents) { System.out.println("姓名:" + student.getName()); System.out.println("年龄:" + student.getAge()); System.out.println("性别:" + student.getGender()); } } } ``` 以上代码实现了一个简单的学生管理系统,包括学生类、学生管理系统类以及一个主程序入口类。可以通过`addStudent`方法添加学生,`removeStudent`方法删除学生,`updateStudent`方法更新学生信息,并通过`getAllStudents`方法获取所有学生信息。在主程序入口中,创建了一个学生管理系统实例,并进行了简单的测试和展示。这些代码仅作为示例,实际开发中可能需要更多的功能和实现细节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值