This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


MIND


This article assumes you're familiar with Active Server Pages and VBScript.
Download the code (3KB)

Build Simple Hit Counters for Your Active Server Pages
Manohar Kamath

It’s easy to tabulate page hits, site visits, and visitor tracking in your ASP files.
So you finally created an ASP-based Web site and now you're waiting for the traffic to pour in. How will you know how many people visit your site? Believe it or not, Web statistics are probably the single most important factor in determining the effectiveness of your site. Large sites such as Microsoft's, Netscape's, and Yahoo have sophisticated methods of computing traffic. These statistics not only provide information on user preferences, but they are also a way of knowing what people expect of your Web site.
      To really understand the usage statistics of a large Web site, it is important to get some robust reporting tools that will watch over all the activity of your site as visitors pass through. But sometimes, all you really need is a simple page counter. In this article I will discuss various forms of counters you can write with ASP. While this is by no means an exhaustive list, I have tried to include the most common types.
      The counters described here will be most useful if you have a Web host account without any detailed hit analysis. If you require more advanced counter analysis, consider using a tool like the Microsoft® Usage Analyst, part of the Microsoft Site Server package. The examples in this article will work only with ASP files, so you cannot use them to track HTML files unless you're doing simple redirects to them.
      I didn't think of using counters until I noticed that my site was becoming popular. I needed to know how many users visited my site and how often they visited. At that time, my host had not yet installed any hit analysis software so I had to resort to ASP counters.
      Creating a Web counter is not difficult at all. In fact, even a few years ago when Web pages were just becoming popular, there were counters that you could include on your Web page. In the early days, counters were CGI scripts that looked up an entry in a database, obtained the count, incremented the count, and returned the result to the browser. Back then, there was no concept of maintaining state—if you refreshed the counter page, the count increased.
      Today, counters are much more complex. Not only do they have to compute traffic on individual pages, they also do so for whole sites. Counters are able to keep track of state, so when a user refreshes the browser the count does not increase. Besides ASP, languages counters can be written in include Visual Basic® 6.0, Perl, C++ with ISAPI, and Java.

A Simple Page Counter
      If you have a bare-bones site with just a few pages, a simple counter is probably all you'll need. The principle behind this counter is that a user visit increments the count for each page in the application (or site). Where will you store the count? The natural choice is the Application object because it represents the application or the site itself (if you are on a Web host without virtual directory choices). Moreover, Application variables are more or less permanent (they don't go away unless you take the server down).
      In a simple site, the Application("Count") variable is incremented every time the page is called. You can place this anywhere on the page, but I prefer it near the top to make the page more readable and logical. I then lock the Application object to avoid having multiple sessions access the count simultaneously, which would bump it to an incorrect value. The following code should be inserted into the ASP page you want to track:

 <%
   ' Lock the Application object
   Application.Lock
   ' Increment the count
     Application("Count") = Application("Count") + 1
 
   ' Unlock the Application object
   Application.Unlock
 %>
Simple, sure, but this could be a messy way of doing things if you have 20 pages and want to keep a count for each page. Instead of naming a variable for each page, I came up with another scheme.

A Simple, Multiple-page Counter
      If you have many pages on your site, you can end up writing tracking code for each. And keeping track of where you keep track of hits is confusing, too! To overcome this problem, I use a modified approach. The Request.ServerVariables("SCRIPT_NAME") value is the path for the requested ASP file. Since this will be different for each page, you can use it as an index into the Application object to store the individual counts. Confused? The following code might make things clearer:

 <%
     ' Lock the application
     Application.Lock
         ' Get the name of the file name executed
         sFileName = Request.ServerVariables("SCRIPT_NAME")
 
         ' Increment the count for this file
         Application(sFileName) = Application(sFileName) + 1
 
     ' Unlock the application
     Application.Unlock
 %>
The variable name of the counter corresponds to the script path, and this code works exactly like the first example. Copy this code into a text file (count.inc, for example), and include the following code in each ASP page in your site:
 <!— #include file = "count.inc" —>
 <%
     ' Your ASP page follows
 %>
Now you have a simple but effective way of counting hits on each of your ASP pages. But how do you print the count? This method does not allow for a detailed traffic report, but you can retrieve the count in one of two ways. If the page you're on is the same one for which you want to report the hit count, just use this code:

 <%
     ' Get the name of the ASP page requested
     sFileName = Request.ServerVariables("SCRIPT_NAME")
 
     ' Get the value of the hit count for that page
     Response.Write Application(sFileName)
 %>
If you know the file names in your site, and want to provide cross-page numbers, you can access the count for each by using the hardcoded file name as the index:

 <%
   Response.Write "<BR>Default Page - " & Application("/default.asp")
   Response.Write "<BR>Personal Page - " & Application("/personal.asp")
 %>

A Simple Site Counter
      I discussed how to write counters for individual pages. But what if you have a larger site with more than 100 pages? To find out how many people visit your site without having to mess around with each page, use a site counter.
      The site counter method relies on the fact that the Session_OnStart event is fired once for each new session (in other words, for each new visitor). This counter keeps the user's state just like the Session object does, and is useful for people with Web hosting accounts where the entire site is treated like a single application (that is, the entire site has one global.asa). The following code goes into the global.asa file in your application:


 <SCRIPT LANGUAGE=VBScript RUNAT=Server>
 Sub Session_OnStart
   ' Lock the Application object
   Application.Lock
 
     ' Increment the count
      Application("Visits") = Application("Visits") + 1
 
   ' Unlock the Application object
   Application.Unlock
 End Sub
 </SCRIPT>
Application("Visits") gives you the count for the whole site or the whole application. You can copy the code to each global.asa in your entire site so you can keep a tab on the hits for each virtual directory. If your site is well organized, with each virtual directory representing a theme or a section, you can use this running total as a fairly accurate way to determine the most popular sections.

The Indestructible Site Counter
      In all the previous cases, I used an Application variable to keep count. But what happens if the administrator brings the server down for maintenance? You guessed it! You will lose the count (as I have many times). This led me to write an indestructible site counter, using files to store the count. This counter is also coded within the Session_OnStart event of global.asa. Like the previous example, the counter is session-based and keeps track of the exact number of site visitors.
      The key to this method is to read a counter file, increment the count, and write the count back to the same file. To do this, create a file (count.txt, for example) in your site's virtual root. This starter file should contain 0 on a single line—this creates an initial value for the count.
      When the user first navigates to the site, the Session_OnStart event is fired. (Let's assume all the pages on the site are ASP files.) The Application object is locked so that no two users can access the count at the same time. The counter.txt file is read to obtain the current visit count. This value is then incremented and stored in an Application variable, Application("Visits"). This value is written to the counter.txt file, and the Application lock is simultaneously released.
      Quite simple, huh? This counter should serve its purpose for sites with a small number of visitors. However, it has an inherent problem: the Application object is locked and unlocked for every session created. Not only that, but there is some file I/O within this locked area, and this takes up some time. You may not want to use this for a site with a large number of hits. One way to get around this problem is described in the next counter I'm going to build (see Figure 1). Although the line


 Application("Visits") = lVisits
in Figure 1 is optional, it is useful because it prevents having to read the count.txt file each time I want to retrieve the count. Instead, I can just use Application("Visits"). A sample message could look something like this:

 <P>There were <% =Application("Visits") %> visit(s) to this site</P>

The Visitor Counter
      So far, I have talked about visits to my Web site, where each visit refers to a user session. If a user comes to my site and browses through the pages, the entire session is considered a visit. If the user comes back to the site after a day, a new session is created and the visit is incremented. But how do you keep track of total visitors, as opposed to mere visits? One way of doing this is by setting a cookie the first time a user comes into the site. During subsequent visits, this cookie is checked and the visitor count can be changed accordingly. This setup requires some changes to the code in Figure 1.
       Figure 2 shows a new counter that not only keeps track of the number of visits, but also the number of distinct visitors to the site. When the application starts, the counter file is read once. When you first create the file counter.txt in the root of your application, it will need two lines of 0 as initial values. These values are read in the Application_OnStart event and placed in two Application variables, Application("Visits") and Application("Visitors").
      During the lifetime of the counter, these Application variables are incremented in the Session_OnStart event whenever a new session starts. For example, Application("Visits") is incremented each time a session starts. Application("Visitors") is incremented for every session, unless the user's browser returns the VisitorID cookie. If the cookie is not found, the variable is incremented and this value is used to create a VisitorID cookie to be sent back to the browser.
      Since counter.txt is read only in the Application_OnStart event, file I/O is reduced drastically. Also, the counts are kept in Application variables and are written to the file once for every 100 visitors. This further reduces file I/O. You may change this interval by changing the value of the cWriteInterval constant. (Thanks to some users from the Microsoft ASP newsgroup, microsoft.public.inetserver.iis.activeserverpages, who pointed this out to me.)

Page Counter and Counter Components
      Counter and Page Counter are add-on components for Internet Information Server (IIS). The Page Counter component is a volatile counter that can be used to store page or site hits. It can be downloaded at http://backoffice.microsoft.com/downtrial/moreinfo/iissamples.asp.
      The Counters component is a nonvolatile counter; its counts are stored in a text file. This is a very useful and flexible component, available as a part of the Microsoft Internet Information Server Resource Kit (Microsoft Press, 1998).
      I won't discuss these two components in detail here because they are not standard parts of IIS and your Web host may not support them.
      Details on the Page Counter component is available at http://msdn.microsoft.com/library/psdk/iishelp/iis/htm/asp/pagecnt_00vo.htm.
      If you are interested in building a counter with the Counters component refer to http://msdn.microsoft.com/library/psdk/
maccomps_3790.htm
.

Conclusion
      I have explained some simple-to-use counters for tabulating page hits, site visits, and visitor tracking. The appropriate counter depends on the size of your site. All of these counters (except the Counter and Page Counter components) are designed with Web host accounts with a medium hit rate in mind. With some imagination, you can design your own counter to suit your needs.

From the August 1998 issue of Microsoft Interactive Developer.