JavaのPID毎に別ファイルに出力するようにしたかったのだが、Windows上では500個ちょっとオープンしたところで"Too Many Open Files"エラーが出たため、500を超えたら一旦すべてクローズするように暫定対処した。できれば参照の少ないファイルから先にクローズしていくようにしたい。Javaで言うところのLinkedHashMapみたいなものは無いのだろうか。
スクリプト言語としてはずいぶん昔にPerlを触った以来だが、やっつけで書きやすい割にPerlよりは可読性が高いように感じる。
import sys import re from datetime import datetime, timedelta from functools import reduce if len(sys.argv) != 3 : print("\nUsage:\npython", sys.argv[0], "logfile yyyy/mm/dd") exit() mydate = datetime.strptime(sys.argv[2], '%Y/%m/%d') mydateStr = mydate.strftime('%Y/%m/%d ') try : f = open(sys.argv[1]) mem = open("mem.log", 'w') mem.write("time,mem av,mem used,mem free,mem shard,mem buff,mem actv, mem in_d,swap av,swap used,swap free,swap cached\n") processes = {} maxtime = "" for line in f : line = line.strip() if re.match(r"^\d\d:\d\d:\d\d", line) : if line[0:2] == "00" and timestamp[0:2] != "00" : mydate = mydate + timedelta(1) mydateStr = mydate.strftime('%Y/%m/%d ') timestamp = line[0:8] elif re.match(r"^Mem", line) : data = re.split(r"\s+", line)[1:9:2] elif re.match(r"^\d+k", line) : data = data + re.split(r"\s+", line)[0:5:2] elif re.match(r"^Swap:", line) : data = data + re.split(r"\s+", line)[1:8:2] prefix = mydateStr + timestamp result = reduce((lambda x,y: x + ',' + y.rstrip('k')), data, prefix) mem.write(result + "\n") elif re.search(r"java", line) : data = re.split(r"\s+", line) if data[0] not in processes : processes[data[0]] = open("Pid-" + data[0] + ".log", 'w') processes[data[0]].write("time,PID,USER,PRI,NI,SIZE,RSS,SHARE,STAT,%CPU,%MEM,TIME,CPU,COMMAND\n") prefix = mydateStr + timestamp result = reduce((lambda x,y: x + ',' + y), data, prefix) processes[data[0]].write(result + "\n") if data[10] > maxtime : maxtime = data[10] maxpid = data[0] if len(processes) > 500 : map(lambda x: x.close(), processes) processes = {} print("maxpid:", maxpid) finally : if f != None : f.close() if mem != None : mem.close() map(lambda x: x.close(), processes)
0 件のコメント:
コメントを投稿