致力为服务插曲 篇七 springboot项目的自定义日志输出及docker部署下的日志输出

需求背景

将已有的,maven管理的多模块微服务springboot项目,用docker进行项目部署

项目打包部署

参考:使用Docker部署Spring boot项目_funtaster的博客-CSDN博客_docker springboot

springboot项目(docker打包插件,docker配置文件)

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!-- Docker maven plugin -->
            <plugin>
                <!--插件依赖-->
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <!--配置-->
                <configuration>
                    <!--项目镜像命名-->
                    <imageName>${docker.image.prefix}.${project.artifactId}</imageName>
                    <!--Dockerfile文件所在目录-->
                    <dockerDirectory>src/main/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
            <!-- Docker maven plugin -->

        </plugins>
    </build>

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD love-master-0.0.1-SNAPSHOT.jar love-master.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/love-master.jar"]

安装docker

官方安装文档

#所需包
    yum install -y yum-utils  device-mapper-persistent-data  lvm2
#设置稳定存储库
    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#安装最新版本的Docker Engine - 社区和容器
    yum install docker-ce docker-ce-cli containerd.io
#要安装特定版本的Docker Engine - Community,请列出repo中的可用版本,然后选择并安装
    yum list docker-ce --showduplicates | sort -r
#返回的列表取决于启用的存储库,并且特定于您的CentOS版本
    yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
    (yum install docker-ce-19.03.1 docker-ce-cli-19.03.1 containerd.io)
#启动Docker
    systemctl start docker
##允许远程
 vi /usr/lib/systemd/system/docker.service

 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375

使用maven命令生成docker镜像(整个工程都是maven管理的)

    #找到项目所在目录
    cd /home/program/parentProject/
    #根目录下进行 install
    mvn clean install package -Dmaven.test.skip=true
    #进入web模块下
    cd moduleProject/
    #执行maven命令生成jar包和镜像
    mvn package docker:build -Dmaven.test.skip=true
    #查看镜像是否存在
    docker images
    #运行镜像(参考日志下的运行)
    docker run -p 8080:8080 --name containerName -d imageName

Doker日志

参考:理解docker部署springboot-容器日志处理(四)_txxs的博客-CSDN博客_docker springboot 日志

1.实时查看输出层日志

#docker logs -f -t --since="2017-05-31" --tail=10 edu_web_1
 docker logs -f -t --tail 行数 容器名
    --since : 此参数指定了输出日志开始日期,即只输出指定日期之后的日志。
    -f : 查看实时日志
    -t : 查看日志产生的日期
    -tail=10 : 查看最后的10条日志。
    edu_web_1 : 容器名称

2.数据卷的方式

docker run -v /home/docker_logs/:/home/logs/love/all -v /home/docker_logs/:/home/logs/love/info -v /home/docker_logs/:/home/logs/love/err/ -p 8888:8888  --name love-master -d springboot.love-master

-v docker日志输出目录:宿主机输出日志 (有多个日志文件,则按上述格式多加几个就好了)
-d 后台运行 springboot.love-master 镜像名称
-p 容器端口:宿主机端口 (端口映射,当使用nginx代理时[负载均衡],要配置成制定的容器端口)
-name 容器名称

这里我写了多个,是因为我在springboot日志框架logback下写了对应配置,将日志进行了级别分类

查看日志,发现已经有了,但是日志时间不对,差了8个小时,猜测时区不对

在docker容器和系统时间不一致(日志打印时间不对)

参考:Docker中部署springboot时间不对的问题

1.检查系统时间和容器时间

#系统
date
#容器
#进入容器
docker exec -it containerId sh
date

2.在启动容器时,把系统时间挂载到容器内,添加如下参数

-v /etc/localtime:/etc/localtime

3.这时系统和容器时间一致了,日志时间还是不对

JVM是通过/etc/timezone文件获取时区的,需要在容器中映射或者写入时区文件

在Dockfile中新增命令

RUN echo "Asia/Shanghai" > /etc/timezone

其他

logback-boot.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
	scan 自动重新加载  配置文件发生变化后进行重新配置
	scanPeriod 属性控制扫描周期,其值可以带时间单位,包括:milliseconds、seconds、minutes 和 hours.没写明时间单位,则默认为毫秒
	                           默认情况下,每隔一分钟扫描一次
-->
<configuration scan="true" scanPeriod="30 minutes">
    <!--
		引用资源文件,引用变量,用法同spring资源文件的加载
		<property resource="resource1.properties" />
		直接指定变量
		<property name="LOG_HOME" value="" />
    -->
    <property resource="logback.properties" />

    <!-- 设置上下文名称后,可以方便地区分来自不同应用程序的记录 -->
    <contextName>${logback.appName}</contextName>

    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%15.15t] %-40.40logger{39} : %m%n}"/>
    <!-- <encoder>元素class 属性是必要的,表示将被实例化的 encoder 类的全限定名.
    因为太常用了,所以当 encoder 是 PatternLayoutEncoder 时,可以省略 class 属性 -->
    <!--
        %date{yyyy-MM-dd HH:mm:ss} 时间
        [%thread] 线程名称
        %-5level 级别
        %logger 类名
        %msg%n信息
    -->
    <!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,%i索引【从数字0开始递增】,,, -->
    <!-- name 属性指定 appender 的名称,class 属性指定 appender 类的全限定名 -->
    <!-- appender是configuration的子节点,是负责写日志的组件。 -->
    <!-- ConsoleAppender:把日志输出到控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <encoder>
            <!--<pattern>%d %p (%file:%line\)- %m%n</pattern>-->
            <!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName %-5level -&#45;&#45; [%thread] %logger{36} [%file:%line]:%msg%n</pattern>-->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
    <!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是sys.log -->
    <!--             2.如果日期没有发生变化,但是当前日志的文件大小超过2MB时,对当前日志进行分割 重命名-->
    <appender name="love_all" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logback.home}/${logback.all}/${logback.allFileName}.log</file>
        <!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
        <!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
            <!-- 文件名:log/sys.2017-12-05.0.log -->
            <fileNamePattern>${logback.home}/${logback.all}/${logback.allFileName}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为2MB,只是为了演示 -->
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <!-- pattern节点,用来设置日志的输入格式 -->
            <!--<pattern>%d %p (%file:%line\)- %m%n</pattern>-->
            <!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName %-5level -&#45;&#45; [%thread] %logger{36} [%file:%line]:%msg%n</pattern>-->
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <appender name="love_debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logback.home}/${logback.debug}/${logback.debugFileName}.log</file>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logback.home}/${logback.debug}/${logback.debugFileName}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 100MB -->
                <maxFileSize>2MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName %-5level -&#45;&#45; [%thread] %logger{36} [%file:%line]:%msg%n</pattern>-->
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <appender name="love_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logback.home}/${logback.info}/${logback.infoFileName}.log</file>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logback.home}/${logback.info}/${logback.infoFileName}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 100MB -->
                <maxFileSize>2MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName %-5level -&#45;&#45; [%thread] %logger{36} [%file:%line]:%msg%n</pattern>-->
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <appender name="love_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logback.home}/${logback.err}/${logback.errFileName}.log</file>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logback.home}/${logback.err}/${logback.errFileName}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 100MB -->
                <maxFileSize>2MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName %-5level -&#45;&#45; [%thread] %logger{36} [%file:%line]:%msg%n</pattern>-->
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
    <!-- 也就是只要是发生在这个根包下面的所有日志操作行为的权限都是xxxx -->
    <!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE  -->
    <logger name="org.springframework.web" level="INFO" />
    <logger name="org.springframework.web.servlet.mvc.method.annotation" level="INFO" />
    <logger name="org.mybatis.spring" level="DEBUG" />
    <logger name="org.mybatis" level="DEBUG" />
    <!--<logger name="cn.penghf" level="INFO"/>-->

    <root level="DEBUG">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="love_info"/>
        <appender-ref ref="love_all"/>
        <appender-ref ref="love_error"/>
        <appender-ref ref="love_debug"/>
    </root>


</configuration>

logback.properties

logback.appName=love
#logback.home=/home/logs/love
logback.home=D:/dev/logs
logback.debug=debug
logback.info=info
logback.err=err
logback.all=all

#包含所有的日志信息
logback.allFileName=love_all
#debug等级的日志文件
logback.debugFileName=love_debug
#info等级的日志文件
logback.infoFileName=love_info
#error等级的日志文件
logback.errFileName=love_err

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

day day day ...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值