Codebase list python-osprofiler / ab01236
Merge "Unify and fix `list_traces` function" Zuul authored 6 years ago Gerrit Code Review committed 6 years ago
6 changed file(s) with 66 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
167167 fields = ("base_id", "timestamp")
168168 pretty_table = prettytable.PrettyTable(fields)
169169 pretty_table.align = "l"
170 traces = engine.list_traces({}, fields)
170 traces = engine.list_traces(fields)
171171 for trace in traces:
172172 row = [trace[field] for field in fields]
173173 pretty_table.add_row(row)
5252 and implemented by any class derived from this class.
5353 """
5454
55 default_trace_fields = {"base_id", "timestamp"}
56
5557 def __init__(self, connection_str, project=None, service=None, host=None):
5658 self.connection_str = connection_str
5759 self.project = project
100102 """Returns backend specific name for the driver."""
101103 return cls.__name__
102104
103 def list_traces(self, query, fields):
104 """Returns array of all base_id fields that match the given criteria
105
106 :param query: dict that specifies the query criteria
107 :param fields: iterable of strings that specifies the output fields
105 def list_traces(self, fields=None):
106 """Query all traces from the storage.
107
108 :param fields: Set of trace fields to return. Defaults to 'base_id'
109 and 'timestamp'
110 :return List of traces, where each trace is a dictionary containing
111 at least `base_id` and `timestamp`.
108112 """
109113 raise NotImplementedError("{0}: This method is either not supported "
110114 "or has to be overridden".format(
8989
9090 return result
9191
92 def list_traces(self, query={"match_all": {}}, fields=[]):
92 def list_traces(self, fields=None):
9393 """Returns array of all base_id fields that match the given criteria
9494
9595 :param query: dict that specifies the query criteria
9696 :param fields: iterable of strings that specifies the output fields
9797 """
98 for base_field in ["base_id", "timestamp"]:
99 if base_field not in fields:
100 fields.append(base_field)
98 query = {"match_all": {}}
99 fields = set(fields or self.default_trace_fields)
101100
102101 response = self.client.search(index=self.index_name,
103102 doc_type=self.conf.profiler.es_doc_type,
5959 data["service"] = self.service
6060 self.db.profiler.insert_one(data)
6161
62 def list_traces(self, query, fields=[]):
63 """Returns array of all base_id fields that match the given criteria
62 def list_traces(self, fields=None):
63 """Query all traces from the storage.
6464
65 :param query: dict that specifies the query criteria
66 :param fields: iterable of strings that specifies the output fields
65 :param fields: Set of trace fields to return. Defaults to 'base_id'
66 and 'timestamp'
67 :return List of traces, where each trace is a dictionary containing
68 at least `base_id` and `timestamp`.
6769 """
68 ids = self.db.profiler.find(query).distinct("base_id")
70 fields = set(fields or self.default_trace_fields)
71 ids = self.db.profiler.find("*").distinct("base_id")
6972 out_format = {"base_id": 1, "timestamp": 1, "_id": 0}
7073 out_format.update({i: 1 for i in fields})
7174 return [self.db.profiler.find(
6969 data["timestamp"]
7070 self.db.set(key, jsonutils.dumps(data))
7171
72 def list_traces(self, query="*", fields=[]):
73 """Returns array of all base_id fields that match the given criteria
72 def list_traces(self, fields=None):
73 """Query all traces from the storage.
7474
75 :param query: string that specifies the query criteria
76 :param fields: iterable of strings that specifies the output fields
75 :param fields: Set of trace fields to return. Defaults to 'base_id'
76 and 'timestamp'
77 :return List of traces, where each trace is a dictionary containing
78 at least `base_id` and `timestamp`.
7779 """
78 for base_field in ["base_id", "timestamp"]:
79 if base_field not in fields:
80 fields.append(base_field)
81 ids = self.db.scan_iter(match=self.namespace + query)
80 fields = set(fields or self.default_trace_fields)
81
82 # With current schema every event is stored under its own unique key
83 # To query all traces we first need to get all keys, then
84 # get all events, sort them and pick up only the first one
85 ids = self.db.scan_iter(match=self.namespace + "*")
8286 traces = [jsonutils.loads(self.db.get(i)) for i in ids]
87 traces.sort(key=lambda x: x["timestamp"])
88 seen_ids = set()
8389 result = []
8490 for trace in traces:
85 result.append({key: value for key, value in trace.iteritems()
86 if key in fields})
91 if trace["base_id"] not in seen_ids:
92 seen_ids.add(trace["base_id"])
93 result.append({key: value for key, value in trace.items()
94 if key in fields})
8795 return result
8896
8997 def get_report(self, base_id):
125125 enabled=True,
126126 trace_sqlalchemy=False,
127127 hmac_keys="SECRET_KEY")
128
129 def test_list_traces(self):
130 # initialize profiler notifier (the same way as in services)
131 initializer.init_from_conf(
132 CONF, {}, self.PROJECT, self.SERVICE, "host")
133 profiler.init("SECRET_KEY")
134
135 # grab base_id
136 base_id = profiler.get().get_base_id()
137
138 # execute profiled code
139 foo = Foo()
140 foo.bar(1)
141
142 # instantiate report engine (the same way as in osprofiler CLI)
143 engine = base.get_driver(CONF.profiler.connection_string,
144 project=self.PROJECT,
145 service=self.SERVICE,
146 host="host",
147 conf=CONF)
148
149 # generate the report
150 traces = engine.list_traces()
151 LOG.debug("Collected traces: %s", traces)
152
153 # ensure trace with base_id is in the list of traces
154 self.assertIn(base_id, [t["base_id"] for t in traces])