个人开发环境搭建

环境总览

系统

  • Windows10
    • Jdk, Maven
    • Idea
    • Apifox, Navicat, AnotherRedisDesktop
  • Ubuntu20.04
    • Jdk, Node, Go, Python
    • Mysql, Redis, ElasticSearch, Kibana, Logstash
    • Samba

服务器环境搭建

  • Samba
    • 指令安装
      • 使用指令安装:        sudo apt-get install samba
      • 添加samba用户:    sudo smbpasswd -a user
      • 备份配置文件:        sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
      • 修改配置文件:        sudo vim /etc/samba/smb.conf
      • 添加以下内容
        • [share]
          comment = samba home directory
          path = /home/file/share
          public = yes
          browseable = yes
          writeable = yes
          create mask = 0777
          directory mask = 0777
          avaliable = yes
      • 完成以上配置后,将配置中的共享目录权限设置为777,直接允许所有用户查看、修改、执行
    • 重启samba使配置生效sudo service smbd restart
    • 防火墙放开端口445
    • Windows电脑使用新建的samba用户密码访问共享文件夹
  • ElasticSearch
    • 下载压缩包
      • 下载地址: https://www.elastic.co/cn/elasticsearch/
      • 选择版本并下载对应的包,较新的es可能会需要较高的jdk版本,我本来用了es852,但没有那么高的jdk环境,虽然es自带jdk但我选择了回退es版本,选择了762。es与jdk的支持关系在这里可以找到https://www.elastic.co/cn/support/matrix#matrix_jvm
    • 改配置
      • jvm.option,因为我是实体台式机装的ubuntu,就没管这个配置文件,若硬件资源有限,可以改一下这个文件里的jvm启动参数 -Xms1g -Xmx1g
      • elasticsearch.yml,只弄了一台,没有搞es集群的情况下的配置如下:设置集群名称 cluster.name: xxx,设置节点名称 node.name: node-1,设置外部访问端口号以便客户端进行访问http.port: 9200,设置第一次符合主节点条件的节点cluster.initial_master_nodes: ["node-1"],es数据存储位置path.data: /home/dylan/apps/cache/es/data,es日志存放位置path.logs: /home/dylan/apps/cache/es/logs,允许外部机器访问network.host: 0.0.0.0,当前节点的ipnetwork.publish_host: 192.168.2.111
    • 编写启动脚本
      • 直接后台启动 ~/apps/elasticsearch762/bin/elasticsearch -d
  • Kibana
    • 下载压缩包
      • 下载地址  https://www.elastic.co/downloads/kibana
      • es选的762,kibana也选了762
    • 改配置
      •   外部机器可访问server.host: "0.0.0.0"
      •   我就一个es节点elasticsearch.hosts: ["http://192.168.2.111:9200"]
    • 编写启动脚本
      • 后台启动kibana并将日志写入固定文件nohup ~/apps/kibana762/bin/kibana >>~/apps/kibana762/logs/server.log 2>&1 &
  • Logstash
    • 下载压缩包,注意zip

      • 下载地址  https://www.elastic.co/downloads/logstash
      • 也是下载了跟es对应的版本,但是否有必要跟es的版本一致我没有深究
    • 编写启动脚本,加载配置文件

      • 启动并加载配置文件: ~/apps/logstash762/bin/logstash -f ./apps/logstash762/creaters/mylog-log2es.conf
    • 编写配置文件进行日志监听,我这种方式只能按行读取json对象,grok那些我还没研究,目前的详情如下:

      mylog-log2es.conf
      input{
      	file {
      		path => "/home/logs/java/**/output*.log"
      		start_position => "beginning"
      		#设置编码
      		codec => json {charset => "UTF-8"}
      	}
      }
      filter {
      	json {
      		source => "message"
      	}
      }
      output {
      	# 将ds-blog的日志输出到es的ds-blog索引中
      	if "ds-blog"  in [app]{
      		elasticsearch {
      			hosts => ["http://192.168.2.111:9200"]
      			index => "ds-blog-%{+YYYY.MM.dd}"
      			template_overwrite => "false"
      		}
      	}
      	# 将ds-chat的日志输出到es的ds-chat索引中
      	if "ds-chat"  in [app]{
      		elasticsearch {
      			hosts => ["http://192.168.2.111:9200"]
      			index => "ds-chat-%{+YYYY.MM.dd}"
      			template_overwrite => "false"
      		}
      	}
      	# 将cm-batch的日志输出到es的cm-batch索引中
      	if "cm-batch"  in [app]{
      		elasticsearch {
      			hosts => ["http://192.168.2.111:9200"]
      			index => "cm-batch-%{+YYYY.MM.dd}"
      			template_overwrite => "false"
      		}
      	}
      	# 将cm-files的日志输出到es的cm-files索引中
      	if "cm-files"  in [app]{
      		elasticsearch {
      			hosts => ["http://192.168.2.111:9200"]
      			index => "cm-files-%{+YYYY.MM.dd}"
      			template_overwrite => "false"
      		}
      	}
      	# 将cm-licence的日志输出到es的cm-licence索引中
      	if "cm-licence"  in [app]{
      		elasticsearch {
      			hosts => ["http://192.168.2.111:9200"]
      			index => "cm-licence-%{+YYYY.MM.dd}"
      			template_overwrite => "false"
      		}
      	}
              # 将plt-gateway的日志输出到es的plt-gateway索引中
              if "plt-gateway"  in [app]{
                      elasticsearch {
                              hosts => ["http://192.168.2.111:9200"]
                              index => "plt-gateway-%{+YYYY.MM.dd}"
                              template_overwrite => "false"
                      }
              }
      }
      

服务日志配置(SpringBoot)

  • 服务日志以json格式输出至指定文件,logback-spring.xml中添加appender,并组装json格式的日志文本

    logback-spring.xml
    <!--  将文本中的 " 修改为 \" 打印json格式的时候会用到 在需要输出文本的地方使用这里定义的 %strmsg 而不是 %message -->
    <conversionRule conversionWord="strmsg" converterClass="com.mylog.tools.utils.logconverter.LogJsonConverter" />
    <appender name="jsonFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--See http://logback.qos.ch/manual/appenders.html#RollingFileAppender -->
        <!--and http://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy -->
        <!--for further documentation -->
        <encoder>
            <pattern>
                {"timestamp": "%date{"yyyy-MM-dd HH:mm:ss:SSS"}","app": "${applicationName}","level": "%level","pid": "${PID:-}","thread": "%thread","class": "%logger","method": "%method","line": "%line","strmsg": "%strmsg","statck_trace":"%xEx"}\n
            </pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logDir}/output_%d{yyyy-MM-dd'.log'}</fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
            <totalSizeCap>15GB</totalSizeCap>
        </rollingPolicy>
    </appender>
    
  • 自定义logback的logConverter,将日志文本中的双引号前添加转义符避免影响logstash解析json并输入到es

    LogJsonConverter
    import ch.qos.logback.classic.pattern.MessageConverter;
    import ch.qos.logback.classic.spi.ILoggingEvent;
    import org.slf4j.helpers.MessageFormatter;
    
    import java.util.Objects;
    import java.util.stream.Stream;
    
    /**
     * @author Dylan
     * @Description LogJsonConverter
     * @Date : 2022/12/17 - 22:53
     */
    public class LogJsonConverter extends MessageConverter {
    
        /*
        * **真坑啊,logback 生成json格式的文件 存储在服务器的固定地址 然后由logstash对日志文件进行读取并发送到ES
        *   json格式 一条日志记录的内容是作为一个字段存在json对象中的一个属性 ( "strmsg" : "%strmsg" )
        *       然而spring cloud alibaba 的nacos 在启动时会输出一些日志 这些日志中竟然包含了双引号,这就导致logstash在读取日志并解析json的时候出现异常
        *       并最终导致ES上的日志记录没有正常解析,以一堆字符串的形式出现
        *   解决方案:
        *       在将日志以json格式输出到文件中时,strmsg字段的取值从这里进行获取,由convert方法对一条日志进行加工,
        *     最终目的是使打印到日志文件中的strmsg字段不会影响到整个json的正常解析
        *       PS: 以我的了解,slf4j的日志包括两部分 原文和变量 (log.info("原文{}",变量)),这里的convert触发的时机是两部分合成最终字符串之前
        *       主要进行两个动作:
        *           1. 对日志的原文进行双引号转义 即: 将 " 修改为 \" 以避免影响整个json的解析
        *           2. 对日志的各个变量进行双引号转义 即: 将 " 修改为 \" 以避免影响整个json的解析
        * */
        @Override
        public String convert(ILoggingEvent event) {
            try {
                if (event.getLoggerName().contains("org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter")) {
                    String loggerName = event.getLoggerName();
                }
                // 将日志 的参数toString的结果 中的双引号改为 \"
                Object[] argumentArray = null;
                if (Objects.nonNull(event.getArgumentArray()) && event.getArgumentArray().length > 0) {
                    argumentArray = Stream.of(event.getArgumentArray()).map(m -> {
                        // 所有的对象最终都要toString再写入日志 这里提前将其toString 放入参数列表中
                        String temp = m.toString();
                        String strArgument;
                        strArgument = temp.replaceAll("\"", "\\\\\"").replaceAll("\n", " ").replaceAll("\r", " ");
                        return strArgument;
                    }).toArray();
                }
                // 将日志 的原文 中的双引号改为 \"
                String message = event.getMessage();
                String replacedVar = message;
                if (message.contains("\"")){
                    replacedVar = message.replaceAll("\"", "\\\\\"");
                }
                if (message.contains("\r") || message.contains("\n")){
                    replacedVar = replacedVar.replaceAll("\n", " ").replaceAll("\r", " ");
                }
                String res = MessageFormatter.arrayFormat(replacedVar, Objects.isNull(argumentArray) ? event.getArgumentArray() : argumentArray).getMessage();
                return res;
            }catch (Exception e){
                return e.getMessage();
            }
        }
    }
    
  • 编写jar包启动脚本

    startCommand.sh
    #! /bin/bash
    nohup java -jar xx1-1.2.0-SNAPSHOT.jar --spring.profiles.active=test --spring.cloud.nacos.discovery.ip=192.168.2.111 > ./logs/xx1.log &
    nohup java -jar xx2-1.2.0-SNAPSHOT.jar --spring.profiles.active=test --spring.cloud.nacos.discovery.ip=192.168.2.111 > ./logs/xx2.log &
    nohup java -jar xx3-1.2.0-SNAPSHOT.jar --spring.profiles.active=test --spring.cloud.nacos.discovery.ip=192.168.2.111 > ./logs/xx3.log &
    nohup java -jar xx4-1.2.0-SNAPSHOT.jar --spring.profiles.active=test --spring.cloud.nacos.discovery.ip=192.168.2.111 > ./logs/xx4.log &
    nohup java -jar xx5-1.2.0-SNAPSHOT.jar --spring.profiles.active=test --spring.cloud.nacos.discovery.ip=192.168.2.111 > ./logs/xx5.log &
    nohup java -jar xx6-1.2.0-SNAPSHOT.jar --spring.profiles.active=test --spring.cloud.nacos.discovery.ip=192.168.2.111 > ./logs/xx6.log &
    
posted @ 2022-12-24 17:30  惊邪  阅读(28)  评论(0编辑  收藏  举报