Unix/Linux中的守护进程(Daemon)类似于Windows中的后台服务进程,一直在后台长时间运行的进程。它通常在系统启动后就运行,没有控制终端,也无法和前台的用户交互,在系统关闭时才结束。Daemon程序一般都作为服务程序使用,等待客户端程序与它通信。我们也把运行的Daemon程序称作守护进程。比如的网络服务程序,可以在完成创建套接口,绑定套接口,设置套接口为监听模式后,变成守护进程进入后台执行而不占用控制终端,这是网络服务程序的常用模式。UNIX下的网络服务程序,如WebServer(Nginx、Apache等),FTP(vsftp),SSH(openssh)等一般都是由守护进程(Daemon)来实现的。守护进程不占用终端,在后台运行。UNIX的守护进程一般都命名为 *d 的形式,如httpd,vsftpd,sshd等。守护进程一旦脱离了终端,退出就成了问题,这时需要使用 ps 命令查出进程ID然后再使用kill命令停止。
Linux系统专门提供了一个用来创建daemon进程的库函数,该函数的原型是:
#inlude
int daemon(int nochdir, int noclose);
其中参数 nochdir 指定是否要切换当前工作路径到"/“根目录,而参数noclose 指定是否要关闭标准输入、标准输出和标准出错(即重定向到/dev/null)。在创建守护进程的时候,往往需要将进程的工作目录修改为”/"根目录,并将标准输入、标准输出和标准出错关闭。所以这两个参数我们一般都是传0。
日志系统syslogsyslog是一种工业标准的协议,可用来记录设备的日志。在UNIX系统,路由器、交换机等网络设备中,系统日志(System Log)记录系统中任何时间发生的大小事件。管理者可以通过查看系统记录,随时掌握系统状况。UNIX的系统日志是通过syslogd这个进程记录系统有关事件记录,也可以记录应用程序运作事件。通过适当的配置,我们还可以实现运行syslog协议的机器间通信,通过分析这些网络行为日志,藉以追踪掌握与设备和网络有关的状况。
下面我们介绍一下Linux系统自带的日志系统 syslog 函数:
一、openlog函数
#include
void openlog(const char *ident,int option, int facility)
函数说明:打开日志设备,以供读取和写入.
参数说明:
1、ident:是一个标记,ident 所表示的字符串将固定的加在每行日志的前面一标识这个日志,通常就写成当前程序的名称以
作标记。
2、option:指定openlog函数和接下来调用的syslog函数的控制标志。
opion | 说明 |
---|---|
LOG_CONS | 如果将信息发送给 syslogd 守护进程时发生错误,直接将相关信息输出到终端 |
LOG_NDELAY | 立即打开与系统日志的连接(通常情况下,只有在产生第一条日志信息的情况下才会打开与日志系统的连接) |
LOG_ODELAY | 类似于 LOG_NDELAY 参数,与系统日志的连接只有在 syslog 函数调用时才会创建 |
LOG_PERROR | 在将信息写入日志的同时,将信息发送到标准错误输出 |
LOG_PID | 每条日志信息中都包含进程号 |
3、facility:指定记录消息程序的类型,与 syslogd 守护进程的配置文件 syslog.conf 中的 facility 对应。
facility | 说明 |
---|---|
LOG_AUTH | 认证系统(login、su、getty等) |
LOG_AUTHPRIV | 同 LOG_AUTH 但只登陆到所选择的单个用户可读的文件中。 |
LOG_CRON | cron 守护进程 |
LOG_DAEMON | 其他系统守护进程,如 routed |
LOG_FTP | 文件传输协议:ftpd、tftpd |
LOG_KERN | 内核产生的消息 |
LOG_LPR | 系统打印机缓冲池:lpr、lpd |
LOG_MAIL | 电子邮件系统 |
LOG_NEWS | 网络新闻系统 |
LOG_SYSLOG | 由 syslogd(8)产生的内部消息 |
LOG_USER | 随机用户进程产生的消息 |
LOG_UUCP | UUCP子系统 |
LOG_LOCAL0~LOG_LOCAL7 | 本地使用保留 |
二、syslog函数
void syslog(int priority, const char *format,...);
函数说明:写入日志,与文件系统调用 printf使用方法类似,但在前面指定日志级别。
参数说明:
priority:表示消息的级别,与 syslogd 守护进程的配置文件 syslog.conf 中的 level 对应。
LOG_EMERG | 紧急情况 |
---|---|
LOG_ALERT | 应该被立即改正的问题,如系统数据库破坏 |
LOG_CRIT | 重要情况,如硬盘错误 |
LOG_ERR | 错误 |
LOG_WARNING | 警告信息 |
LOG_NOTICE | 不是错误情况,但是可能需要处理 |
LOG_INFO | 情报错误 |
LOG_DEBUG | 包含情报的信息,通常指在调试一个程序时使用 |
三、closelog函数
void closelog(void);
函数说明:关闭日志设备,与文件系统调用的close类似;调用closelog也是可选择的,它只是关闭被用于与syslog守护进程通信的描述
符。
1#include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8
9 int main(int argc, char **argv)
10 {
11 char *progname = basename(argv[0]);
12
13 if( daemon(0, 0) < 0)//守护进程daemon放在后台运行
14 {
15 printf("Program daemon() failure: %s\n", strerror(errno));
16 return -1;
17 }
18 openlog("daemon", LOG_CONS | LOG_PID, 0);//打开日志系统,以供读取和写入.
19 syslog(LOG_NOTICE, "Program '%s'start running\n", progname);
20 syslog(LOG_EMERG, "Program '%s' running with a emergency message\n", progname );
21 while(1)
22 {
23 //Do Something here
24 ;
25 }
26 closelog();//关闭日志系统
27
28 return 0;
29 }
注意:所有程序(包括Linux内核) 调用syslog()函数的输出相关信息都会记录到 /var/log/messages 日志文件中,因为该文件中记录了所有的信息,这也意味着当前程序记录的消息容易被别的程序冲刷掉,所以我们在做项目写网络程序的时候,一般会使用标准文件IO库(fopen、fwrite()等)自己实现日志系统,而不是直接调用该函数。