linux服务器操作日志,linux服务器日志

  linux服务器操作日志,linux服务器日志

  主机信息

  就像我们可以确定用户信息一样,程序也可以确定运行它的计算机的信息。uname命令提供了此信息。Uname也用作系统调用,在C程序中提供相同的信息。我们可以使用man2uame查看详细信息。

  许多情况下都需要主机信息。也许我们想根据网络上运行的机器的名称来定义一个程序的行为,也就是说,它是学生的机器还是管理员的机器。出于授权的目的,我们可能希望限制一个程序只能在一台机器上运行。所有这些意味着我们需要一种方法来确定程序运行的机器的信息。

  如果系统中安装了网络组件,那么我们可以通过gethostname函数轻松获得它的网络名称:

  #包括unistd.h

  int gethostname(char *name,size _ t name len);

  Gethostname函数将机器的网络名称写入name指示的字符串中。假设该字符串的长度至少与namelen字符一样长。如果成功,gethostname函数将返回0,否则将返回-1。

  我们可以通过调用uname系统来获得关于主机的更多详细信息:

  #包含sys/utsname.h

  int uname(struct utsname * name);

  uname函数将主机信息写入name参数指向的结构。在sys/ustname.h中定义了utsname结构,其中大多数至少包含以下成员:

  成员描述

  Char sysname[]操作系统名称

  字符节点名[]主机名

  Char release[]系统发布级别

  Char version[]系统版本号

  收费机硬件类型[]

  如果成功,uname函数将返回一个非负数;否则,它将返回-1,并设置errno来指示错误。

  测试主机信息

  下面是一个获取主机信息的程序hostget.c:

  #包含sys/utsname.h

  #包括unistd.h

  #包含stdio.h

  int main()

  {

  充电计算机[256];

  struct utsname uts

  if(gethostname(computer,255)!=0 uname( uts) 0) {

  fprintf(stderr,"无法获取主机信息/n ");

  出口(1);

  }

  printf("计算机主机名是%s/n ",计算机);

  printf(" System is % s on % s hardware/n ",uts.sysname,uts . machine);

  printf("节点名是%s/n ",uts . Nodename);

  printf("版本为%s,%s/n ",uts.release,uts . Version);

  退出(0);

  }

  该程序将产生以下特定于Linux的输出。如果我们的机器在网络中,我们将找到包含网络的扩展主机名:

  $ ./hostget

  计算机主机名是beast

  系统是i686硬件上的Linux

  节点名是beast

  版本为2.4.19-4GB,协调世界时2002年11月27日00:56:40第1周

  操作原理

  这个程序将调用gethostname函数来获取主机的网络名称。在前面的示例中,它的名称是tilde。通过调用unmae函数可以获得更详细的信息。注意,uname函数返回的字符串是依赖于实现的;在这个例子中,版本号包含编译内核的数据。

  可以通过gethostid函数获得唯一的主机号:

  #包括unistd.h

  long gethostid(void);

  gethostid函数返回一个唯一的主机号。授权管理通常使用该功能来确保软件程序只能在具有合法授权的机器上运行。在Sun工作站上,它将返回一个在制造时就设置在机器的不可变内存中的数字,因此它对于系统硬件来说是唯一的。

  其他系统,比如Linux,将根据机器的网络地址返回一个值,这对于授权来说通常是足够安全的。

  杂志

  许多程序需要记录它们的动作。系统通常将信息写入终端或日志文件。这些消息可能指示错误、警告或有关系统状态的更多一般信息。例如,su程序可能会记录用户试图获得超级权限但失败的事实。

  通常,这些日志信息会被记录在一个目录下的系统文件中。可能这是/usr/adm或者/var/log。在通常的Linux安装中,/var/log/messages文件包含系统信息,/var/log/mail包含其他邮件系统的日志信息,/var/log/debug包含调试信息。我们可以在/etc/syslog.conf文件中查看我们的系统配置。

  以下是一些日志信息:

  以下是一些示例日志消息:

  Feb 8 08:38:37 beast内核:klogd 1.4.1,日志源=/proc/kmsg启动。

  2月8日08:38:37 beast内核:正在检查/boot/System.map-2.4.19-4GB

  2月8日08:38:37 beast内核:从/boot/System.map加载了20716个符号-

  2.4.19-4GB。

  beast内核:符号匹配内核版本2.4.19。

  beast内核:从17个模块中加载了372个符号。

  Feb 8 08:38:37 beast内核:Linux Tulip驱动版本0 . 9 . 15-pre 11(2011年5月11日,

  2002)

  Feb 8 08:38:37 beast内核:PCI:找到设备00:0d.0的IRQ 5

  Feb 8 08:38:37 beast内核:eth0: ADMtek彗星rev 17在0xe400,

  00:04:5A:5F:46:52,IRQ 5。

  .

  2月8日08:39:20 beast/usr/sbin/CRON[932]:(CRON)启动(fork ok)

  2月8日09:50:35野兽苏:(对root) neil on /dev/pts/4

  从这里我们可以看到日志中记录的信息。当内核启动并检测到已安装的硬件时,会报告前面的一些错误。任务调用者cron报告说是他启动了它。最后,su程序报告用户neil访问了一个超级帐户。

  一些Unix系统没有以这种可读的方式提供日志信息,但是提供了管理员工具来读取系统事件的数据库。我们可以查看我们的系统文档以获取详细信息。

  虽然系统信息的格式和存储会发生变化,但生成这些信息的方法是标准的。Unix系统使用syslog功能为日志信息的生成提供接口:

  #包含syslog.h

  void syslog(int priority,const char *消息,参数.);

  syslog功能将日志信息发送到日志工具。每个消息都有一个优先级参数,该参数由安全级别和工具值的位或获得。安全级别控制如何生成这些消息,而工具值记录消息来源。

  工具值包括LOG_USER,用于指示消息来自用户程序,LOG_LOCAL0、LOG_LOCAL1到LOG_LOCAL7,可由本地管理员赋予含义。

  下表按降序列出了安全级别:

  安全级别描述

  记录紧急情况

  LOG_ALERT高优先级问题,如数据库崩溃

  LOG_CRIT严重错误,如硬件故障

  LOG_ERR中的错误

  日志警告警告

  日志_注意需要注意的特殊情况

  日志信息消息

  LOG_DEBUG调试消息

  根据我们的系统配置,LOG_EMERG消息可能会广播给所有用户,LOG_ALERT消息可能会通过邮件发送给管理员,LOG_DEBUG消息会被忽略,其他消息会不分昼夜地写。当我们想要创建日志消息时,我们可以编写一个简单的程序来调用syslog日志程序。

  syslog创建的日志消息由标题和正文组成。标题由节目指示器以及日期和时间创建。消息正文由syslog的消息参数创建,类似于printf格式的字符串。传递给syslog的其余参数用于在消息字符串中指定printf样式的约定。此外,指示符%m可用于插入与当前错误变量errno相关联的错误消息字符串。这对于记录错误消息很有用。

  测试-系统日志

  在这个程序中,我们试图打开一个不存在的文件:

  #包含syslog.h

  #包含stdio.h

  int main()

  {

  文件* f;

  f=fopen("not_here "," r ");

  如果(!f)

  syslog(LOG_ERRLOG_USER," oops-% m/n ");

  退出(0);

  }

  当我们编译并运行syslog.c程序时,我们不会看到任何输出,但是文件/var/log/messages现在包含以下记录:

  2月8日09:59:14 beast系统日志:哎呀-没有这样的文件或目录

  操作原理

  在这个程序中,我们试图打开一个不存在的文件。当操作失败时,我们会看到syslog将其记录在系统日志中。

  我们可以注意到,日志消息并没有指出哪个程序调用了日志程序;他只是记录了syslog被消息调用的事实。%m格式约定已被错误描述替换。在本例中,找不到该文件。这比仅仅打印出原始错误号要有用得多。

  syslog.h中定义了可用于修改记录器行为的其他函数,它们是:

  #包含syslog.h

  void close log(void);

  void openlog(const char *ident,int logopt,int facility);

  int setlogmask(int mask pri);

  我们可以通过调用openlog函数来修改日志消息的表达方式。这将让我们设置一个字符串ident,它将被添加到日志消息的前面。我们可以用他来指出是哪个程序创建了这条消息。facility参数记录了syslog调用将来要使用的参数值。默认值为LOG_USER。logopt参数配置未来syslog调用的行为。零个或多个按位“或”运算的结果:

  Logopt参数描述

  LOG_PID包含消息中的进程标识符,这是系统分配给进程的唯一标识号。

  如果消息不能被记录,则LOG_CONS被发送到终端。

  LOG_ODELAY在第一次调用时打开日志程序。

  LOG_NDELAY会立即打开日志程序,而不是第一次调用。

  open函数分配并打开一个文件描述符,用于写入日志程序。我们可以调用closelog函数来关闭它。注意,在调用syslog函数之前不需要调用openlog,因为syslog本身会在需要的时候打开。

  我们可以使用setlogmask函数来设置日志掩码,以控制日志消息的优先级。将来,那些调用syslog函数的优先级没有在日志掩码中设置的人将被拒绝。例如,我们可以使用这个方法来关闭LOG_DEBUG消息,而无需修改程序体。

  我们可以使用LOG_MASK(priority)为日志消息创建一个掩码,这将创建一个只有一个优先级的掩码,或者使用LOG_UPTO(priority),这将创建一个包含所有优先级(包括优先级)的掩码。

  测试日志掩码

  在本例中,我们将实际了解logmask的用法:

  #包含syslog.h

  #包含stdio.h

  #包括unistd.h

  int main()

  {

  int logmask

  openlog("logmask ",LOG_PIDLOG_CONS,LOG _用户);

  syslog(LOG_INFO,"信息性消息,pid=%d ",getpid());

  syslog(LOG_DEBUG,“调试消息,应该会出现”);

  LOG mask=setlogmask(LOG _ UPTO(LOG _ NOTICE));

  syslog(LOG_DEBUG,“调试消息,不应该出现”);

  退出(0);

  }

  这个logmask.c程序不会产生任何输出,但是在特定的Linux系统上,在/var/log/messages的末尾,我们会看到下面一行:

  2月8日10:00:50 beast日志掩码[1833]:信息性消息,pid=1833

  配置为接收调试日志消息的文件应包含以下行:

  Feb 8 10:00:50 beast日志掩码[1833]:应该会出现调试消息

  操作原理

  Cheng使用他的名字logmask来初始化日志程序,请求消息包含进程标识符。消息记录在/var/log/messages中,而调试信息记录在/var/log/debug文件中。第二个调试信息不会出现,因为我们调用了setlogmask函数,忽略了所有优先级小于LOG_NOTICE的兴趣消除。

  如果我们的安装没有记录调试信息的功能,或者配置不同,那么我们可能看不到调试消息的输出。要允许所有调试消息,请在/etc/syslog.conf的末尾添加以下行,然后重新启动。但是,请务必查看我们的系统文档,以获得准确的配置方法:

  *.调试/变量/日志/调试

  Logmask.c使用getpid函数,其相关的getppid函数定义如下:

  #包含sys/types.h

  #包括unistd.h

  PID _ t getpid(void);

  PID _ t getppid(void);

  这两个函数返回调用进程及其父进程的进程标识符。要了解更多关于PID的知识,你可以查看第11章。

linux服务器操作日志,linux服务器日志