C语言实现日志备份守护进程的示例详解

实训背景

假设你是一名运维工程师,需要为公司的监控系统开发一个简单的日志备份守护进程。该进程需满足以下需求:

  • 后台运行:脱离终端,长期监控指定目录(如 /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

© 版权声明
THE END
支持一下吧
点赞12 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容