Skip to content

Commit c1fd50b

Browse files
committed
Merge remote-tracking branch 'vector-im/j94/call-metrics-alternative'
2 parents 974fc48 + cbdeabc commit c1fd50b

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

mautrix/api.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,17 @@
2020

2121
from mautrix.errors import make_request_error, MatrixConnectionError, MatrixRequestError
2222
from mautrix.util.logging import TraceLogger
23+
from mautrix.util.opt_prometheus import Counter
2324
from mautrix import __version__ as mautrix_version, __optional_imports__
2425

2526
if __optional_imports__:
2627
# Safe to import, but it's not actually needed, so don't force-import the whole types module.
2728
from mautrix.types import JSON
2829

30+
API_CALLS = Counter("bridge_matrix_api_calls",
31+
"The number of Matrix client API calls made", ("method",))
32+
API_CALLS_FAILED = Counter("bridge_matrix_api_calls_failed",
33+
"The number of Matrix client API calls which failed", ("method",))
2934

3035
class APIPath(Enum):
3136
"""
@@ -251,7 +256,8 @@ async def request(self, method: Method, path: PathBuilder | str,
251256
content: dict | list | bytes | str | None = None,
252257
headers: dict[str, str] | None = None,
253258
query_params: Mapping[str, str] | None = None,
254-
retry_count: int | None = None) -> JSON:
259+
retry_count: int | None = None,
260+
metrics_method: str | None = "") -> JSON:
255261
"""
256262
Make a raw Matrix API request.
257263
@@ -295,8 +301,12 @@ async def request(self, method: Method, path: PathBuilder | str,
295301
backoff = 4
296302
while True:
297303
self._log_request(method, path, content, orig_content, query_params, req_id)
304+
API_CALLS.labels(method=metrics_method).inc()
298305
try:
299306
return await self._send(method, full_url, content, query_params, headers or {})
307+
except Exception:
308+
API_CALLS_FAILED.labels(method=metrics_method).inc()
309+
raise
300310
except MatrixRequestError as e:
301311
if retry_count > 0 and e.http_status in (502, 503, 504):
302312
self.log.warning(f"Request #{req_id} failed with HTTP {e.http_status}, "

mautrix/appservice/api/appservice.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ def request(self, method: Method, path: PathBuilder,
167167
content: Optional[Union[Dict, bytes, str]] = None, timestamp: Optional[int] = None,
168168
headers: Optional[Dict[str, str]] = None,
169169
query_params: Optional[Dict[str, Any]] = None,
170-
retry_count: Optional[int] = None) -> Awaitable[Dict]:
170+
retry_count: Optional[int] = None, metrics_method: Optional[str] = ""
171+
) -> Awaitable[Dict]:
171172
"""
172173
Make a raw HTTP request, with optional AppService timestamp massaging and external_url
173174
setting.
@@ -193,7 +194,8 @@ def request(self, method: Method, path: PathBuilder,
193194
if not self.is_real_user:
194195
query_params["user_id"] = self.identity or self.bot_mxid
195196

196-
return super().request(method, path, content, headers, query_params, retry_count)
197+
return super().request(method, path, content, headers, query_params, retry_count,
198+
metrics_method)
197199

198200

199201
class ChildAppServiceAPI(AppServiceAPI):

mautrix/client/api/events.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def sync(self, since: SyncToken = None, timeout: int = 30000, filter_id: FilterI
5454
request["full_state"] = "true" if full_state else "false"
5555
if set_presence:
5656
request["set_presence"] = str(set_presence)
57-
return self.api.request(Method.GET, Path.sync, query_params=request, retry_count=0)
57+
return self.api.request(Method.GET, Path.sync, query_params=request, retry_count=0, metrics_method="sync")
5858

5959
# endregion
6060
# region 8.3 Getting events for a room
@@ -76,7 +76,7 @@ async def get_event(self, room_id: RoomID, event_id: EventID) -> Event:
7676
.. _/event/{eventId} API reference:
7777
https://matrix.org/docs/spec/client_server/r0.5.0#get-matrix-client-r0-rooms-roomid-event-eventid
7878
"""
79-
content = await self.api.request(Method.GET, Path.rooms[room_id].event[event_id])
79+
content = await self.api.request(Method.GET, Path.rooms[room_id].event[event_id], metrics_method="getEvent")
8080
try:
8181
return Event.deserialize(content)
8282
except SerializerError as e:
@@ -102,7 +102,8 @@ async def get_state_event(self, room_id: RoomID, event_type: EventType,
102102
https://matrix.org/docs/spec/client_server/r0.5.0#get-matrix-client-r0-rooms-roomid-state-eventtype-statekey
103103
"""
104104
content = await self.api.request(Method.GET,
105-
Path.rooms[room_id].state[event_type][state_key])
105+
Path.rooms[room_id].state[event_type][state_key],
106+
metrics_method="getStateEvent")
106107
try:
107108
return state_event_content_map[event_type].deserialize(content)
108109
except KeyError:
@@ -123,7 +124,7 @@ async def get_state(self, room_id: RoomID) -> List[StateEvent]:
123124
.. _/state API reference:
124125
https://matrix.org/docs/spec/client_server/r0.5.0#get-matrix-client-r0-rooms-roomid-state
125126
"""
126-
content = await self.api.request(Method.GET, Path.rooms[room_id].state)
127+
content = await self.api.request(Method.GET, Path.rooms[room_id].state, metrics_method="getState")
127128
try:
128129
return [StateEvent.deserialize(event) for event in content]
129130
except SerializerError as e:
@@ -161,7 +162,7 @@ async def get_members(self, room_id: RoomID, at: Optional[SyncToken] = None,
161162
if not_membership:
162163
query["not_membership"] = not_membership.value
163164
content = await self.api.request(Method.GET, Path.rooms[room_id].members,
164-
query_params=query)
165+
query_params=query, metrics_method="getMembers")
165166
try:
166167
return [StateEvent.deserialize(event) for event in content["chunk"]]
167168
except KeyError:
@@ -188,7 +189,7 @@ async def get_joined_members(self, room_id: RoomID) -> Dict[UserID, Member]:
188189
.. _/members:
189190
https://matrix.org/docs/spec/client_server/r0.5.0#get-matrix-client-r0-rooms-roomid-members
190191
"""
191-
content = await self.api.request(Method.GET, Path.rooms[room_id].joined_members)
192+
content = await self.api.request(Method.GET, Path.rooms[room_id].joined_members, metrics_method="getJoinedMembers")
192193
try:
193194
return {user_id: Member(membership=Membership.JOIN,
194195
displayname=member.get("display_name", ""),
@@ -234,7 +235,7 @@ async def get_messages(self, room_id: RoomID, direction: PaginationDirection,
234235
"filter_json": filter_json,
235236
}
236237
content = await self.api.request(Method.GET, Path.rooms[room_id].messages,
237-
query_params=query_params)
238+
query_params=query_params, metrics_method="getMessages")
238239
try:
239240
return PaginatedMessages(content["start"], content["end"],
240241
[Event.deserialize(event) for event in content["chunk"]])
@@ -276,7 +277,7 @@ async def send_state_event(self, room_id: RoomID, event_type: EventType,
276277
"""
277278
content = content.serialize() if isinstance(content, Serializable) else content
278279
resp = await self.api.request(Method.PUT, Path.rooms[room_id].state[event_type][state_key],
279-
content, **kwargs)
280+
content, **kwargs, metrics_method="sendStateEvent")
280281
try:
281282
return resp["event_id"]
282283
except KeyError:
@@ -311,7 +312,7 @@ async def send_message_event(self, room_id: RoomID, event_type: EventType,
311312
raise ValueError("Event type not given")
312313
url = Path.rooms[room_id].send[event_type][txn_id or self.api.get_txn_id()]
313314
content = content.serialize() if isinstance(content, Serializable) else content
314-
resp = await self.api.request(Method.PUT, url, content, **kwargs)
315+
resp = await self.api.request(Method.PUT, url, content, **kwargs, metrics_method="sendMessageEvent")
315316
try:
316317
return resp["event_id"]
317318
except KeyError:
@@ -515,7 +516,7 @@ async def redact(self, room_id: RoomID, event_id: EventID, reason: Optional[str]
515516
https://matrix.org/docs/spec/client_server/r0.5.0#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
516517
"""
517518
url = Path.rooms[room_id].redact[event_id][self.api.get_txn_id()]
518-
resp = await self.api.request(Method.PUT, url, content={"reason": reason}, **kwargs)
519+
resp = await self.api.request(Method.PUT, url, content={"reason": reason}, **kwargs, metrics_method="redact")
519520
try:
520521
return resp["event_id"]
521522
except KeyError:

pyproject.toml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[tool.isort]
2+
profile = "black"
3+
force_to_top = "typing"
4+
from_first = true
5+
line_length = 99
6+
7+
[tool.black]
8+
line-length = 99
9+
target-version = ["py37"]

0 commit comments

Comments
 (0)