Awstats部署说明

Awstats介绍

AWStats是在Sourceforge上发展很快的一个基于Perl的WEB日志分析工具。通过分析服务器的访问日志,可以了解服务器的使用情况,方便服务器的维护和管理。

基础安装

  1. AWStats使用perl编写,因此需要perl的环境支持。对于windows用户,下载ActivePerl,并安装。

  2. AWStats官网获取最新的AWStats。

  3. 将AWStats解压,并进入目录awstats\tools,执行命令perl awstats_configure.pl,按照提示完成配置(依次输入apache位置/apache配置文件位置/统计站点的域名)。
  4. 修改Apache配置文件Apache2.2\conf\httpd.conf,找到Awstats新添加的配置(配置文件的最下面),将里面的文件位置换成AWStats的实际位置。
  5. 修改文件awstats\wwwroot\cgi-bin\awstats.pl,将第一行的perl路径换成实际位置(如:#!c:\perl\bin\perl.exe)。
  6. 重新启动apache,浏览器中输入http://mysite/awstats/awstats.pl?config=mysite,查看AWStats是否正常运行。

日志分析的相关配置

在完成基础配置后AWStats已可以正常运行,但由于没有进行日志分析,将看不到任何的统计信息。

  1. Apache默认只使用一个日志文件,如果日志文件太大,将给日志分析带来极大的负担。修改Log配置,将Log配置修改为CustomLog "|bin/rotatelogs.exe -l logs/access%Y-%m-%d.log 86400" combined。每天生成一个文件。

  2. Apache的日志文件格式LogFormat,如果包含LogFormat "%h %l %u %t \"%r\" %>s %b" common,则注释掉,不然日志信息中将不包含User-Agent信息(浏览器/操作系统类型等)。

  3. Awstats的站点配置文件在awstats\wwwroot\cgi-bin,配置文件名字为 awstats.你的站点名字.conf(如:awstats.mysite.conf)。
  4. 修改LogFile配置Apache的日志位置和文件名的格式,文件格式需要和apache的日志文件格式相匹配。如:LogFile="D:/AppServ/Apache2.2/logs/access%YYYY-24-%MM-24-%DD-24.log"。这里表示日志格式为2008-10-10.log,-24表示24小时以前,也就是前一天日志文件。

  5. LogFormat默认为1,如果Apache日志中没有包含User-Agent信息,则需要将LogFormat设置为4。

  6. 进入目录awstats\wwwroot\cgi-bin,执行脚本awstats.pl -config=mysite -update -lang=cn完成日志分析。如果日志分析成功,重新进入AWStats,将可看到服务器的访问信息。
  7. 在windows的计划任务中创建任务awstats.pl -config=mysite -update -lang=cn,设置每天晚上对前一天的日志进行分析。

Awstats访问权限设置

Awstats默认情况系任何人都可以访问。可以通过apache限制Awstats限制只有登陆的用户才能访问。

  1. 在Apache的配置文件,Awstats的目录权限配置中添加访问权限控制。

    <Directory "D:/AppServ/awstats/wwwroot">
    Options None
    AllowOverride None
    AuthName "admin onssw Access"
    Order allow,deny
    Allow from all

    AuthType Basic
    AuthName "Restricted Files"
    AuthUserFile D:/AppServ/Apache2.2/conf/passwords
    Require user admin
    </Directory>

  2. 使用Apache2.2\bin\htpasswd.exe生成密码问题。htpasswd -c D:\AppServ\Apache2.2\conf\passwords admin。

  3. 在配置好Awstats的访问权限后,每次访问Awstats将被要求登陆。输入用户名admin和刚设置的密码,完成登陆验证。

ClearQuest二次开发

ClearQuest API概述

Rational ClearQuest 是重要的变更管理工具,Rational ClearQuest 更能让客户根据自己的具体需求,灵活的设计变更管理流程。除此之外,Rational ClearQuest 还提供了一套编程接口,即 Rational ClearQuest API,让用户和开发人员可以根据需要通过编程来实现 Rational ClearQuest 的相关功能,同时还可以通过编程来实现模式中 Hook 脚本的开发和定制,从而使整个 Rational ClearQuest 产品的功能更加灵活和强大。
通过CQ的二次开发接口,我们可以更灵活的定义自己的统计,或是使用脚本来批量修改CQ中的MR。
ClearQuest API 提供了VBS实现和Perl实现。也就是说可以使用VBS或Perl进行CQ的二次开发,两种开发方式提供了完全一致的开发接口。同时由于VBS是用过调用COM来使用CQ接口,理论上可以使用其他开发语言通过直接调用COM的方式来使用CQ的API。
由于VBS和COM都为MS的专有技术,VBS的脚本只能在windows平台上执行,Perl脚本则可以实现跨平台。 相比VBS,Perl的使用面更广,功能也更为强大,且考虑到Perl的跨平台性,使用Perl进行CQ的二次开发会是一个比较好的选择。

Perl语言基础知识

需要使用CQ的API需要先安装CQ的客户端。CQ的客户端有带一个专供CQ使用的perl引擎,cqperl,在运行perl脚本时候直接使用cqperl xx.pl运行。
考虑到熟悉Perl的用户并不多,在介绍CQ API前先对Perl的相关语法等做个简单的介绍。这里只提供基础的入门介绍,以便perl程序的阅读,如需要更深入的了解请阅读参考中的相关文档。

基本语法

perl里面语句也是用“;”来分开的。注释使用“#”。

变量符号
  • 标量定义,以$号开头,如:$num =1;
  • 数组定义,以@开头,如:@array = (1,2,3);
    数组元素调用 @array[index],其中index表示数组下标,如上例,@array[0]的值是1

  • 散列定义,以%开头,如:%hash=("a",1,"b",2);
    散列调用 %hash,其中key表示键值,如上例,%hash{"b"}的值是1

变量范围
  • $xx什么都不写,表示全局变量。整个文件中都可以访问到;
  • local $xx 表示局部变量,但是这个值可以被其调用的子程序访问到
  • my $xx 表示局部变量,只能在这一个函数里面可以使用,子程序就不能使用
函数定义
sub FunctionName
{
local ($a,$b)=@_;
return “”;
}

注意: 函数后便没有(),也没有参数列表定义。也就是说,他接受任何形式的参数,以数组的方式传递过来。所以内部使用的话,就用@_这个默认当前参数来取之。

操控语句(语法)
  • 除" " "0"(空字符,0),以外都为真。
  • if/while/until/for等语法类似c/cpp/java
  • 使用foreach进行遍历。

    foreach $user (@users) {
    do something...
    }

  • 跳出控制结构: next 和 last。next跳过当前操作,进入下一循环。last直接跳出循环。
  • perl包含文件。具体说明参考Perl中的文件包含(do, require, use)

ClearQuest API使用说明/范例

连接CQ库

CQ的数据存储在数据库(用户数据库)中,我们公司使用的是SQL Server。虽然可以通过直接访问SQL Server数据库的方式获取MR信息,但由于数据库的表结构复杂且受权限的约束(没有开放写权限),很多时候直接访问数据库并不是一个好主意。
在使用CQ API时,首先要做的是和CQ建立session,连接上CQ的库(模式库)。主要步骤为:

  • 创建session对象

    my $session = CQSession::Build();

  • 登陆CQ库

    $session->UserLogon(login_name, password, database_name, database_set);
    • login_name 登陆的用户名,也就是使用CQ客户端登陆的用户名。
    • password 用户密码,同CQ客户端登陆的密码。
    • database_name 库名
    • database_set 库集。
  • 操作完成后关闭session。

    CQSession::Unbuild($session);

  • 创建查询

    在成功建立session后就可以对CQ库进行操作了。
    创建查询的主要步骤如下。

    • 创建Query对象。

      my $queryDef = $session->BuildQuery(entitydef_name);
      • entitydef_name 这个就是在CQ客户端创建查询时候选择的record type。
    • 设定需要返回的字段(同CQ客户端上选择的输出字段)。

      $queryDef->BuildField("id");#id
      $queryDef->BuildField("Headline");#标题
      ......

    • 创建查询条件。
      • 创建查询条件对象。

        my $operator = $querydef->BuildFilterOperator(bool_operator);
        • bool_operator 这个为逻辑条件。常用的逻辑条件如:$CQPerlExt::CQ_BOOL_OP_AND(与) $CQPerlExt::CQ_COMP_OP_EQ(等于)
      • 为查询对象,设置过滤条件。

        $operator->BuildFilter(field_name, comparison_operator, value);

      • field_name 进行过滤的字段名,同CQ客户端中设置的过滤条件字段。
      • comparison_operator 逻辑判断条件。$CQPerlExt::CQ_COMP_OP_EQ 等。
      • value 该字段的值
  • 创建结果集

    my $resultSet = $session->BuildResultSet($queryDef);

  • 执行查询,获取查询结果
    • 执行查询

      $resultSet->Execute();

    • 遍历,获取查询的结果集的值。

      while (($resultSet->MoveNext()) == 1)
      {
      my $mr_id=$resultSet->GetColumnValue(1);
      }
      • 使用$resultset->GetColumnValue(columnNum);获取字段的返回结果,其中columnNum为返回字段的序列,由1开始。

    编辑MR

    除获取MR外,对MR进行一些编辑也是常用的操作。编辑MR主要需要以下操作。

    • 获取需要编辑的MR对象

      $session->GetEntity(entity def_name, display_name);
      • def_name 这里同BuildQuery的参数类似

      • display_name 这里填写MR ID
  • 编辑对象

    $session->EditEntity(entity, edit_action_name);
    • entity 需要编辑的对象
    • edit_action_name 编辑操作的名称,(例如: "modify" or "resolve")
  • 设定字段的值

    $entity->SetFieldValue(field_name, new_value);
    • field_name 字段名称
    • new_value 修改后的值
  • 提交/回滚修改
    • 提交 $entity->Commit();

    • 回滚 $entity->Revert();

  • 完整范例

    在这个范例中,将查找出在dbname里Product为prd10000且Verified的MR,并将其Close。

    use CQPerlExt;
    ###连接CQ###
    my $loginName = "loginName";
    my $loginPassword = "loginPassword";
    my $databaseName = "dbname";
    my $databaseSet = "dbset";
    my $session = CQSession::Build();
    $session->UserLogon($loginName, $loginPassword, $databaseName, $databaseSet);

    ###创建查询,查询出需要close的MR###
    my $queryDef = $session->BuildQuery("Dev_Defect");
    $queryDef->BuildField("id");#id
    my $operator1 = $queryDef->BuildFilterOperator($CQPerlExt::CQ_BOOL_OP_AND);

    @Product = ("%prd10000%");
    $operator1->BuildFilter("Product", $CQPerlExt::CQ_COMP_OP_LIKE, \@NE_Product);
    @State = ("Verified");
    $operator1->BuildFilter("State", $CQPerlExt::CQ_COMP_OP_EQ, \@State);

    my $resultSet = $session->BuildResultSet($queryDef);
    $resultSet->EnableRecordCount();
    $resultSet->Execute();
    my $count = $resultSet->GetRecordCount();#获取查询出的MR个数
    print "count: $count\n";
    ###遍历查询出的MR,并进行Close操作###
    while (($resultSet->MoveNext()) == 1)
    {
    $id = $resultSet->GetColumnValue(1);
    print "$id\n";
    ###执行Close操作###
    $entity = $session->GetEntity( "Dev_Defect", $id );
    $session->EditEntity($entity,"close");
    $entity->SetFieldValue("Closed_Information", "Close");
    my $Status = $entity->Validate();
    if($Status eq "")
    {
    # 提交数据记录
    $entity->Commit();
    }
    else
    {
    # 打印错误信息
    print $Status;
    $entity->Revert();
    }
    }
    CQSession::Unbuild($session);

    参考资料

    老照片换域名了

        lzpian.com还有一个多月就到期了。因为这个站点不打算再进行维护,所以也懒得去给域名续费了。为了防止域名到期后无法访问,今天为老照片新增加了一个二级域名 http://lzpian.haoluobo.com/ ,并将lzpian.com重新重定向到新域名上。
        不过在进行重定向的时候遇到些问题,那些设置了跳过规则的文件都重定向到 lzpian.com 去了。整了半天也没明白是咋回事。估计和虚拟主机的设置有关。考虑过些天等lzpian快到期的时候将lzpian.com去掉看看。

    新发布一个Django的脚手架DjangoSide

        前一段时间在邮件列表和limodou讨论django app重用的问题。limodou认为django的app没有对app的配置文件和静态文件的管理提出一个很好的方案。但在我看来在这方面django做的已经算是不错的了,唯一缺少或许只是一个规范而已。对于django,每个人都有各自的认识,而且在书写的时候又很少考虑到重用的问题,所以写出的代码各不相同,重用性很低,完全没有发挥出django app的优势。
        DjangoSide是个演示性质的项目。主要演示如何和第三方的django应用进行整合,简单的注册登陆的实现,以及静态资源的组织等。目前项目还只是将基础的框架目录结构给搭建好了,里面提供了一个blog的整合实例。主工程(djangoside)还未正式的开始开发(其实也没多少需要开发的东西)。

        至于项目的详细可以在项目页面看到,我这里就不多写了。
        项目地址:http://code.google.com/p/djangoside/

    assembla太强了

        assembla是一个提供免费SVN和项目管理工具的服务商。以前用过一段时间,后来挺久没去过,最近再去发现服务功能做了一些改动,其中wiki的改动实在让人无语。以前的wiki使用的wiki语法,但现在已经改成了同时支持wiki语法和WYSIWYG。就这么看上去似乎还是不错,但真正去用就会发现根本无法忍受。WYSIWYG和wiki语法之间根本就无法平滑的切换,而且在提交后文本内容就已经转成了html,根本无法再使用wiki语法进行编辑。简单的说,assembla的wiki功能基本上是废掉了。
        虽然wiki被废掉,这点比较不爽,不过今天发现assembla居然提供了Trac,一个完整的Trac。Trac的wiki功能完善(而且我自己也在用Trac的wiki)。不过assembla的数据导出服务似乎是收费的,而且我已经在自己服务器上将Trac的部署好了,因此目前只使用assembla的SVN服务。
        需要项目管理,SVN服务器的兄弟去看看吧,绝对是一个优秀的免费服务。

    Trac的SEO能力实在不怎么样

        本以为wiki不被收录是因为进了搜索引擎的黑名单,于是换了新域名,哪知道还是老样子。google虽然有收录,但权重N低,baidu始终不做理会。为了防止trac自带的wiki页面导致搜索引擎错误的将我打入黑名单,我还特意在robots里将这些页面做了屏蔽。
        我看了下其他的trac站点,似乎也都不太被搜索引擎待见。可能是trac自身的问题吧。
        不去管它好了。

    我的wiki开放了

    wiki地址:http://vik.haoluobo.com/
        本来计划先将wiki的内容整理完再部署到服务器上,可是因为一些以外,wiki整理的速度变慢了很多。于是就先将已经整理的部分部署上去。部署wiki的时候顺便也将“老照片”和“国学阅读网”不能访问的问题给修复了。由于bluehost的调整,网站已经挂了好些天了,只是一直都懒得去整。
        最近真是多事之秋。汶川的大地震近年来少有的大灾难,而我也遭遇了有史以来最严重的伤害,肉体上的伤害。新买了自行车没多久就将我摔了。虽然没有啥大伤害,可是身上有多处擦伤。而且现在“年纪一大把”,伤口恢复的速度远比不上从前。
        受了伤,一面有些郁闷,一面也会有些胡思乱想。按说每次以外都是小概率事件,是N多细节的累加。如果我当初决定走另外一条路,如果我决定早点回去了,甚至路上多一个坑。很可能我就不会被那个倒霉的缝被绊倒了。只是,如果就是没有如果。不管怎么样,这件事已经发生了,这已经成了一个无法改变的事实。再说来,通常人们说的如果都是好的方面。谁知道如果真的如果了,又是否会和《蝴蝶效应》中的故事一样。
        也许这次的意外也会有些好处了。因为我还有机会回头,在一定程度上说可以回头的意外都不算太糟糕。
        受伤后为了能早点恢复,我的生活习惯已经好了不少了。以前经常有事没事的熬夜,现在时间差不多就睡了。早上通常匆匆忙忙的随便吃点东西,就去公司。现在也会早点起床,到公司后慢慢的吃早餐。会注意营养多吃鸡蛋。因为忌口,我放过了美味的鸡翅而选择番茄炒蛋:(。
        伤口在基本愈合后应当还会有个调养期。为了不留下太明显的痕迹,我想我应当会去做些运动。
        如果这次的伤害没有留下啥太严重的后果,而我能借次机会培养一个健康的生活习惯,那还是不错的。但现在,确实很郁闷,每天都在想啥时候能快点好:(。

    Borland终于将CodeGear给卖了

        前些天发现有些通过网友搜素Borland卖Delphi的访问我的主页。然后又在QQ群里看到了CodeGear出售的消息。CodeGear以2300w$的价格给贱卖了。Borland还保留700w$的资产,也就是说整个开发部门总共也才值3kw$。
        买家叫Embarcadero,一个我没听说过的公司。虽然是个地板价,不过我想这对Borland来说也算是一个解脱吧,终于将这个烫手山芋给脱手了。
        Delphi社区普遍关心CodeGear被卖了以后Delphi的前途,毕竟Delphi就borland一家在做,如果没人接手玩下去,那将直接面临玩完的危险。从我的角度来说,我是非常不看好Delphi的前途(其实早就不看好了),也不看好CodeGear的前途。CodeGear这几年出的新东西,甚至连让我尝试的冲动都没多少。
        2300w,本来就是一个地板价,更何况这还并不是Delphi卖出的价钱。说不定Delphi在里面属于陪嫁的嫁妆而已。Embarcadero或许只是看重了CodeGear的技术团队。作为一次收购,Embarcadero很可能会对CodeGear的产品线进行重组,砍掉一些不盈利的项目。Delphi就很可能会在黑名单中。
        食之无味弃之可惜。在我看来Delphi应当还会做做show,做一些维护性的工作,就别指望他能得到一些啥优秀资源了。
        或许对我来说,Delphi的版本号发展到了7就已经终结,虽然对他的unicode版还有些许期待。

    相册搬家了

        前些天用了一下好看簿,感觉还不错。加上pconline越来越不好玩,决定给相册搬家了。
        以前用pconline的摄影部落主要是这里有不少摄友,感觉在部落里YY片片还挺有意思。不过可能是pconline处于流量的考虑,添加了在回复时候推荐自己最新照片的功能。而且照片的出现顺序也开始改为按照最新评论时间进行排序。一些摄友为了推销自己的摄影作品,到处回复。这样做网站的活跃度是上去了,可是评论的质量却大大的降低了。不少人是为了回复而回复。
        pconline的相册不支持外联,虽然这个东西对我的影响不是太大,不过如果有个好用且支持外联的相册那不是更好。
        当然用好看簿也是有一定风险的。就我的感受,好看簿还未真正形成自己的竞争优势。如果哪天好看簿不玩了,那我就得另外去找一个窝了。

    我的好看簿地址:http://vicalloy.haokanbu.com

    真的被Pylucene给打败了

        既然在线程内调用pylucene会有问题,于是我将pylucene做成了一个独立的程序,将执行结果pickle后输出到控制库。主程序在遇到查询请求的时候执行这个独立程序,获取控制台输出后再unpickle获取查询结果。
        本以为这将是一个可行的方案,哪知道部署到服务器上还是不行。
        真的败给pylucene了,暂时是不想再被pylucene折磨了,以后有时间还是看看Xapian吧。