作者 钟来

添加日志功能

... ... @@ -172,6 +172,19 @@
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
<build>
... ...
package com.zhonglai.luhui.mqtt.comm.service;
import com.alibaba.fastjson.JSON;
import com.ruoyi.system.domain.IotDevice;
import com.zhonglai.luhui.mqtt.comm.dto.DeviceSensorData;
import com.zhonglai.luhui.mqtt.comm.dto.LogDeviceOperation;
import com.zhonglai.luhui.mqtt.comm.dto.ServerDto;
import com.zhonglai.luhui.mqtt.comm.dto.business.BusinessDto;
import com.zhonglai.luhui.mqtt.comm.dto.business.BusinessDtoClassNew;
... ... @@ -10,8 +9,12 @@ import com.zhonglai.luhui.mqtt.comm.factory.BusinessAgreement;
import com.zhonglai.luhui.mqtt.comm.factory.BusinessAgreementFactory;
import com.zhonglai.luhui.mqtt.comm.factory.Topic;
import com.zhonglai.luhui.mqtt.comm.util.ByteUtil;
import com.zhonglai.luhui.mqtt.comm.util.DateUtils;
import com.zhonglai.luhui.mqtt.service.db.DeviceService;
import lombok.SneakyThrows;
import org.apache.log4j.FileAppender;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttException;
... ... @@ -21,7 +24,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Date;
@Component
public class MqttCallback implements MqttCallbackExtended {
... ... @@ -59,12 +62,29 @@ public class MqttCallback implements MqttCallbackExtended {
public void messageArrived(String s, MqttMessage mqttMessage) {
//接收到消息
log.info("接收到消息topc:{}, mqttMessage {},payload 十六进制 {}",s,mqttMessage, ByteUtil.hexStringToSpace(ByteUtil.toHexString(mqttMessage.getPayload())));
StringBuffer buffer = new StringBuffer();
buffer.append("topic:");
buffer.append(s);
buffer.append("\r\n");
buffer.append("mqttMessage字符串:");
buffer.append(mqttMessage.toString());
buffer.append("\r\n");
buffer.append("mqttMessage十六进制:");
buffer.append(ByteUtil.hexStringToSpace(ByteUtil.toHexString(mqttMessage.getPayload())));
buffer.append("\r\n");
buffer.append("\r\n");
Topic topic = new Topic(s);
if(null == topic)
{
log.error("消息{},topic为空,不做解析");
getLoggerByName("error").error("消息《"+s+"》解析为空 》》》内容:\r\n"+buffer.toString());
return;
}
//日志记录
getLoggerByName(topic.getClientid()).info(buffer.toString());
//准备数据
byte[] data = mqttMessage.getPayload();
IotDevice iotDevice = deviceService.getDeviceById(topic.getClientid());
... ... @@ -110,4 +130,37 @@ public class MqttCallback implements MqttCallbackExtended {
}
}
public static org.apache.log4j.Logger getLoggerByName(String name) {
// 生成新的Logger
// 如果已經有了一個Logger實例返回現有的
org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(name);
// 清空Appender。特別是不想使用現存實例時一定要初期化
logger.removeAllAppenders();
// 設定Logger級別。
// logger.setLevel(Level.DEBUG);
// 設定是否繼承父Logger。
// 默認為true。繼承root輸出。
// 設定false後將不輸出root。
logger.setAdditivity(true);
// 生成新的Appender
FileAppender appender = new RollingFileAppender();
PatternLayout layout = new PatternLayout();
// log的输出形式
String conversionPattern = "%d{HH:mm:ss} [%p] -%m%n";
layout.setConversionPattern(conversionPattern);
appender.setLayout(layout);
// log输出路径
// 这里使用了环境变量[catalina.home],只有在tomcat环境下才可以取到
// String tomcatPath = java.lang.System.getProperty("catalina.home");
appender.setFile( "logs/" + name+"_"+ DateUtils.parseDateToStr("yyyyMMdd",new Date()) + ".log");
// log的文字码
appender.setEncoding("UTF-8");
// true:在已存在log文件后面追加 false:新log覆盖以前的log
appender.setAppend(true);
// 适用当前配置
appender.activateOptions();
// 将新的Appender加到Logger中
logger.addAppender(appender);
return logger;
}
}
... ...
package com.zhonglai.luhui.mqtt.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.system.domain.IotDevice;
import com.ruoyi.system.domain.IotTerminal;
import com.ruoyi.system.domain.IotThingsModel;
import com.zhonglai.luhui.mqtt.comm.dao.BaseDao;
import com.zhonglai.luhui.mqtt.comm.dto.thingsmodels.ThingsModelBase;
import com.zhonglai.luhui.mqtt.comm.dto.thingsmodels.ThingsModelDataTypeEnum;
import com.zhonglai.luhui.mqtt.comm.factory.Topic;
import com.zhonglai.luhui.mqtt.comm.service.ClienNoticeService;
import com.zhonglai.luhui.mqtt.comm.util.DateUtils;
import com.zhonglai.luhui.mqtt.dto.Message;
import com.zhonglai.luhui.mqtt.dto.MessageCode;
import com.zhonglai.luhui.mqtt.service.db.DeviceService;
... ... @@ -19,12 +10,10 @@ import com.zhonglai.luhui.mqtt.service.db.mode.TerminalDataThingsModeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@Api(tags = "设备操作")
... ... @@ -102,5 +91,4 @@ public class DeviceController {
public Message updateIotTerminal(@RequestBody IotTerminal iotTerminal) {
return deviceService.updateIotTerminal(iotTerminal);
}
}
... ...
package com.zhonglai.luhui.mqtt.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.util.IOUtils;
import com.zhonglai.luhui.mqtt.comm.util.DateUtils;
import com.zhonglai.luhui.mqtt.dto.Message;
import com.zhonglai.luhui.mqtt.dto.MessageCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@Api(tags = "设备操作")
@Controller
@RequestMapping("/log")
public class LogController {
@ApiOperation("获取一天的日志")
@ApiImplicitParams({
@ApiImplicitParam(value = "时间(格式:20230114)",name = "time"),
@ApiImplicitParam(value = "设备imei",name = "imei"),
})
@RequestMapping(value = "getOneDateLog/{imei}/{time}",method = RequestMethod.GET)
public void getOneDateLog(HttpServletResponse response, @PathVariable String imei, @PathVariable String time) throws IOException {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type","text/html;charset=utf-8");
PrintWriter printWriter = response.getWriter();
String dateString = DateUtils.parseDateToStr("yyyyMMdd",new Date());
String fileName= imei+"_"+time+".log";
if(dateString.equals(time))
{
File logsFile = new File("logs/"+fileName);
if (!logsFile.exists())
{
printWriter.println(JSON.toJSONString(new Message(MessageCode.DEFAULT_FAIL_CODE,"文件"+logsFile.getPath()+"不存在")));
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(logsFile));
String line;
while((line = reader.readLine()) != null){
printWriter.println(line);
printWriter.println("<br/>");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
IOUtils.close(printWriter);
IOUtils.close(reader);
}
}
File logsFile = new File("zip/"+time+".zip");
BufferedReader reader = null;
try {
ZipFile zipFile = new ZipFile(logsFile);
reader = new BufferedReader(new InputStreamReader(zipFile.getInputStream(new ZipEntry(fileName))));
String line;
while((line = reader.readLine()) != null)
{
printWriter.println(line);
printWriter.println("<br/>");
}
} catch (IOException e) {
printWriter.println(JSON.toJSONString(new Message(MessageCode.DEFAULT_FAIL_CODE,e.getMessage())));
}finally {
IOUtils.close(printWriter);
IOUtils.close(reader);
}
}
}
... ...
package com.zhonglai.luhui.mqtt.service;
import com.zhonglai.luhui.mqtt.comm.util.DateUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import java.io.*;
import java.util.Calendar;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class LogTask {
public static void main(String[] args) {
LogTask logTask = new LogTask();
logTask.pack();
}
//每天凌晨1点钟,打包日志
@Scheduled(cron = "0 0 1 * * ?")
private void pack() {
File logsFile = new File("logs/");
if(logsFile.exists() )
{
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE,-1);
String dateString = DateUtils.parseDateToStr("yyyyMMdd",cal.getTime());
String logfilename = "_"+ dateString +".log";
String[] files = logsFile.list((dir, name) -> {
if(name.indexOf(logfilename)>=0)
{
return true;
}
return false;
});
if(null != files && files.length != 0 )
{
String savePath = "zip/"+dateString+".zip";
File saveFile = new File(savePath);
if(!saveFile.getParentFile().exists())
{
saveFile.getParentFile().mkdirs();
}
batchZip(saveFile,logsFile.getPath(),files);
for(String fp:files)
{
new File(logsFile.getPath()+"/"+fp).delete();
}
}
}
}
//每天凌晨2点钟,删除30天之前的压缩包
@Scheduled(cron = "0 0 2 * * ?")
private void del()
{
File logsFile = new File("zip/");
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE,-30);
String dateString = DateUtils.parseDateToStr("yyyyMMdd",cal.getTime());
String[] files = logsFile.list((dir, name) -> {
if(name.compareTo(dateString)<=0)
{
return true;
}
return false;
});
if(null != files && files.length != 0 )
{
for(String fp:files)
{
new File(logsFile.getPath()+"/"+fp).delete();
}
}
}
/**
* 批量压缩
* @param saveFile 压缩文件保存地址
* @param files 被压缩文件地址列表
*/
private void batchZip(File saveFile,String path,String[] files)
{
ZipOutputStream zip = null;
try {
zip = new ZipOutputStream(new FileOutputStream(saveFile));
for(String filepath:files)
{
zip(zip,path+"/"+filepath);
}
zip.finish();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null != zip)
{
try {
zip.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 压缩
* @param zip 压缩文件流
* @param filepath 被压缩文件地址
* @throws IOException
*/
private void zip( ZipOutputStream zip,String filepath) throws IOException {
String[] fss = filepath.split("\\/");
zip.putNextEntry(new ZipEntry(fss[fss.length-1]));
//用字节方式读取源文件
InputStream is = null;
BufferedInputStream bis = null;
try {
is = new FileInputStream(filepath);
//创建一个缓存区
bis = new BufferedInputStream(is);
//字节数组,每次读取1024个字节
byte[] b = new byte[1024];
//循环读取,边读边写
while (bis.read(b) != -1) {
//写入压缩文件
zip.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭流
if(null != bis)
{
bis.close();
}
if(null != is)
{
is.close();
}
}
}
}
... ...
... ... @@ -101,7 +101,7 @@ public class DeviceService {
for (String sk:saveJson.keySet())
{
ThingsModelItemBase thingsModelItemBase = (ThingsModelItemBase) saveJson.get(sk);
if(null != thingsModelItemBase.getIs_save_log() && 1==thingsModelItemBase.getIs_save_log() && null != logDeviceOperationList)
if(null != thingsModelItemBase.getMode_type() && (2==thingsModelItemBase.getMode_type() || 3==thingsModelItemBase.getMode_type()) && null != logDeviceOperationList)
{
if(null!=thingsModelItemBase.getSaveView() && null != oldjs && oldjs.containsKey(sk) && !thingsModelItemBase.getSaveView().equals(oldjs.getJSONObject(sk).getString("saveView")))
{
... ...
... ... @@ -339,6 +339,23 @@
<version>2.1.1</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.24</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.24</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
... ...