0

我一直在搜索这个网站,并看到了多个时间增量的参考,但还没有完全找到我要找的东西。

基本上,我有一个通信服务器接收到的消息列表,我想计算每条消息发出和接收之间的延迟时间。它看起来像这样:

161336.934072 - TMsg out: [O] enter order. RefID [123] OrdID [4568]
161336.934159 - TMsg in: [A] accepted. ordID [456]  RefNumber [123] 

与这些消息混合在一起的还有其他消息,但是,我只想捕获 Out 消息和具有相同 RefID 的消息之间的差异。

到目前为止,从主日志中梳理出哪些消息是Tmessages我一直在这样做,但它确实效率低下。我不需要每次都制作新文件。:

big_file = open('C:/Users/kdalton/Documents/Minicomm.txt', 'r')
small_file1 = open('small_file1.txt', 'w')
for line in big_file:
    if 'T' in line: small_file1.write(line)
big_file.close()
small_file1.close()

如何计算两条消息之间的时间增量并从主日志中整理出这些消息?

4

2 回答 2

1

首先,不要写出原始日志行。其次使用字典。

tdeltas = {} # this is an empty dict
if "T" in line:
   get Refid number
   if Refid in tedeltas:
      tdeltas[Refid] = timestamp - tdeltas[Refid]
   else:
      tdeltas[Refid] = timestamp

然后在最后,转换为列表并打印

allRefids = sorted(tdeltas.keys())
for k in allRefids:
   print k+": "+tdeltas[k]+" secs"

您可能希望将日期转换timedatetime模块中的对象,然后使用 timedelta 对象存储在字典中。这项任务可能不值得,但值得学习如何使用 datetime 模块。

此外,我已经忽略了从输入字符串中解析 Refid 以及将时间从字符串转换为浮点数并返回的可能问题。

实际上,如果你有一个不被接受的 Refid,仅仅存储 deltas 会引起混乱。如果我真的这样做,我会在值中存储一个元组,其中包含开始日期时间、结束日期时间和增量。对于新记录,它看起来像这样:(161336.934072,0,0)并且在检测到接受后,它看起来像这样:(161336.934072,161336.934159,.000087)。如果日志记录活动是连续的,比如说一个 24x7 运行的全球电子商务网站,那么我会定期扫描字典以查找具有非零增量的任何条目,报告它们并删除它们。然后我会取剩余的值,按开始日期时间对它们进行排序,然后报告并删除任何开始日期时间太旧的地方,因为这表明失败的事务永远不会完成。

此外,在真正的电子商务网站中,我可能会考虑使用 Redis 或 Memcache 之类的东西作为外部字典,以便报告和维护可以由另一个服务器/应用程序完成。

于 2011-11-23T17:47:11.623 回答
0

此生成器函数返回一个元组,其中包含 id 以及 out 和 in 消息之间的时间戳差异。(如果您想对时差做一些更复杂的事情,请查看datetime.timedelta)。请注意,这假设 out 消息总是出现在消息之前。

def get_time_deltas(infile):
    entries = (line.split() for line in open(INFILE, "r"))
    ts = {} 
    for e in entries:
        if len(e) == 11 and " ".join(e[2:5]) == "TMsg out: [O]":
            ts[e[8]] = e[0]   # store timestamp for id
        elif len(e) == 10 and " ".join(e[2:5]) == "TMsg in: [A]":   
            in_ts, ref_id = e[0], e[9]
            # Raises KeyError if out msg not seen yet. Handle if required.
            out_ts = ts.pop(ref_id)   # get ts for this id
            yield (ref_id[1:-1], float(in_ts) - float(out_ts))

您现在可以从中获取列表:

>>> INFILE = 'C:/Users/kdalton/Documents/Minicomm.txt'
>>> list(get_time_deltas(INFILE))
[('123', 8.699999307282269e-05), ('1233', 0.00028700000257231295)]

或将其写入文件:

>>> with open("out.txt", "w") as outfile:
...     for id, td in get_time_deltas(INFILE):
...          outfile.write("Msg %s took %f seconds\n", (id, td))

或者将其链接到更复杂的工作流程中。


更新:

(响应查看实际数据)

试试这个:

def get_time_deltas(infile):
    entries = (line.split() for line in open(INFILE, "r"))
    ts = {} 
    for e in entries:
        if " ".join(e[2:5]) == "OuchMsg out: [O]":
            ts[e[8]] = e[0]   # store timestamp for id
        elif " ".join(e[2:5]) == "OuchMsg in: [A]":   
            in_ts, ref_id = e[0], e[7]
            out_ts = ts.pop(ref_id, None)   # get ts for this id
            # TODO: handle case where out_ts = None (no id found)
            yield (ref_id[1:-1], float(in_ts) - float(out_ts))

INFILE = 'C:/Users/kdalton/Documents/Minicomm.txt'
print list(get_time_deltas(INFILE))

此版本的变化:

  • 字段的数量与发布的示例输入中所述的不同。删除了基于条目号的检查
  • ordIDfor inmessages 是消息中匹配的refID那个out
  • 用来OuchMsg代替TMsg

更新 2

要获得增量的平均值:

deltas = [d for _, d in get_time_deltas(INFILE)] 
average = sum(deltas) / len(deltas)

或者,如果您之前生成了一个包含所有数据的列表,我们可以重用它而不是重新解析文件:

data = list(get_time_deltas(INFILE))
# .. use data for something some operation ...

# calculate average using the list
average = sum(d for _, d in data) / len(data)
于 2011-11-23T18:04:27.543 回答