1 | #!/usr/bin/env python
|
---|
2 | #
|
---|
3 | # Copyright (c) 2010 Brian Knox (taotetek@gmail.com)
|
---|
4 | # License: GNU LGPLv3
|
---|
5 | #
|
---|
6 | # This file is part of Multi-Mechanize
|
---|
7 | #
|
---|
8 | """a collection of functions and classes for multi-mechanize results files"""
|
---|
9 |
|
---|
10 | import re
|
---|
11 | import fileinput
|
---|
12 | from datetime import datetime
|
---|
13 |
|
---|
14 | try:
|
---|
15 | from sqlalchemy.ext.declarative import declarative_base
|
---|
16 | from sqlalchemy.orm import sessionmaker, relation
|
---|
17 | from sqlalchemy import create_engine
|
---|
18 | from sqlalchemy import Column, Integer, String, Float, DateTime
|
---|
19 | from sqlalchemy import ForeignKey, UniqueConstraint
|
---|
20 | except ImportError:
|
---|
21 | print "(optional: please install sqlalchemy to enable db logging)"
|
---|
22 |
|
---|
23 |
|
---|
24 | Base = declarative_base()
|
---|
25 |
|
---|
26 | class GlobalConfig(Base):
|
---|
27 | """class representing a muli-mechanize global config"""
|
---|
28 | __tablename__ = 'mechanize_global_configs'
|
---|
29 |
|
---|
30 | id = Column(Integer, nullable=False, primary_key=True)
|
---|
31 | run_time = Column(Integer, nullable=False)
|
---|
32 | rampup = Column(Integer, nullable=False)
|
---|
33 | results_ts_interval = Column(Integer, nullable=False)
|
---|
34 | user_group_configs = relation("UserGroupConfig",
|
---|
35 | primaryjoin="UserGroupConfig.mechanize_global_configs_id==GlobalConfig.id")
|
---|
36 | results = relation("ResultRow",
|
---|
37 | primaryjoin="GlobalConfig.id==ResultRow.mechanize_global_configs_id")
|
---|
38 |
|
---|
39 | def __init__(self, run_time=None, rampup=None, results_ts_interval=None):
|
---|
40 | self.run_time = str(run_time)
|
---|
41 | self.rampup = int(rampup)
|
---|
42 | """rampup time for the rest run"""
|
---|
43 | self.results_ts_interval = int(results_ts_interval)
|
---|
44 |
|
---|
45 | def __repr__(self):
|
---|
46 | return "<GlobalConfig('%i', '%i', '%i')>" % (
|
---|
47 | self.run_time, self.rampup, self.results_ts_interval)
|
---|
48 |
|
---|
49 | class UserGroupConfig(Base):
|
---|
50 | """class representing a multi-mechanize user group config"""
|
---|
51 | __tablename__ = 'mechanize_user_group_configs'
|
---|
52 |
|
---|
53 | id = Column (Integer, nullable=False, primary_key=True)
|
---|
54 | mechanize_global_configs_id = Column(Integer, ForeignKey('mechanize_global_configs.id'), nullable=False)
|
---|
55 | user_group = Column(String(50), nullable=False)
|
---|
56 | threads = Column(Integer, nullable=False)
|
---|
57 | script = Column(String(50), nullable=False)
|
---|
58 |
|
---|
59 | def __init__(self, user_group=None, threads=None, script=None):
|
---|
60 | self.user_group = str(user_group)
|
---|
61 | self.threads = int(threads)
|
---|
62 | self.script = str(script)
|
---|
63 |
|
---|
64 | def __repr__(self):
|
---|
65 | return "<UserGroupConfig('%s','%s','%s')>" % (
|
---|
66 | self.user_group, self.threads, self.script)
|
---|
67 |
|
---|
68 | class ResultRow(Base):
|
---|
69 | """class representing a multi-mechanize results.csv row"""
|
---|
70 | __tablename__ = 'mechanize_results'
|
---|
71 | __table_args__ = (
|
---|
72 | UniqueConstraint('run_id','trans_count', name='uix_1')
|
---|
73 | )
|
---|
74 |
|
---|
75 | id = Column(Integer, nullable=False, primary_key=True)
|
---|
76 | mechanize_global_configs_id = Column(Integer,
|
---|
77 | ForeignKey('mechanize_global_configs.id'), nullable=False)
|
---|
78 | project_name = Column(String(50), nullable=False, index=True)
|
---|
79 | run_id = Column(DateTime, nullable=False, index=True)
|
---|
80 | trans_count = Column(Integer, nullable=False, index=True)
|
---|
81 | elapsed = Column(Float, nullable=False, index=True)
|
---|
82 | epoch = Column(Float, nullable=False, index=True)
|
---|
83 | user_group_name = Column(String(50), nullable=False)
|
---|
84 | scriptrun_time = Column(Float, nullable=False)
|
---|
85 | error = Column(String(255))
|
---|
86 | custom_timers = Column(String(50))
|
---|
87 |
|
---|
88 | global_config = relation("GlobalConfig",
|
---|
89 | primaryjoin="ResultRow.mechanize_global_configs_id==GlobalConfig.id")
|
---|
90 |
|
---|
91 | timers = relation("TimerRow",
|
---|
92 | primaryjoin="ResultRow.id==TimerRow.mechanize_results_id")
|
---|
93 |
|
---|
94 | def __init__(self, project_name=None, run_id=None, trans_count=None,
|
---|
95 | elapsed=None, epoch=None, user_group_name=None,
|
---|
96 | scriptrun_time=None, error=None, custom_timers=None):
|
---|
97 | self.project_name = str(project_name)
|
---|
98 | self.run_id = run_id
|
---|
99 | self.trans_count = int(trans_count)
|
---|
100 | self.elapsed = float(elapsed)
|
---|
101 | self.epoch = int(epoch)
|
---|
102 | self.user_group_name = str(user_group_name)
|
---|
103 | self.scriptrun_time = float(scriptrun_time)
|
---|
104 | self.error = str(error)
|
---|
105 | self.custom_timers = str(custom_timers)
|
---|
106 |
|
---|
107 | def __repr__(self):
|
---|
108 | return "<ResultRow('%s','%s','%i','%.3f','%i','%s','%.3f','%s','%s')>" % (
|
---|
109 | self.project_name, self.run_id, self.trans_count, self.elapsed,
|
---|
110 | self.epoch, self.user_group_name, self.scriptrun_time,
|
---|
111 | self.error, self.custom_timers)
|
---|
112 |
|
---|
113 | class TimerRow(Base):
|
---|
114 | """class representing a multi-mechanize custom timer result"""
|
---|
115 | __tablename__ = 'mechanize_custom_timers'
|
---|
116 | id = Column(Integer, nullable=False, primary_key=True)
|
---|
117 | mechanize_results_id = Column(Integer,
|
---|
118 | ForeignKey('mechanize_results.id'), nullable=False)
|
---|
119 | timer_name = Column(String(50), nullable=False, index=True)
|
---|
120 | elapsed = Column(Float, nullable=False, index=True)
|
---|
121 |
|
---|
122 | def __init__(self, timer_name=None, elapsed=None):
|
---|
123 | self.timer_name = str(timer_name)
|
---|
124 | self.elapsed = int(elapsed)
|
---|
125 |
|
---|
126 | def __repr__(self):
|
---|
127 | return "<TimerRow('%s', '%s')>" % (self.timer_name, self.elapsed)
|
---|
128 |
|
---|
129 | result_rows = relation("ResultRow",
|
---|
130 | primaryjoin="TimerRow.mechanize_results_id==ResultRow.id")
|
---|
131 |
|
---|
132 | def load_results_database(project_name, run_localtime, results_dir,
|
---|
133 | results_database, run_time, rampup, results_ts_interval,
|
---|
134 | user_group_configs):
|
---|
135 | """parse and load a multi-mechanize results csv file into a database"""
|
---|
136 |
|
---|
137 | logline_re = re.compile('(.+),(.+),(.+),(.+),(.+),(.?),(\{.+\})')
|
---|
138 |
|
---|
139 | engine = create_engine(results_database, echo=False)
|
---|
140 | ResultRow.metadata.create_all(engine)
|
---|
141 | TimerRow.metadata.create_all(engine)
|
---|
142 | GlobalConfig.metadata.create_all(engine)
|
---|
143 | UserGroupConfig.metadata.create_all(engine)
|
---|
144 |
|
---|
145 | sa_session = sessionmaker(bind=engine)
|
---|
146 | sa_current_session = sa_session()
|
---|
147 |
|
---|
148 | run_id = datetime(run_localtime.tm_year, run_localtime.tm_mon,
|
---|
149 | run_localtime.tm_mday, run_localtime.tm_hour, run_localtime.tm_min,
|
---|
150 | run_localtime.tm_sec)
|
---|
151 |
|
---|
152 | results_file = results_dir + 'results.csv'
|
---|
153 |
|
---|
154 | global_config = GlobalConfig(run_time, rampup, results_ts_interval)
|
---|
155 | sa_current_session.add(global_config)
|
---|
156 |
|
---|
157 | for i, ug_config in enumerate(user_group_configs):
|
---|
158 | user_group_config = UserGroupConfig(ug_config.name,
|
---|
159 | ug_config.num_threads, ug_config.script_file)
|
---|
160 | global_config.user_group_configs.append(user_group_config)
|
---|
161 |
|
---|
162 | for line in fileinput.input([results_file]):
|
---|
163 | line = line.rstrip()
|
---|
164 | match = logline_re.match(line)
|
---|
165 | if match:
|
---|
166 | result_row = ResultRow(project_name, run_id, match.group(1),
|
---|
167 | match.group(2), match.group(3), match.group(4),
|
---|
168 | match.group(5), match.group(6), match.group(7))
|
---|
169 |
|
---|
170 | global_config.results.append(result_row)
|
---|
171 | timer_data = eval(match.group(7))
|
---|
172 | for index in timer_data:
|
---|
173 | timer_row = TimerRow(index, timer_data[index])
|
---|
174 | result_row.timers.append(timer_row)
|
---|
175 |
|
---|
176 | sa_current_session.add(result_row)
|
---|
177 |
|
---|
178 | sa_current_session.commit()
|
---|
179 | sa_current_session.close()
|
---|