Geeks With Blogs
AzamSharp Some day I will know everything. I hope that day never comes.
Every website needs counter to keep track of visitors. If you are implementing a hit counter always remember to start the count from 10,000 :) just kidding. You can easily make a hit counter by using a Application variable and increase its count in Application_BeginRequest or Session_Start events for every user visit. The problem is that once the server restarts your application level variables will be reinitialized and hence they will loose all count. A good way is to store the visitor count in the database. You must have some maximum count which when reached pushes the application variable into the database. This will save accessing the database on each request. Here is a little code snippet from my counter. You can always merge "Visit" and "GetTotalCount" method as save one extra database access. The complete code will be explained in the article. Here is the link to the article Implementing Hit Counter in Asp.net
 

protected void Session_Start(Object sender, EventArgs e)
		{
			
			Application[TOTALUSERS] = Convert.ToInt32(Application[TOTALUSERS]) + 1; 
			// If you need a running count should declare another Application variable
			Application[RUNNINGCOUNT] = Convert.ToInt32(Application[RUNNINGCOUNT]) + 1; 

			if((int)(Application[TOTALUSERS])  >= Convert.ToInt32((ConfigurationSettings.AppSettings["MAX"])) )
			{
				Visit.Count((int) Application[TOTALUSERS]); 
				// Initialize the count again 
				Application[TOTALUSERS] = 0; 
				// Retrieve the count from the database 
				Application[RUNNINGCOUNT] = Visit.GetTotalCount(); 
			}
 

		}


Posted on Wednesday, July 20, 2005 10:21 AM | Back to top


Comments on this post: Implementing Hit Counters in Asp.net

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
This is a good example for a simple crosscutting concern that can be implemented in an http module to be reused in all your asp.net applications. For performance reasons it might make sense to store the counter in a singleton instead of Application[...] to avoid the lookup in the hashtable (especially when you track requests)
Left by fx on Jul 20, 2005 1:18 PM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
Thanks for the comment. I will check if I can implement Singleton on this and remove Application variable.
Left by AzamSharp on Jul 20, 2005 2:03 PM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
Don't you think the counter needs to be locked while being incremented ?
Left by enaoui@hotmail.Com on Jul 21, 2005 2:57 AM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
You are right ! You can use the lock keyword in C# to lock the Counter.
Left by Azamsharp on Jul 21, 2005 5:13 AM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
I mean Application.Lock() and Application.Unlock()

:)
Left by AzamSharp on Jul 21, 2005 7:20 AM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
Using lock and unlock for incrementing the counter will have a very negative effect on performance because concurrent requests will be locked. The only time I'd lock is when you dump the counter to the db, otherwise a counter singleton will do just fine

Even when persisting your counter I'd be very wary about using such a global lock like Application.Lock
Left by fx on Jul 21, 2005 8:24 AM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
You are right ! It will kill performance. Let me know the details of your counter Singleton pattern.


You can than use the lock keyword of C#.

Thanks,
AzamSharp
Left by AzamSharp on Jul 21, 2005 8:38 AM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
You could use a class like this to instantiate counters for your needs (see counterID):

public class Counter
{
// Identifier for counter (e.g. "Sessions", "Requests", "Errors")
private string _counterID;
public string CounterID
{
get { return (this._counterID); }
}

private int _persistenceThreshold=1000;
public int PersistenceThreshold
{
get { return (this._persistenceThreshold); }
}

private int _currentValue;
public int CurrentValue
{
get { return (this._currentValue); }
}

private int tempCounter=0;

public Counter(string id)
{
_counterID=id;
Load();
}

public Counter(string id, int threshold) : this(id)
{
_persistenceThreshold = threshold;
}

private void Load()
{
// Get the last counter value from persistentent storage (db, file, PerfCounter)
}

private void Save()
{
lock (this)
{
if (tempCounter > 0)
{
// Save counter to persistent storage (db, file, PerfCounter)
tempCounter = 0;
}
}
}

public void Increment()
{
_currentValue++;
if (tempCounter > PersistenceThreshold)
{
Save();
}
tempCounter++;
}
}

and then add in the http module:



public class CounterModule : IHttpModule
{
...
private Counter _requestCounter = new Counter("Request", 1000);
private Counter _errCounter = new Counter("Error", 10);
... // other counters

public void OnBeginRequest(Object s, EventArgs e)
{
_requestCounter.Increment();
}

public void OnError(Object s, EventArgs e)
{
_errCounter.Increment();
}

}

Then all you need to do is to register CounterModule in your web.config and
you should be good to go (Alternatively you can just hook them into Global.asax)

Of course the whole thing is kind of a void exercise, since the .Net Perfcounters were specifically designed for the task at hand
Left by fx on Jul 21, 2005 1:42 PM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
Thanks a lot ! I will check your code :)

Left by AzamSharp on Jul 21, 2005 2:23 PM

# re: Implementing Hit Counters in Asp.net
Requesting Gravatar...
There are two things that would worry me about fx's code:

1) It looks like the code is assuming there will be only one CounterModule created in an application. There will almost always be multiple instances of an HttpModule instantiated by the runtime - this will throw the counts off. You can use static int members to share the value across module instances.

2) The ++ operator isn't thread-safe - use Interlocked.Increment instead.
Left by Scott Allen on Jul 26, 2005 5:59 PM

Your comment:
 (will show your gravatar)


Copyright © Mohammad Azam | Powered by: GeeksWithBlogs.net