实训背景
假设你是一名运维工程师,需要为公司的监控系统开发一个简单的日志备份守护进程。该进程需满足以下需求:
- 后台运行:脱离终端,长期监控指定目录(如 /var/log/app/)中的日志文件。
- 自动备份:每隔 5 分钟将新增的日志文件压缩备份到 /backup/logs/ 目录。
- 日志记录:记录守护进程自身的操作日志到 /var/log/backup_daemon.log。
- 系统服务化:通过 systemd 管理进程的启动、停止和状态查看。
环境准备
操作系统:Ubuntu 22.04 或 CentOS 8(需 root 权限)
工具:
- 安装 GCC 编译器:sudo apt install gcc(Ubuntu)或 sudo dnf install gcc(CentOS)
- 文本编辑器(如 vim 或 nano)
目录创建:
sudo mkdir -p /var/log/app /backup/logs
实训步骤
任务1:编写守护进程代码(C语言)
目标:创建一个脱离终端的守护进程,监控目录并备份文件。
1.编写代码 backup_daemon.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> #include <dirent.h> #include <string.h> void daemonize() { pid_t pid = fork(); if (pid < 0) exit(EXIT_FAILURE); if (pid > 0) exit(EXIT_SUCCESS); // 父进程退出 setsid(); // 创建新会话 chdir("/"); // 切换工作目录 umask(0); // 重置文件权限掩码 // 关闭标准输入输出 close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } void log_message(const char *message) { int fd = open("/var/log/backup_daemon.log", O_WRONLY | O_CREAT | O_APPEND, 0644); if (fd != -1) { time_t now = time(NULL); char buf[256]; strftime(buf, sizeof(buf), "[%Y-%m-%d %H:%M:%S] ", localtime(&now)); write(fd, buf, strlen(buf)); write(fd, message, strlen(message)); write(fd, "\n", 1); close(fd); } } void backup_logs() { DIR *dir = opendir("/var/log/app"); if (!dir) { log_message("Failed to open log directory!"); return; } struct dirent *entry; while ((entry = readdir(dir)) != NULL) { if (entry->d_type == DT_REG) { // 普通文件 char src_path[256], dest_path[256]; snprintf(src_path, sizeof(src_path), "/var/log/app/%s", entry->d_name); snprintf(dest_path, sizeof(dest_path), "/backup/logs/%s.tar.gz", entry->d_name); // 模拟压缩备份(实际可调用 tar 命令) log_message("Backing up a log file..."); char cmd[512]; snprintf(cmd, sizeof(cmd), "tar -czf %s %s > /dev/null 2>&1", dest_path, src_path); system(cmd); } } closedir(dir); } int main() { daemonize(); log_message("Daemon started successfully."); while (1) { backup_logs(); sleep(300); // 每隔5分钟执行一次 } return 0; }
2.编译代码
gcc backup_daemon.c -o backup_daemon
任务2:配置为 systemd 服务
目标:将守护进程注册为系统服务,实现开机自启和状态管理。
创建服务文件
sudo vim /etc/systemd/system/backup_daemon.service
编写服务配置
[Unit] Description=Log Backup Daemon After=network.target [Service] Type=simple ExecStart=/usr/local/bin/backup_daemon Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target
部署并启动服务
sudo cp backup_daemon /usr/local/bin/ sudo systemctl daemon-reload sudo systemctl start backup_daemon sudo systemctl enable backup_daemon
验证服务状态
systemctl status backup_daemon
任务3:测试与日志查看
目标:验证守护进程的功能和日志记录是否正常。
生成测试日志文件
sudo touch /var/log/app/test.log
查看备份目录
ls /backup/logs # 5分钟后应出现 test.log.tar.gz
查看守护进程日志
tail -f /var/log/backup_daemon.log
任务4:调试与进程管理
目标:使用命令管理守护进程并调试问题。
查看进程信息
ps -ef | grep backup_daemon
停止服务
sudo systemctl stop backup_daemon
手动启动调试模式
/usr/local/bin/backup_daemon # 观察终端输出(需先停止服务)
实训总结
通过本案例,学员将掌握以下技能:
- 使用 C 语言编写守护进程的核心步骤(fork、setsid、关闭文件描述符等)。
- 通过 systemd 将进程注册为系统服务,实现标准化管理。
- 日志记录与调试方法,排查守护进程运行问题。
知识要点
守护进程特点:后台运行、脱离终端、生命周期长。
创建守护进程步骤:两次 fork、setsid、关闭文件描述符、重定向 I/O。
systemd 服务管理:服务文件编写、systemctl 命令使用。
日志管理:通过文件记录操作日志,使用 tail 或 journalctl 查看。
调试技巧:ps 查看进程状态、systemctl status 分析服务问题。
扩展思考:
- 如何优化备份逻辑(如仅备份新增文件)?
- 如何通过信号(如 SIGHUP)实现守护进程配置热加载?
以上就是C语言实现日志备份守护进程的示例详解的详细内容,更多关于C语言日志备份的资料请关注脚本之家其它相关文章!
来源链接:https://www.jb51.net/program/3398713hd.htm
© 版权声明
本站所有资源来自于网络,仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您(转载者)自己承担!
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
THE END
暂无评论内容