我在Mongo中有很多系统日志文件,下面是一个例子。我想做的是按天/小时/月在图表中对它们进行分组。该值将是特定时间段内的文档计数。
{
u'syslog_message': u'[10724525.839722] [UFW BLOCK] IN=venet0 OUT= MAC= SRC=1.2.3.4 DST=9.8.7.6 LEN=52 TOS=0x08 PREC=0x20 TTL=50 ID=55384 PROTO=TCP SPT=349 DPT=123 WINDOW=14600 RES=0x00 SYN URGP=0 ',
u'received_from': u'1.3.5.7:1234',
u'@version': u'1',
u'@timestamp': datetime.datetime(2014, 11, 20, 15, 9, 55),
u'syslog_timestamp': u'Nov 20 15:09:55',
u'syslog_facility': u'user-level',
u'syslog_severity': u'notice',
u'host': u'2.4.6.8:2468',
u'syslog_program': u'kernel',
u'syslog_hostname': u'server01',
u'received_at': u'2014-11-20 20:09:55 UTC',
u'message': u'<4>Nov 20 15:09:55 server01 kernel: [10724525.839722] [UFW BLOCK] IN=venet0 OUT= MAC= SRC=1.2.3.4 DST=2.3.4.5 LEN=52 TOS=0x08 PREC=0x20 TTL=50 ID=55384 PROTO=TCP SPT=1234 DPT=543 WINDOW=14600 RES=0x00 SYN URGP=0 ',
u'_id': ObjectId('546e4a93e98673fe8f11a4d2'),
u'type': u'syslog',
u'syslog_severity_code': 5,
u'syslog_facility_code': 1
}
我使用Chartkick在Flask中用Python呈现这些数据,结果很好,但所有消息都在图表上逐一显示。我想制作数月,数周,数小时等的桶。
为此我可以使用键&#39; @ timestamp&#39;中的值。这样可以正常工作,但是在Python中对一个计数进行分组意味着首先检索所有文档并且这不是正确的:D
问题:
我可以在Pymongo中使用什么正确的查询来获取count_by_week等,或者我应该在服务器上使用类似聚合的东西以及它看起来像什么?
四台服务器,由于缺乏计时时间分组,请注意上面的平线。
答案 0 :(得分:2)
您希望在插入时更新计数,如@alernerdev建议的那样,或者您想在服务器上进行聚合。我不熟悉Pymongo,但看起来它使用的语法与我使用过的MongoDB的JavaScript驱动程序非常相似。因此,要将其作为服务器端aggregation,您可以执行以下操作:
db.logs.aggregate([
{"$group": {"_id": {"week": {"$week": "$@timestamp"}, "year": {"$year": "$@timestamp"}}, "count": {"$sum": 1}}}
])
这将按年份和年份对日志条目进行分组,并计算每个组中的文档数。
答案 1 :(得分:1)
您应该以与在检索期间使用它的方式相匹配的方式构建模式 - 换句话说,在进入数据库的过程中进行数据聚合。对于每个插入,使用$ inc和$ set并按小时,天,周等更新所需的统计数据。