我正在写一个有sinatra和heroku的网站,我想找到一种方法来跟踪我网站的每次访问。我见过实际的分析程序(例如google analytics)并选择不使用它们,因为我想自己学习如何做到这一点。
我对访问的定义:
当某人或某物(机器人)访问您的网站时,就会发生访问。它由一个或多个页面浏览/点击组成。一位访问者可以多次访问您的网站。
来源:http://www.opentracker.net/article/hits-or-pageviews
对于每次访问,我想跟踪:
此网站不经常查看,因此我想在使用activerecord访问的postgres数据库中记录每次访问。 日志记录的工作方式是:
ip
,mac_address
,time
和view_id
已登录Visit
PageView
time
和view_id
已登录Visit
数据库格式
示例迁移文件:
class Main < ActiveRecord::Migration
def change
create_table :visits do |item|
item.string :ip
item.string :mac_address
item.datetime :time
item.int :visit_id
end
create_table :pageviews do |item|
item.int :visit_id
item.string :page
item.datetime :time
end
end
答案 0 :(得分:1)
对于每次访问,我想跟踪:
- 访客IP地址
- 时间访问开始(页面已打开)
- 时间访问结束(页面已关闭)
醇>
您之前在列表中也有MAC地址,但只是重申一下 - 它们不是用于路由互联网,只是用于本地网络,因此即使您可以获得该信息,保存该信息也毫无意义。
HTTP是一种无状态协议,这意味着#3不可能通过HTTP方法实现,但可以通过javascript完成。可能最简单的方法是以可接受的间隔轮询,更新时间。
#1和#2已被您的基本服务器日志捕获,它们将是我使用的 - 为什么重复工作? - 但我会添加如何使用Sinatra通过模型来完成它。
如果您使用before
过滤器,则可以轻松捕获#1和#2。 Request object有你想要的一些东西,你需要时间,并确保它是该ip的唯一用户:
before do
# this is pseudo code, Sequel style, you can work this bit out
# for ActiveRecord
user =
if user_id = session[:user]
User[user_id]
else
User.create
end
# you may want to check if there's an existing session for this page
# as refreshes would run this again. It's up to you.
user.add_visit Visit.create(page: request.path,ip: request.ip, start: Time.now.rfc2822])
session[:analytics] = visit.id
session[:user] = user.session_id # *don't* just bung the
# user id in there
end
您需要一条将结束时间记录到
的路线patch "/analytics", :provides => :json do
visit_id = session[:analytics]
user = User[ :session_id => session[:user] ]
visit = user.visits.find(:id => visit_id)
visit.end = Rack::Utils.rfc2822(params[:end])
visit.save
halt 204 # take your pick of success numbers
# you should also check for errors
# and check the input is valid
# and you may want to return some JSON to the
# calling javascript.
# Also think about how to restrict access to this
# route to only authorised callers. Since you're providing the
# javascript, you can place variables in them by generating
# parts on the fly and serving it via a Sinatra route etc.
end
我不会写javascript,这应该是直截了当的。
注意,我基本上把这个代码从我的背后拉出来,所以考虑任何或所有可能会破坏并且不稳定,但是这样你就可以得到这个想法。就像我上面提到的,我可能会削减大部分内容并使用日志和一些明智的正则表达式。