前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我造了一个轮子去写系统日志

我造了一个轮子去写系统日志

作者头像
用户7386338
发布2020-05-29 11:04:16
2980
发布2020-05-29 11:04:16
举报
文章被收录于专栏:Java患者Java患者Java患者

前言

在我们工作的项目中,每个项目都会涉及到操作日志,每个公司当然也有自己的想法自己做操作日志的保存。我今天造了一个简单的轮子来写日志。采用的技术是ExecutorsBlockingQueue

Executors

一个线程池接口,定义了一个可以接收Runnable对象的方法executor,该方法接收要给Runnable实例后,可以用来执行一个任务,一般使用execute(new RunnableTask())方法异步执行。

为什么要开另外一个线程?

为什么要异步执行?因为这里考虑到操作日志不应该影响到我们的性能,我们在操作之后,无需等到日志写完才response。

BlockingQueue

Blocking 即为阻塞,Queue即为队列,BlockingQueue阻塞队列类。

其实就是一个队列的数据结构,线程一直以队列的数据结构从BlockingQueue里面拿数据,如果没数据了,那么线程就一直阻塞进入等待状态,一直等一直等,直到有其他线程在BlockingQueue中添加了数据,被阻塞的线程被唤醒。同样,如果BlockingQueue是满的,有线程从队列中存放数据,线程也会被阻塞,一直等一直等,等到不满的时候,线程唤醒,继续存放数据。

实例

操作内容

package com.zero.na;

import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class WriteLogUtil {

    private ExecutorService executorService;
    private BlockingQueue<Map<String, String>> bqBuff;

    public WriteLogUtil() {
        executorService = Executors.newSingleThreadExecutor();
        bqBuff = new ArrayBlockingQueue<>(1024);

        executorService.execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Map<String, String> item = null;
                    try {
                        item = bqBuff.take();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (item != null) {
                        write(item);
                    }

                }
            }
        });
    }

    private final static WriteLogUtil instance = new WriteLogUtil();

    public static WriteLogUtil getInstance() {
        return instance;
    }

    public void appLog(Map<String, String> log) {
        saveLog(log);
    }

    private void saveLog(Map<String, String> log) {
        bqBuff.add(log);
    }

    private void write(Map<String, String> item) {
        System.out.println(item);
    }
}

测试1

package com.zero.na;

import java.util.HashMap;
import java.util.Map;

public class Test1 {

    public static void main(String[] args) {
        WriteLogUtil instance = WriteLogUtil.getInstance();
        Map<String, String> map = new HashMap<>();
        map.put("name", "zero");
        map.put("detail", "第一个客户支付了十块钱");

        instance.appLog(map);

    }
}

测试2

package com.zero.na;

import java.util.HashMap;
import java.util.Map;

public class Test2 {

    public static void main(String[] args) {
        WriteLogUtil instance = WriteLogUtil.getInstance();
        Map<String, String> map = new HashMap<>();
        map.put("name", "zero");
        map.put("detail", "第二个客户支付了二十块钱");

        instance.appLog(map);

    }
}

我们可以看到这个线程永远都不会停止,因为我们会有一个线程一直在while(true),一直在执行,永远都在等待。这个时候我们的用例写好了。这个时候我们的日志可以选择写在MongoDB数据库中。

这个我们下篇讲。。。。。。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java患者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Executors
  • BlockingQueue
  • 实例
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档