|
有效监测Web站点状态
(作者:青苹果工作室编译 2000年09月27日 16:37)
也许你已经花了几十甚至上百个小时来建造你的站点,也许还会花更多的时间去尝试和构建通信量。你把它提交给一个巨大的搜索引擎,加入了所有的条幅广告交换程序,与所有可能相关的站点都交换了链接,并且为条幅或信件形式的广告进行了少量的投资。但是,你的站点到底有多少访问者呢?他们来自何处?他们最喜欢站点的哪些部分?哪种通信量的构建方法起了作用?
在哪里能找到这些信息?最好的方法就是下载你的系统记录文件,然后运行一个好的记录分析程序对它们进行分析,如WebTrend's LogAnalyzer。它会为你提供有关你的站点访问者和通信量的最好、最详细的图景(请看用WebTrend's LogAnalyzer做的这个报告)。这么说问题已经解决了,那么可以就这样结束文章了吗?还有一些问题。
如果你的站点通信量很大,那么你的记录文件也是非常大的,比如说Haneng.com的记录文件通常都不小于70-80MB。如果你只用调制解调器来连接,那么下载量就太大了,即使你在一个速度更快的专线上,也要等上好一会。而且要记住,每当你想查看你的状态时都要下载这个文件。而且你所需要的记录文件分析程序也要花点钱。
另一种可供选择的方法是使用网上提供的免费计数器服务,比如HitBox。但是它们也有缺点。为了使用它不得不在站点上显示一个小广告,而且使用起来也不方便---既增加了下载的时间,又把设计搞乱。这种服务依赖于客户机端代码,通常你必须把它们包含到你的页面上,如JavaScript或Java applets。并且不是所有的浏览器都支持这些功能,即使支持,很多人也会出于安全考虑而把这些功能关闭。
至少,你要花费大量的时间和金钱,只是为了用记录分析程序来检查一下昨天的信件广告是否带来了通信量的增加,而且计数器服务在跟踪所有的访问者时也有时会失败。那么我们该怎么办?象许多好的程序员一样,自己来创建监测程序!虽然我们所做的不能完全取代一个好的记录分析程序或计数器服务,但是我们能使最重要的信息更容易得到,而且保证与所有的浏览器都兼容。
经典的计数器
第一步是用ASP代码和文本文件创建一个标准的访问者计数器。这是一个好的开始,以后我们可以在这基础上创建更多。现在,我们想要这样设计:
首先要创建一个ASP文件,把所有想要跟踪的页面都包括进去。每当页面被请求时,计数器就加1。
我们还要一个文本文件来保存记数值。另一个选择是使用一个应用程序变量,但是这样每当网络服务器重新启动时都会丢失记数值。
这里是包含文件Count.asp的代码:
< %
'Create instance of the FileSystemObject object
Set MyFileObj = Server.CreateObject("Scripting.FileSystemObject")
'The path of the counter.txt file
CounterFilePath = Server.MapPath("cgi-bin\counter.txt")
'Read from the counter file if it exists
IF MyFileObj.FileExists(CounterFilePath) THEN
Set CounterFile = MyFileObj.OpenTextFile(CounterFilePath)
IF NOT CounterFile.AtEndOfStream THEN
Count = TRIM(CounterFile.ReadAll)
END IF
CounterFile.Close
END IF
'Add 1 if count from Counterfile is ok, else set count = 1
IF IsNumeric(Count) THEN
Count = Count + 1
ELSE
Count = 1
END IF
'Write to the counter file
Set CounterOutStream=MyFileObj.OpenTextFile(CounterFilePath, 2, TRUE)
CounterOutStream.Write(Count)
CounterOutStream.Close
% >
在Set CounterOutStream=MyFileObj.OpenTextFile(CounterFilePath, 2, TRUE)行中,参数“2”指示任何存储在文件中的以前信息都要被删除并用新的信息来取代。参数TRUE指示如果文件不存在,就要创建一个。
这个文件将上述文件包含进去,那么每次被网络服务器请求,都给记数值增加1。这个文件还显示完整的记数值。将文件存储为default.asp,并且要保证与counter.asp位于同一个路径下。
This page have been viewed times!
包含的注释已经足够解释脚本如何工作了。要记住在Count.asp中修改目录,这样就可以在网络服务器用户帐号有权写入的目录中显示路径。通常称为 /cgi-bin/ 的目录有这样的许可设置。
Session 计数器
在这里我向你展示的第二个脚本是一个在站点上计算活动sessions 的脚本。活动sessions的个数几乎等于当前浏览你的站点的人数。这里说“几乎”是因为sessions是由cookies设置并控制的,所以说一个没有激活cookies的用户每次访问一个新网页的时候都会启动一个新的session 。
那么,我们该如何写这个计数器?怎样才能知道有多少活动sessions?答案全在一个Global.asa文件中。这个文件中可能有4个脚本,其中2个对我们有用,它们是Session_OnStart 和 Session_OnEnd。这两个脚本运行的时间分别是访问者从你的站点第一次请求一个页面时和访问者离开这个站点时。从技术上说,网络服务器是无法知道访问者何时离开的,所以实际上运行是在一个规定的时段结束后。(这个时段在用户最后一个请求后开始,规定的时间间隔是20分钟)。
我们在Session_OnStart 中创建的脚本向记数值中加1,在Session_OnEnd的脚本中则减1。这种情况下,在重新启动过程中,我们不需要记住记数值,所以我们用一个应用程序变量来存放记数值。
这是我们需要向Global.asa 文件做的一些改动:
< SCRIPT LANGUAGE=VBScript RUNAT=Server >
Sub Session_OnStart
'Add one to Application("SessionCount")
IF IsNumeric(Application("SessionCount")) THEN
Application("SessionCount") = Application("SessionCount") + 1
ELSE
Application("SessionCount") = 1
END IF
End Sub
< /SCRIPT >
< SCRIPT LANGUAGE=VBScript RUNAT=Server >
Sub Session_OnEnd
'Subtract one from Application("SessionCount")
IF IsNumeric(Application("SessionCount")) THEN
Application("SessionCount") = Application("SessionCount") - 1
ELSE
Application("SessionCount") = 0
END IF
End Sub
< /SCRIPT >
下面是显示值的脚本。在下载文件中它被称为View.asp:
< HTML >
< BODY >
There are currently < B >< % =Application("SessionCount")% >< /B > active sessions.
< /BODY >
< /HTML >
更多的高级状态
启动我的站点后,我就想知道,每周有多少点击,有没有进步,我对站点的推销是否成功。我所需要的是快速地获得本周有多少访问者以及以前几周有多少访问者这样的信息。为此,我写了一个脚本,包括如下功能:
a.计算每周网页被访问数;
b.在一个Access数据库中存储这个记数值;
c.以图表方式显示统计信息。
用这个脚本,我可以从图表中很快地看到被点击数有所增长(营销是成功的),没有改变(营销不成功)或减少了(需要更多/更新的营销方式)。
在代码最重要的部分,我将一一向你讲解,但是首先来解释一些事情。我为每个星期都设置了一个ID,以便识别它们。ID的设置很简单,只不过是年和星期的数,如199943的意思是1999年的第43周。当前的星期ID和当前的记数值存储在应用程序变量中。应用程序变量与session变量相同,只不过它不依赖于cookies,所有的用户都能使用。
最重要的文件是WeekCount.asp。在每个我们需要监视的页面中都要包含这个文件。这脚本有4个主要任务;
1、查看网络服务器是否被重新启动。如果是,就读数据库中的最新值。
2、如果星期改变了,它就保存当前星期记数值,然后为这个新的星期创建一个数据库数值。记数值被设置为0,星期ID也改变。
3、给记数值加1。
4、每浏览5个页面,就在数据库中储存记数值。
首先,我们从应用程序变量中恢复记数值和星期ID:
Application.Lock
App_Area1_WeekID = TRIM(Application("Area1_WeekID"))
App_Area1_WeekCount = TRIM(Application("Area1_WeekCount"))
我们用Application.Lock和 Application.UnLock 来避免记数值的不准确。如果不使用它们,就可能遇到这种情况:两个用户同时点击,只能记录下一个。用Application.Lock,我们在application 对象中锁住所有的变量,那么在用Application.UnLock开锁或到达页面的结尾之前,任何用户都不能修改它。锁住应用程序变量并非想永远地阻止其他用户修改它们,只是迫使能有序地修改它们。
其次,我们设置了一些变量。DataSource变量被设置到数据源和驱动器,在这里,它是一个Access 数据文件,我们将使用一个非DSN链接。我还设置了Now_WeekID,它是服务器的当前星期ID。
任务1:检查网络服务器是否被重新启动。如果是,就读数据库中的最新值。
现在我们从任务1开始。下面的代码执行检查功能:
IF Len(App_Area1_WeekID) = 0 OR Len(App_Area1_WeekCount) = 0 THEN...
IF...THEN语句检测应用程序变量是否为空,显示脚本是从网络服务器启动后第一次运行。如果它们为空,我们就在数据库中搜索最新的邮件:
SELECT * FROM Area1 ORDER BY Area1_WeekID DESC.
因为我们已经选择了现在的星期ID,所以返回的记录集的第一行就是最新的。(比如说我们得到数据库中1999年的第52周和2000年的第一周,那么就有199952 和 200001 。当以星期ID的降序排列时,就先得到200001。如果我们选择用其它方式,比如521999和012000,就做不到了。)
如果找到了项目,那么应用程序变量(App_Area1_WeekID 和App_Area1_WeekCount )就被刷新。如果没有找到,我们就设置App_Area1_WeekCount为0 ,将App_Area1_WeekID设置为这周的ID。
任务2:如果星期改变了,它就保存当前星期记数值,然后为这个新的星期创建一个数据库邮件。记数值被设为0,星期ID也被改变。
任务2:查看星期是否改变了。
IF NOT App_Area1_WeekID = Now_WeekID THEN.
如果它改变了,就用当前记数值刷新数据库。我们生成这样的SQL查询:
SQL_query = "UPDATE Area1 SET Area1_Count = " & App_Area1_WeekCount & " WHERE Area1_WeekID = '" &App_Area1_WeekID & "'"
随后,用新的星期ID建立一个新的邮件,将记数值设置为0。然后,将App_Area1_WeekCount设置为0,将App_Area1_WeekID设置为这星期的ID。
任务3:给记数值加1。
任务3,给记数值加1。只有一行代码:
Application("Area1_WeekCount") = Application("Area1_WeekCount") + 1
任务4:每浏览5次页面,就在数据库中存储记数值。
最后一个任务是每5次页面浏览,就将记数值存储到数据库中。我们可以把代码写成每次脚本运行都保存记数值,但是这样会给系统带来很大的压力,尤其是通信量很高的站点(也许你的站点现在没有这么高的通信量,但是要为将来打算)。如果你还想保存更多的系统资源,那么你可以修改这个数字,比如25次浏览保存记数值。但是这就有一个矛盾。服务器每次启动,都有一些记数值没有保存下来。如果我们的记数值是999,而最后写到数据库的数字是995。这就意味着,在我们的数据库中,这个星期的记数值是995。当网络服务器重新启动,它读取的记数值是995,计数器也被设成这个数字。那么就在计数器中损失了4个页面访问数。虽然不多,但是这是你应该知道的误差。如果你将这个倍数设置为25,那么每次重新启动都会损失24次页面访问。
那么我们如何来检测这个倍数值呢?在代码中IF...THEN语句完成这个检测:
IF App_Area1_WeekCount/5 = Fix(App_Area1_WeekCount/5) THEN
要理解这是如何工作的,你需要知道Fix 函数是做什么的。如果你不知道,我就给你简单地讲解一下。(如果你已经知道了,可以跳到下一段)。Fix 把数字转换为整数(简单地说,数字可以有小数点,而整数没有)。如果数字有小数点,它就舍弃小数点后的部分,将数字变成整数,象这样:
| 数字 | Fix | 结果 | | 0.2 | Fix (0.2) | 0 | | 0.99 | Fix (0.99) | 0 | | 1 | Fix (1) | 1 |
如果记数值是995,那么我们就得到以下结果:
App_Area1_WeekCount/5 = 199
Fix(App_Area1_WeekCount/5) = 199
但是如果记数值为199,那么:
App_Area1_WeekCount/5 = 199.8
Fix(App_Area1_WeekCount/5) = 199
要改变这个时间倍数,用你想要的数字除即可,如果我们想要时间倍数是25,就用下面这行代替IF...THEN 这一行:
IF App_Area1_WeekCount/25 = Fix(App_Area1_WeekCount/25) AND NOT App_Area1_WeekCount = 0 THEN
如果记数值是5的倍数,并且没有为0的记数值(不需要将0存储到数据库中),那么我们就刷新数据库记数值。
以上就是weekcount.asp的全部内容。为了测试它,尝试包含文件default.asp。用:
< !--#INCLUDE FILE="weekcount.asp"-- >
< HTML > < BODY >
Count this week: < %=Application("Area1_WeekCount")% >
</BODY></HTML>
将记数值包含到你所有需要监控的页面中。
数据挖掘
现在我们就有了一个数据库,其中包含着以前各周及当前这一周的页面访问数的信息。现在你可以对它进行数据挖掘了。用一些ASP和SQL,你可以轻易地从中提取出你所想要的信息。每周的记数值、自开始到目前的总的记数值(将所有周的记数值加起来)、页面访问数最多的周(使用ORDER...BY 语句)、每年的页面访问数(例如把以1999开头的星期ID的记数值加起来)等。你还可以用多种方式显示这个信息,如表格、列表、图表等。现在我向你提供一个脚本,它在一个条形图中显示以前6周和本周的记数值。
我们把stas.asp 页面分成3部分:
1、从数据库中收集数据。
2、处理数据,找到最大值,并以此找到条形图中的条高度。
3、生成条形图。
这里是我们所使用的数据库表格:
我创建一个可以在其中存储每个条信息的数组:
DIM BarChartArray(6,3)
然后,与数据库连接,恢复最近7周的数字(包括当前这一周)。信息保存到数列中:
Set MyConn = Server.CreateObject("ADODB.Connection")
MyConn.Open DataSource
SQL_query = "SELECT * FROM Area1 ORDER BY Area1_WeekID DESC"
Set RS = MyConn.Execute(SQL_query)
i = 0
WHILE NOT RS.EOF AND NOT i > UBound(BarChartArray)
BarChartArray(i,1) = TRIM(RS("Area1_WeekID"))
BarChartArray(i,2) = TRIM(RS("Area1_Count"))
i = i + 1
RS.MoveNext
WEND
RS.Close
Set RS = nothing
MyConn.Close
Set MyConn = nothing
接着,运行两个较小块代码,任务是找到每个条的高度。看看以下代码:
BarChartArray(i,3) = FIX((BarChartArray(i,2)/Maximum)*150)
BarChartArray(i,2)包含第i周的记数值。我们用这个记数值除以数列中最高的记数值,然后用这个数乘以150。这意味着最高的条是150个象素高,其它的条要低一些,高度互成比例。
实际的条形图是通过为每个记数值调整图象的尺寸来生成的。
ImgColor设置成兰色或灰色,与两个图象文件名相匹配。Grey.gif是一个1*1象素灰色GIF图象,而blue.gif是一个1*1象素兰色GIF图象。
记住要将路径修改到数据库文件(还要记住将其放在一个有写入许可的文件夹中)。并且要确保包含文件路径正确。你也许已经注意到,变量都称为 Area1。有一个很好的窍门是将你的站点分成许多小区,这样你就可以跟踪站点的哪部分是最受欢迎的。只需要将所有的变量重命名为 Area2、 Area3等即可,并且各用一个新的表格来刷新数据库。
现在,你已经有了一个好的基础来建造一个记录通信量的工具。希望你能够得到更多关于你的站点和访问者的信息,这会帮助你建设一个更好的站点。
|
|
 |