php利用syslog函数分布式将log集中…

使用php的syslog函数,调用本地的syslog服务,然后从本地syslog发送到中央syslog服务器进行分析整理,配置如下

首先我们先写一个php的测试文件

\<\?php
define_syslog_variables();
openlog(“TextLog”, LOG_PID, LOG_LOCAL0);

$data = date(“Y/m/d H:i:s”);
syslog(LOG_DEBUG,”Messagge: $data”);

closelog();
\?\>
注意,我们用local0这个openlog所以在本地的syslog.conf中需配置local0具体配置如下

vi /etc/syslog.conf
local0.*                @index-server
保存退出以后/etc/init.d/syslog restart

index-server是中央服务器的hostname也可以是IP地址

然后我们配置中央服务器的syslog
vi /etc/sysconfig/syslog
将SYSLOGD_OPTIONS=”-m 0″改成SYSLOGD_OPTIONS=”-m 0 -r” 
存盘退出
vi /etc/syslog.conf
local0.*                        /var/log/php.log
#这里就是从各个机器打过来的log放在哪个文件里。。这个文件可能会比较大,建议对这个文件作每日存档
#还有local0.debug 可以打在/var/log/php_debug.log中类似这种。。。可以自由发挥。。
存盘退出以后/etc/init.d/syslog restart

在远端机执行t.php
Sep  2 04:17:58 app01 TextLog[2408]: Messagge: 2010/09/02 04:17:56
你看。。app01的log已经写入index-server的php.log文件中了!是不是很简单,很好用??至于t.php如何封装一下,优化一下。。

 

这里面的三个函数openlog, syslog, closelog是一套系统日志写入接口。另外那个vsyslog和syslog功能一样,只是参数格式不同。
    通常,syslog守护进程读取三种格式的记录消息。此守护进程在启动时读一个配置文件。一般来说,其文件名为/etc/syslog.conf,该文件决定了不同种类的消息应送向何处。例如,紧急消息可被送向系统管理员(若已登录),并在控制台上显示,而警告消息则可记录到一个文件中。该机制提供了syslog函数,其调用格式如下
#include
void openlog (char*ident,int option ,int facility);
void syslog(int priority,char*format,……)
void closelog();

    调用openlog是可选择的。如果不调用openlog,则在第一次调用syslog时,自动调用openlog。调用closelog也是可选择的,它只是关闭被用于与syslog守护进程通信的描述符。调用openlog 使我们可以指定一个ident,以后, 此ident 将被加至每则记录消息中。ident 一般是程序的名称(例如 ,cron ,ine 等)


程序的用法示例代码如下:


#include
int main(int argc, char **argv)
{
    openlog("MyMsgMARK", LOG_CONS | LOG_PID, 0);
    syslog(LOG_DEBUG,
           "This is a syslog test message generated by program '%s'\n",
           argv[0]);
    closelog();
    return 0;
}
 
编译生成可执行程序后,运行一次程序将向/var/log/message文件添加一行信息如下:
        Feb 12 08:48:38 localhost MyMsgMARK[7085]: This is a syslog test message generated by program './a.out'
 
openlog及closelog函数说明
此函数原型如下:
void openlog(const char *ident, int option, int facility);
此函数用来打开一个到系统日志记录程序的连接,打开之后就可以用syslog或vsyslog函数向系统日志里添加信息了。而closelog函数就是用来关闭此连接的。
openlog的第一个参数ident将是一个标记,ident所表示的字符串将固定地加在每行日志的前面以标识这个日志,通常就写成当前程序的名称以作标记。第二个参数option是下列值取与运算的结果:LOG_CONS, LOG_NDELAY, LOG_NOWAIT, LOG_ODELAY, LOG_PERROR, LOG_PID,各值意义请参考man openlog手册
LOG_CONS

   Write directly to system console if there is an error while sending to system logger.

LOG_NDELAY
   Open the connection immediately (normally, the connection is opened when the first message is logged).

LOG_NOWAIT
   Don’t wait for child processes that may have been created while logging the message.  (The GNU C library does not create a child process, so this option has no effect on Linux.)

LOG_ODELAY
   The converse of LOG_NDELAY; opening of the connection is delayed until syslog() is called. (This is the  default,  and  need not be specified.)

LOG_PERROR
   (Not in SUSv3.) Print to stderr as well.

LOG_PID
    Include PID with each message. 
第三个参数facility指明记录日志的程序的类型。

       The facility argument is used to specify what type of program  is  logging  the  message.
       This  lets the configuration file specify that messages from different facilities will be
       handled differently.
       LOG_AUTH       
security/authorization messages (DEPRECATED Use LOG_AUTHPRIV instead)

       LOG_AUTHPRIV   security/authorization messages (private)

       LOG_CRON       clock daemon (cron and at)

       LOG_DAEMON     system daemons without separate facility value

       LOG_FTP        ftp daemon

       LOG_KERN       kernel messages (these can't be generage from user processes)

       LOG_LOCAL0 through LOG_LOCAL7
                      
reserved for local use

       LOG_LPR        line printer subsystem

       LOG_MAIL       mail subsystem

       LOG_NEWS       USENET news subsystem

       LOG_SYSLOG     messages generated internally by syslogd(8)
      
       LOG_USER (default)
                      
generic user-level messages

       LOG_UUCP       UUCP subsystem

 

syslog函数及参数
syslog函数用于把日志消息发给系统程序syslogd去记录,此函数原型是:
void syslog(int priority, const char *format, ...);
第一个参数是消息的紧急级别,第二个参数是消息的格式,之后是格式对应的参数。就是printf函数一样使用。

如果我们的程序要使用系统日志功能,只需要在程序启动时使用openlog函数来连接syslogd程序,后面随时用syslog函数写日志就行了。

level
       This determines the importance of the message.  The levels are, in  order  of  decreasing
       
importance:

       LOG_EMERG      system is unusable

       LOG_ALERT      action must be taken immediately

       LOG_CRIT       critical conditions

       LOG_ERR        error conditions

       LOG_WARNING    warning conditions

       LOG_NOTICE     normal, but significant, condition

       LOG_INFO       informational message
      
       LOG_DEBUG      
debug-level message

       The function setlogmask(3) can be used to restrict logging to specified levels only.

 

NOTES
       The  argument  ident  in  the  call  of openlog() is probably stored as-is.  Thus, if the
       string it points to is changed, syslog() may start prepending the changed string, and  if
       the  string it points to ceases to exist, the results are undefined.  Most portable is to
       
use a string constant.

       Never pass a string with user-supplied data as a format, use the following instead:

           syslog(priority, "%s", string);

SEE ALSO
       logger(1), setlogmask(3), syslog.conf(5), syslogd(8)

 

 

vsyslog与syslog函数的功能是一样的。

 #include

   void vsyslog(int priority, const char *format, va_list ap);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       vsyslog(): _BSD_SOURCE

 

 

用计算机编程是一件单调乏味的事情,但是它也很有趣。编程有趣的一面在于了解使用旧工具的新方法。最近,我签了一份合同帮助解决基于 Linux®、Apache、MySQL 和 Linux、Apache、MySQL、PHP/Perl (LAMP) 的大型复杂内容管理系统 (CMS) 中的若干个错误。该 CMS 的架构是标准的 LAMP 模型,使用运行 Apache V2.0 的 Enterprise Red Hat Linux。驱动 Web 站点的代码由分布在 Apache 文档根目录的 30 个子目录中的几百个 PHP 源模块组成。系统的 Apache 和 MySQL 部分不需要更改,因为我的所有纠错操作都是在 PHP 工作区中进行的。

在研究了该 CMS 的工作原理一段时间之后,我渐渐开始欣赏该系统优雅的设计并且意识到在大多数成熟的编程环境中,此系统只依赖于少量的可用 PHP 函数(在这里想起了旧的 80/20 法则,其中 80% 的工作是用 20% 的可用函数来完成的)。本文将展示如何调试未知的复杂系统,以帮助您了解那些很少使用的函数,并提供如何使用 syslog() 函数的丰富功能来应用新知识的示例。

调试程序

虽然表面上 PHP 编程语言有成百上千个函数可用,但是在读到与本文类似的文章之前,您可能从未使用过某些函数(或许大多数函数)。另一种深入学习语言的方法是调试别人已经用该语言编写的程序。我总是对程序员用具有创造性的方法使用工具印象深刻。

调试像计算机编程一样,一半是科学,一半是艺术。在不是由您创建的系统中跟踪并不明显的错误时,需要能够很快地定位这些错误在代码中的位置。由于要处理的代码模块有成百上千个,因此最佳起点是显示找到错误的输出位置,然后从该位置开始逆向查找来隔离问题。

例如,如果知道输出的计算值不正确,则必须设计一种方法来查看导致出现问题的中间值。通过重要的数据库查询得到的错误数据可以证明存在其他问题。您必须能够查看生成(并由代码提交给 MySQL 引擎)的 SQL 语句以查看问题是不是出在语句里。

完成此操作的一项古老技术是插入可以打印这些字符串和值的代码。不幸的是,使用诸如 PHP 之类的工具或任何基于 Web 的应用程序,您不希望在这样的系统固有输出(即,被发送给浏览器的 HTML 代码)中掺入调试信息,尤其是在要检验的系统是一台生产服务器时。

您可以创建自定义日志记录文件并向其中写入日志消息,但是为什么不使用已经提供给您的工具呢?请始终记住:不要把工具尘封起来。您值得花一些时间查看语言创建者是否已经提供了一种库例程或函数,可以执行您通常需要的功能。实际上,只要您觉得某些内容很明显应当是编程包的一部分,那么它很可能就包含在其中。

我意识到需要使用类似于 UNIX® 的 syslog 的工具。我想 PHP 很有可能有 syslog 功能,因此在快速查看了 PHP 文档后,我找到了它!PHP syslog() 函数是我多年来没注意到的函数,直到我签约来做这个项目。使用 syslog(),我可以搜索直至找到并消除生产系统中的大多数错误,除了需要几分钟时间执行各个函数之外,不会引入其他副作用。

随着知识的积累并且在专业领域中越来越有经验,显然可以采用不同的方法来做事情,并且某种方法将最终成为执行必要任务的首选方法。必须始终牢记的是您认为很明显的事情对其他人来说并不一定是明显的。对您来说很简单的事情对于其他人来说可能非常复杂。

使用诸如 syslog() 函数之类的工具可以控制复杂度,并允许通过配置文件(例如 syslog.conf)来轻松地进行自定义。例如,可以插入代码来设定 SQL 语句的格式,将它记录到 syslog() 中并将其传递给 MySQL 来执行。随后,对 syslog.conf 文件稍微修改一下,把文本发送给另一个日志文件或者可能就发送给位桶(bit bucket)。几个星期或几个月之后,如果有必要再次查看发生的情况,则再对 syslog.conf 文件进行简单更改将还原该功能。

syslog

syslog 在 UNIX 世界中有着丰富多彩的历史。syslog 最初是作为 Sendmail 项目的一部分开发的,实践证明它非常有用,因此许多其他工具引入了 syslog 功能,证明了最简单的想法有时最有效。

简要地说,syslog 允许应用程序将带有标记的消息写入一组公共系统日志文件中,这些日志文件可以驻留在程序员和网络管理员能够轻松访问的位置。这意味着,例如,您可以配置 Web 服务器上的 syslog 以记录另一台服务器上的系统消息 —— 这台服务器可能是在安全防火墙后面几层并且更易于让前述管理员访问。但是按照我的目的,我只接受将文件写入 /var/log 目录的默认行为。

syslog 机制是在启动时启动的,并且其初始行为是由 syslog.conf 文件中的规则定义的。这些规则使您可以很好地调整使用该机制记录的内容 —— 在一台高容量而且工作繁重的服务器上使用 syslog 机制可以转换为可改变大小的日志文件。

每条规则都包含两个字段:selector 和 action。基本上,selector 字段选择要记录的工具(例如,kern、user、mail、lpr)和工具拥有的优先级。优先级字段包含一个关键字,例如 debug、info、notice 或者 warning。而规则的 action 字段用于定义对匹配 selector 字段的那类消息执行的操作。规则可以指定记录消息的文件,将记录消息发送给哪台计算机,将消息发送给什么用户(以控制台消息的形式)等。

日志记录

研究与 syslog 工具相关的信息和手册页以了解如何根据需要配置系统。在我的例子中,我需要知道在生产 CMS 系统每次运行时各个 PHP 变量的值是什么。我还需要知道某些模块何时启动及何时停止以及各个中间变量值。在说明需要记录哪些信息的细节之前,让我们先来设置日志的基本信息。

使用您最喜欢用的编辑器,创建清单 1 中所示的文件,将其命名为 test.php 并把它放在 Apache 文档根目录中(在我的系统中,它是 /var/www)。


清单 1. test.php

                
\<\html>
  \
\
  \
  \
\<\?php syslog(LOG_NOTICE, "{$_SERVER['REMOTE_ADDR']}: test.php - PHP Index page accessed."); echo '

PHP Test Page

'; \?\> \<\/body> \

您同样应当安装并配置了 PHP。如果没有,请查看 参考资料 以获得介绍如何安装和配置的链接。如果一切配置正确,那么当您访问 URL 为 http://localhost/test.php 的页面时应当会在浏览器中看到以下文本:

 

PHP Test Page

接下来,打开一个 X 终端窗口并键入以下命令来查看记录到 /var/log/messages 文件中的内容:

 

tail /var/log/messages

如果一切运行正常,您应当会在接近清单末尾的位置看到下面一行:

 

Jul 23 14:43:42 localhost apache2: 127.0.0.1: test.php - PHP Index page accessed.

如果您看到了,那很好。您现在已经准备好开始详细调试所使用的复杂系统。

我发现了一个优秀实践:对所有 PHP/MySQL 调用使用 syslog(),这样每次都与 Web 站点交互,可以看到实时生成了哪些 SQL 查询以构建返回给您的页面。一种简单的实现方法是打开另一个 X 终端窗口并结合使用 tail 命令与 -f 选项来 “实时” 查看消息日志:

 

tail -f /var/log/messages

记录的内容

现在您已经检验了日志可以正常工作并且可以看到记录机制的结果,下面的提示介绍了如何使用这些工具尽可能快速地缩短学习陌生系统的过程。

必须知道哪些模块执行了超出其文档所述范围的操作。由于这个原因,我喜欢记录标记模块开头和结尾的日志消息。这样,您可以对 Web 站点的页面进行操作,同时监视运行 tail -f /var/log/messages 命令的另一个 X 终端窗口。这样可以看到哪些模块在执行并且浏览器每次请求新页面时的顺序。

我还需要记录在 PHP 代码运行期间被调用的各个程序之间的边界。例如,查询数据库时调用 MySQL,或者修改数据格式时调用外部程序(例如,Extensible Stylesheet Language Transformation(XSLT)引擎)。系统地把这些检查点插入每个 PHP 代码模块中,这种实践将帮助您熟悉模块的名称和位置。当浏览各个页面时代码把您在另一个 X 终端中看到的消息发送给您时,您将获得推动和增强系统知识的重要反馈。

结束语

syslog 工具是调试由其他人编写的应用程序的强大工具。它允许您查看哪些模块正被执行,哪些 SQL 语句正在执行,以及在您浏览 Web 站点时哪些变量值发生更改。这有助于查找可能会发生问题的模块。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值