IIS中加入piwik跟踪代码
好久没来写博了...
今天写一下如何在IIS中加入piwik跟踪代码。
背景:
• piwik 开源php站点统计程序 http://piwik.org
• HttpModule: http://www.cnblogs.com/stwyhm/archive/2006/08/09/471729.html
实现思路:通过HttpModule在aspx页面的body前加入统计代码。
代码实现:
1. 新建dll项目
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
namespace PiwikAnalytics
{
/// 修改于网上流传的Google Analytics (https://www.google.com/analytics/) script
public class PiwikAnalyticsModule : IHttpModule
{
static string GoogleScript = string.Empty;
HttpApplication application;
public void Dispose()
{
//context.BeginRequest -= new EventHandler(OnBeginRequest);
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(OnBeginRequest);
application = context;
}
void OnBeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
//web.config中定义的站点字符串,后面会有介绍
string sites = ConfigurationManager.AppSettings["PiwikAnalyticsSites"];
//此处未进行异常处理,大家发布时记得加上哦~
string[] siteArr = sites.Split(';');
string siteid = "5";
foreach (string site in siteArr)
{
if (application.Request.Url.OriginalString.ToLower().IndexOf(site.Split(',')[0]) > 0)
{
siteid = site.Split(',')[1];
}
}
GoogleScript = @" <!-- Piwik -->
<script type=""text/javascript"">
var pkBaseURL = ((""https:"" == document.location.protocol) ? ""https://yourpiwik.com/piwik/"" : ""http://yourpiwik.com/piwik/"");
document.write(unescape(""%3Cscript src='"" + pkBaseURL + ""piwik.js' type='text/javascript'%3E%3C/script%3E""));
</script>
<script type=""text/javascript"">
//try {
var piwikTracker = Piwik.getTracker(pkBaseURL + ""piwik.php"", " + siteid + @");
piwikTracker.trackPageView();
piwikTracker.enableLinkTracking();
//} catch (err) { }
</script>
<noscript>
<p>
<img id=""img1"" src=""http://pm.taobao.ali.com/piwik/piwik.php?idsite="+siteid+@""" style=""border: 0"" alt="""" /></p>
</noscript>
<!-- End Piwik Tag -->";
//这里需要针对ASPX页面进行拦截
string[] temp = application.Request.CurrentExecutionFilePath.Split('.');
if (temp.Length > 0 && temp[temp.Length - 1].ToLower() == "aspx")
{
application.Response.Filter = new AnalyticsStream(application.Response.Filter);
}
}
class AnalyticsStream : Stream
{
Stream innerStream;
MemoryStream memory = new MemoryStream();
public AnalyticsStream(Stream innerStream)
{
this.innerStream = innerStream;
}
public override void Close()
{
memory.Position = 0;
using (StreamWriter writer = new StreamWriter(innerStream))
{
using (StreamReader reader = new StreamReader(memory))
{
while (!reader.EndOfStream)
{
// Find </body>
if (MatchesOrWrite(reader, writer, '<', null) &&
MatchesOrWrite(reader, writer, '/', "<") &&
MatchesOrWrite(reader, writer, 'b', "</") &&
MatchesOrWrite(reader, writer, 'o', "</b") &&
MatchesOrWrite(reader, writer, 'd', "</bo") &&
MatchesOrWrite(reader, writer, 'y', "</bod") &&
MatchesOrWrite(reader, writer, '>', "</body"))
{
//string script = String.Format(GoogleScript, accountNumber) + "</body>";
writer.Write(GoogleScript);
while (!reader.EndOfStream)
writer.Write((char)reader.Read());
}
}
}
}
base.Close();
}
private bool MatchesOrWrite(StreamReader reader, StreamWriter writer, char target, string buffered)
{
if (!reader.EndOfStream)
{
char current = (char)reader.Read();
if (current == target)
{
return true;
}
else
{
writer.Write(buffered);
writer.Write(current);
}
}
else
{
writer.Write(buffered);
}
return false;
}
public override bool CanRead
{
get { return memory.CanRead; }
}
public override bool CanSeek
{
get { return memory.CanSeek; }
}
public override bool CanWrite
{
get { return memory.CanWrite; }
}
public override void Flush()
{
memory.Flush();
}
public override long Length
{
get { return memory.Length; }
}
public override long Position
{
get
{
return memory.Position;
}
set
{
memory.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
return memory.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
memory.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
memory.Write(buffer, offset, count);
}
}
}
}
2.
编译得到PiwikAnalytics.dll,注册到GAC中【需要强命名的哦~】,不然要每个子站点都拷贝一份。
如何在visual studio中强命名程序集:(推荐) http://www.cnblogs.com/awpatp/archive/2010/02/07/1665530.html
文章中也提到了如果获取程序集的PublicKeyToken,其实不用那么麻烦,把程序集放到GAC中,有一列会显示PublicKeyToken的~。
• GAC注册:http://www.cnblogs.com/mljmalongjiang/archive/2008/07/31/1257135.html
• 另外有种更简便的方式,直接把dll托到 c:\windows\assembly文件夹中【推荐】
另外一种方式强命名程序集:http://www.cnblogs.com/zhongge/articles/1207183.html
经过上述步骤,我们已经把PiwikAnalytics.dll注册到GAC了,那我们在web.config中做一下配置就要大功告成了!
3. web.config默认路径C:\inetpub\wwwroot,如果没有web.config可直接新建的~
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="PiwikAnalyticsSites" value="site,4;meeting,6"/>
</appSettings>
<system.web>
<authentication mode="Windows"/>
<httpModules>
<add name="PiwikAnalytics" type="PiwikAnalytics.PiwikAnalyticsModule"/>
</httpModules>
<compilation debug="true">
<assemblies>
<add assembly="PiwikAnalytics, version=1.0.0.0, Culture=neutral,PublicKeyToken=0c64deee0d840dfb" />
</assemblies>
</compilation>
</system.web>
</configuration>
要记得把从步骤2中得到的PublicKeyToken替换成你自己的哦~
到此时,重启iis,刷新页面。再去piwik中查看,大功告成!
需特别注意的地方:
1. 注册module时,要按照自己的实际情况配置
2. 上述方式不适用于MVC和模板模式开发
3. 每次改写代码的时候都需要重新生成一次DLL,并且重新注册GAC,并且对站点相应应用程序池中的进行回收
More:另外介绍2个pwiki客户端查看软件
• Desktop Web Analytics
• Piwik Connector
Over 收工!
浙公网安备 33010602011771号