daemon 进程如何打日志到控制台?

本文探讨了如何在容器中处理daemon进程的日志输出问题,解释了daemon进程与控制终端、会话、进程组的关系,并提供了一个简单的C语言实现的daemonize例程,说明了如何通过重定向文件描述符使daemon进程的日志输出到控制台。
摘要由CSDN通过智能技术生成

问题起源

前几日,遇到一个问题,需要收集在容器里一个 daemon 进程的输出日志。一般来说,容器里的进程只需要打日志到标准输出就可以了,但 daemon 进程比较特殊,daemon 进程没有控制终端,也没有继承相应的文件描述符。
上述问题可以转化为一个通用的问题:如何让一个 daemon 进程输出日志到当前的控制台上?
另外,supervisor 及 docker 在启动的时候,是不允许启动后台进程的,这是为什么呢?
在解答之前,先来看一些相关的基础知识。

基础知识

  • 控制终端
    控制终端的本质是一个设备文件,由会话首进程打开,由终端驱动程序控制。控制终端接收用户从终端的输入,将输入内容传送给与该终端相关联的前台进程;或者发送相应的信号到相应的前台进程。
    1.一个控制终端对应着一个标准输入、标准输出及标准错误输出(fd 0, 1, 2)。
    2.一个控制终端对应一个会话。
    3.一个控制终端对应着一组前台进程组,多组后台进程组,这些进程组属于同一个会话。用户在终端输入 CTRL-C 时,控制终端会发送信号到前台进程组的所有进程。
    4.一个控制终端对应着一个会话首进程,该进程是建立会话的第一个进程,通常为 shell 进程,终端断开后收到相应的信号(挂起信号),进行相应的清理工作。
  • 会话
    一个会话包含多个进程组。
    一个会话包含一个会话首进程,只有会话首进程可以打开控制终端。
  • 进程组
    多个进程组成一个进程组。有一个进程组长,进程组长的 pid 即为该进程组的 group id。通常通过 fork 调用生成的进程都属于同一个进程组。一个进程只能为它自己或者子进程设置 group id。

    image
    会话、进程组、控制终端的关系

查看一个进程的 pid,gpid,spid,command

ps -p 32036 -o pid,ppid,pgid,sid,tpgid,comm
  PID  PPID  PGID   SID TPGID COMMAND
32036  1098 32036 32036    -1 sshd

上述命令打印 32036 号进程,父进程为 1098,进程组号为 32036,会话号为 32036。

ps -o pid,ppid,pgid,sid,tpgid,comm

打印前台进程组的进程信息。

ps axjf

查看进程树。

  • daemon 进程
    daemon 进程:我只想做一个安静的好进程。主要有以下特点:后台运行(无控制终端,且不能打开新的控制终端,不接收控制台信号),无标准输出、标准错误输出(不会打印到控制台,或者重定向到其它文件),无标准输入(不接收控制台输入)。
  • 一些系统调用

    1. umask() 设置文件模式创建屏蔽字。子进程一般会继承父进程的文件模式创建屏蔽字。

      
      #include <sys/types.h>
      
      
      #include <sys/stat.h>
      
      
      mode_t umask(mode_t mask);
    2. setsid() 创建一个新会话。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值