之前是用mysql数据库来保存用户的访问日志,现在已经超过2亿了,速度非常慢,还分了三张表,要换一种记录日志的方式。现在暂时没有时间做数据挖掘,要做的只是把日志先存起来,所以直接用linux自带的rsyslog来做。用户访问时,以UDP的方式,将访问信息封装成JSON发到rsyslog的端口,rsyslog会以文本的方式直接记录下来。以后就可以用syslog-ng之类的工具写到mongo或其他数据库。
修改配置文件
新建一个配置文件:
$ sudo vi /etc/rsyslog.d/00-dmyz.conf
默认的日志格式是日期:主机:信息(datetime, host, msg),现在只需要保存msg,host和datetime之类都写在的msg里,以日期作为文件名来存放日志:
$template logFormat, "%rawmsg%\n"
$template DynaFile, "/var/log/%$YEAR%-%$MONTH%-%$DAY%.log"
$ActionFileDefaultTemplate logFormat
user.info -?DynaFile
然后修改 /etc/rsyslog.conf 打开UDP端口用来接收日志:
# provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
写入数据
python提供了socket,可以先用以下列方式测试写入是否正常:
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto(simplejson.dumps("log_id": 1),('127.0.0.1',514))
如果一切正常,在/var/log/ 目录下会生成以当前日期作为文件名的.log文件,如果出错,最有可能是权限问题。还有,如果把生成的文件删除了,需要重启一次rsyslog服务,它才会重新生成。
以下是按天从mysql读出日志数据,发送到UDP 514端口的Python代码:
import socket
import simplejson
import datetime
from subprocess import Popen, PIPE
def select_logs_by_time():
alchemy = AlchemyMysql('logs') #这里是读取mysql用的
table = alchemy.query()
i = 0
while i <= 20:
start_datetime = datetime.datetime.strptime('2012-02-10 00:00:00', "%Y-%m-%d %H:%M:%S") + datetime.timedelta(days=i)
end_datetime = datetime.datetime.strptime('2011-02-10 23:59:59', "%Y-%m-%d %H:%M:%S") + datetime.timedelta(days=i)
print str(start_datetime) + ' - ' + str(end_datetime)
logs = table.select().where(table.c.date >= str(start_datetime)).where(table.c.date <= str(end_datetime)).execute()
for log in logs:
send_log(log)
date_time = str(start_datetime).split(' ')[0]
Popen(['cp','/var/log/dmyz/2012-06-14.log', '/var/log/dmyz/'+date_time+'.log'], stdout=PIPE)
i = i+1
def send_log(log):
data = {
"thread_id" : log['thread_id'],
"site_id" : log['site_id'],
"user_agent" : log['user_agent'],
"url" : log['url'],
"referer" : log['referer'],
"user_id" : log['user_id'],
"ip" : log['ip'],
"elapsed_time" : log['elapsed_time'],
# "unique" : log['unique']
}
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto(simplejson.dumps(data),('127.0.0.1',514))
if __name__ == '__main__':
select_logs_by_time()
效果是,现在每天近千万的PV,生成的日志文件是1G左右,用bzip2压缩后只有100多MB,需要统计今天的访问量用wc命令就可以了。
网上搜rsyslog,居然直接搜出你这篇。
yeah = =v 那所有阅读转载的人都应该装上多说以表示感谢——这样的
一般的日志记录都是直接用文件记录的吧,用数据库来记录日志很不划算- –
ps. 突然发现在每个博文里好像看不到发表的日期,略蛋疼。