日志分析删除

news2024/10/12 9:25:20

日志分析

场景

运维嫌弃生产环境打印日志过多,而且日志存储需要费用,让我们减少打印日志大小,所以需要分析日志在哪里打印的过多

解决方案

读取生产日志文件,统计分析打印日志的地方,最后删除代码中打印日志的地方

实现-LogParAnalyzer

public class LogParAnalyzer {


    //日志原始文件
    private File log;
    private List<Pattern> list;
    private ExecutorService executorService;

    //生成的分割文件
    private String subPath = "D:\\split\\";
    private List<File> files;

    public LogParAnalyzer(File log, List<String> patterns) {
        this.log = log;
        executorService = Executors.newFixedThreadPool(30);
        list = new ArrayList<>();
        try {
            for (String pattern : patterns) {
                Pattern p = Pattern.compile(pattern);
                list.add(p);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }



    public void analyze() throws Exception {
        // 使用 try-with-resources 自动关闭 BufferedReader
        int chunkSize = 100000;
        try (BufferedReader reader = new BufferedReader(new FileReader(log))) {
            File file = new File(subPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            String line;
            List<CompletableFuture<?>> task = new ArrayList<>();
            int cur = 0;
            List<String> list = new ArrayList<>();
            AtomicInteger batch = new AtomicInteger(0);
            while ((line = reader.readLine()) != null) {
                //sb 会通过Arrays.copy复制字节数组,内存频繁复制
                list.add(line);
                cur++;
                if ((cur % chunkSize) == 0) {
                    //深拷贝
                    List<String> tt = list.stream().map(String::new).collect(Collectors.toList());
                    list.clear();
                    CompletableFuture f =
                            CompletableFuture.runAsync(() -> processChunk(tt, batch.get()), executorService);
                    task.add(f);
                    batch.incrementAndGet();
                }
            }
            if (list.size()>0) {
                CompletableFuture f =
                        CompletableFuture.runAsync(() -> processChunk(list, batch.get()), executorService);
                task.add(f);
            }
            //等待所有任务结束
            CompletableFuture.allOf(task.toArray(new CompletableFuture[0])).get();
            System.out.println("task execute finished");
        }
    }


    private void processChunk(List<String> lines, int batch) {
        try {
            System.out.println(Thread.currentThread().getName()+" execute "+ batch+".txt start");
            Map<String, AtomicInteger> map = new HashMap<>();
            try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(subPath + batch + ".txt"))) {
                lines.forEach(line -> {
                    for (Pattern pattern : list) {
                        Matcher matcher = pattern.matcher(line);
                        if (matcher.find()) {
                            String group = matcher.group(0);
                            map.computeIfAbsent(group, k -> new AtomicInteger(1)).incrementAndGet();
                        }
                    }

                    if (map.size() > 0) {
                        //每个文件只保存100前100条
                        writeBatchToFile(writer, map);
                    }
                });
            }
            System.out.println(Thread.currentThread().getName()+" execute "+ batch+".txt end");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void writeBatchToFile(BufferedWriter writer, Map<String, AtomicInteger> map) {
        Map<String, AtomicInteger> limit = limit(map, 100);
        try {
            for (Map.Entry<String, AtomicInteger> entry : limit.entrySet()) {
                writer.write(entry.getKey() + "=" + entry.getValue().get());
                writer.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //清除缓存
        map.clear();
        limit.clear();
    }

    public void mergeAndSort() throws Exception {
        files = Files.list(Paths.get(subPath))
                .map(Path::toFile)
                .filter(f -> f.length() > 0)
                .collect(Collectors.toList());

        // 创建 ForkJoinPool
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        MergeFileTask mergeFileTask = new MergeFileTask(files.toArray(new File[0]), forkJoinPool);
        Path finalPath = mergeFileTask.invoke();
        System.out.println("final path: " + finalPath.toAbsolutePath());
        try (BufferedReader reader = Files.newBufferedReader(finalPath)) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        }
        mergeFileTask.finished();
    }

    public void finished() throws IOException {
        if (!CollectionUtils.isEmpty(files)){
            files.stream().parallel().forEach(File::delete);
        }
        Files.deleteIfExists(Paths.get(subPath));
    }

    public Map<String, AtomicInteger> limit(Map<String, AtomicInteger> map, int limit) {
        // 排序并过滤结果
        return map.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.comparing(AtomicInteger::get).reversed()))
                .limit(limit)
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue, // 解决键冲突
                        LinkedHashMap::new
                ));
    }

}

测试

@Test
public void bb() throws Exception {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    File log = new File("E:\\log_total.log\\log_total.log");
    //2023-09-26 11:10:00.123 INFO - none --- [main] com.example.service.UserService.create:42 - User service started successfully.
    //匹配出 com.example.service.UserService.create:42
    //c.y.c.w..*指文件名太长,缩写
    List<String> list = Arrays.asList("(com\\.xx\\.[\\w\\.\\*]*:\\d*)", "(c\\.y\\.c\\.[\\w\\.\\*]*:\\d*)");
    LogParAnalyzer logAnalyzer = new LogParAnalyzer(log, list);
    logAnalyzer.analyze();
    logAnalyzer.mergeAndSort();
    logAnalyzer.finished();
    stopWatch.stop();
    System.out.println(stopWatch.prettyPrint());
    //最后统计格式
    //c.y.c.s.service.impl.Service.complete:98 count: 6
}

good luck!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2207618.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

esp32-c3 Supermini 模块下载

1.此模块自带usb 功能&#xff0c;可以直接利用数据线连接模块与pc进行下载。此模块不带uart to usb 集成块。 2. 此模块下载只能用自带type c 数据口与pc usb 连接进行。不能用usb 转 uart 对模块下载&#xff0c;但可以通讯 3. 利用idf.py 对模块下载前&#xff0c;必…

Thread类的用法练习

目录 1.继承 Thread, 重写 run 2.实现 Runnable, 重写 run 3.继承 Thread, 重写 run, 使用匿名内部类 4.实现 Runnable, 重写 run, 使用匿名内部类 5.使用 lambda 表达式 6.请回答以下代码的输出, 并解释原因 1.继承 Thread, 重写 run 2.实现 Runnable, 重写 run 3.继承 Th…

四、远程登录到Linux服务器

说明 linux 服务器是开发小组共享&#xff0c;正式上线的项目是运行在公网&#xff0c;因此需要远程登录到 Linux 进行项目管理或者开发 Xshell 1、特点 Xshell 是目前最好的远程登录到 Linux 操作的软件&#xff0c;流畅的速度并且完美解决了中文乱码的问题&#xff0c; 是目…

计算机毕业设计 基于Python+Django的旅游景点数据分析与推荐系统的设计与实现 Python毕业设计 Python毕业设计选题【附源码+安装调试】

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

黑马程序员C++提高编程学习笔记

黑马程序员C提高编程 提高阶段主要针对泛型编程和STL技术 文章目录 黑马程序员C提高编程一、模板1.1 函数模板1.1.1 函数模板基础知识 案例一&#xff1a; 数组排序1.2.1 普通函数与函数模板1.2.2 函数模板的局限性 1.2 类模板1.2.1 类模板的基础知识1.2.2 类模板与函数模板1.…

ssm基于SSM框架的餐馆点餐系统的设计+VUE

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 摘要 I Abstract II 1绪论 1 1.1研究背景与意义 1 1.1.1研究背景 1 1.1.2研究意义 1 1.2国内外研究…

有什么方法可以保护ppt文件不被随意修改呢?

在工作或学习中&#xff0c;我们常常需要制作powerpoint演示文稿&#xff0c;担心自己不小心改动了或者不想他人随意更改&#xff0c;我们可以如何保护PPT呢&#xff1f;下面小编就来分享两个常用的方法。 方法一&#xff1a;为PPT设置打开密码 为PPT设置打开密码是最直接有效…

Prim算法实现最小生成树

Prim算法是一种用来寻找图的最小生成树的贪心算法。最小生成树是连接图中所有顶点的边的子集&#xff0c;这些边的权重总和最小&#xff0c;且形成一个树形结构&#xff0c;包含所有顶点。 Prim算法的基本步骤如下&#xff1a; 初始化&#xff1a; 选择任意一个顶点作为起始点…

全栈开发要掌握的技术

文章目录 1、前端开发2、后台开发2.1 编程语言2.2 网络框架 3、数据库开发3.1 RDBMS3.2 NoSQL 数据库 4、移动开发4.1 本地开发4.2 跨平台开发 5、云计算5.1 云平台5.2 容器化和协调 6、用户界面/用户体验设计6.1 设计工具6.2 原型和线框图 7、基础设施和 DevOps7.1 基础设施即…

C语言读取data.json文件并存入MySQL数据库小案例

本地有一个data.json文件 data.json [{"id": 1,"name": "Alice","age": 30},{"id": 2,"name": "Bob","age": 25} ]要将 data.json 文件中的数据存储到 MySQL 数据库中&#xff0c;首先需要…

快速入门Tomcat服务(业务发布基础技能)

文章目录 1 Tomcat简介 2 安装tomcat 2.1 安装jdk 2.2 安装Tomcat 3 Tomcat目录结构 4 Tomcat重要配置文件 1 Tomcat简介 Tomcat是Sun公司官方推荐的Servlet和JSP容器&#xff0c;在中小型系统和并发访问用户不是很多的场合下&#xff0c;其作为轻量级应用服务…

如何在Node.js里实现依赖注入

什么是依赖注入 依赖注入是一种用于在开发过程中实现控制反转&#xff08;IoC&#xff09;的技术。在IoC中&#xff0c;对程序流的控制是颠倒的&#xff1a;依赖项不是控制其依赖项的创建和管理的组件&#xff0c;而是从外部源提供给组件。 在传统的编程模式中&#xff0c;一个…

【ECC校验及使用】

ECC校验及使用 1 RAM ECC Demo 在IC设计中会经常用到ram来进行存储&#xff0c;在存储数据时我们写读时需要知道在传输过程中有没有出现差错&#xff0c;因此需要额外的校验位也存储下来&#xff1b; ECC验证能纠正1bit错误&#xff0c;能发现2bit错误&#xff0c;但是无法纠正…

第十三章:监控过程组(13.1控制质量--13.7监督沟通)

前言&#xff1a; 监督 是收集项目绩效数据&#xff0c;计算绩效指标&#xff0c;并报告和发布绩效信息。 控制 是比较实际绩效与计划绩效&#xff0c;分析偏差&#xff0c;评估趋势以改进过程&#xff0c;评价可选方案&#xff0c;并建 议必要的纠正措施。 13.1 控制质量 本过…

数据库SQL基础教程(二)

目录 连接(JOIN) 语法&#xff1a; 不同的 SQL JOIN INNER JOIN 关键字 LEFT JOIN 关键字 SQL LEFT JOIN 语法 RIGHT JOIN 关键字 SQL RIGHT JOIN 语法 FULL OUTER JOIN 关键字 SQL FULL OUTER JOIN 语法 UNION 操作符 SQL UNION 语法 SQL UNION ALL 语法 SELECT I…

大数据毕业设计选题推荐-B站短视频数据分析系统-Python数据可视化-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

软媒市场新蓝海:软文媒体自助发布与自助发稿的崛起

在信息时代的浪潮中,软媒市场以其独特的魅力和无限的潜力,成为了企业营销的新宠。随着互联网的飞速发展,软文媒体自助发布平台应运而生,为企业提供了更加高效、便捷的营销方式。而自助发稿功能的加入,更是让软媒市场的蓝海变得更加广阔。 软媒市场的独特价值 软媒市场之所以能…

YOLO_V8分割

YOLO_V8分割 YOLO安装 pip install ultralytics YOLO的数据集转化看csdn 数据标注EIseg EIseg这块&#xff0c;正常安装就好&#xff0c;但是numpy和各类包都容易有冲突&#xff0c;python版本装第一点 数据标注过程中&#xff0c;记得把JSON和COCO都点上&#xff0c;把自…

计算机毕业设计 基于Hadoop平台的岗位推荐系统的设计与实现 Python毕业设计 Python毕业设计选题【附源码+安装调试】

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

python脚本封装APK,轻松随意无须复杂配置

优点&#xff1a;轻松随意不设置&#xff0c;缺点&#xff1a;新用户试用&#xff0c;VI专属能力。 (笔记模板由python脚本于2024年10月11日 06:16:14创建&#xff0c;本篇笔记适合“资深”编程的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.py…