如何计算日志文件条目中每小时的访问次数?

时间:2017-08-22 07:33:45

标签: python python-3.x parsing logging

我有一个日志文件,其中每一行都包含IP地址,访问时间和访问的URL。我想计算每小时的访问次数。

访问时间数据如下所示

[01/Jan/2017:14:15:45 +1000]
[01/Jan/2017:14:15:45 +1000]
[01/Jan/2017:15:16:05 +1000]
[01/Jan/2017:16:16:05 +1000] 

如何改进它以便我不需要为每小时设置变量和if语句?

twoPM = 0
thrPM = 0
fouPM = 0
timeStamp = line.split('[')[1].split(']')[0]
formated_timeStamp = datetime.datetime.strptime(timeStamp,'%d/%b/%Y:%H:%M:%S %z').strftime('%H')
if formated_timeStamp == '14':
    twoPM +=1
if formated_timeStamp == '15':
    thrPM +=1
if formated_timeStamp == '16':
    fouPM +=1

3 个答案:

答案 0 :(得分:3)

  1. 您可以在strptime格式说明中加入括号:

    datetime.datetime.strptime(line.strip(),'[%d/%b/%Y:%H:%M:%S %z]')
    
  2. 您可以使用任何.hour对象的datetime.datetime属性提取小时:

    timestamp = datetime.datetime.strptime(…)
    hour = timestamp.hour
    
  3. 您可以使用collections.Counter计算元素数量:

    from collections import Counter
    
    
    def read_logs(filename):
        with open(filename) as log_file:
             for line in log_file:
                 timestamp = datetime.datetime.strptime(
                         line.strip(),
                         '[%d/%b/%Y:%H:%M:%S %z]')
                 yield timestamp.hour
    
    
    def count_access(log_filename):
        return Counter(read_logs(log_filename))
    
    
    if __name__ == '__main__':
        print(count_access('/path/to/logs/'))
    

答案 1 :(得分:2)

您没有说每小时访问是每天还是什么。所以有很多方法可以实现。但这是一个简单的版本:

import collections
import io

log_data = '''
[01/Jan/2017:14:15:45 +1000]
[01/Jan/2017:14:15:45 +1000]
[01/Jan/2017:15:16:05 +1000]
[01/Jan/2017:16:16:05 +1000]
'''

def filter_lines(file):
    for line in file:
        if line.startswith('['):
            yield line

def extract_hour_from_line(seq):
    for line in seq:
        yield line.split(':')[1]

def access_per_hour(file):

    aph = collections.Counter(extract_hour_from_line(filter_lines(file)))
    return aph


if __name__ == '__main__':
    logfile = io.StringIO(log_data)
    aph = access_per_hour(logfile)
    print(aph)

这使用StringIO将您提供的行作为示例转换为可以读取的内存“文件”。你可以打开你的日志文件,正如你无疑已经做的那样,正常处理这个问题。

collections.Counter类接受一个序列并生成一个类似字典的对象,其中键是序列中的项,值是计数 - 每个序列中出现的次数。

此版本的代码只计算所有不同的小时值,而不考虑访问发生的 date 。也就是说,周二的12:00和周三的12:00被视为同一小时。如果您只是构建按小时需求的直方图,这非常有用。

如果您想进行更高级的分组,可以尝试使用filter_lines功能来限制您想要查看的整行。例如,仅限日期范围之间的行,或仅访问特定URL的行。

如果您希望将不同日期视为不同日期,则可以使用extract_hour_from_line函数构造不同的值 - 例如,连接日期和小时。

答案 2 :(得分:1)

您可以使用字典:

per_hour = {}
per_hour[formated_timeStamp] += 1

所以你会得到一些东西

{'0': 12, '1': 8, '2': 41, ...}

其中键代表一小时。