zoukankan      html  css  js  c++  java
  • syslog日志系统——日志采集

    摘自:https://blog.csdn.net/hunkcai/article/details/83859172

    日志采集的流程

    客户端埋点

    客户端埋点就是在客户系统植入日志发送的代码,可以是前端页面、app界面、后端服务等,把需要的日志信息发送到指定的日志采集接口。
    日志的发送应该采用异步方式,这样不会对客户系统代码的执行造成影响。

    日志采集


    日志采集接口把接收过来的日志数据写入到日志文件,日志文件以天为单位进行存储。

    日志采集接口代码


    接口采用@IgnoreToken标记不需要进行令牌校验。
    采用@CrossOrigin标记,让接口能够跨域访问,支持AJAX跨域请求。

    @ApiOperation(value = "提交日志")
    @ApiImplicitParams({
    @ApiImplicitParam(name = "logData", value = "日志数据", dataType = "LogData", paramType = "body")
    })
    @RequestMapping(path = "/log/add", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @IgnoreToken
    @CrossOrigin
    public ResponseData addLog(@RequestBody LogData logData) {
    
    String logID = logService.logToFile(logData);
    
    return ResponseData.success(logID);
    }

    日志文件格式的设计


    日志以文本格式保存,每条日志按行写入。
    日志行的格式如下:

    时间戳|日志ID|日志数据JSON

    日志按行保存的好处是,可以利用BufferedReader的readLine方法进行日志的按行读取。
    日志按行保存,要对日志数据JSON部分进行处理,把换行符替换掉。

    日志按行保存的主要代码

    public String logToFile(LogData logData){
    LogGroupData groupData = getLogGroup(logData.getKey());
    logData.setGroupID(groupData.getGroupID());
    
    String date = ConvertUtil.formatDate(new Date(), "yyyyMMdd");
    String path = PathUtil.combine(logFolder, "LOG" + date + ".log");
    
    String uuid = UUID.randomUUID().toString();
    String json = JSON.toJSONString(logData);
    
    StringBuilder sb = new StringBuilder();
    sb.append("[" + ConvertUtil.formatDate(new Date()) + "]|");
    sb.append(uuid + "|");
    for (int i = 0; i < json.length(); i++) {
    char c = json.charAt(i);
    if (c == '
    ' || c == '
    ')//换行符替换为空格
    sb.append(" ");
    else
    sb.append(c);
    }
    
    FileUtil.appendLine(path, sb.toString());
    
    return uuid;
    }

    日志写入文件的主要代码


    利用RandomAccessFile类写入,用文件琐控制并发。如果是海量日志的场合,可以部署多几个采集点。

    public static void appendLine(String path, String line) {
    
    RandomAccessFile fout = null;
    FileChannel channel = null;
    try {
    File file = new File(path);
    if (!file.getParentFile().exists()) {
    file.getParentFile().mkdirs();
    }
    byte[] bytes = line.getBytes("utf-8");
    fout = new RandomAccessFile(file, "rw");
    long filelength = fout.length();//获取文件的长度
    fout.seek(filelength);//将文件的读写指针定位到文件的末尾
    channel = fout.getChannel();//打开文件通道
    FileLock fileLock = null;
    while (true) {
    try {
    fileLock = channel.tryLock();//不断的请求锁,如果请求不到,等一秒再请求
    break;
    } catch (Exception e) {
    logger.error("[FileUtil.appendLine]请求琐失败。");
    Thread.sleep(1000);
    }
    }
    fout.write(bytes);
    fout.writeChar('
    ');
    fileLock.release();
    channel.close();
    fout.close();
    
    } catch (Exception e1) {
    logger.error(e1.getMessage(), e1);
    } finally {
    IOUtil.close(channel);
    IOUtil.close(fout);
    }
    }

    日志汇总


    通过定时任务,把各个采集点的日志文本导入数据库/大数据存储。

  • 相关阅读:
    VS2008 查找失效怎么办
    Winfrom弹出下拉编辑控件,DataGridView弹出查询对话框下拉录入,支持TextBox
    修改SQL Server 2005的默认端口
    C#操作XML小结
    金蝶KIS系列 KISBOS 二次开发学习资料 例子 习题 讲解
    Datawindow.net中实现让当前行选中,并且当前行以其他颜色显示
    sqlserver 截取字符串
    python3定时爬虫
    linux下安装pyenv及使用pyenv管理不同的python版本
    CentOS7下安装mysql最快捷方式及mysql远程访问连接实现
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/12425223.html
Copyright © 2011-2022 走看看