正在加载……
Mysql日期和时间函数
Posted in LAMP on July 20, 2006 / 评论(0) »

Mysql日期和时间函数    
  posted   by   kevin   on   2004,   September   7,   8:26   PM.   技术资料      
  本文出自:http://linuxdb.yeah.net   作者:   晏子     (2001-07-05   15:00:00)    
   
   
  对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见7.3.6   日期和时间类型。        
   
  这里是一个使用日期函数的例子。下面的查询选择了所有记录,其date_col的值是在最后30天以内:        
   
  mysql>   SELECT   something   FROM   table        
  WHERE   TO_DAYS(NOW())   -   TO_DAYS(date_col)   <=   30;        
   
  DAYOFWEEK(date)        
  返回日期date的星期索引(1=星期天,2=星期一,   ……7=星期六)。这些索引值对应于ODBC标准。        
  mysql>   select   DAYOFWEEK('1998-02-03');        
  ->   3        
   
  WEEKDAY(date)        
  返回date的星期索引(0=星期一,1=星期二,   ……6=   星期天)。        
  mysql>   select   WEEKDAY('1997-10-04   22:23:00');        
  ->   5        
  mysql>   select   WEEKDAY('1997-11-05');        
  ->   2        
   
  DAYOFMONTH(date)        
  返回date的月份中日期,在1到31范围内。        
  mysql>   select   DAYOFMONTH('1998-02-03');        
  ->   3        
   
  DAYOFYEAR(date)        
  返回date在一年中的日数,   在1到366范围内。        
  mysql>   select   DAYOFYEAR('1998-02-03');        
  ->   34        
   
  MONTH(date)        
  返回date的月份,范围1到12。        
  mysql>   select   MONTH('1998-02-03');        
  ->   2        
   
  DAYNAME(date)        
  返回date的星期名字。        
  mysql>   select   DAYNAME("1998-02-05");        
  ->   'Thursday'        
   
  MONTHNAME(date)        
  返回date的月份名字。        
  mysql>   select   MONTHNAME("1998-02-05");        
  ->   'February'        
   
  QUARTER(date)        
  返回date一年中的季度,范围1到4。        
  mysql>   select   QUARTER('98-04-01');        
  ->   2        
   
  WEEK(date)        
           
  WEEK(date,first)        
  对于星期天是一周的第一天的地方,有一个单个参数,返回date的周数,范围在0到52。2个参数形式WEEK()允许    
  你指定星期是否开始于星期天或星期一。如果第二个参数是0,星期从星期天开始,如果第二个参数是1,    
  从星期一开始。        
  mysql>   select   WEEK('1998-02-20');        
  ->   7        
  mysql>   select   WEEK('1998-02-20',0);        
  ->   7        
  mysql>   select   WEEK('1998-02-20',1);        
  ->   8        
   
  YEAR(date)        
  返回date的年份,范围在1000到9999。        
  mysql>   select   YEAR('98-02-03');        
  ->   1998        
   
  HOUR(time)        
  返回time的小时,范围是0到23。        
  mysql>   select   HOUR('10:05:03');        
  ->   10        
   
  MINUTE(time)        
  返回time的分钟,范围是0到59。        
  mysql>   select   MINUTE('98-02-03   10:05:03');        
  ->   5        
   
  SECOND(time)        
  回来time的秒数,范围是0到59。        
  mysql>   select   SECOND('10:05:03');        
  ->   3        
   
  PERIOD_ADD(P,N)        
  增加N个月到阶段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意阶段参数P不是日期值。        
  mysql>   select   PERIOD_ADD(9801,2);        
  ->   199803        
   
  PERIOD_DIFF(P1,P2)        
  返回在时期P1和P2之间月数,P1和P2应该以格式YYMM或YYYYMM。注意,时期参数P1和P2不是日期值。        
  mysql>   select   PERIOD_DIFF(9802,199703);        
  ->   11        
   
  DATE_ADD(date,INTERVAL   expr   type)        
           
  DATE_SUB(date,INTERVAL   expr   type)        
           
  ADDDATE(date,INTERVAL   expr   type)        
           
  SUBDATE(date,INTERVAL   expr   type)        
  这些功能执行日期运算。对于MySQL   3.22,他们是新的。ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同义词。    
  在MySQL   3.23中,你可以使用+和-而不是DATE_ADD()和DATE_SUB()。(见例子)date是一个指定开始日期的    
  DATETIME或DATE值,expr是指定加到开始日期或从开始日期减去的间隔值一个表达式,expr是一个字符串;它可以以    
  一个“-”开始表示负间隔。type是一个关键词,指明表达式应该如何被解释。EXTRACT(type   FROM   date)函数从日期    
  中返回“type”间隔。下表显示了type和expr参数怎样被关联:   type值   含义   期望的expr格式        
  SECOND   秒   SECONDS        
  MINUTE   分钟   MINUTES        
  HOUR   时间   HOURS        
  DAY   天   DAYS        
  MONTH   月   MONTHS        
  YEAR   年   YEARS        
  MINUTE_SECOND   分钟和秒   "MINUTES:SECONDS"        
  HOUR_MINUTE   小时和分钟   "HOURS:MINUTES"        
  DAY_HOUR   天和小时   "DAYS   HOURS"        
  YEAR_MONTH   年和月   "YEARS-MONTHS"        
  HOUR_SECOND   小时,   分钟,   "HOURS:MINUTES:SECONDS"        
  DAY_MINUTE   天,   小时,   分钟   "DAYS   HOURS:MINUTES"        
  DAY_SECOND   天,   小时,   分钟,   秒   "DAYS   HOURS:MINUTES:SECONDS"        
   
  MySQL在expr格式中允许任何标点分隔符。表示显示的是建议的分隔符。如果date参数是一个DATE值并且你的计算仅仅    
  包含YEAR、MONTH和DAY部分(即,没有时间部分),结果是一个DATE值。否则结果是一个DATETIME值。        
   
  mysql>   SELECT   "1997-12-31   23:59:59"   +   INTERVAL   1   SECOND;        
  ->   1998-01-01   00:00:00        
  mysql>   SELECT   INTERVAL   1   DAY   +   "1997-12-31";        
  ->   1998-01-01        
  mysql>   SELECT   "1998-01-01"   -   INTERVAL   1   SECOND;        
  ->   1997-12-31   23:59:59        
  mysql>   SELECT   DATE_ADD("1997-12-31   23:59:59",        
  INTERVAL   1   SECOND);        
  ->   1998-01-01   00:00:00        
  mysql>   SELECT   DATE_ADD("1997-12-31   23:59:59",        
  INTERVAL   1   DAY);        
  ->   1998-01-01   23:59:59        
  mysql>   SELECT   DATE_ADD("1997-12-31   23:59:59",        
  INTERVAL   "1:1"   MINUTE_SECOND);        
  ->   1998-01-01   00:01:00        
  mysql>   SELECT   DATE_SUB("1998-01-01   00:00:00",        
  INTERVAL   "1   1:1:1"   DAY_SECOND);        
  ->   1997-12-30   22:58:59        
  mysql>   SELECT   DATE_ADD("1998-01-01   00:00:00",        
  INTERVAL   "-1   10"   DAY_HOUR);        
  ->   1997-12-30   14:00:00        
  mysql>   SELECT   DATE_SUB("1998-01-02",   INTERVAL   31   DAY);        
  ->   1997-12-02        
  mysql>   SELECT   EXTRACT(YEAR   FROM   "1999-07-02");        
  ->   1999        
  mysql>   SELECT   EXTRACT(YEAR_MONTH   FROM   "1999-07-02   01:02:03");        
  ->   199907        
  mysql>   SELECT   EXTRACT(DAY_MINUTE   FROM   "1999-07-02   01:02:03");        
  ->   20102        

如果你指定太短的间隔值(不包括type关键词期望的间隔部分),MySQL假设你省掉了间隔值的最左面部分。例如,    
  如果你指定一个type是DAY_SECOND,值expr被希望有天、小时、分钟和秒部分。如果你象"1:10"这样指定值,    
  MySQL假设日子和小时部分是丢失的并且值代表分钟和秒。换句话说,"1:10"   DAY_SECOND以它等价于"1:10"   MINUTE_SECOND    
  的方式解释,这对那MySQL解释TIME值表示经过的时间而非作为一天的时间的方式有二义性。如果你使用确实不正确的日期,    
  结果是NULL。如果你增加MONTH、YEAR_MONTH或YEAR并且结果日期大于新月份的最大值天数,日子在新月用最大的天调整。        
   
  mysql>   select   DATE_ADD('1998-01-30',   Interval   1   month);        
  ->   1998-02-28        
   
  注意,从前面的例子中词INTERVAL和type关键词不是区分大小写的。        
  TO_DAYS(date)        
  给出一个日期date,返回一个天数(从0年的天数)。        
  mysql>   select   TO_DAYS(950501);        
  ->   728779        
  mysql>   select   TO_DAYS('1997-10-07');        
  ->   729669        
   
  TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。        
   
  FROM_DAYS(N)        
  给出一个天数N,返回一个DATE值。        
  mysql>   select   FROM_DAYS(729669);        
  ->   '1997-10-07'        
   
  TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。        
   
  DATE_FORMAT(date,format)        
  根据format字符串格式化date值。下列修饰符可以被用在format字符串中:   %M   月名字(January……December)        
  %W   星期名字(Sunday……Saturday)        
  %D   有英语前缀的月份的日期(1st,   2nd,   3rd,   等等。)        
  %Y   年,   数字,   4   位        
  %y   年,   数字,   2   位        
  %a   缩写的星期名字(Sun……Sat)        
  %d   月份中的天数,   数字(00……31)        
  %e   月份中的天数,   数字(0……31)        
  %m   月,   数字(01……12)        
  %c   月,   数字(1……12)        
  %b   缩写的月份名字(Jan……Dec)        
  %j   一年中的天数(001……366)        
  %H   小时(00……23)        
  %k   小时(0……23)        
  %h   小时(01……12)        
  %I   小时(01……12)        
  %l   小时(1……12)        
  %i   分钟,   数字(00……59)        
  %r   时间,12   小时(hh:mm:ss   [AP]M)        
  %T   时间,24   小时(hh:mm:ss)        
  %S   秒(00……59)        
  %s   秒(00……59)        
  %p   AM或PM        
  %w   一个星期中的天数(0=Sunday   ……6=Saturday   )        
  %U   星期(0……52),   这里星期天是星期的第一天        
  %u   星期(0……52),   这里星期一是星期的第一天        
  %%   一个文字“%”。        
   
  所有的其他字符不做解释被复制到结果中。        
   
  mysql>   select   DATE_FORMAT('1997-10-04   22:23:00',   '%W   %M   %Y');        
  ->   'Saturday   October   1997'        
  mysql>   select   DATE_FORMAT('1997-10-04   22:23:00',   '%H:%i:%s');        
  ->   '22:23:00'        
  mysql>   select   DATE_FORMAT('1997-10-04   22:23:00',        
  '%D   %y   %a   %d   %m   %b   %j');        
  ->   '4th   97   Sat   04   10   Oct   277'        
  mysql>   select   DATE_FORMAT('1997-10-04   22:23:00',        
  '%H   %k   %I   %r   %T   %S   %w');        
  ->   '22   22   10   10:23:00   PM   22:23:00   00   6'        
  MySQL3.23中,在格式修饰符字符前需要%。在MySQL更早的版本中,%是可选的。        
   
  TIME_FORMAT(time,format)        
  这象上面的DATE_FORMAT()函数一样使用,但是format字符串只能包含处理小时、分钟和秒的那些格式修饰符。    
  其他修饰符产生一个NULL值或0。        
  CURDATE()        
           
  CURRENT_DATE        
  以'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。        
  mysql>   select   CURDATE();        
  ->   '1997-12-15'        
  mysql>   select   CURDATE()   +   0;        
  ->   19971215        
   
  CURTIME()        
           
  CURRENT_TIME        
  以'HH:MM:SS'或HHMMSS格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。        
  mysql>   select   CURTIME();        
  ->   '23:50:26'        
  mysql>   select   CURTIME()   +   0;        
  ->   235026        
   
  NOW()        
           
  SYSDATE()        
           
  CURRENT_TIMESTAMP        
  以'YYYY-MM-DD   HH:MM:SS'或YYYYMMDDHHMMSS格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的    
  上下文被使用。        
  mysql>   select   NOW();        
  ->   '1997-12-15   23:50:26'        
  mysql>   select   NOW()   +   0;        
  ->   19971215235026        
   
  UNIX_TIMESTAMP()        
           
  UNIX_TIMESTAMP(date)        
  如果没有参数调用,返回一个Unix时间戳记(从'1970-01-01   00:00:00'GMT开始的秒数)。如果UNIX_TIMESTAMP()用一    
  个date参数被调用,它返回从'1970-01-01   00:00:00'   GMT开始的秒数值。date可以是一个DATE字符串、一个DATETIME    
  字符串、一个TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地时间的一个数字。        
  mysql>   select   UNIX_TIMESTAMP();        
  ->   882226357        
  mysql>   select   UNIX_TIMESTAMP('1997-10-04   22:23:00');        
  ->   875996580        
   
  当UNIX_TIMESTAMP被用于一个TIMESTAMP列,函数将直接接受值,没有隐含的“string-to-unix-timestamp”变换。        
   
  FROM_UNIXTIME(unix_timestamp)        
  以'YYYY-MM-DD   HH:MM:SS'或YYYYMMDDHHMMSS格式返回unix_timestamp参数所表示的值,取决于函数是在一个字符串    
  还是或数字上下文中被使用。        
  mysql>   select   FROM_UNIXTIME(875996580);        
  ->   '1997-10-04   22:23:00'        
  mysql>   select   FROM_UNIXTIME(875996580)   +   0;        
  ->   19971004222300        
   
  FROM_UNIXTIME(unix_timestamp,format)        
  返回表示   Unix   时间标记的一个字符串,根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条    
  目同样的修饰符。        
  mysql>   select   FROM_UNIXTIME(UNIX_TIMESTAMP(),        
  '%Y   %D   %M   %h:%i:%s   %x');        
  ->   '1997   23rd   December   03:43:30   x'        
   
  SEC_TO_TIME(seconds)        
  返回seconds参数,变换成小时、分钟和秒,值以'HH:MM:SS'或HHMMSS格式化,取决于函数是在一个字符串还是在数字    
  上下文中被使用。        
  mysql>   select   SEC_TO_TIME(2378);        
  ->   '00:39:38'        
  mysql>   select   SEC_TO_TIME(2378)   +   0;        
  ->   3938        
   
  TIME_TO_SEC(time)        
  返回time参数,转换成秒。        
  mysql>   select   TIME_TO_SEC('22:23:00');        
  ->   80580        
  mysql>   select   TIME_TO_SEC('00:39:38');        
  ->   2378    

1. 预先的知识:
什么是RS232/RS484及其应用?
引用:
RS232接口就是串口,电脑机箱后方的9芯(或25芯)插座,旁边一般有 "|O|O|" 样标识。 
一般机箱有两个,新机箱有可能只有一个。笔记本电脑有可能没有。 
有很多工业仪器将它作为标准通信端口。通信的内容与格式一般附在仪器的用户说明书中。 

计算机与计算机或计算机与终端之间的数据传送可以采用串行通讯和并行通讯二种方式。由于串行通讯方式具有使用线路少、成本低,特别是在远程传输时,避免了多条线路特性的不一致而被广泛采用。 在串行通讯时,要求通讯双方都采用一个标准接口,使不同 的设备可以方便地连接起来进行通讯。 RS-232-C接口(又称 EIA RS-232-C)是目前最常用的一种串行通讯接口。它是在1970年由美国电子工业协会(EIA)联合贝尔系统、 调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标 准。它的全名是“数据终端设备(DTE)和数据通讯设备(DCE)之间 串行二进制数据交换接口技术标准”该标准规定采用一个25个脚的 DB25连接器,对连接器的每个引脚的信号内容加以规定,还对各种信 号的电平加以规定。 

(1)接口的信号内容 实际上RS-232-C的25条引线中有许多是很少使用的,在计算机与终端通讯中一般只使用3-9条引线。RS-232-C最常用的9条引线的信号内容见附表1所示 

(2)接口的电气特性 在RS-232-C中任何一条信号线的电压均为负逻辑关系。即:逻 辑“1”,-5— -15V;逻辑“0” +5— +15V 。噪声容限为2V。即 要求接收器能识别低至+3V的信号作为逻辑“0”,高到-3V的信号 作为逻辑“1” 
(3) 接口的物理结构 RS-232-C接口连接器一般使用型号为DB-25的25芯插头座,通常插头在DCE端,插座在DTE端. 一些设备与PC机连接的RS-232-C接口,因为不使用对方的传送控制信号,只需三条接口线,即“发送数据”、“接收数据”和“信号地”。所以采用DB-9的9芯插头座,传输线采用屏蔽双绞线。 

(4)传输电缆长度 由RS-232C标准规定在码元畸变小于4%的情况下,传输电缆长度应为50英尺,其实这个4%的码元畸变是很保守的,在实际应用中,约有99%的用户是按码元畸变10-20%的范围工作的,所以实际使用中最大距离会远超过50英尺,美国DEC公司曾规定允许码元畸变为10%而得出附表2 的实验结果。其中1号电缆为屏蔽电缆,型号为DECP.NO.9107723 内有三对双绞线,每对由22# AWG 组成,其外覆以屏蔽网。2号电缆为不带屏蔽的电缆。型号为DECP.NO.9105856-04是22#AWG的四芯电缆。 

1.RS-232-C是美国电子工业协会EIA(Electronic Industry Association)制定的一种串行物理接口标准。RS是英文“推荐标准”的缩写,232为标识号,C表示修改次数。RS-232-C总线标准设有25条信号线,包括一个主通道和一个辅助通道,在多数情况下主要使用主通道,对于一般双工通信,仅需几条信号线就可实现,如一条发送线、一条接收线及一条地线。RS-232-C标准规定的数据传输速率为每秒50、75、 100、150、300、600、1200、2400、4800、9600、19200波特。RS-232-C标准规定,驱动器允许有2500pF的电容负载,通信距离将受此电容限制,例如,采用150pF/m的通信电缆时,最大通信距离为15m;若每米电缆的电容量减小,通信距离可以增加。传输距离短的另一原因是RS-232属单端信号传送,存在共地噪声和不能抑制共模干扰等问题,因此一般用于20m以内的通信。 

2.RS-485总线,在要求通信距离为几十米到上千米时,广泛采用RS-485 串行总线标准。RS-485采用平衡发送和差分接收,因此具有抑制共模干扰的能力。加上总线收发器具有高灵敏度,能检测低至200mV的电压,故传输信号能在千米以外得到恢复。 RS-485采用半双工工作方式,任何时候只能有一点处于发送状态,因此,发送电路须由使能信号加以控制。RS-485用于多点互连时非常方便,可以省掉许多信号线。应用RS-485 可以联网构成分布式系统,其允许最多并联32台驱动器和32台接收器。 



以往,PC与智能设备通讯多借助RS232、RS485、以太网等方式,主要取决于设备的接口规范。但RS232、RS485只能代表通讯的物理介质层和链路层,如果要实现数据的双向访问,就必须自己编写通讯应用程序,但这种程序多数都不能符合ISO/OSI的规范,只能实现较单一的功能,适用于单一设备类型,程序不具备通用性。在RS232或RS485设备联成的设备网中,如果设备数量超过2台,就必须使用RS485做通讯介质,RS485网的设备间要想互通信息只有通过“主(Master)”设备中转才能实现,这个主设备通常是PC,而这种设备网中只允许存在一个主设备,其余全部是从(Slave)设备。而现场总线技术是以ISO/OSI模型为基础的,具有完整的软件支持系统,能够解决总线控制、冲突检测、链路维护等问题。

来源网址:http://zhidao.baidu.com/question/4578886.html




从串口双机对联线缆指南
引用:
  (一)串行通讯电缆的制作

  无论是9孔插头,还是25孔插头,其串行通讯电缆连接时都要遵循下列对接关系:

  SG←→SG TXD←→RXD RXD←→TXD RTS←→CTS
  CTS←→RTS DTR←→DSR DSR←→DTR

  根据上述对接关系,就可以非常方便地连接串行通讯电缆。这里顺便介绍一下上述各引脚所代表的含义:

  SG英文全称为Signal Ground/Common Return,表示信号地;
  TXD指Transmitted Data,表示数据发送;
  RXD指Received Data,表示接收数据;
  RTS指Request To Send,表示发送请求;
  CTS指Clear To Send,表示清除请求;
  DTR指Data Terminal Ready,表示数据终端准备就绪;
  DSR指Data Signal Rate Selector,表示数据置位准备就绪。

  在制作9芯串口连线时,需要2个9孔插头和1.5米长的至少7芯的扁平电缆,引脚连线如下所示。

  9孔插头-9孔插头引脚连线为:2-3、3-2、4-6、5-5、6-4、7-8、8-7。
  9孔插头-25孔插头引脚连线为:2-2、3-3、4-6、5-7、6-20、7-5、8-4。
  25孔插头-25孔插头引脚连线为:2-3、3-2、4-5、5-4、6-20、7-7、20-6。


来源网址:http://win2000server.vicp.net:88/Article_Show.asp?ArticleID=25




二、测试环境的构建:
1.  参考上面的《(一)串行通讯电缆的制作》,首先把两台电脑通过串口连结起来。
  当然,你也完全可以这么操作一台电脑上面的两个串口,而不需要两台电脑;如果你有两个串口的话。
  因为我以前做过工业控制底层开发,所以我可以很容易的构建这个基本的环境;
  实际上,只要:RxD TxD对接,GND直连即可,俗称三线连接。
  这一点不做任何答疑。

2. PHP运行环境的构建:
操作系统:WindowsXP(其他Windows系统没有测试)
PHP5.1.4: http://cn.php.net/get/php-5.1.4-Win32.zip/from/a/mirror
PECL5.1.4:http://cn.php.net/get/pecl-5.1.4-Win32.zip/from/a/mirror
解压PHP5.1.4,把PECL5.1.4之中的php_dio.dll放到PHP5.1.4的ext目录之下
把PHP5.1.4之中的php.ini-dist拷贝粘贴为php.ini,并打开设置然后保存:

extension=php_dio.dll


  这一点不做任何答疑。

三:参考资料:
1. 参考手册文档:
http://cn.php.net/manual/zh/ref.dio.php
http://cn.php.net/manual/zh/ref.exec.php
  如果代码之中有你没有见过,或者没有使用过,或者不熟悉的函数,请访问以上网址。
  主要使用了PHP的Direct IO Functions.

四:演示代码:
[font=Times New Roman]


<?php
// --------------------------------------------------------------------------
// File name   : RS232_Server.php
// Description : RS232演示上位机程序
// Requirement : PHP 5.1.4 (cli) (http://www.php.net)
//
// Copyright(C), HonestQiao, 2006, All Rights Reserved.
//
// Author: HonestQiao (honestqiao@hotmail.com/QQ:5601680) 
//
// 程序简介:
// 本程序与RS232_Client构成一个完整的演示系统,展示了PHP在RS232串口通讯上的应用。
// 程序之中实现了一个基础但是完整的RS232通讯协议(HQB232),通讯协议格式如下:
// 协议内容:
//             C->S 01 //请求通讯
//             S->C 02 //响应通讯
//             C->S LEN DATA //LEN表示数据(DATA)长度 DATA表示实际数据
//             C->S 03 //结束通讯
// 说明:S表示上位机 C表示下位机
//       HQB232表示HonestQiao演示的基础(Base)RS232通讯协议,包含了协议的
//   请求和响应,数据帧的结构。
//       演示过程为通讯的请求和响应,十次数据帧的发送, 通讯的结束
//       数据帧的结构为当前的序号,microtime(),随机字符串
//        
//       欢迎探讨PHP在RS232串口通讯上的应用。
// --------------------------------------------------------------------------
set_time_limit(0);
exec('mode COM1: baud=115200 data=8 stop=1 parity=n xon=on');

$fd = dio_open('COM1:', O_RDWR);
if(!$fd)
{
die("Error when open COM1");
}

$ff = dio_stat($fd);print_r($ff);
echo "HQB232 SERVER is listenning on COM1\n";
/// read
$len = 2;
$t=0;while (($t++)<1000) 
{
$data = dio_read($fd, $len);
if ($data) {
if($data==chr(0).chr(1)){
echo "S_RECV:01\n";
echo "S_SEND:02\n";
dio_write($fd,chr(0).chr(2));
break;
}
}
}

/// read
$len = 2;
$t=0;while (($t++)<1000) 
{
$len = 2;
$data = dio_read($fd, $len);
if($data==chr(0).chr(3)){
echo "S_RECV:03\n";
break;
}
elseif ($data) {
$len = intval($data);
$data = dio_read($fd, $len);
if($data){
echo "S_RECV:($len)$data\n";
}
}
}
dio_close($fd);
?> 



 


<?php
// --------------------------------------------------------------------------
// File name   : RS232_Client.php
// Description : RS232演示下位机程序
// Requirement : PHP 5.1.4 (cli) (http://www.php.net)
//
// Copyright(C), HonestQiao, 2006, All Rights Reserved.
//
// Author: HonestQiao (honestqiao@hotmail.com/QQ:5601680) 
//
// 程序简介:
// 本程序与RS232_Server构成一个完整的演示系统,展示了PHP在RS232串口通讯上的应用。
// 程序之中实现了一个基础但是完整的RS232通讯协议(HQB232),通讯协议格式如下:
// 协议内容:
//             C->S 01 //请求通讯
//             S->C 02 //响应通讯
//             C->S LEN DATA //LEN表示数据(DATA)长度 DATA表示实际数据
//             C->S 03 //结束通讯
// 说明:S表示上位机 C表示下位机
//       HQB232表示HonestQiao演示的基础(Base)RS232通讯协议,包含了协议的
//   请求和响应,数据帧的结构。
//       演示过程为通讯的请求和响应,十次数据帧的发送, 通讯的结束
//       数据帧的结构为当前的序号,microtime(),随机字符串
//        
//       欢迎探讨PHP在RS232串口通讯上的应用。
// --------------------------------------------------------------------------
set_time_limit(0);
exec('mode COM2: baud=115200 data=8 stop=1 parity=n xon=on');

$fd = dio_open('COM2:', O_RDWR);
if(!$fd)
{
die("Error when open COM2");
}

$ff = dio_stat($fd);print_r($ff);
echo "HQB232 CLIENT is start on COM2\n";
dio_write($fd,chr(0).chr(1));echo "C_SEND:01\n";
$len = 2;
$t=0;while(($t++)<1000)
{
$data = dio_read($fd, $len);
if($data==chr(0).chr(2)){
echo "C_RECV:02\n";
break;
}
}
$len = 2;
$t=0;while(($t++)<10)
{
$sdata = sprintf("%03d",$t) . "=" . microtime() . " (" . randomkeys(rand(0,35)) . ")";
$slen = strlen($sdata);
$stxlen = sprintf("%02d",$slen);
dio_write($fd,"$stxlen");
dio_write($fd,"$sdata");echo "C_SEND:($stxlen)$sdata\n";
//sleep(1);
}
dio_write($fd,chr(0).chr(3));echo "C_SEND:03\n";
dio_close($fd);

function randomkeys($length)
  {
   $pattern = "1234567890abcdefghijklmnopqrstuvwxyz";
   for($i=0;$i<$length;$i++)
   {
     $key .= $pattern{rand(0,35)};
   }
   return $key;
}
?>

[/font]

五、演示过程:
上位机:开始->运行->CMD
然后转到PHP5.1.4目录之下,执行:
php -f RS232_Server.php

下位机:开始->运行->CMD
然后转到PHP5.1.4目录之下,执行:
php -f RS232_Client.php


实际结果如下:



F:\usr\local\php5>php -f e:\RS232_Server.php
Array
(
    [device] => 3
    [inode] => 0
    [mode] => 8192
    [nlink] => 1
    [uid] => 0
    [gid] => 0
    [device_type] => 3
    [size] => 0
    [atime] => 0
    [mtime] => 0
    [ctime] => 0
)
HQB232 SERVER is listenning on COM1
S_RECV:01
S_SEND:02
S_RECV:(53)001=0.19238200 1150031774 (krruv981gpf1pmi1fz4qz09e9)
S_RECV:(42)002=0.19144800 1150031775 (jrhw41mphuy0ui)
S_RECV:(40)003=0.19148500 1150031776 (lqq560p6v17r)
S_RECV:(36)004=0.19148900 1150031777 (3ct02xmc)
S_RECV:(28)005=0.19212700 1150031778 ()
S_RECV:(33)006=0.19162500 1150031779 (2ilqf)
S_RECV:(34)007=0.19167800 1150031780 (vwmdfc)
S_RECV:(62)008=0.19168700 1150031781 (idb0laix4a6ryxz5nb7u74iaza601it6sv)
S_RECV:(56)009=0.19170100 1150031782 (r9ypgtvu4j7w1u141qx6im20ajy7)
S_RECV:(53)010=0.19171000 1150031783 (wq5mp1sdfuet1tp0x3vk67n47)
S_RECV:03

F:\usr\local\php5>



 



F:\usr\local\php5>php -f e:\RS232_Client.php
Array
(
    [device] => 3
    [inode] => 0
    [mode] => 8192
    [nlink] => 1
    [uid] => 0
    [gid] => 0
    [device_type] => 3
    [size] => 0
    [atime] => 0
    [mtime] => 0
    [ctime] => 0
)
HQB232 CLIENT is start on COM2
C_SEND:01
C_RECV:02
C_SEND:(53)001=0.19238200 1150031774 (krruv981gpf1pmi1fz4qz09e9)
C_SEND:(42)002=0.19144800 1150031775 (jrhw41mphuy0ui)
C_SEND:(40)003=0.19148500 1150031776 (lqq560p6v17r)
C_SEND:(36)004=0.19148900 1150031777 (3ct02xmc)
C_SEND:(28)005=0.19212700 1150031778 ()
C_SEND:(33)006=0.19162500 1150031779 (2ilqf)
C_SEND:(34)007=0.19167800 1150031780 (vwmdfc)
C_SEND:(62)008=0.19168700 1150031781 (idb0laix4a6ryxz5nb7u74iaza601it6sv)
C_SEND:(56)009=0.19170100 1150031782 (r9ypgtvu4j7w1u141qx6im20ajy7)
C_SEND:(53)010=0.19171000 1150031783 (wq5mp1sdfuet1tp0x3vk67n47)
C_SEND:03

F:\usr\local\php5>
六:说明
1. exec('mode COM1: baud=115200 data=8 stop=1 parity=n xon=on');
    exec('mode COM2: baud=115200 data=8 stop=1 parity=n xon=on');

mode是CMD下面的命令,表示设置串口的参数,因为dio_tcsetattr() 未在Windows下面实现,所以需要使用CMD的mode命令来进行设置,具体用法,请看:help mode

2. 通讯协议使用ASCII文本进行,没有使用HEX十六进制。因为是演示程序,所以协议非常简单,但是一个协议基本的内容都有了。

3. 下位机程序的sleep(1),这个是通讯之中常见的情况,数据传输和上位机处理需要一定的时间。

4. 演示的为RS232,以此类推,你也可以用到其他的场合。例如:简单修改,应用到HTTP通讯。

5. 硬件环境的建立,PHP环境的建立,不做任何答疑。

6. 欢迎探讨。

7. 感谢mikespook的意见,附加,如果是*nix,则:
'/dev/ttyS0'表示第一个COM端口,依此类推;端口的设置,应该在dio_open之后,使用:
dio_tcsetattr($fd, array(
  'baud' => 9600,
  'bits' => 8,
  'stop'  => 1,
  'parity' => 0
));
 mikespook回复于:2006-06-11 22:08:31

帮乔版补充一点~~
linux下com口读写采用文件的方式~比较简单~~所以dio这个ext只用于windows下~~


 HonestQiao回复于:2006-06-11 22:16:12

引用:原帖由 mikespook 于 2006-6-11 22:08 发表
帮乔版补充一点~~
linux下com口读写采用文件的方式~比较简单~~所以dio这个ext只用于windows下~~ 



注意,该模块完全适合在*nix下面使用。
为何:举一个例子:
dio_tcsetattr()这个函数是设置端口参数的,如果使用PHP文件读写,那么将不好设置了(虽然可以有方法设置)。


PHP supports the direct io functions as described in the Posix Standard (Section 6) for performing I/O functions at a lower level than the C-Language stream I/O functions (fopen(), fread(),..). The use of the DIO functions should be considered only when direct control of a device is needed. In all other cases, the standard filesystem functions are more than adequate.

[ 本帖最后由 HonestQiao 于 2006-6-11 22:18 编辑 ]


 mikespook回复于:2006-06-11 22:53:54

The use of the DIO functions should be considered only when direct control of a device is needed. In all other cases, the standard filesystem functions are more than adequate. 

我是这样理解这句话的~~
“DIO函数应当只用在有必要直接操作设备的时候。其他任何时候,标准的文件系统函数将更加适合。”
*nix下“一切皆文件”的思想,操作com亦可~~印象中WIN下的COM好像在WINNT家族中也是使用文件的方式访问~~

hCOM = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

这样独占访问好像也可以~~
----------------------
不过使用 dio 可以在不编写ext的情况下访问如加密狗,刷读卡设备等等~~


 james.liu回复于:2006-06-11 22:59:13

赫赫,,你以前用什么语言写工控


 mikespook回复于:2006-06-11 23:03:57

没写过工控程序,之前在单片机上做试验都用的是ASM和C~~
好像也有PASCAL的解释器,但是那个是试验箱带的东西~~

对于工控程序这种实时要求很高的程序来说,角本语言非常不适合做核心开发~~ASM和C有着绝对的话语权~~
如果哪天像JAVA CPU一样出现固化的PHP解释器,那就比较爽了~~呵呵~~


 HonestQiao回复于:2006-06-11 23:06:46

是啊,既然提供了这么好的东西,应该多用用。

使用文件的方式,适合与你的程序可能会接受多个封装操作端,但是进行想通的处理。

C++做的,主要是ARM的。

原文链接:http://bbs.chinaunix.net/viewthread.php?tid=771726
转载请注明作者名及原文出处
apache 如何设置禁止IP直接访问
Posted in LAMP on July 18, 2006 / 评论(0) »
apache虚拟主机默认情况下ip地址方式访问(http://xxx.xxx.xxx.xxx) 对应第一个虚拟主机,所以我们可以先建一个指向错误页面的虚拟主机,达到禁止用ip访问网页的目的。

  方法一:建一个虚拟主机,

  ServerName IPAddress (比如192.168.0.1)

  DocumentRoot /usr/local/apache/nosite/

  这样就可以了。

  在/usr/local/apache/nosite/下面建一个index.htm,提示用户,不允许IP访问。或其它出错信息。

  方法二:

  ServerName IPAddress (比如192.168.0.1)

  DocumentRoot /usr/local/apache/nosite/

  Order deny,allow

  Deny from all

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
http://www.chedong.com/tech/rotate_merge_log.html

关键词:webalizer apache log analysis  sort merge cronolog 日志 分析

内容摘要:你完全不必耐心地看完下面的所有内容,因为结论无非以下2点:
1 用  cronolog 干净,安全地轮循apache“日”志
2 用 sort -m 合并排序多个日志

根据个人的使用经历:
1  先介绍apache日志的合并方法;
2  然后根据由此引出的问题说明日志轮循的必要性和解决方法,介绍如何通过cronolog对apache日志进行轮循;
中间有很多在设计日志合并过程中一些相关工具的使用技巧和一些尝试的失败经历……
我相信解决以上问题的路径不止这一条途径,以下方案肯定不是最简便或者说成本最低的,希望能和大家有更多的交流。


多服务器日志合并统计的必要性

越来越多大型的WEB服务使用DNS轮循来实现负载均衡:使用多个同样角色的服务器做前台的WEB服务,这大大方便了服务的分布规划和扩展性,但多个服务器的分布使得日志的分析统计也变得有些麻烦。如果使用webalizer等日志分析工具对每台机器分别做日志统计:
1  会对数据的汇总带来很多麻烦,比如:统计的总访问量需要将SERVER1 SERVER2...上指定月份的数字相加。
2  会大大影响统计结果中唯一访客数unique visits,唯一站点数unique  sites的等指标的统计,因为这几个指标并非几台机器的代数相加。

统一日志统计所带来的好处是显而易见的,但如何把所有机器的统计合并到一个统计结果里呢?
首先也许会想:多个服务器能不能将日志记录到同一个远程文件里呢?我们不考虑使用远程文件系统记录日志的问题,因为带来的麻烦远比你获得的方便多的多……
因此,要统计的多个服务器的日志还是:分别记录=>并通过一定方式定期同步到后台=>合并=>后用日志分析工具来进行分析。

首先,要说明为什么要合并日志:因为webalizer没有将同一天的多个日志合并的功能
先后运行
webalizer  log1
webalizer log2
webalizer  log3
这样最后的结果是:只有log3的结果。

能不能将log1<<log2<<log3简单叠加呢?
因为一个日志的分析工具不是将日志一次全部读取后进行分析,而且流式的读取日志并按一定时间间隔,保存阶段性的统计结果。因此时间跨度过大(比如2条日志间隔超过5分钟),一些日志统计工具的算法就会将前面的结果“忘掉”。因此,  log1<<log2<<log3直接文件连接的统计结果还是:只有log3的统计结果。

多台服务日志合并问题:把多个日志中的记录按时间排序后合并成一个文件

典型的多个日志文件的时间字段是这样的:
log1 log2 log3
00:15:00 00:14:00  00:11:00
00:16:00 00:15:00 00:12:00
00:17:00 00:18:00 00:13:00
00:18:00  00:19:00 00:14:00
14:18:00 11:19:00 10:14:00
15:18:00 17:19:00  11:14:00
23:18:00 23:19:00  23:14:00

日志合并必须是按时间将多个日志的交叉合并。合并后的日志应该是:
00:15:00 来自log1
00:15:00  来自log2
00:16:00 来自log1
00:17:00 来自log3
00:18:00 来自log2
00:19:00  来自log1
....

如何合并多个日志文件?
下面以标准的clf格式日志(apache)为例:
apche的日志格式是这样的:
%h  %l %u %t \"%r\" %>s %b
具体的例子:
111.222.111.222 - - [03/Apr/2002:10:30:17  +0800] "GET /index.html HTTP/1.1" 200  419

最简单的想法是将日志一一读出来,然后按日志中的时间字段排序
cat log1 log2 log3 |sort -k 4 -t "  "
注释:
-t " ": 日志字段分割符号是空格
-k 4: 按第4个字段排序,也就是:[03/Apr/2002:10:30:17  +0800] 这个字段
-o log_all:  输出到log_all这个文件中

但这样的效率比较低,要知道。如果一个服务已经需要使用负载均衡,其服务的单机日志条数往往都超过了千万级,大小在几百M,这样要同时对多个几百M的日志进行排序,机器的负载可想而之……
其实有一个优化的途径,要知道:即使单个日志本身已经是一个“已经按照时间排好序“的文件了,而sort对于这种文件的排序合并提供了一个优化合并算法:使用  -m merge合并选项,
因此:合并这样格式的3个日志文件log1 log2 log3并输出到log_all中比较好方法是:
sort -m -t  " " -k 4 -o log_all log1 log2 log3
注释:
-m: 使用  merge优化算法

注意:合并后的日志输出最好压缩以后再发给webalizer处理
有的系统能处理2G的文件,有的不能。有的程序能处理大于2G的文件,有的不能。尽量避免大于2G的文件,除非确认所有参与处理的程序和操作系统都能处理这样的文件。所以输出后的文件如果大于2G,最好将日志gzip后再发给webalizer处理:大于2G的文件分析过程中文件系统出错的可能性比较大,并且gzip后也能大大降低分析期间的I/O操作。

日志的按时间排序合并就是这样实现的。

日志的轮循机制

让我们关心一下数据源问题:webalizer其实是一个按月统计的工具,支持增量统计:因此对于大型的服务,我可以按天将apache的日志合并后送给  webalizer统计。WEB日志是如何按天(比如每天子夜00:00:00)截断呢?
如果你每天使用crontab:每天0点准时将日志备份成access_log_yesterday
mv  /path/to/apache/log/access_log  /path/to/apache/log/access_log_yesterday
的话:你还需要:马上运行一下:apache restart  否则:apache会因为的日志文件句柄丢失不知道将日志记录到哪里去了。这样归档每天子夜重启apache服务会受到影响。
比较简便不影响服务的方法是:先复制,后清空
cp  /path/to/apache/log/access_log /path/to/apache/log/access_log_yesterday
echo  >/path/to/apache/log/access_log

严肃的分析员会这样做发现一个问题:
但cp不可能严格保证严格的0点截断。加入复制过程用了6秒,截断的access_log_yesterday日志中会出现复制过程到00:00:06期间的日志。对于单个日志统计这些每天多出来几百行日志是没有问题的。但对于多个日志在跨月的1天会有一个合并的排序问题:
[31/Mar/2002:59:59:59  +0800]
[31/Mar/2002:23:59:59 +0800]
[01/Apr/2002:00:00:00  +0800]
[01/Apr/2002:00:00:00 +0800]

要知道[01/Apr/2002:00:00:00  这个字段是不可以进行“跨天排序”的。因为日期中使用了dd/mm/yyyy,月份还是英文名,如果按照字母排序,很有可能是这样的结果:排序导致了日志的错误
[01/Apr/2002:00:00:00  +0800]
[01/Apr/2002:00:00:00 +0800]
[01/Apr/2002:00:00:00  +0800]
[01/Apr/2002:00:00:00 +0800]
[01/Apr/2002:00:00:00  +0800]
[01/Apr/2002:00:00:00 +0800]
[01/Apr/2002:00:00:00  +0800]
[31/Mar/2002:59:59:59 +0800]
[31/Mar/2002:59:59:59  +0800]
[31/Mar/2002:23:59:59 +0800]
[31/Mar/2002:59:59:59  +0800]
[31/Mar/2002:23:59:59  +0800]

这些跨天过程中的非正常数据对于webalizer等分析工具来说简直就好像是吃了一个臭虫一样,运行的结果是:它可能会把前一个月所有的数据都丢失!因此这样的数据会有很多风险出现在处理上月最后一天的数据的过程中。

问题的解决有几个思路:
1  事后处理:
。所以一个事后的处理的方法是:用grep命令在每月第1天将日志跨月的日志去掉,比如:
grep -v "01/Apr"  access_log_04_01 >  access_log_new

修改SORT后的日志:所有跨天的数据去掉。也许对日志的事后处理是一个途径,虽然sort命令中有对日期排序的特殊选项  -M(注意是:大写M),可以让指定字段按照英文月份排序而非字母顺序,但对于apache日志来说,用SORT命令切分出月份字段很麻烦。(我尝试过用  "/"做分割符,并且使用“月份”  “年:时间”这两个字段排序)。虽然用一些PERL的脚本肯定可以实现,但最终我还是放弃了。这不符合系统管理员的设计原则:通用性。并且你需要一直问自己:有没有更简单的方法呢?
还有就是将日志格式改成用TIMESTAMP(象SQUID的日志就没有这个问题,它的日志本身就是使用TIMESTAMP做时间时间戳的),但我无法保证所有的日志工具都能识别你在日期这个字段使用了特别的格式。

2  优化数据源:
最好的办法还是优化数据源。将数据源保证按天轮循,同一天的日志中的数据都在同一天内。这样以后你无论使用什么工具(商业的,免费的)来分析日志,都不会因为日志复杂的预处理机制受到影响。

首先可能会想到的是控制截取日志的时间:比如严格从0点开始截取日志,但在子夜前1分钟还是后一分钟开始截取是没有区别的,你仍然无法控制一个日志中有跨  2天记录的问题,而且你也无法预测日志归档过程使用的时间。
因此必须要好好考虑一下使用日志轮循工具的问题,这些日志轮循工具要符合:
1  不中断WEB服务:不能停apache=>移动日志=>重启apache
2  保证同一天日志能够按天轮循:每天一个日志00:00:00-23:59:59
3  不受apache重启的影响:如果apache每次重启都会生成一个新的日志是不符合要求的
4  安装配置简单

首先考虑了apache/bin目录下自带的一个轮循工具:rotatelogs  这个工具基本是用来按时间或按大小控制日志的,无法控制何时截断和如何按天归档。
然后考虑logrotate后台服务:logrotate是一个专门对各种系统日志(syslogd,mail)进行轮循的后台服务,比如SYSTEM  LOG,但其配置比较复杂,放弃,实际上它也是对相应服务进程发出一个-HUP重启命令来实现日志的截断归档的。

在apache的FAQ中,推荐了经过近2年发展已经比较成熟的一个工具cronolog:安装很简单:configure=>make=>  make  install

他的一个配置的例子会让你了解它有多么适合日志按天轮循:对httpd.conf做一个很小的修改就能实现:
TransferLog  "|/usr/sbin/cronolog /web/logs/%Y/%m/%d/access.log"
ErrorLog  "|/usr/sbin/cronolog  /web/logs/%Y/%m/%d/errors.log"

然后:日志将写入
/web/logs/2002/12/31/access.log
/web/logs/2002/12/31/errors.log
午夜过后:日志将写入
/web/logs/2003/01/01/access.log
/web/logs/2003/01/01/errors.log
而2003  2003/01 和 2003/01/01  如果不存在的话,将自动创建

所以,只要你不在0点调整系统时间之类的话,日志应该是完全按天存放的(00:00:00-23:59:59),后面日志分析中:  [31/Mar/2002:15:44:59这个字段就和日期无关了,只和时间有关。

测试:考虑到系统硬盘容量,决定按星期轮循日志
apache配置中加入:
#%w  weekday
TransferLog "|/usr/sbin/cronolog  /path/to/apache/logs/%w/access_log"

重启apache后,除了原来的CustomLog  /path/to/apche/logs/access_log继续增长外,系统log目录下新建立了  3/目录(测试是在周3),过了一会儿,我忽然发现2个日志的增长速度居然不一样!
分别tail了2个日志才发现:
我设置CustomLog使用的是combined格式,就是包含(扩展信息的),而TransferLog使用的是缺省日志格式,看了apache的手册才知道,TransferLog是用配置文件中离它自己最近的一个格式作为日志格式的。我的httpd.conf里写的是:
LogFormat  ..... combined
LogFormat ... common
...
CustomLog ...  combined
TransferLog  ...

所以TrasferLog日志用的是缺省格式,手册里说要让TRANSFER日志使用指定的格式需要:
LogFormat "%h %l  %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
TransferLog  "|/usr/local/sbin/cronolog  /path/to/apache/logs/%w/access_log"

重启,OK,日志格式一样了。
这样的设置结果其实是同时在logs目录下分别记录2个日志access_log和%w/access_log,能不能只记录%w/下的日志那?
查apache手册,更简单的方法:直接让CustomLog输出到cronolog归档日志,并且还能指定格式。
CustomLog  "|/usr/local/sbin/cronolog /path/to/apache/logs/%w/access_log"  combined

最后是一个日志同步的问题。

任务:每天凌晨找到前1天的日志,另存一个文件准备发送到服务器上。
比如我要保留前1周的日志:每天复制前1天的日志到指定目录,等待日志服务器来抓取:
/bin/cp  -f /path/to/apache/logs/`date -v-1d +%w`/access_log  /path/for/backup/logs/access_log_yesterday

在FREEBSD上使用以下命令
date -v-1d  +%w
注释:
-v-1d: 前1天,而在GNU/Linux上这个选项应该是date -d yesterday
+%w:  weekday,由于使用的都是标准时间函数库,所有工具中的WEEKDAY定义都是一样的 0-6 =>  周日-周六

注意:
写到CRONTAB里的时候"%"前面需要加一个"\"转义:每天0点5分进行一次日志归档,
另外一个问题就是在cront中需要用:rm  -f {} ; 而不是rm -f {}\;
5 0 * * * /bin/cp /path/to/logs/`date -v-1d  +\%w`/access_log /path/to/for_sync/logs/access_yesterday
37 10 * * *  /usr/bin/find /home/apache/logs/ -name access_log -mtime +1 -exec /bin/rm -f {}  ;

首次开始cronolog日志统计是周3,一周以后日志又将轮循回3/access_log
但这次日志是追加到3/access_log还是重新创建一个文件呢?>>access_log  or >access_log?
我测试的结果是日志将被追加:
[01/Apr/2002:23:59:59  +0800]
[01/Apr/2002:23:59:59 +0800]
[08/Apr/2002:00:00:00  +0800]
[08/Apr/2002:00:00:00  +0800]

肯定是不希望每次日志还带着上周的数据的并重复统计一次的(虽然对结果没影响),而且这样%w/下的日志不是也越来越多了吗?
解决方法1  把每天的cp改成mv
解决方法2 每天复制完成后:删除6天以前的access_log日志
find /path/to/apache/logs  -name access_log -mtime +6 -exec rm -f  {}\;
多保留几天的日志还是有必要的:万一日志分析服务器坏了一天呢?

以下是把apache安装在/home/apache下每天统计的一个脚本文件:
#!/bin/sh

#backup old  log
/bin/cp -f /home/apache/logs/`date -d yesterday +%w`/access_log  /home/apache/logs/access_log_yesterday

#remove old log
/usr/bin/find  /home/apache/logs -name access_log -mtime +6 -exec rm -f {}\;

#analysis  with webalizer
/usr/local/sbin/webalizer

总结:
1 用 cronolog  干净,安全地轮循日志
2 用 sort -m 排序合并多个日志


参考资料:

日志分析统计工具:
http://directory.google.com/Top/Computers/Software/Internet/Site_Management/Log_Analysis/

Apche的日志设置:
http://httpd.apache.org/docs/mod/mod_log_config.html

Apache的日志轮循:
http://httpd.apache.org/docs/misc/FAQ.html#rotate

Cronolog
http://www.cronolog.org

Webalizer
http://www.mrunix.net/webalizer/
Webalzer的Windows版
http://www.medasys-lille.com/webalizer/

AWStats的使用简介
http://www.chedong.com/tech/awstats.html

附1:Webalizer配置文件说明:重要的地方做了翻译并附有一些重要的配置修改

#
# Webalizer 样例配置文件
# Copyright 1997-2000 by Bradford L. Barrett  (brad@mrunix.net)
# 翻译: 车东 (chedong@bigfoot.com)
#
# Distributed under  the GNU General Public License.  See the
# files "Copyright" and "COPYING"  provided with the webalizer
# distribution for additional  information.
#
# 这是一个Webalizer (版本 2.01)的配置文件样例
#  所有以'#'开始的行都是被程序忽略的注释,此外空白行也会被跳过,其他行都是具体的配置选项。
# 并按照"ConfigOption   Value"的格式,ConfigOption是合法的配置选项关键词,而Value是相应选项对应的值
#  非法的键/值会被忽略并会有相应的警告提示。关键词和值之间至少需要一个空格或制表符tab分割
#
#  从0.98版本开始,Webalizer会找缺省在当前目录下找一个名为webalizer.conf缺省配置文件
#  如果没有找到,会使用/etc/webalizer.conf


# LogFile  定义了WEB服务的日志文件,如果这里没有定义,并且命令行参数也没有指定文件名,
# 则将STDIN(系统标准输入)作为输入数据源
#  如果日志文件扩展名为'.gz' (是一个gzip压缩文件),程序会一边读取一边进行解压缩。

LogFile         /home/apache/log/access_log_yesterday

# LogType  定义了日志的类型,Webalizer一般用于CLF和Combined格式的WEB服务日志格式
指定这个选项,你可以处理FTP日志(比如wu-ftp生成的xferlog,和Squid自己的日志
值可以是:'clf',  'ftp' 或'squid', 缺省是'clf'
# JNH :  新的'iis'是为IIS设计的,IIS4缺省使用标准日志格式,IIS5缺省使用W3C格式
#  webalizer会自动根据日志的文件名进行识别:标准格式的日志文件名以I开头,W3C的是E
#  你可以在一个目录下同时存放2种日志,webalizer会全部读取并生成一份报告

LogType    iis

# OutputDir  报告的输出目录地址,必须是完整的全路径名,但相对路径也许也行,
# 如果没有指定,输出目录就是当前目录。

OutputDir       /home/apache/htdocs/usage/

# HistoryName  允许你设置webalizer生成的历史数据文件名
#  历史数据文件保存了12个月内的数据,这些数据会用来生成首页的HTML页面index.html
#  缺省文件名是:"webalizer.hist",缺省存放在指定的输出目录中, 也可以使用绝对路径指定到其他目录中。

#HistoryName     webalizer.hist

# Incremental  增量处理允许你处理被分隔成多个小文件的大日志,对于大型站点的按周,按天的日志轮循会非常有用
#  为了继续上次的处理,Webalizer在退出前会保存当时处理的数据并在下次运行是恢复当时的状态
在这个模式下,Webalizer会扫描并忽略重复的记录,请看README文件,里面有更详细的解说
值可以是:'yes'或'no'缺省为'no'.
#  'webalizer.current'这个文件用来保存当前数据,位置在OutputDir设置的输出目录中
#  启用这个选项前,请至少阅读一下README文件中的增量处理一节

Incremental    yes

# IncrementalName  允许你设置保存当前数据的文件名,和HistoryName选项一样,除非设置绝对路径,否则文件就在缺省输出目录中,
#  这个选项只有在启用了Incremental模式后才有意义

#IncrementalName     webalizer.current

# ReportTitle是标题文字,除非这个字符串是空的,否则主机名会空一格后显示在后面,
#  缺省是英文:"Usage Statistics for".

#ReportTitle    Usage Statistics  for

# HostName 定义了报告对应的主机名,用在报告的标题和URL统计里,这样
#  即使在一个虚拟主机的统计中,点击URL统计的链接也可以转向相应的正确地址。
# 或者生成报告的服务器是在另外一台机器,clicking on URL's  in the report to go to the proper location in
# the event you are running the  report on a 'virtual' web server,
# or for a server different than the one  the report resides on.
#  如果这里没有指定webalizer会尝试调用uname命令获得系统的主机名,如果失败缺省为"localhost"

HostName        www.chedong.com

# HTMLExtension  允许你设置生成报告的文件扩展名,一般缺省是"html",但你也可以根据站点改成你需要的名字
(像配置PHP一样 embeded  pages)?

#HTMLExtension  html

# PageType  你告诉Webalizer那种类型的URL是你定义的'页面访问'(Page View).  大部分人认为一个html或cgi请求文档是页面,
#  而嵌入在页面中的图片和声音不算,如果没有指定,如果是WEB日志统计,页面的扩展名就是'htm*'和'cgi',
# 如果是ftp日志,扩展名就是'txt'  对于Servlet这样没有扩展名的请求Webalizer也是算页面的。

PageType    htm*
PageType     cgi
PageType    asp
PageType    p*
#PageType    phtml
#PageType     php3
#PageType    pl

# UseHTTPS  如果分析的站点使用安全服务器,URL的链接将是以'https://'开头,而不是缺省的'http://'.
如果需要,把它设置成'yes'。缺省是'no'.   这个配置只影响'Top URL's'里的链接.

#UseHTTPS       no

# DNSCache  指定了用于反相DNS解析的DNS缓存文件,如果你希望对所有日志中所有的IP地址进行反相域名解析
# addresses found in the log  file.  如果没有指定绝对路径(文件名不是以'/'开头),这个文件缺省就在输出目录下
更多详细说明请参考DNS.README
# JNH :  如果你使用ListServer选项,你必须指定DnsCache的全路径

#DNSCache    dns_cache.db

#  DNSChildren 允许你设置用多少个"子"进程进行DNS解析和更新DNS缓存文件。
#  如果指定了数字,Webalizer会创建DNS缓存文件并且每次运行都会更新,DNS解析会在
日志分析之前根据指定的数值调起子进程进行。如果使用DNS解析,DNS缓存文件名也必须指定。
#  DNS lookups.  If used, the DNS cache filename MUST be specified as
# well.   缺省值是0,等于禁用DNS缓存文件,子进程的个数可以是用1  到100之间,如果更大会影响系统运行。
比较合理的值是5到20之间,更多详细信息请参考DNS.README

#DNSChildren     0

# HTMLPre 定义了输出页面中最开头的HTML代码,缺省是以下的DOCTYPE声明
#  每行最长是80个字符,如果需要更多代码可以使用多条配置。

#HTMLPre <!DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.0 Transitional//EN">

# HTMLHead  定义了插入到<HEAD></HEAD>中间,紧接在<TITLE>行后的HTML代码
#  每行最长是80个字符,如果需要更多代码可以使用多条配置。

#HTMLHead <META NAME="author"  CONTENT="The Webalizer">

# HTMLBody  定义了第一行<BODY>标签的HTML代码,缺省如下:
#  每行最长是80个字符,如果需要更多代码可以使用多条配置。


#HTMLBody <BODY BGCOLOR="#E8E8E8"  TEXT="#000000" LINK="#0000FF" VLINK="#FF0000">

# HTMLPost  定义了输出页面中紧跟在第个<HR>标签后面紧跟在标题
# 和"summary period"-"Generated  on:"这几行后面的代码。
# As with HTMLHead, you can define as many of these as you want  and
# they will be inserted in the output stream in order of apperance.
#  每行最长是80个字符,如果需要更多代码可以使用多条配置。

#HTMLPost     <BR  CLEAR="all">

# HTMLTail defines the HTML code to insert at the bottom  of each
# HTML document, usually to include a link back to your home
#  page or insert a small graphic.  It is inserted as a table
# data element  (ie: <TD> your code here </TD>) and is right
# alligned with the  page.  Max string size is 80 characters.

#HTMLTail <IMG  xsrc="msfree.png" ALT="100% Micro$oft free!">

# HTMLEnd defines the  HTML code to add at the very end of the
# generated files.  It defaults to  what is shown below.  If
# used, you MUST specify the </BODY> and  </HTML> closing tags
# as the last lines.  Max string length is 80  characters.

#HTMLEnd </BODY></HTML>

# The Quiet option  suppresses output messages... Useful when run
# as a cron job to prevent  bogus e-mails.  Values can be either
# "yes" or "no".  Default is "no".   Note: this does not suppress
# warnings and errors (which are printed to  stderr).

#Quiet        no

# ReallyQuiet will supress all messages  including errors and
# warnings.  Values can be 'yes' or 'no' with 'no' being  the
# default.  If 'yes' is used here, it cannot be overriden from
# the  command line, so use with caution.  A value of 'no' has
# no  effect.

#ReallyQuiet    no

# TimeMe allows you to force the  display of timing information
# at the end of processing.  A value of 'yes'  will force the
# timing information to be displayed.  A value of 'no' has  no
# effect.

#TimeMe        no

# GMTTime allows reports to show  GMT (UTC) time instead of local
# time.  Default is to display the time the  report was generated
# in the timezone of the local machine, such as EDT or  PST.  This
# keyword allows you to have times displayed in UTC instead.   Use
# only if you really have a good reason, since it will probably
#  screw up the reporting periods by however many hours your local
# time zone  is off of GMT.

#GMTTime        no

# Debug prints additional  information for error messages.  This
# will cause webalizer to dump bad  records/fields instead of just
# telling you it found a bad one.   As usual,  the value can be
# either "yes" or "no".  The default is "no".  It shouldn't  be
# needed unless you start getting a lot of Warning or Error
# messages  and want to see why.  (Note: warning and error messages
# are printed to  stderr, not stdout like normal messages).

#Debug        no

#  FoldSeqErr forces the Webalizer to ignore sequence errors.
# This is useful  for Netscape and other web servers that cache
# the writing of log records  and do not guarentee that they
# will be in chronological order.  The use of  the FoldSeqErr
# option will cause out of sequence log records to be  treated
# as if they had the same time stamp as the last valid record.
#  Default is to ignore out of sequence log records.

#FoldSeqErr     no

# VisitTimeout 用来定义一个访客回话的超时时间,缺省为30分钟。
#  Visits是根据访客发出请求的时间和来自这个访客所在站点(IP)的最后访问时间决定的,
#  如果2者时间间隔超过VisitTimeout的值,这个请求就被认为是一个新的访客,访客数也被加1
#  值为超时的秒数(缺省为=1800秒=30分钟)

#VisitTimeout    1800

# IgnoreHist  shouldn't be used in a config file, but it is here
# just because it might be  usefull in certain situations.  If the
# history file is ignored, the main  "index.html" file will only
# report on the current log files contents.   Usefull only when you
# want to reproduce the reports from scratch.  USE WITH  CAUTION!
# Valid values are "yes" or "no".  Default is  "no".

#IgnoreHist    no

# Country Graph allows the usage by  country graph to be disabled.
# Values can be 'yes' or 'no', default is  'yes'.

#CountryGraph    yes

# DailyGraph and DailyStats allows the  daily statistics graph
# and statistics table to be disabled (not  displayed).  Values
# may be "yes" or "no". Default is  "yes".

#DailyGraph    yes
#DailyStats    yes

# HourlyGraph and  HourlyStats allows the hourly statistics graph
# and statistics table to be  disabled (not displayed).  Values
# may be "yes" or "no". Default is  "yes".

#HourlyGraph    yes
#HourlyStats    yes

# GraphLegend  allows the color coded legends to be turned on or off
# in the graphs.  The  default is for them to be displayed.  This only
# toggles the color coded  legends, the other legends are not changed.
# If you think they are hideous  and ugly, say 'no' here :)

#GraphLegend    yes

# GraphLines allows  you to have index lines drawn behind the graphs.
# I personally am not crazy  about them, but a lot of people requested
# them and they weren't a big deal  to add.  The number represents the
# number of lines you want displayed.   Default is 2, you can disable
# the lines by using a value of zero ('0').   [max is 20]
# Note, due to rounding errors, some values don't work quite  right.
# The lower the better, with 1,2,3,4,6 and 10 producing nice  results.

#GraphLines    2

# The "Top" options below define the  number of entries for each table.
# Defaults are Sites=30, URL's=30,  Referrers=30 and Agents=15, and
# Countries=30. TopKSites and TopKURLs (by  KByte tables) both default
# to 10, as do the top entry/exit tables  (TopEntry/TopExit).  The top
# search strings and usernames default to 20.   Tables may be disabled
# by using zero (0) for the  value.

#TopSites        30
#TopKSites       10
#TopURLs          30
#TopKURLs        10
#TopReferrers    30
#TopAgents        15
#TopCountries    30
#TopEntry        10
#TopExit          10
#TopSearch       20
#TopUsers        20

# All*  关键词允许显示所有的URL,独立站点(IP),引用链接(Referrers)
# 用户浏览器,  搜索关键词和用户名,如果启用,会生成另外一个HTML页面并有链接
#  加在相应栏目的下面,注意以下2点,这些统计必然比TOP统计要大的多,第2,这些对外都是可见的
#  值可以是yes或no,缺省都是no,对于一个公开发布的站点,这些按月生成的统计
#  会非常大。会需要很多磁盘空间,如果访问很多也会带来很多流量。
 
#AllSites    no
AllURLs             yes
#AllReferrers    no
#AllAgents    no
AllSearchStr     yes
#AllUsers       no

# The Webalizer normally strips the  string 'index.' off the end of
# URL's in order to consolidate URL totals.   For example, the URL
# /somedir/index.html is turned into /somedir/ which is  really the
# same URL.  This option allows you to specify additional  strings
# to treat in the same way.  You don't need to specify 'index.'  as
# it is always scanned for by The Webalizer, this option is just to
#  specify _additional_ strings if needed.  If you don't need any,
# don't  specify any as each string will be scanned for in EVERY
# log record... A  bunch f them will degrade performance.  Also,
# the string is scanned for  anywhere in the URL, so a string of
# 'home' would turn the URL  /somedir/homepages/brad/home.html into
# just /somedir/ which is probably not  what was intended.

#IndexAlias     home.htm
#IndexAlias     homepage.htm

# The Hide*, Group* and Ignore* and Include* keywords allow  you to
# change the way Sites, URL's, Referrers, User Agents and  Usernames
# are manipulated.  The Ignore* keywords will cause The Webalizer  to
# completely ignore records as if they didn't exist (and thus not
#  counted in the main site totals).  The Hide* keywords will prevent
# things  from being displayed in the 'Top' tables, but will still be
# counted in the  main totals.  The Group* keywords allow grouping
# similar objects as if they  were one.  Grouped records are displayed
# in the 'Top' tables and can  optionally be displayed in BOLD and/or
# shaded. Groups cannot be hidden, and  are not counted in the main
# totals. The Group* options do not, by default,  hide all the items
# that it matches.  If you want to hide the records that  match (so just
# the grouping record is displayed), follow with an identical  Hide*
# keyword with the same value.  (see example below)  In addition,
#  Group* keywords may have an optional label which will be displayed
# instead  of the keywords value.  The label should be seperated from
# the value by at  least one 'white-space' character, such as a space
# or tab.
#
# The  value can have either a leading or trailing '*' wildcard
# character.  If no  wildcard is found, a match can occur anywhere
# in the string. Given a string  "www.yourmama.com", the values "your",
# "*mama.com" and "www.your*" will all  match.
# Your own site should be hidden

#HideSite     *mrunix.net
#HideSite    localhost

# Your own site gives most  referrals
#HideReferrer    mrunix.net/

# This one hides non-referrers  ("-" Direct requests)
#HideReferrer    Direct Request

# Usually you  want to hide these
HideURL        *.gif
HideURL        *.GIF
HideURL         *.jpg
HideURL        *.JPG
HideURL        *.png
HideURL         *.PNG
HideURL        *.ra
HideURL         *.css

# Hiding agents is kind of  futile
#HideAgent    RealPlayer

# You can also hide based on  authenticated username
#HideUser    root
#HideUser    admin

#  Grouping options
#GroupURL    /cgi-bin/*    CGI Scripts
#GroupURL     /images/*    Images
#GroupSite    *.aol.com
#GroupSite     *.compuserve.com
#GroupReferrer    yahoo.com/    Yahoo!
#GroupReferrer     excite.com/     Excite
#GroupReferrer    infoseek.com/    InfoSeek
#GroupReferrer    webcrawler.com/ WebCrawler

#GroupUser       root            Admin users
#GroupUser      admin           Admin  users
#GroupUser      wheel           Admin users

# The following is a  great way to get an overall total
# for browsers, and not display all the  detail records.
# (You should use MangleAgent to refine  further...)

#GroupAgent    MSIE        Micro$oft Internet  Exploder
#HideAgent    MSIE
#GroupAgent    Mozilla         Netscape
#HideAgent    Mozilla
#GroupAgent    Lynx*         Lynx
#HideAgent    Lynx*

# HideAllSites allows forcing individual  sites to be hidden in the
# report.  This is particularly useful when used in  conjunction
# with the "GroupDomain" feature, but could be useful in  other
# situations as well, such as when you only want to display  grouped
# sites (with the GroupSite keywords...).  The value for this
#  keyword can be either 'yes' or 'no', with 'no' the default,
# allowing  individual sites to be displayed.

#HideAllSites    no

# The  GroupDomains keyword allows you to group individual hostnames
# into their  respective domains.  The value specifies the level of
# grouping to perform,  and can be thought of as 'the number of dots'
# that will be displayed.  For  example, if a visiting host is named
# cust1.tnt.mia.uu.net, a domain  grouping of 1 will result in just
# "uu.net" being displayed, while a 2 will  result in "mia.uu.net".
# The default value of zero disable this feature.   Domains will only
# be grouped if they do not match any existing "GroupSite"  records,
# which allows overriding this feature with your own if  desired.

#GroupDomains    0

# The GroupShading allows grouped rows  to be shaded in the report.
# Useful if you have lots of groups and  individual records that
# intermingle in the report, and you want to  diferentiate the group
# records a little more.  Value can be 'yes' or 'no',  with 'yes'
# being the default.

#GroupShading    yes

#  GroupHighlight allows the group record to be displayed in BOLD.
# Can be  either 'yes' or 'no' with the default 'yes'.

#GroupHighlight     yes

# The Ignore* keywords allow you to completely ignore log records  based
# on hostname, URL, user agent, referrer or username.  I hessitated  in
# adding these, since the Webalizer was designed to generate  _accurate_
# statistics about a web servers performance.  By choosing to  ignore
# records, the accuracy of reports become skewed, negating why I  wrote
# this program in the first place.  However, due to popular demand,  here
# they are.  Use the same as the Hide* keywords, where the value can  have
# a leading or trailing wildcard '*'.  Use at your own risk  ;)

#IgnoreSite    bad.site.net
#IgnoreURL     /test*
#IgnoreReferrer    file:/*
#IgnoreAgent     RealPlayer
#IgnoreUser     root

# The Include* keywords allow you to  force the inclusion of log records
# based on hostname, URL, user agent,  referrer or username.  They take
# precidence over the Ignore* keywords.   Note: Using Ignore/Include
# combinations to selectivly process parts of a  web site is _extremely
# inefficent_!!! Avoid doing so if possible (ie: grep  the records to a
# seperate file if you really want that kind of  report).

# Example: Only show stats on Joe User's  pages...
#IgnoreURL    *
#IncludeURL    ~joeuser*

# Or based on an  authenticated username
#IgnoreUser     *
#IncludeUser    someuser

#  The MangleAgents allows you to specify how much, if any, The Webalizer
#  should mangle user agent names.  This allows several levels of detail
# to be  produced when reporting user agent statistics.  There are six
# levels that  can be specified, which define different levels of detail
# supression.   Level 5 shows only the browser name (MSIE or Mozilla)
# and the major version  number.  Level 4 adds the minor version number
# (single decimal place).   Level 3 displays the minor version to two
# decimal places.  Level 2 will add  any sub-level designation (such
# as Mozilla/3.01Gold or MSIE 3.0b).  Level 1  will attempt to also add
# the system type if it is specified.  The default  Level 0 displays the
# full user agent field without modification and  produces the greatest
# amount of detail.  User agent names that can't be  mangled will be
# left unmodified.

#MangleAgents    0

#  搜索引擎关键词允许你设置搜索引擎和URL中的查询格式,用于统计用户通过那些关键词
#  被用来找到你的站点。第1个关键词是从WEB日志中的referrer字段识别搜索引擎,第2个是
#  URL中的关键词的参数名。

SearchEngine    yahoo.com    p=
SearchEngine     altavista.com    q=
SearchEngine    google.com    q=
SearchEngine     eureka.com    q=
SearchEngine    lycos.com    query=
SearchEngine     hotbot.com    MT=
SearchEngine    msn.com        MT=
SearchEngine     infoseek.com    qt=
SearchEngine    webcrawler     searchText=
SearchEngine    excite        search=
SearchEngine     netscape.com    search=
SearchEngine    mamma.com     query=
SearchEngine    alltheweb.com    query=
SearchEngine     northernlight.com  qr=
SearchEngine    baidu.com   word=
SearchEngine    sina.com.cn word=
SearchEngine    sohu.com    word=
SearchEngine    163.com q=



# Dump*  用来将统计导出成用制表符(TAB)分割的文本文件,从而方便导入到其他应用中做统计。
# 比如数据库和统计软件

# DumpPath  specifies the path to dump the files.  If not specified,
# it will default to  the current output directory.  Do not use a
# trailing slash  ('/').

#DumpPath    /var/lib/httpd/logs

# The DumpHeader keyword  specifies if a header record should be
# written to the file.  A header  record is the first record of the
# file, and contains the labels for each  field written.  Normally,
# files that are intended to be imported into a  database system
# will not need a header record, while spreadsheets usually  do.
# Value can be either 'yes' or 'no', with 'no' being the  default.

#DumpHeader    no

# DumpExtension allow you to specify  the dump filename extension
# to use.  The default is "tab", but some  programs are pickey about
# the filenames they use, so you may change it here  (for example,
# some people may prefer to use  "csv").

#DumpExtension    tab

# 控制各个大类统计的导出。
# 值可以是'yes'或  'no'缺省为'no'.

#DumpSites    no
DumpURLs    yes
DumpReferrers    yes
#DumpAgents     no
#DumpUsers    no
DumpSearchStr   yes

# End of configuration file...   Have a nice day!

# begin of JNH mofications
# new entry for Win32  release

# NOUVELLE ENTREE pour les serveurs NT

# nom de la page  par defaut sur le serveur
# replace file "Index" for unix systems by other  name

# IndexPage default

# 所有的日志存放目录
#  文件个数限制为一个目录下250,如果需要处理更多你需要移动文件并再次运行。

# FolderLog        C:\JnhDev\WebAlizer32\Exemple de Logs\IIS4.0\Log Standard\
FolderLog  C:\WINNT\system32\LogFiles\W3SVC3\
ExtentionLog log

# when you  use mix type of log in same folder, webalizer sort file for order by
# name,  but if begin of file file is mix sort didn't make work, then you can disable  it
# default is no

# DisableSort yes


# Name of file contain  list of server to process like for each line :
# Name of  Customer<SPACE>Folder of log<SPACE>Folder output<SPACE>Host  Name1;Host Name 2
# sample (extract of production file, who have 255  lines)
# all of option in this file apply to all reports ...
# New in this  file you can use coma (") for delimit field
# wA001 c:\WA001\LogIIS\  c:\wA001\stats wa001.LeRelaisInternet.com;www1.jeanlouisaubert.com
# wA002  c:\WA002\LogIIS\ c:\wA002\stats  wa002.LeRelaisInternet.com;www.restotel.fr;www.nordpage.fr
# wA003  c:\WA003\LogIIS\ c:\wA003\stats  Wa003.LeRelaisInternet.com;www.autobusavapeur.com

#ServerList  c:\jnhdev\webalizer\listeserv.txt

# If you have dayly rotation on log  name, you can change name after process a file
# to have less no productive  work day
# to use this option you need to use "HistoryName" and  "Incremental"

RenameLog  yes
NewExtension sav


# 2 New Options for optimize  DNS resolution : is time to live in data base cache
# for good dns resolution  (default is 30 days) and for bad resolution, like
# no reverse IP, in this  case it's better to store errors in database file
# cause each day bad dns  consume a lot of time (default 7 days)

#TtlDns          30
#TtlDnsError    7

# new option for convert each record date to  Local time before process it ...
# Test only
# default =  No

ConvertTime yes


# end of JNH .. HAve a nice day  !!!

注意:对IIS日志需要通过配置将发送字节数sc_size和referer2个字段启用。


原文出处:<a  xhref="http://www.chedong.com/tech/rotate_merge_log.html">http://www.chedong.com/tech/rotate_merge_log.html</a>

PHP.INI中译版
Posted in LAMP on July 13, 2006 / 评论(0) »
[PHP]

;;;;;;;;;;;;;;;;;;;
; 关于这个文件 ;
;;;;;;;;;;;;;;;;;;;

;  这个文件控制了PHP许多方面的观点。为了让PHP读取这个文件,它必须被命名为
;  'php.ini'。PHP 将在这些地方依次查找该文件:当前工作目录;环境变量PHPRC
; 指明的路径;编译时指定的路径。
;  在windows下,编译时的路径是Windows安装目录。
; 在命令行模式下,php.ini的查找路径可以用 -c 参数替代。

;  该文件的语法非常简单。空白字符和用分号';'开始的行被简单地忽略(就象你可能
; 猜到的一样)。 章节标题(例如 :  [Foo])也被简单地忽略,即使将来它们可能
; 有某种的意义。
;
; 指示被指定使用如下语法:
; 指示标识符 = 值
;  directive = value
; 指示标识符 是 *大小写敏感的* - foo=bar 不同于 FOO = bar。
;
;  值可以是一个字符串,一个数字,一个 PHP 常量 (如: E_ALL or M_PI), INI 常量中的
; 一个 (On, Off, True,  False, Yes, No and None) ,或是一个表达式
; (如: E_ALL & ~E_NOTICE),  或是用引号括起来的字符串("foo").
;
; INI 文件的表达式被限制于位运算符和括号。
; | bitwise OR
;  & bitwise AND
; ~ bitwise NOT
; ! boolean NOT
;
; 布尔标志可用 1, On,  True or Yes 这些值置于开的状态。
; 它们可用 0, Off, False or No 这些值置于关的状态。
;
;  一个空字符串可以用在等号后不写任何东西表示,或者用 None 关键字:
;
; foo = ; 将foo置为空字符串
; foo = none  ; 将foo置为空字符串
; foo = "none" ; 将foo置为字符串'none'
;
;  如果你值设置中使用常量,而这些常量属于动态调入的扩展库(不是 PHP 的扩展,就是
; Zend  的扩展),你仅可以调入这些扩展的行*之后*使用这些常量。
;
; 所有在 php.ini-dist 文件里设定的值与内建的默认值相同(这是说,如果  php.ini 
; 没被使用或者你删掉了这些行,默认值与之相同)。


;;;;;;;;;;;;;;;;;;;;
; 语言选项  ;
;;;;;;;;;;;;;;;;;;;;

engine = On 
; 使 PHP scripting language  engine(PHP 脚本语言引擎)在 Apache下有效。
short_open_tag = On 
; 允许 <?  标识(这种简单表示)。否则 仅有 <?php and <script> tags 将被识别。
asp_tags = Off 
;  允许ASP-style <% %> tags
precision = 14 
;  浮点类型数显示时的有效位数

y2k_compliance = Off 
; 是否打开 2000年适应  (可能在非Y2K适应的浏览器中导致问题)

output_buffering = Off 
; 输出缓存允许你甚至在输出正文内容之后发送  header(标头,包括cookies)行
; 其代价是输出层减慢一点点速度。你可以使用输出缓存在运行时打开输出缓存,
; 或者在这里将指示设为  On 而使得所有文件的输出缓存打开。

implicit_flush = Off 
; 强制flush(刷新)让PHP  告诉输出层在每个输出块之后自动刷新自身数据。
; 这等效于在每个 print() 或 echo() 调用和每个 HTML  块后调用flush()函数。
;  打开这项设置会导致严重的运行时冲突,建议仅在debug过程中打开。

allow_call_time_pass_reference =  On 
; 是否让强迫函数调用时按引用传递参数。这一方法遭到抗议,
; 并可能在将来版本的PHP/Zend里不再支持。
;  受到鼓励的指定哪些参数按引用传递的方法是在函数声明里。
; 你被鼓励尝试关闭这一选项并确认你的脚本仍能正常工作,以保证在将来版本的语言里
;  它们仍能工作。(你将在每次使用该特点时得到一个警告,而参数将按值而不是按引用
; 传递)。

; Safe Mode  安全模式
safe_mode = Off
safe_mode_exec_dir =
safe_mode_allowed_env_vars =  PHP_ 
; ?Setting certain environment variables
; ?may be a potential  security breach.
; 该指示包含用逗号分隔的前缀列表。安全模式中,用户仅可以替换
; 以在此列出的前缀开头的环境变量的值。
;  默认地,用户将仅能 设定以PHP_开头的环境变量,(如: PHP_FOO=BAR)。
; 注意: 如果这一指示为空,PHP  将让用户更改任意环境变量!

safe_mode_protected_env_vars = LD_LIBRARY_PATH
;  这条指示包含一个用逗号分隔的环境变量列表,那是最终用户将不能用putenv () 更改的。
;  这些变量甚至在safe_mode_allowed_env_vars 设置为允许的情况下得到保护。

disable_functions  = 
; 这条指示让你可以为了安全的原因让特定函数失效。
; 它接受一个用逗号分隔的函数名列表。
; 这条指示 *不受*  安全模式是否打开的影响。

; 语法高亮模式的色彩。
; 只要能被<font  color=???>接受的东西就能工作。

highlight.string = #DD0000
highlight.comment =  #FF8000
highlight.keyword = #007700
highlight.bg =  #FFFFFF
highlight.default = #0000BB
highlight.html = #000000

; Misc  杂项
expose_php = Off
; 决定 PHP 是否标示它装在服务器上的事实(例如:加在它 —PHP—给Web服务
;  发送的信号上)。
; (我个人的意见,在出现什么power-by的header的时候,把这关掉。)
; 它不会有安全上的威胁,  但它使检查你的服务器上是否安装了PHP成为了可能。


;;;;;;;;;;;;;;;;;;;
; Resource Limits  ;
;;;;;;;;;;;;;;;;;;;

max_execution_time = 30 ; 每个脚本的最大执行时间,  按秒计
memory_limit = 8388608 ; 一个脚本最大可使用的内存总量  (这里是8MB)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Error handling and  logging ;
; 出错控制和登记 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  错误报告是按位的。或者将数字加起来得到想要的错误报告等级。
; E_ALL - 所有的错误和警告
; E_ERROR - 致命性运行时错
;  E_WARNING - 运行时警告(非致命性错)
; E_PARSE - 编译时解析错误
; E_NOTICE -  运行时提醒(这些经常是是你的代码的bug引起的,
;也可能是有意的行为造成的。(如:基于未初始化的变量自动初始化为一个
;空字符串的事实而使用一个未初始化的变量)

;  E_CORE_ERROR - 发生于PHP启动时初始化过程中的致命错误
; E_CORE_WARNING -  发生于PHP启动时初始化过程中的警告(非致命性错)
; E_COMPILE_ERROR - 编译时致命性错
; E_COMPILE_WARNING  - 编译时警告(非致命性错)
; E_USER_ERROR - 用户产生的出错消息
; E_USER_WARNING -  用户产生的警告消息
; E_USER_NOTICE - 用户产生的提醒消息
; 例子:
; error_reporting = E_ALL  & ~E_NOTICE ; 显示所有的错误,除了提醒
; error_reporting =  E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR ; 仅显示错误
error_reporting = E_ALL &  ~E_NOTICE ; 显示所有的错误,除了提醒
display_errors = On ; 显示出错误信息(作为输出的一部分)
;  在最终发布的web站点上,强烈建议你关掉这个特性,并使用
; 错误日志代替(参看下面)。
; 在最终发布的web站点继续让  display_errors 有效可能
; 暴露一些有关安全的信息,例如你的web服务上的文件路径、
;  你的数据库规划或别的信息。

log_errors = Off ;  在日志文件里记录错误(服务器指定的日志,stderr标准错误输出,或error_log(下面的))
;  正如上面说明的那样,强烈建议你在最终发布的web站点以日志记录错误
; 取代直接错误输出。

track_errors = Off ;  保存最近一个 错误/警告 消息于变量  $php_errormsg (boolean)
;error_prepend_string = "<font  color=ff0000>" ; 于错误信息前输出的字符串
;error_append_string = "</font>" ;  于错误信息后输出的字符串
;error_log = filename ; 记录错误日志于指定文件
;error_log = syslog ;  记录错误日志于系统日志 syslog (NT 下的事件日志, Windows 95下无效)
warn_plus_overloading = Off ;  当将‘+’用于字符串时警告


;;;;;;;;;;;;;;;;;
; Data Handling  ;
;;;;;;;;;;;;;;;;;
variables_order = "EGPCS" ; 这条指示描述了PHP 记录 
; GET,  POST, Cookie, Environment and Built-in 这些变量的顺序。
; (以 G, P, C, E & S  代表,通常以 EGPCS 或 GPC 的方式引用)。
; 按从左到右记录,新值取代旧值。

register_globals = On ;  是否将这些 EGPCS 变量注册为全局变量。
; 若你不想让用户数据不在全局范围内混乱的话,你可能想关闭它。
; 这和 track_vars  连起来用更有意义 — 这样你可以通过
;  $HTTP_*_VARS[] 数组访问所有的GPC变量。

register_argc_argv  = On ; 这条指示告诉 PHP 是否声明 argv和argc 变量
; (注:这里argv为数组,argc为变量数)
;  (其中包含用GET方法传来的数据)。
; 若你不想用这些变量,你应当关掉它以提高性能。

track_vars = On ;  使 $HTTP_*_VARS[]数组有效,这里*在使用时用
; ENV, POST, GET, COOKIE or  SERVER替换

gpc_order = "GPC" ; 这条指示被人反对。用 variables_order 代替。

;  Magic quotes
magic_quotes_gpc = On ; 在输入的GET/POST/Cookie数据里使用魔术引用
;  (原文就这样,呵呵,所谓magic quotes 应该是指用转义符加在引用性的控制字符上,如 \'....)
magic_quotes_runtime=  Off ; 对运行时产生的数据使用魔术引用,
;  例如:用SQL查询得到的数据,用exec()函数得到的数据,等等
magic_quotes_sybase = Off ; 采用  Sybase形式的魔术引用(用 '' 脱出 ' 而不用 \')

; 自动在 PHP  文档之前和之后添加文件
auto_prepend_file =
auto_append_file =

; 象4.04b4一样,PHP  默认地总是在 “Content-type:” 头标输出一个字符的编码方式。
; 让输出字符集失效,只要设置为空。
; PHP 的内建默认值是  text/html
default_mimetype = "text/html"
;default_charset =  "iso-8859-1"

;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories  ;
;;;;;;;;;;;;;;;;;;;;;;;;;
include_path = ; include 路径设置,UNIX:  "/path1:/path2" Windows: "\path1;\path2"
doc_root = ; php  页面的根路径,仅在非空时有效
user_dir = ; 告知 php 在使用 /~username  打开脚本时到哪个目录下去找,仅在非空时有效
;upload_tmp_dir = ;  存放用HTTP协议上载的文件的临时目录(在没指定时使用系统默认的)
upload_max_filesize = 2097152 ; 文件上载默认地限制为2  Meg 
extension_dir = c:\php\ ; 存放可加载的扩充库(模块)的目录
enable_dl = On ;  是否使dl()有效。
; 在多线程的服务器上 dl()函数*不能*很好地工作,
; 例如IIS or  Zeus,并在其上默认为禁止


;;;;;;;;;;;;;;;;;;;;;;
; 动态扩展 ;
; Dynamic  Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
; 若你希望一个扩展库自动加载,用下面的语法:
;  extension=modulename.extension
; 例如,在windows上,
; extension=msql.dll
;  or 在UNIX下,
; extension=msql.so
; 注意,这只应当是模块的名字,不需要目录信息放在里面。
; 用上面的  extension_dir 指示指定扩展库的位置。


;Windows  扩展
;extension=php_nsmail.dll
extension=php_calendar.dll
;extension=php_dbase.dll
;extension=php_filepro.dll
extension=php_gd.dll
;extension=php_dbm.dll
;extension=php_mssql.dll
;extension=php_zlib.dll
;extension=php_filepro.dll
;extension=php_imap4r2.dll
;extension=php_ldap.dll
;extension=php_crypt.dll
;extension=php_msql2.dll
;extension=php_odbc.dll
;  注意, MySQL的支持现在是内建的,因此,不需要用它的dll


;;;;;;;;;;;;;;;;;;;
; 模块设定 ;
;  Module Settings  ;
;;;;;;;;;;;;;;;;;;;

[Syslog]
define_syslog_variables = Off ;  是否定义各种的系统日志变量
; 如: $LOG_PID,  $LOG_CRON, 等等。
; 关掉它是个提高效率的好主意。
;  运行时,你可以调用函数define_syslog_variables(),来定义这些变量


[mail function]
SMTP  =localhost ;仅用于win32系统
sendmail_from =me@localhost.com;仅用于win32系统
;sendmail_path =  ;仅用于unix, 也可支持参数(默认的是'sendmail -t -i')

[Debugger]
debugger.host =  localhost
debugger.port = 7869
debugger.enabled =  False

[Logging]
; 这些配置指示用于示例的日志记录机制。
; 看 examples/README.logging  以得到更多的解释
;logging.method = db
;logging.directory =  /path/to/log/directory

[SQL]
sql.safe_mode =  Off

[ODBC]
;uodbc.default_db = Not yet  implemented
;uodbc.default_user = Not yet implemented
;uodbc.default_pw =  Not yet implemented
uodbc.allow_persistent = On ; 允许或禁止  持久连接
uodbc.check_persistent = On ; 在重用前检查连接是否还可用
uodbc.max_persistent = -1  ; 持久连接的最大数。-1 代表无限制
uodbc.max_links = -1 ; 连接的最大数目(持久和非持久)。-1  代表无限制
uodbc.defaultlrl = 4096 ; 控制 LONG 类型的字段。返回变量的字节数,0 代表通过(?)0 means  passthru
uodbc.defaultbinmode = 1 ; 控制 二进制数据。0 代表?????Handling of binary  data. 0 means passthru, 1 return as is, 2 convert to char
; 见有关 odbc_binmode  和 odbc_longreadlen 的文档以得到 uodbc.defaultlrl 和 uodbc.defaultbinmode  的解释。

[MySQL]
mysql.allow_persistent = On ; 允许或禁止  持久连接
mysql.max_persistent = -1 ; 持久连接的最大数。-1 代表无限制
mysql.max_links = -1 ;  连接的最大数目(持久和非持久)。-1 代表无限制
mysql.default_port = ; mysql_connect()  使用的默认端口,如不设置,mysql_connect()
; 将使用变量  $MYSQL_TCP_PORT,或在/etc/services  下的mysql-tcp 条目(unix),
; 或在编译是定义的 MYSQL_PORT(按这样的顺序)
;  Win32环境,将仅检查MYSQL_PORT。
mysql.default_socket = ; 用于本地 MySql 连接的默认的套接字名。为空,使用  MYSQL 内建值

mysql.default_host = ; mysql_connect()  默认使用的主机(安全模式下无效)
mysql.default_user = ; mysql_connect()  默认使用的用户名(安全模式下无效)
mysql.default_password = ; mysql_connect()  默认使用的密码(安全模式下无效)
; 注意,在这个文件下保存密码通常是一个*坏*主意
; *任何*可以使用PHP访问的用户可以运行
;  'echo cfg_get_var("mysql.default_password")'来显示那个密码!
;  而且当然地,任何有读该文件权力的用户也能看到那个密码。

[mSQL]
msql.allow_persistent = On ; 允