Skip to content

Commit 50bed92

Browse files
committed
refac/bump: refactoring folder tree and version to 1.0.1
1 parent b95b2d6 commit 50bed92

File tree

5 files changed

+114
-111
lines changed

5 files changed

+114
-111
lines changed

dev/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ twine check dist/*
2828
# upload to testpypi
2929
twine upload -r testpypi dist/*
3030

31+
# upload to pypi
32+
twine upload dist/*
33+
34+
3135
```

sentry_mongo/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Version of the sentry_mongo package
22
__version__ = "1.0.1"
33

4-
from sentry_mongo.__main__ import MongoIntegration
4+
from sentry_mongo.integrations import *

sentry_mongo/__main__.py

Lines changed: 0 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,2 @@
1-
from pymongo import monitoring
2-
import sentry_sdk
3-
from sentry_sdk.integrations import Integration
4-
5-
6-
class MongoIntegration(Integration):
7-
"""
8-
The sentry_sdk integration of MongoDB.
9-
"""
10-
11-
identifier = "mongodb"
12-
13-
@staticmethod
14-
def setup_once():
15-
monitoring.register(MongoCommandListener())
16-
17-
18-
class MongoCommandListener(monitoring.CommandListener):
19-
"""
20-
Create spans using Mongo command listener.
21-
22-
This class handles and store the context of spans, at each executed mongo command we create
23-
a new span and store it for later use. At the end of the command life, we retrieve this span and close it.
24-
"""
25-
26-
_commands_to_listen = ["updates", "deletes", "documents"]
27-
_operations_to_listen = ["filter", "limit", "sort", "skip", "pipeline", "query"]
28-
"""
29-
These are the type of mongo commands/operators that are gonna to be written to a span.
30-
The _commands_to_listen refers to commands that involves tampering with multiple objets.
31-
The _operations_to_listen refers to operations in general that we want to have information saved.
32-
We made this bit so we can keep track of the number of documents affected by the _commands_to_listen,
33-
while _operations_to_listen we wanted to store individual information of any operator involved in the command,
34-
e.g. how many objects to limit.
35-
"""
36-
37-
def __init__(self):
38-
self._spans = dict()
39-
"""
40-
Make sure that every class instance has it's own dict of spans;
41-
Keys on this dict should represent the event.request_id object;
42-
"""
43-
44-
def started(self, event):
45-
"""
46-
Here we gather info about the event, create a new span and store it on memory.
47-
"""
48-
49-
def get_span(event):
50-
cmd_type = str(event.command_name)
51-
command = str(event.command.get(cmd_type))
52-
description = f"mongodb.{command}.{cmd_type}"
53-
data = {}
54-
55-
"""Builds span description"""
56-
for atr in self._operations_to_listen:
57-
value = event.command.get(atr)
58-
if value is not None:
59-
data[atr] = str(value)
60-
description += f".{atr}"
61-
62-
if event.command.get("collection"):
63-
"""Concatenates collection name to description"""
64-
data["collection"] = str(event.command["collection"])
65-
description += f".{data['collection']}"
66-
67-
for atr in self._commands_to_listen:
68-
"""Gather information about the number of documents affected"""
69-
value = event.command.get(atr)
70-
if value is not None:
71-
data[f"number of documents affected by {atr}"] = len(value)
72-
data[atr] = str(value)
73-
74-
span = sentry_sdk.start_span(op="mongodb", description=description)
75-
76-
"""Add tags to the span"""
77-
span.set_tag("db.type", "mongodb")
78-
span.set_tag("db.instance", str(event.database_name))
79-
span.set_tag("db.statement", command)
80-
span.set_tag("request_id", str(event.request_id))
81-
span.set_tag("connection_id", str(event.connection_id))
82-
83-
for k, v in data.items():
84-
"""Append our gathered data to the span"""
85-
span.set_data(k, v)
86-
return span
87-
88-
span = get_span(event)
89-
span = span.__enter__()
90-
91-
if span is not None:
92-
"""Save the span in memory so we can latter use it"""
93-
self._spans[event.request_id] = span
94-
95-
def succeeded(self, event):
96-
self._stop("ok", event)
97-
98-
def failed(self, event):
99-
self._stop("internal_error", event)
100-
101-
def _stop(self, status, event):
102-
"""Finishes span context and removes it from the memory"""
103-
span = self._spans.get(event.request_id, None)
104-
if span is not None:
105-
span.set_status(status)
106-
span.__exit__(None, None, None)
107-
del self._spans[event.request_id]
108-
109-
1101
if __name__ == "__main__":
1112
pass

sentry_mongo/integrations.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
from pymongo import monitoring
2+
import sentry_sdk
3+
from sentry_sdk.integrations import Integration
4+
5+
6+
class MongoIntegration(Integration):
7+
"""
8+
The sentry_sdk integration of MongoDB.
9+
"""
10+
11+
identifier = "mongodb"
12+
13+
@staticmethod
14+
def setup_once():
15+
monitoring.register(MongoCommandListener())
16+
17+
18+
class MongoCommandListener(monitoring.CommandListener):
19+
"""
20+
Create spans using Mongo command listener.
21+
22+
This class handles and store the context of spans, at each executed mongo command we create
23+
a new span and store it for later use. At the end of the command life, we retrieve this span and close it.
24+
"""
25+
26+
_commands_to_listen = ["updates", "deletes", "documents"]
27+
_operations_to_listen = ["filter", "limit", "sort", "skip", "pipeline", "query"]
28+
"""
29+
These are the type of mongo commands/operators that are gonna to be written to a span.
30+
The _commands_to_listen refers to commands that involves tampering with multiple objets.
31+
The _operations_to_listen refers to operations in general that we want to have information saved.
32+
We made this bit so we can keep track of the number of documents affected by the _commands_to_listen,
33+
while _operations_to_listen we wanted to store individual information of any operator involved in the command,
34+
e.g. how many objects to limit.
35+
"""
36+
37+
def __init__(self):
38+
self._spans = dict()
39+
"""
40+
Make sure that every class instance has it's own dict of spans;
41+
Keys on this dict should represent the event.request_id object;
42+
"""
43+
44+
def started(self, event):
45+
"""
46+
Here we gather info about the event, create a new span and store it on memory.
47+
"""
48+
49+
def get_span(event):
50+
cmd_type = str(event.command_name)
51+
command = str(event.command.get(cmd_type))
52+
description = f"mongodb.{command}.{cmd_type}"
53+
data = {}
54+
55+
"""Builds span description"""
56+
for atr in self._operations_to_listen:
57+
value = event.command.get(atr)
58+
if value is not None:
59+
data[atr] = str(value)
60+
description += f".{atr}"
61+
62+
if event.command.get("collection"):
63+
"""Concatenates collection name to description"""
64+
data["collection"] = str(event.command["collection"])
65+
description += f".{data['collection']}"
66+
67+
for atr in self._commands_to_listen:
68+
"""Gather information about the number of documents affected"""
69+
value = event.command.get(atr)
70+
if value is not None:
71+
data[f"number of documents affected by {atr}"] = len(value)
72+
data[atr] = str(value)
73+
74+
span = sentry_sdk.start_span(op="mongodb", description=description)
75+
76+
"""Add tags to the span"""
77+
span.set_tag("db.type", "mongodb")
78+
span.set_tag("db.instance", str(event.database_name))
79+
span.set_tag("db.statement", command)
80+
span.set_tag("request_id", str(event.request_id))
81+
span.set_tag("connection_id", str(event.connection_id))
82+
83+
for k, v in data.items():
84+
"""Append our gathered data to the span"""
85+
span.set_data(k, v)
86+
return span
87+
88+
span = get_span(event)
89+
span = span.__enter__()
90+
91+
if span is not None:
92+
"""Save the span in memory so we can latter use it"""
93+
self._spans[event.request_id] = span
94+
95+
def succeeded(self, event):
96+
self._stop("ok", event)
97+
98+
def failed(self, event):
99+
self._stop("internal_error", event)
100+
101+
def _stop(self, status, event):
102+
"""Finishes span context and removes it from the memory"""
103+
span = self._spans.get(event.request_id, None)
104+
if span is not None:
105+
span.set_status(status)
106+
span.__exit__(None, None, None)
107+
del self._spans[event.request_id]
108+

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@
2323
],
2424
packages=["sentry_mongo"],
2525
include_package_data=True,
26-
install_requires=["sentry_sdk~=1.5", "pymongo~=3.12"],
26+
install_requires=["sentry_sdk", "pymongo==3.*"],
2727
)

0 commit comments

Comments
 (0)