【jar包启动,每天生成一个日志文件】

📕我是廖志伟,一名Java开发工程师、《Java项目实战------深入理解大型互联网企业通用技术》(基础篇)(进阶篇)、(架构篇)、《解密程序员的思维密码------沟通、演讲、思考的实践》作者、清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。
📙不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

文章目录


启动项目

通常来说启动一个jar包命令会生成一个日志文件,如下:

Java包启动命令

复制代码
nohup java -jar mcp-server-article-1.0.0.jar > mcp-server-article-$(date +%Y%m%d).log 2>&1 &

但是这种日志文件会随时间的推移越来越大,所以如果没有在程序端有做配置,那么我们可以配置一些脚本,让它每天生成一个日志文件。

每天生成一个日志文件

复制代码
sudo nano /opt/app/logrotate_postrotate.sh

内容:

复制代码
#!/bin/bash
# 设置严格模式,遇到未定义变量或命令执行失败时立即退出脚本
set -eu  
# 开启调试模式,会在执行命令前打印出命令本身
set -x
# 定义日志文件路径,脚本执行过程的输出将被记录到该文件
LOG_FILE="/opt/app/logrotate.log"
{
    # 输出脚本开始执行的时间
    echo "$(date) Starting postrotate script"
    # 输出当前工作目录
    echo "$(date) Current working directory: $(pwd)"
    # 输出当前环境变量信息
    echo "$(date) Environment variables:"
    env
    # 提示即将尝试向 mcp-server-article 进程发送 HUP 信号
    echo "$(date) Attempting to send HUP signal to mcp-server-article process"

    # 使用 pgrep 命令查找 mcp-server-article-1.0.0.jar 进程的 PID
    # 若未找到进程,使用 || true 避免脚本因 pgrep 命令失败而退出
    pids=$(pgrep -f mcp-server-article-1.0.0.jar || true)  
    # 检查是否找到了匹配的进程 PID
    if [ -n "$pids" ]; then
        # 输出找到的进程 PID
        echo "$(date) Found PIDs: $pids"
        # 遍历所有找到的进程 PID
        for pid in $pids; do
            # 提示即将向当前 PID 对应的进程发送 HUP 信号
            echo "$(date) Sending HUP signal to PID $pid"
            # 尝试向当前 PID 对应的进程发送 HUP 信号
            if ! kill -HUP "$pid"; then
                # 若发送信号失败,输出失败信息
                echo "$(date) Failed to send HUP signal to PID $pid"
            else
                # 若发送信号成功,输出成功信息
                echo "$(date) Successfully sent HUP signal to PID $pid"
            fi
        done
    else
        # 若未找到匹配的进程,输出未找到进程的信息
        echo "$(date) No mcp-server-article-1.0.0.jar process found"
    fi

    # 输出脚本执行结束的时间
    echo "$(date) Ending postrotate script"
} 2>&1 >> "$LOG_FILE"
# 关闭调试模式,不再打印执行的命令
set +x
# 关闭严格模式,恢复脚本默认的错误处理行为
set +eu

按 Ctrl + X,再按 Y,最后按 Enter 保存并退出。

授权:

复制代码
sudo chmod +x /opt/app/logrotate_postrotate.sh

内容:

复制代码
# 以 root 用户身份执行后续操作,确保脚本有足够权限完成日志轮转和发送信号等操作
su root root
# 匹配 /opt/app 目录下所有以 mcp-server-article- 开头,以 .log 及其后续扩展结尾的日志文件
/opt/app/mcp-server-article-*.log* {
    # 每天执行一次日志轮转操作
    daily
    # 如果指定的日志文件不存在,不报错,继续执行后续的日志轮转流程
    missingok
    # 保留最近 7 个旧日志文件,超过该数量的旧日志文件会被删除
    rotate 7
    # 对轮转后的旧日志文件进行压缩,节省磁盘空间
    compress
    # 延迟压缩上一次轮转的日志文件,确保当前日志文件不被压缩,避免日志写入到已压缩的文件中
    delaycompress
    # 如果日志文件为空,不进行轮转操作,避免产生不必要的空压缩文件
    notifempty
    # 多个匹配的日志文件只执行一次 postrotate 脚本,减少脚本重复执行带来的开销
    sharedscripts
    # 轮转后创建新的日志文件,权限设置为 644(所有者有读写权限,组用户和其他用户有读权限),属主和属组均为 root
    create 644 root root
    # 日志轮转完成后执行的脚本,可用于执行一些额外的操作,如发送信号给应用程序
    postrotate
        /opt/app/logrotate_postrotate.sh
    endscript
}

使用 cat -A 命令查看配置文件,确保没有隐藏字符:

复制代码
cat -A /opt/app/mcp-server-article

若发现类似 ^M 这样的字符,说明存在 Windows 风格的换行符,需要转换为 Unix 风格。可以使用 dos2unix 工具进行转换:

复制代码
sudo apt-get install dos2unix
dos2unix /opt/app/mcp-server-article

把之前的文件删除,重新创建一个新的,然后 使用 file 命令检查文件编码,确保为 UTF-8 编码。

复制代码
file /opt/app/mcp-server-article

保存配置文件后,重新执行 logrotate 命令:

复制代码
sudo logrotate -fv /opt/app/mcp-server-article

查看 /opt/app/logrotate.log 文件,确认日志轮转和 postrotate 脚本执行情况:

复制代码
cat /opt/app/logrotate.log

如果出现以下内容说明配置成功

复制代码
root@VM-12-10-ubuntu:/opt/app# cat logrotate.log 
Fri Aug 22 09:05:28 PM CST 2025 Starting postrotate script
Fri Aug 22 09:05:28 PM CST 2025 Current working directory: /opt/app
Fri Aug 22 09:05:28 PM CST 2025 Environment variables:
SHELL=/bin/bash
SUDO_GID=0
SUDO_COMMAND=/usr/sbin/logrotate -fv /opt/app/mcp-server-article
SUDO_USER=root
PWD=/opt/app
LOGNAME=root
HOME=/root
LANG=en_US.UTF-8
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.avif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:*~=00;90:*#=00;90:*.bak=00;90:*.crdownload=00;90:*.dpkg-dist=00;90:*.dpkg-new=00;90:*.dpkg-old=00;90:*.dpkg-tmp=00;90:*.old=00;90:*.orig=00;90:*.part=00;90:*.rej=00;90:*.rpmnew=00;90:*.rpmorig=00;90:*.rpmsave=00;90:*.swp=00;90:*.tmp=00;90:*.ucf-dist=00;90:*.ucf-new=00;90:*.ucf-old=00;90:
TERM=xterm-color
USER=root
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
SUDO_UID=0
MAIL=/var/mail/root
_=/usr/bin/env
Fri Aug 22 09:05:28 PM CST 2025 Attempting to send HUP signal to mcp-server-article process
Fri Aug 22 09:05:28 PM CST 2025 Found PIDs: 2366611
Fri Aug 22 09:05:28 PM CST 2025 Sending HUP signal to PID 2366611
Fri Aug 22 09:05:28 PM CST 2025 Successfully sent HUP signal to PID 2366611
Fri Aug 22 09:05:28 PM CST 2025 Ending postrotate script

📥博主的人生感悟和目标

希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

📙经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续出版。

《Java项目实战---深入理解大型互联网企业通用技术》基础篇的购书链接:https://item.jd.com/14152451.html

《Java项目实战---深入理解大型互联网企业通用技术》基础篇繁体字的购书链接:http://product.dangdang.com/11821397208.html

《Java项目实战---深入理解大型互联网企业通用技术》进阶篇的购书链接:https://item.jd.com/14616418.html

《Java项目实战---深入理解大型互联网企业通用技术》架构篇待上架

《解密程序员的思维密码--沟通、演讲、思考的实践》购书链接:https://item.jd.com/15096040.html

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

相关推荐
David爱编程37 分钟前
Java 守护线程 vs 用户线程:一文彻底讲透区别与应用
java·后端
即将进化成人机1 小时前
Maven架构的依赖管理和项目构建
java·架构·maven
qianmoq1 小时前
第03章:无限流:generate()和iterate()的神奇用法
java
whitepure1 小时前
万字详解JVM
java·jvm·后端
我崽不熬夜1 小时前
Java的条件语句与循环语句:如何高效编写你的程序逻辑?
java·后端·java ee
我崽不熬夜2 小时前
Java中的String、StringBuilder、StringBuffer:究竟该选哪个?
java·后端·java ee
草明2 小时前
docker stats 增加一列容器名称的显示
java·开发语言·docker
期待のcode2 小时前
Maven的概念与Maven项目的创建
java·maven
我崽不熬夜3 小时前
Java中的基本数据类型和包装类:你了解它们的区别吗?
java·后端·java ee