作者 crossoverJie

:sparkles: Introducing new features.异步写入聊天记录

@@ -19,6 +19,9 @@ public class AppConfiguration { @@ -19,6 +19,9 @@ public class AppConfiguration {
19 @Value("${cim.user.userName}") 19 @Value("${cim.user.userName}")
20 private String userName; 20 private String userName;
21 21
  22 + @Value("${cim.msg.logger.path}")
  23 + private String msgLoggerPath ;
  24 +
22 public Long getUserId() { 25 public Long getUserId() {
23 return userId; 26 return userId;
24 } 27 }
@@ -34,4 +37,12 @@ public class AppConfiguration { @@ -34,4 +37,12 @@ public class AppConfiguration {
34 public void setUserName(String userName) { 37 public void setUserName(String userName) {
35 this.userName = userName; 38 this.userName = userName;
36 } 39 }
  40 +
  41 + public String getMsgLoggerPath() {
  42 + return msgLoggerPath;
  43 + }
  44 +
  45 + public void setMsgLoggerPath(String msgLoggerPath) {
  46 + this.msgLoggerPath = msgLoggerPath;
  47 + }
37 } 48 }
1 package com.crossoverjie.cim.client.service.impl; 1 package com.crossoverjie.cim.client.service.impl;
2 2
  3 +import com.crossoverjie.cim.client.config.AppConfiguration;
3 import com.crossoverjie.cim.client.service.MsgLogger; 4 import com.crossoverjie.cim.client.service.MsgLogger;
4 import org.slf4j.Logger; 5 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory; 6 import org.slf4j.LoggerFactory;
  7 +import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.stereotype.Service; 8 import org.springframework.stereotype.Service;
7 9
  10 +import java.io.IOException;
  11 +import java.nio.charset.Charset;
  12 +import java.nio.file.*;
  13 +import java.time.LocalDate;
  14 +import java.util.Arrays;
  15 +import java.util.List;
8 import java.util.concurrent.ArrayBlockingQueue; 16 import java.util.concurrent.ArrayBlockingQueue;
9 import java.util.concurrent.BlockingQueue; 17 import java.util.concurrent.BlockingQueue;
10 18
@@ -26,15 +34,18 @@ public class AsyncMsgLogger implements MsgLogger { @@ -26,15 +34,18 @@ public class AsyncMsgLogger implements MsgLogger {
26 private static final int DEFAULT_QUEUE_SIZE = 16; 34 private static final int DEFAULT_QUEUE_SIZE = 16;
27 private BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(DEFAULT_QUEUE_SIZE); 35 private BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(DEFAULT_QUEUE_SIZE);
28 36
29 - private volatile boolean started = false ;  
30 - private Worker worker = new Worker() ; 37 + private volatile boolean started = false;
  38 + private Worker worker = new Worker();
31 39
  40 + @Autowired
  41 + private AppConfiguration appConfiguration;
32 42
33 @Override 43 @Override
34 public void log(String msg) { 44 public void log(String msg) {
35 //开始消费 45 //开始消费
36 startMsgLogger(); 46 startMsgLogger();
37 try { 47 try {
  48 + // TODO: 2019/1/6 消息堆满是否阻塞线程?
38 blockingQueue.put(msg); 49 blockingQueue.put(msg);
39 } catch (InterruptedException e) { 50 } catch (InterruptedException e) {
40 LOGGER.error("InterruptedException", e); 51 LOGGER.error("InterruptedException", e);
@@ -49,7 +60,7 @@ public class AsyncMsgLogger implements MsgLogger { @@ -49,7 +60,7 @@ public class AsyncMsgLogger implements MsgLogger {
49 while (started) { 60 while (started) {
50 try { 61 try {
51 String msg = blockingQueue.take(); 62 String msg = blockingQueue.take();
52 - LOGGER.info("写入聊天记录={}", msg); 63 + writeLog(msg);
53 } catch (InterruptedException e) { 64 } catch (InterruptedException e) {
54 break; 65 break;
55 } 66 }
@@ -58,24 +69,53 @@ public class AsyncMsgLogger implements MsgLogger { @@ -58,24 +69,53 @@ public class AsyncMsgLogger implements MsgLogger {
58 69
59 } 70 }
60 71
  72 +
  73 + private void writeLog(String msg) {
  74 +
  75 + msg = appConfiguration.getUserName() + ":" + "【" + msg + "】";
  76 +
  77 + LocalDate today = LocalDate.now();
  78 + int year = today.getYear();
  79 + int month = today.getMonthValue();
  80 + int day = today.getDayOfMonth();
  81 +
  82 + String dir = appConfiguration.getMsgLoggerPath() + appConfiguration.getUserName() + "/";
  83 + String fileName = dir + year + month + day + ".log";
  84 +
  85 + Path file = Paths.get(fileName);
  86 + boolean exists = Files.exists(Paths.get(dir), LinkOption.NOFOLLOW_LINKS);
  87 + try {
  88 + if (!exists) {
  89 + Files.createDirectories(Paths.get(dir));
  90 + }
  91 +
  92 + List<String> lines = Arrays.asList(msg);
  93 +
  94 + Files.write(file, lines, Charset.forName("UTF-8"), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
  95 + } catch (IOException e) {
  96 + LOGGER.info("IOException", e);
  97 + }
  98 +
  99 + }
  100 +
61 /** 101 /**
62 * 开始工作 102 * 开始工作
63 */ 103 */
64 - private void startMsgLogger(){  
65 - if (started){  
66 - return ; 104 + private void startMsgLogger() {
  105 + if (started) {
  106 + return;
67 } 107 }
68 108
69 worker.setDaemon(true); 109 worker.setDaemon(true);
70 worker.setName("AsyncMsgLogger-Worker"); 110 worker.setName("AsyncMsgLogger-Worker");
71 - started = true ; 111 + started = true;
72 worker.start(); 112 worker.start();
73 } 113 }
74 114
75 115
76 @Override 116 @Override
77 public void stop() { 117 public void stop() {
78 - started = false ; 118 + started = false;
79 worker.interrupt(); 119 worker.interrupt();
80 } 120 }
81 } 121 }
@@ -8,6 +8,9 @@ swagger.enable = true @@ -8,6 +8,9 @@ swagger.enable = true
8 8
9 logging.level.root=info 9 logging.level.root=info
10 10
  11 +#消息记录存放路径
  12 +cim.msg.logger.path = /opt/logs/cim/
  13 +
11 14
12 ###=======生产模拟======### 15 ###=======生产模拟======###
13 # 群发消息 16 # 群发消息
  1 +package com.crossoverjie.cim.client.service.impl;
  2 +
  3 +import com.crossoverjie.cim.client.CIMClientApplication;
  4 +import com.crossoverjie.cim.client.service.MsgLogger;
  5 +import org.junit.Test;
  6 +import org.junit.runner.RunWith;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.boot.test.context.SpringBootTest;
  9 +import org.springframework.test.context.junit4.SpringRunner;
  10 +
  11 +import java.util.concurrent.TimeUnit;
  12 +
  13 +@SpringBootTest(classes = CIMClientApplication.class)
  14 +@RunWith(SpringRunner.class)
  15 +public class AsyncMsgLoggerTest {
  16 +
  17 +
  18 +
  19 + @Autowired
  20 + private MsgLogger msgLogger ;
  21 +
  22 + @Test
  23 + public void writeLog() throws Exception {
  24 + for (int i = 0; i < 10; i++) {
  25 + msgLogger.log("zhangsan:【asdsd】" + i);
  26 + }
  27 +
  28 + TimeUnit.SECONDS.sleep(2);
  29 + }
  30 +
  31 +}
@@ -8,7 +8,12 @@ import org.junit.Test; @@ -8,7 +8,12 @@ import org.junit.Test;
8 import org.slf4j.Logger; 8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory; 9 import org.slf4j.LoggerFactory;
10 10
  11 +import java.io.IOException;
  12 +import java.nio.charset.Charset;
  13 +import java.nio.file.*;
  14 +import java.time.LocalDate;
11 import java.util.ArrayList; 15 import java.util.ArrayList;
  16 +import java.util.Arrays;
12 import java.util.List; 17 import java.util.List;
13 18
14 /** 19 /**
@@ -148,4 +153,31 @@ public class CommonTest { @@ -148,4 +153,31 @@ public class CommonTest {
148 153
149 System.out.println(sb.toString().replace(key,"**" + key+"**")); 154 System.out.println(sb.toString().replace(key,"**" + key+"**"));
150 } 155 }
  156 +
  157 + @Test
  158 + public void log(){
  159 + String msg = "hahahdsadsd" ;
  160 + LocalDate today = LocalDate.now();
  161 + int year = today.getYear();
  162 + int month = today.getMonthValue();
  163 + int day = today.getDayOfMonth();
  164 +
  165 + String dir = "/opt/logs/cim/zhangsan" + "/";
  166 + String fileName = dir + year + month + day + ".log";
  167 + LOGGER.info("fileName={}", fileName);
  168 +
  169 + Path file = Paths.get(fileName);
  170 + boolean exists = Files.exists(Paths.get(dir), LinkOption.NOFOLLOW_LINKS);
  171 + try {
  172 + if (!exists) {
  173 + Files.createDirectories(Paths.get(dir));
  174 + }
  175 +
  176 + List<String> lines = Arrays.asList(msg);
  177 +
  178 + Files.write(file, lines, Charset.forName("UTF-8"), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
  179 + } catch (IOException e) {
  180 + LOGGER.info("IOException", e);
  181 + }
  182 + }
151 } 183 }