Showing posts with label Hit Counter. Show all posts
Showing posts with label Hit Counter. Show all posts

Sunday, October 23, 2011

GoDaddy Site Analytics, User History, Log Parser, Hit Counter Example Tutorial


For $2.99 a month GoDaddy.com provides Site Analytics, which reads your Microsoft web server's IIS log files and summarizes your hit counter along with IP addresses for you similar to WebTrends

You can do this yourself with open source and free code if you have Admin rights to your server, i.e. you can configure request logging in IIS Manager.

Then use Log Parser  to read XML, tab and space separated files, active directory, Windows registry, and Netmon captures. Output as charts, text, or send to a SYSLOG server.

Because you don't have access to the log files at GoDaddy, some useful tools such as Microsoft's Log Parser and Apache Log4Net are of limited use.

Output - slowest pages

Log Parser does charts.
Output - most commonly used .aspx
		  pages

  Download the Apache Software Foundation port of Log4j for C# for ASP.Net at http://logging.apache.org/log4net/download.html


W3SVC Extended Log Format fields:
date
time 
s-sitename 
s-ip
cs-method 
cs-uri-stem 
cs-uri-query
s-port
cs-username 
c-ip
cs(User-Agent) 
sc-status 
sc-substatus 


sc-win32-status

Unfortunately, in the free, shared hosting plans you don't have access to the log files for a number of reasons. However, if you did, you could use code snippets from http://www.mikesdotnetting.com/Article/103/Build-your-own-Whois-Lookup-with-ASP.NET-and-jQuery :


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="IPLookup.aspx.cs" Inherits="IPLookup" %>

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>Untitled Pagetitle>
    <style type="text/css">
        body { font-family:Verdana;font-size:76%; }
        pre { font-size:10pt; }
        span { cursor:pointer; }
        #dns { float:left; }
        #calendar{ float:left;width:350px; }
        #loading { left:300px;z-index:100;position:absolute; }
    style>
head> 
<body> 
     id="form1" runat="server">

    <div id="calendar">
      <asp:Calendar ID="Calendar1" runat="server"
        onselectionchanged="Calendar1_SelectionChanged" />
      <asp:Literal ID="ip_addresses" runat="server" />
    div>
    <div id="dns">div>
    <div id="loading">div>
    form>
body> 
html> 


protected void Calendar1_SelectionChanged(object sender, EventArgs e)
{
    ip_addresses.Text = "";
    List<string> IPs = new List<string>();
    StringBuilder sb = new StringBuilder();
    DateTime date = Calendar1.SelectedDate;
    string filedate = string.Format("{0:yyMMdd}", date);
    string path = @"D:\Logs\ex" + filedate + ".log";

    if (File.Exists(path))
    {
        string content;
        using (StreamReader sr = new StreamReader(path))
        {
            content = sr.ReadToEnd();
        }

        Regex re = new Regex(@"\w\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}\w");
        MatchCollection mc = re.Matches(content);
        foreach (Match mt in mc)
        {
            if (mt.ToString() != "xxx.xxx.xxx.xxx")
                IPs.Add(mt.ToString());
        }

        var result = IPs.Select(i => i).Distinct().ToList();

        foreach (string ip in result)
        {
            sb.Append("" + ip + "\n");
        }

        ip_addresses.Text = "
" + sb.ToString() + "

";

    }
    else
    {
        ip_addresses.Text = "No logs available for that date";
    }
}
private static string GetHtmlPage(string url)
{
    String result;
    WebResponse response;
    WebRequest request = HttpWebRequest.Create(url);
    response = request.GetResponse();
    using (StreamReader sr = new StreamReader(response.GetResponseStream()))
    {
        result = sr.ReadToEnd();
        sr.Close();
    }
    return result;
}
private static string PostHtmlPage(string url, string post)
{
    ASCIIEncoding enc = new ASCIIEncoding();
    byte[] data = enc.GetBytes(post);
    WebRequest request = HttpWebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = data.Length;
    Stream stream = request.GetRequestStream();
    stream.Write(data, 0, data.Length);
    stream.Close();
    WebResponse response = request.GetResponse();
    string result;
    using (StreamReader sr = new StreamReader(response.GetResponseStream()))
    {
        result = sr.ReadToEnd();
        sr.Close();
    }
    return result;
}
[WebMethod]
public static string GetWhois(string ip)
{
    string response = "";
    string arin = "https://ws.arin.net/whois/?queryinput=" + ip;
    string ripe = "http://www.db.ripe.net/whois?form_type=simple&full_query_string=&searchtext=" + ip + "&do_search=Search";
    string apnic = "http://wq.apnic.net/apnic-bin/whois.pl";
    string lacnicFields = "query=" + ip;
    string apnicFields = ".cgifields=object_type&.cgifields=reverse_delegation_domains&do_search=Search&" +
                         "form_type=advancedfull_query_string=&inverse_attributes=None&object_type=All&searchtext=" + ip;
    response = GetHtmlPage(arin);
    Regex pre = new Regex(@"
[.\n\W\w]*</p>", RegexOptions.IgnoreCase);

    Match m = pre.Match(response);
    if (pre.IsMatch(response))
    {
        if (m.Value.IndexOf("OrgName:    RIPE Network Coordination Centre") > 0)
        {
            response = GetHtmlPage(ripe);
            m = pre.Match(response);
        }
        else if (m.Value.IndexOf("OrgName:    Asia Pacific Network Information Centre") > 0)
        {
            response = PostHtmlPage(apnic, apnicFields);
            m = pre.Match(response);
        }
        else if (m.Value.IndexOf("OrgName:    Latin American and Caribbean IP address Regional Registry") > 0)
        {
            response = PostHtmlPage(lacnic, lacnicFields);
            m = pre.Match(response);
        }
        return m.Value;
    }
    else
    {
        return "
No Data

";

    }
}
<script type="text/javascript" src="script/jquery-1.3.2.min.js">script> 
<script type="text/javascript"
  $(document).ready(function() {
    $("span").each(function() {
      $(this).click(function() {
        $("#loading").html("");
        $("#dns").empty();
        $.ajax({
          type: "POST",
          contentType: "application/json; charset=utf-8",
          data: "{ip: '" + $(this).html() + "'}",
          url: "IPLookup.aspx/GetWhois",
          dataType: "json",
          success: function(response) {
            $("#loading").empty();
            $("#dns").html(response.d);
          }
        });
      });
    });
  });
script> 

Wednesday, June 15, 2011


Hit Counter for Logging Users with ASP.net and SQL Server when you don't have access to Windows Server IIS Log Files from Shared/Free Hosting

T-SQL Table for persistent storage and Stored Procedure to save visitor info


SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Log](
LogID int not null identity(1,1) CONSTRAINT PK_Log PRIMARY KEY ([LogID]) ,
[Created] [datetime] NOT NULL  ,
[Page] [varchar](255) NOT NULL,
[UserAgent] [varchar](255) NULL,
[IP] [varchar](15) NULL,  --IPv4 only
[Referrer] [varchar](max) NULL,
[LangCult] [varchar](5) NULL
) ON [PRIMARY]

GO

ALTER PROCEDURE LogCreate
@Created smalldatetime,
@Page varchar(255) = null ,
@UserAgent varchar(255) = null,
@IP varchar(15) = null,
@Referrer varchar(max) = null,
@LangCult varchar(5) = null
AS
BEGIN
INSERT INTO my_Log
(Created, Page, UserAgent, IP, Referrer, [LangCult])
VALUES
(@Created, @Page, @UserAgent, @IP, @Referrer, @LangCult)

RETURN 0
END
GO


C#  This code is called by other pages using  <img src="http://www.YourSite.com/KeepAlive.aspx" height="0" width="0" />

<%@ import namespace="System.Web"%>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Page Language="C#" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    public void Page_Load(object sender, EventArgs e)
    {
        // to encrypt a connection string in web.config:  aspnet_regiis -pe "connectionStrings" -app "/MyWebsite" -prov "DataProtectionConfigurationProvider"

        string strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["myConnectionStringfromWebConfig"].ConnectionString;

        if (strConnString != null)
        {
            using (SqlConnection cn = new SqlConnection(strConnString))
            {
                using (SqlCommand cmd = new SqlCommand("LogCreate", cn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("@Created", SqlDbType.SmallDateTime).Value = DateTime.Now;
                    cmd.Parameters.Add("@Page", SqlDbType.VarChar).Value = this.Request.Url.AbsolutePath;  //Request.CurrentExecutionFilePath)
                    cmd.Parameters.Add("@UserAgent", SqlDbType.VarChar).Value = this.Request.UserAgent;
                    cmd.Parameters.Add("@IP", SqlDbType.VarChar).Value = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

                    string sReferrer = string.Empty;
                    if (Request.UrlReferrer != null) sReferrer = Request.UrlReferrer.ToString();
                    cmd.Parameters.Add("@Referrer", SqlDbType.VarChar).Value = sReferrer;
                 
                    string sUserLanguage = string.Empty;
                    if (Request.UserLanguages[0] != null) sUserLanguage = Request.UserLanguages[0];
                    cmd.Parameters.Add("@LangCult", SqlDbType.VarChar).Value = sUserLanguage;
                 
                    cn.Open();
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }

This'll get you started to view the log.  There's no filtering so if your site experiences a DDOS attack, each page hit will be recorded, making your SQL Server MDF file grow rapidly. 

<%@ import namespace="System.Web"%>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Page Language="C#" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    public void Page_Load(object sender, EventArgs e)
    {
        // to encrypt a connection string in web.config:  aspnet_regiis -pe "connectionStrings" -app "/MyWebsite" -prov "DataProtectionConfigurationProvider"

        string strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["myConnectionStringfromWebConfig"].ConnectionString;

        if (strConnString != null)
        {
            using (SqlConnection cn = new SqlConnection(strConnString))
            {
                using (SqlCommand cmd = new SqlCommand("LogCreate", cn))
                {

                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = "SELECT DISTINCT  ISNULL([LangCult],'') AS [LangCult], [IP], [UserAgent], ISNULL([Referrer],'') AS [Referrer] FROM [ezpl8_Log]";
                 
                    // SqlDataReader is fast-forward, read only
                    SqlDataReader myReader = cmd.ExecuteReader();
                    if (myReader.Read())
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.AppendFormat("<table style=\"font-size:{0}pt;font-family:arial;\">", "8");
                     
                        do
                        {
                            while (myReader.Read())
                                sb.AppendFormat("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>", myReader.GetString(0), myReader.GetString(1), myReader.GetString(2), myReader.GetString(3));
                        } while (myReader.NextResult());

                        sb.AppendFormat("</table>");
                        Response.Write(sb.ToString()); ;
                    }

                }
            }
        }
    }



Young Roofers

Young Roofers
Men Making

Fly. Be Free.

Fly. Be Free.
Man Ready to Hang ... Glide

Burke

Burke
A Man in the Making - 12 years old

Blackwater

Blackwater
A Man in the Mud