SpringBoot整合Graylog做日志收集实现过程

目录
  • 日志收集折腾过程
    • ELK
    • EFK
    • ELFK
    • 自己撸一个
  • Graylog
    • 环境搭建
    • 创建输入
    • Spring Boot整合Graylog
  • 总结

日志收集折腾过程

ELK

之前整合过ELK做日志采集,就是Elasticsearch + Logstash + Kibana:

  • Elasticsearch:存储引擎,存放日志内容,利于全文检索
  • Logstash:数据传输管道,将日志内容传输到Elasticsearch,并且支持过滤内容,将内容格式化后再传输,可以满足绝大部分的应用场景
  • Kibana:开源的分析和可视化平台,在这里查看Elasticsearch中的数据

对我来说ELK有点重,服务占用资源高,并且部署和维护有些复杂,我的个人服务器玩这个有点力不从心,所以一直有在寻找替代方案。

EFK

Elasticsearch + Filebeat + Kibana,用Filebeat替代Logstash做日志的收集,它是由Golang开发,够轻量,占用资源少,如果没有过滤日志内容进行格式化的需求,用这个替代Logstash是很不错的选择。

ELFK

四个框架全用,网上看到有大佬这样用,应该是企业级别的部署,看着我就敬而远之,不敢玩。

自己撸一个

我对EFK的服务占用感到不满,于是自己用Golang写了一个轻量级工具,没有做采集、过滤,仅仅是从日志文件夹中grep出想要的内容,其实和手动grep没区别,不过可以用接口的方式查出想要的内容,而且极其轻量,这个工具我还用过好一段时间。

我把EFK的搭建过程和手撸工具的过程写在了这里,感兴趣可以去看看。

Spring Boot日志收集以及链路追踪

Graylog

最近我在折腾另一个日志收集方案,并且感觉不错,就是Graylog,它需要整合Mongo + Elasticsearch,它比较简单易用,提供网页端可视化页面,相当于Kibana,还支持日志报警。

值得说明的是,它支持处理多行日志,而在ELK中,多行日志需要用Logstash做一些格式化配置,这一点来说Graylog就做的很棒。

至于为什么需要整合Mongo,是因为需要借助Mongo来保存一些Graylog的配置信息。

环境搭建

我喜欢用Docker来搭建环境,所以如果你通过其他方式,可以到官网寻求答案

首先拉取一下镜像:

docker pull elasticsearch:7.12.0
docker pull graylog/graylog:4.3.6
docker pull mongo:4.2

docker-compose.yml:

version: '3'
services:
  mongo:
    image: mongo:4.2
    container_name: mongo # graylog内默认连接名为mongo,所以这个不建议改
    restart: always
    volumes:
      - /home/mycontainers/mongo/data:/data/db # 路径映射
    ports:
      - 27017:27017
    network_mode: mynetwork # 设置网段
  elasticsearch:
    image: elasticsearch:7.12.0
    container_name: elasticsearch # graylog内默认连接名为elasticsearch,所以不建议改
    environment:
      - "TAKE_FILE_OWNERSHIP=true" # 挂载目录需要这个,不然没有权限
      - "discovery.type=single-node"    # 设置为单节点,集群就等进阶再说了
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"    # 分配堆大小
    volumes:
      - /home/mycontainers/es/data:/usr/share/elasticsearch/data
      - /home/mycontainers/es/logs:/usr/share/elasticsearch/logs
    ulimits: # 调整 ulimits 以及 nprocedit
      memlock:
        soft: -1
        hard: -1
    deploy:
      resources:
        limits:
          memory: 1g # 限制使用内存
    ports:
      - 9200:9200
      - 9300:9300
    network_mode: mynetwork
  graylog:
    image: graylog/graylog:4.3.6
    container_name: graylog
    environment:
      # echo -n "Enter Password: " && head -1 < /dev/stdin | tr -d '\n' | sha256sum | cut -d " " -f1
      - GRAYLOG_PASSWORD_SECRET=somepasswordpepper  # 用于密码加密加盐
      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 # 密码,默认是admin,可以用上面的echo命令生成自己的密码
      - GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9009/    # 对外开放的链接,注意端口,我改成了9009
    # volumes:
      # - /home/mycontainers/graylog/config/graylog.conf:/usr/share/graylog/data/config/graylog.conf
    network_mode: mynetwork
    restart: always
    depends_on:
      - mongo # 依赖于mongo和es两个环境
      - elasticsearch
    ports:
      - 9009:9000 # 端口映射
      # Syslog TCP
      - 1514:1514
      # Syslog UDP
      - 1514:1514/udp
      # GELF TCP
      - 12201:12201
      # GELF UDP
      - 12201:12201/udp

执行运行命令:

docker-compose -f docker-compose.yml up

但有时候,我们在之前就已经部署好了Mongo和ES环境,所以不会在一个docker-compose文件中配置三个环境,我们把内容拆开如下:

es.yml:

version: '3'
services:
  elasticsearch:
    image: elasticsearch:7.12.0
    container_name: elasticsearch # graylog内默认连接名为elasticsearch,所以不建议改
    environment:
      - "TAKE_FILE_OWNERSHIP=true"
      - "discovery.type=single-node"
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - /etc/localtime:/etc/localtime
      - /home/mycontainers/es/data:/usr/share/elasticsearch/data
      - /home/mycontainers/es/logs:/usr/share/elasticsearch/logs
    ulimits: # 调整 ulimits 以及 nprocedit
      memlock:
        soft: -1
        hard: -1
    deploy:
      resources:
        limits:
          memory: 1g # 限制使用内存
    ports:
      - 9200:9200
      - 9300:9300
    network_mode: mynetwork

mongo.yml:

version: '3'
services:
  mongo:
    image: mongo:4.2
    container_name: mongo # graylog内默认连接名为mongo,所以这个不建议改
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime
      - /home/mycontainers/mongo/data:/data/db
    ports:
      - 27017:27017
    network_mode: mynetwork

graylog.yml:

version: '3'
services:
  graylog:
    image: graylog/graylog:4.3.6
    container_name: graylog
    environment:
      # echo -n "Enter Password: " && head -1 < /dev/stdin | tr -d '\n' | sha256sum | cut -d " " -f1
      - GRAYLOG_PASSWORD_SECRET=somepasswordpepper
      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      - GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9009/
      - GARYLOG_ELASTICSEARCH_HOSTS=http://elasticsearch:9200 # 链接es,这里是容器间通讯,所以写容器名
      - GRAYLOG_MONGODB_URI=mongodb://mongo:27017/graylog # 同上
    volumes:
      - /home/mycontainers/graylog/config/graylog.conf:/usr/share/graylog/data/config/graylog.conf # 指定配置文件,用于修改时区
    network_mode: mynetwork
    restart: always
    ports:
      - 9009:9000
      # Syslog TCP
      - 1514:1514
      # Syslog UDP
      - 1514:1514/udp
      # GELF TCP
      - 12201:12201
      # GELF UDP
      - 12201:12201/udp

不同点在于手动配置mongo和es,还有多了一个配置文件映射,因为graylog默认UTC时区,我们的日志文件会相差8小时,所以在第一次启动成功graylog后,我们把它的配置文件拷贝出来,修改里面的root_timezone参数,再映射回去即可。

创建输入

现在我们可以访问Graylog了:http://xxx:9009

来创建一个输入:

>

勾选Global,Title随便写一个,其他不用改,保存即可,就能得到:

回到Search标签页,等日志文件输入即可。

Spring Boot整合Graylog

Maven依赖:

<!--graylog日志依赖-->
<dependency>
    <groupId>de.siegmar</groupId>
    <artifactId>logback-gelf</artifactId>
    <version>3.0.0</version>
</dependency>

然后是logback的配置,这个根据需要使用就好,在resource中:

logback-spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--解决在项目目录中生成LOG_PATH_IS_UNDEFINED文件-->
    <property name="LOG_PATH" value="${LOG_PATH:-${java.io.tmpdir:-/logs}}"/>
    <!-- 引入SpringBoot的默认配置文件defaults.xml -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <!-- 引入SpringBoot中内置的控制台输出配置文件console-appender.xml -->
    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
    <!-- 引入自定义的文件输出配置文件logback-spring-file-level.xml -->
    <include resource="logback-spring-file-level.xml"/>
    <!-- 设置root logger的级别为INFO,并将控制台输出和文件输出中的appender都添加到root logger下 -->
    <root level="INFO">
        <!--没有这行,控制台将不会有输出,完全由日志进行输出-->
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="WARN_FILE"/>
        <appender-ref ref="ERROR_FILE"/>
        <appender-ref ref="GELF"/>
    </root>
    <!-- jmx可以动态管理logback配置-->
    <jmxConfigurator/>
</configuration>

logback-spring-file-level.xml:

<?xml version="1.0" encoding="UTF-8"?>
<included>
    <!-- 从配置文件中读取-->
    <springProperty scope="context" name="APP_NAME" source="graylog.appName"/>
    <springProperty scope="context" name="GRAYLOG_HOST" source="graylog.host"/>
    <springProperty scope="context" name="GRAYLOG_PORT" source="graylog.port"/>
    <!--INFO Level的日志-->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- %i用来标记分割日志的序号 -->
            <fileNamePattern>${LOG_PATH}.INFO.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 单个日志文件最大maxFileSizeMB, 保存maxHistory天的历史日志, 所有日志文件最大totalSizeCapMB -->
            <!-- 经过试验,maxHistory是指指定天数内,而不是多少天-->
            <maxFileSize>50MB</maxFileSize>
            <maxHistory>15</maxHistory>
            <totalSizeCap>50MB</totalSizeCap>
        </rollingPolicy>
        <!-- 配置日志的级别过滤器,只保留INFO Level的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 格式化输出-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{"yyyy-MM-dd HH:mm:ss.SSS"} %-5level -[%X{traceId}] - %msg%n</pattern>
        </encoder>
    </appender>
    <!--WARN Level的日志-->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- %i用来标记分割日志的序号 -->
            <fileNamePattern>${LOG_PATH}.WARN.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 单个日志文件最大maxFileSizeMB, 保存maxHistory天的历史日志, 所有日志文件最大totalSizeCapMB -->
            <maxFileSize>50MB</maxFileSize>
            <maxHistory>15</maxHistory>
            <totalSizeCap>50MB</totalSizeCap>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤级别-->
            <level>WARN</level>
            <!--onMatch:符合过滤级别的日志。ACCEPT:立即处理-->
            <onMatch>ACCEPT</onMatch>
            <!--onMismatch:不符合过滤级别的日志。DENY:立即抛弃-->
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{"yyyy-MM-dd HH:mm:ss.SSS"} %-5level -[%X{traceId}] - %msg%n</pattern>
        </encoder>
    </appender>
    <!--ERROR Level的日志-->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- %i用来标记分割日志的序号 -->
            <fileNamePattern>${LOG_PATH}.ERROR.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 单个日志文件最大maxFileSizeMB, 保存maxHistory天的历史日志, 所有日志文件最大totalSizeCapMB -->
            <maxFileSize>50MB</maxFileSize>
            <maxHistory>15</maxHistory>
            <totalSizeCap>50MB</totalSizeCap>
            <!--<cleanHistoryOnStart>true</cleanHistoryOnStart>-->
        </rollingPolicy>
        <!--对指定级别的日志进行过滤-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤级别-->
            <level>ERROR</level>
            <!--onMatch:符合过滤级别的日志。ACCEPT:立即处理-->
            <onMatch>ACCEPT</onMatch>
            <!--onMismatch:不符合过滤级别的日志。DENY:立即抛弃-->
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--日志输出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{"yyyy-MM-dd HH:mm:ss.SSS"} %-5level - [%X{traceId}] - %msg%n</pattern>
        </encoder>
    </appender>
    <!--自定义日志-->
    <appender name="CUSTOM_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- %i用来标记分割日志的序号 -->
            <fileNamePattern>${LOG_PATH}.MYLOGGER.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 单个日志文件最大maxFileSizeMB, 保存maxHistory天的历史日志, 所有日志文件最大totalSizeCapMB -->
            <!-- 经过试验,maxHistory是指指定天数内,而不是多少天-->
            <maxFileSize>300MB</maxFileSize>
            <maxHistory>15</maxHistory>
            <totalSizeCap>300MB</totalSizeCap>
        </rollingPolicy>
        <!-- 配置日志的级别过滤器,只保留INFO Level的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 格式化输出-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{"yyyy-MM-dd HH:mm:ss.SSS"}\t%X{traceId}\t%msg%n</pattern>
        </encoder>
    </appender>
    <!--自定义日志日志不用绑定在root下,只记录指定输出-->
    <logger name="my_logger" additivity="false">
        <appender-ref ref= "CUSTOM_FILE"/>
    </logger>
    <appender name="GELF" class="de.siegmar.logbackgelf.GelfUdpAppender">
        <!--graylog服务地址-->
        <graylogHost>${GRAYLOG_HOST}</graylogHost>
        <!--连接端口-->
        <graylogPort>${GRAYLOG_PORT}</graylogPort>
        <encoder class="de.siegmar.logbackgelf.GelfEncoder">
            <originHost>${APP_NAME:-demo}</originHost>
            <!--发送日志级别名称,默认以数字代表日志级别-->
            <includeLevelName>true</includeLevelName>
        </encoder>
    </appender>
</included>

我们在logback中引用了配置文件的系统变量,所以在application.yml中要添加这一段,当然硬写进xml也可以:

application.yml

logging:
  file:
    path: _mylogs/${server.port}.logs # 日志保存路径
graylog:
  host: mylocalhost # graylog服务host
  port: 12201   # graylog服务端口
  appName: graylogDemo  # 应用名,可填

启动Spring应用,打印几条日志:

@RestController
public class TestController {
    private static final Logger log = LoggerFactory.getLogger(TestController.class);
    @GetMapping("/i")
    public void info() {
        log.info("info...................");
    }
    @GetMapping("/w")
    public void warn() {
        log.warn("warn...................");
    }
    @GetMapping("/e")
    public void error() {
//        log.error("error...................");
        int i = 1/0;
//        LogUtil.error("自定义异常");
    }
}

稍等片刻,顺利的话我们就能在Graylog中查看到刚刚输出的日志了,至此大功告成。

总结

本篇文章只是说明了Graylog的一个入门使用,进阶的玩法可能要后面才有时间整理了。

不管用什么方案做日志收集,我认为只要简单易用,稳定靠谱就好,ELK作为当前主流的日志收集框架,除了部署麻烦些,耗费资源高些之外并没有明显短板,所以ELK也好,Graylog也罢,只要适合自己就可以。

以上就是SpringBoot整合Graylog做日志收集实现过程的详细内容,更多关于SpringBoot Graylog日志收集的资料请关注我们其它相关文章!

(0)

相关推荐

  • ElasticSearch整合SpringBoot搭建配置

    目录 前言 项目搭建 配置客户端 索引API初探 & Index API ping 创建索引 & create 索引是否存在 & exist 删除索引 结束语 前言 目前正在出一个Es专题系列教程, 篇幅会较多, 请持续关注我们 本节来给大家讲一下在Springboot中如何整合es~ 本文偏实战一些,为了方便演示,本节示例沿用上节索引,好了, 废话不多说直接开整吧~ 项目搭建 老规矩,先建maven项目,下面是我的pom.xml <?xml version="1.

  • SpringBoot整合Spring Security过滤器链加载执行流程源码分析(最新推荐)

    目录 1.引言 2.Spring Security过滤器链加载 2.1.注册名为 springSecurityFilterChain的过滤器 3.查看 DelegatingFilterProxy类 4.查看 FilterChainProxy类 4.1 查看 doFilterInternal方法 4.2 查看 getFilters方法 5 查看 SecurityFilterChain接口 6. 查看 SpringBootWebSecurityConfiguration类 总结: 1.引言 在 Sp

  • SpringBoot整合Apache Pulsar教程示例

    目录 正文 准备工作 创建 SpringBoot 项目 添加 Maven 依赖 编写消息生产者 编写消息消费者 测试 总结 正文 推荐一个基于SpringBoot开发的全平台数据(数据库管理工具)功能比较完善,建议下载使用: github.com/EdurtIO/datacap 目前已经支持30多种数据源 Apache Pulsar 是一个开源的分布式 Pub-Sub 消息传递平台.它提供高可用性.持久性和性能,适用于处理大量的实时数据.SpringBoot 是一个非常流行的 Java Web

  • SpringBoot整合Mybatis与MybatisPlus方法详细讲解

    目录 一.整合MyBatis操作 1.配置模式 2.注解模式 3.混合模式 二.整合 MyBatis-Plus 完成CRUD 1.什么是MyBatis-Plus 2.整合MyBatis-Plus 3.CRUD功能 一.整合MyBatis操作 官网:MyBatis · GitHub SpringBoot官方的Starter:spring-boot-starter-* 第三方的starter的格式: *-spring-boot-starter <dependency> <groupId>

  • SpringBoot应用整合ELK实现日志收集的示例代码

    ELK即Elasticsearch.Logstash.Kibana,组合起来可以搭建线上日志系统,本文主要讲解使用ELK来收集SpringBoot应用产生的日志. ELK中各个服务的作用 Elasticsearch:用于存储收集到的日志信息: Logstash:用于收集日志,SpringBoot应用整合了Logstash以后会把日志发送给Logstash,Logstash再把日志转发给Elasticsearch: Kibana:通过Web端的可视化界面来查看日志. 使用Docker Compos

  • Springboot整合ActiveMQ实现消息队列的过程浅析

    目录 pom中导入坐标 书写yml配置 业务层代码 监听器代码 业务层代码 确保你启动了自己电脑的activemq. pom中导入坐标 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> 书写yml配置 spring:  activemq:

  • SpringBoot继承LogStash实现日志收集的方法示例

    一.环境准备 安装Elasticsearch.kibana.logstash,教程链接 安装教程 二.配置SpringBoot 依赖 在springBoot 项目下pom文件增加logStash 依赖包 <!--logStash--> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId>

  • SpringBoot整合redis及mongodb的详细过程

    目录 一.先看Redis的使用: 1. 在pom.xml中添加Redis相关依赖项 2. 在application.properties中添加Redis的相关配置 3. 新建 service/RedisService 接口及其实现类 service/impl/RedisServiceImpl 4. 新建 controller/RedisController 5. 通过Postman进行结果验证 二.MongoDB的使用 1. 首先还是先添加MongoDB相关依赖项 2. 然后是添加MongoDB

  • SpringBoot整合GitLab-CI实现持续集成的过程

    目录 写在前面 一.概述 1.1.什么是CI/CD 1.2.持续集成(CI) 1.3.持续交付(CD) 二.CI/CD流水线 2.1.Pipeline 2.2.Stages 2.3.Jobs 2.4.Runners 三.安装GitLab Runner 3.1.环境准备 3.2.创建Dockerfile 3.3.创建docker-compose 3.4.注册Runner 3.4.项目配置 3.4.1.依赖管理模块 3.4.2.通用模块 3.4.3.服务模块 写在前面 在企业开发过程中,我们开发的功

  • SpringBoot整合Mysql和Redis的详细过程

    目录 一.项目创建 1.1创建项目 1.2目录结构 1.3pom.xml配置文件 二.初始化数据库 三.初始化代码 3.1实体类entity 3.2Mapper接口类 3.3Redis工具类 3.4Service层 3.5Controller层 四.单元测试 4.1Respository和Service层单元测试 4.2Controller层接口测试 一.项目创建 1.1 创建项目 在IDEA中,File--New--Project--Spring Initializer 名称为springbo

  • Springboot 整合 RocketMQ 收发消息的配置过程

    Springboot 整合 RocketMQ 收发消息 创建springboot项目 pom.xml添加rocketmq-spring-boot-starter依赖. <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>2.1.0</version>

  • SpringBoot整合Swagger3生成接口文档过程解析

    前后端分离的项目,接口文档的存在十分重要.与手动编写接口文档不同,swagger是一个自动生成接口文档的工具,在需求不断变更的环境下,手动编写文档的效率实在太低.与新版的swagger3相比swagger2配置更少,使用更加方便. 一.pom文件中引入Swagger3依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId

  • 使用SpringBoot AOP 记录操作日志、异常日志的过程

    平时我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能:我们在操作某些功能时也有可能会发生异常,但是每次发生异常要定位原因我们都要到服务器去查询日志才能找到,而且也不能对发生的异常进行统计,从而改进我们的项目,要是能做个功能专门来记录操作日志和异常日志那就好了, 当然我们肯定有方法来做这件事情,而且也不会很难,我们可以在需要的方法中增加记录日志的代码,和在每个方法中增加记录异常的代码,最终把记录的日志存到数据库中.听起来好像很容易,但是我们做起来会发现,做这项工作很繁

  • Fluentd搭建日志收集服务

    目录 引言 1. 搭建环境准备工作 1.1 安装ruby 1.2 获取fluentd源码 1.3 修改gem源 1.4 安装Bundle 1.5 构建fluentd 1.6 运行fluentd 2. 安装过程遇到的问题 2.1 安装bundler没有zlib包 2.2 没有openssl 3. 完成需求及修改配置 需求1 日志存放路径应用+日期划分 需求2 存放日志文件按文件大小进行切分 需求3 按照日志等级划分日志 需求4 将目录通过nginx映射出去 需求5 生成一个定大小的日志文件,并能够

随机推荐