Skip to content

Commit f76d249

Browse files
authored
Merge pull request #94 from nipreps/rm/sentry
maint: remove sentry telemetry
2 parents d895edc + 12f77cd commit f76d249

File tree

4 files changed

+2
-190
lines changed

4 files changed

+2
-190
lines changed

petprep/cli/run.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,9 @@ def main():
5959
setup_exceptionhook()
6060
config.nipype.plugin = 'Linear'
6161

62-
sentry_sdk = None
6362
if not config.execution.notrack and not config.execution.debug:
64-
import sentry_sdk
63+
from ..utils.telemetry import setup_migas
6564

66-
from ..utils.telemetry import sentry_setup, setup_migas
67-
68-
sentry_setup()
6965
setup_migas(init_ping=True)
7066

7167
# CRITICAL Save the config to a file. This is necessary because the execution graph
@@ -124,14 +120,6 @@ def main():
124120
# Clean up master process before running workflow, which may create forks
125121
gc.collect()
126122

127-
# Sentry tracking
128-
if sentry_sdk is not None:
129-
with sentry_sdk.configure_scope() as scope:
130-
scope.set_tag('run_uuid', config.execution.run_uuid)
131-
scope.set_tag('npart', len(config.execution.participant_label))
132-
sentry_sdk.add_breadcrumb(message='PETPrep started', level='info')
133-
sentry_sdk.capture_message('PETPrep started', level='info')
134-
135123
config.loggers.workflow.log(
136124
15,
137125
'\n'.join(['PETPrep config:'] + [f'\t\t{s}' for s in config.dumps().splitlines()]),
@@ -152,16 +140,10 @@ def main():
152140
for crashfile in crashfolder.glob('crash*.*'):
153141
process_crashfile(crashfile)
154142

155-
if sentry_sdk is not None and 'Workflow did not execute cleanly' not in str(e):
156-
sentry_sdk.capture_exception(e)
157143
config.loggers.workflow.critical('PETPrep failed: %s', e)
158144
raise
159145
else:
160146
config.loggers.workflow.log(25, 'PETPrep finished successfully!')
161-
if sentry_sdk is not None:
162-
success_message = 'PETPrep finished without errors'
163-
sentry_sdk.add_breadcrumb(message=success_message, level='info')
164-
sentry_sdk.capture_message(success_message, level='info')
165147

166148
# Bother users with the boilerplate only iff the workflow went okay.
167149
boiler_file = config.execution.petprep_dir / 'logs' / 'CITATION.md'
@@ -231,7 +213,5 @@ def main():
231213
f': {", ".join(failed_reports)}.'
232214
)
233215
config.loggers.cli.error(msg)
234-
if sentry_sdk is not None:
235-
sentry_sdk.capture_message(msg, level='error')
236216

237217
sys.exit(int((errno + len(failed_reports)) > 0))

petprep/utils/telemetry.py

Lines changed: 0 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -22,169 +22,12 @@
2222
#
2323
"""Stripped out routines for telemetry"""
2424

25-
import os
26-
import re
27-
2825
from nibabel.optpkg import optional_package
29-
from niworkflows.utils.misc import read_crashfile
3026

3127
from .. import __version__, config
3228

33-
sentry_sdk = optional_package('sentry_sdk')[0]
3429
migas = optional_package('migas')[0]
3530

36-
CHUNK_SIZE = 16384
37-
# Group common events with pre specified fingerprints
38-
KNOWN_ERRORS = {
39-
'permission-denied': ['PermissionError: [Errno 13] Permission denied'],
40-
'memory-error': [
41-
'MemoryError',
42-
'Cannot allocate memory',
43-
'Return code: 134',
44-
],
45-
'reconall-already-running': ['ERROR: it appears that recon-all is already running'],
46-
'no-disk-space': ['[Errno 28] No space left on device', '[Errno 122] Disk quota exceeded'],
47-
'segfault': [
48-
'Segmentation Fault',
49-
'Segfault',
50-
'Return code: 139',
51-
],
52-
'potential-race-condition': [
53-
'[Errno 39] Directory not empty',
54-
'_unfinished.json',
55-
],
56-
'keyboard-interrupt': [
57-
'KeyboardInterrupt',
58-
],
59-
}
60-
61-
62-
def sentry_setup():
63-
"""Set-up sentry."""
64-
release = config.environment.version or 'dev'
65-
environment = (
66-
'dev'
67-
if (
68-
os.getenv('PETPREP_DEV', '').lower in ('1', 'on', 'yes', 'y', 'true')
69-
or ('+' in release)
70-
)
71-
else 'prod'
72-
)
73-
74-
sentry_sdk.init(
75-
'https://[email protected]/1137693',
76-
release=release,
77-
environment=environment,
78-
before_send=before_send,
79-
)
80-
with sentry_sdk.configure_scope() as scope:
81-
for k, v in config.get(flat=True).items():
82-
scope.set_tag(k, v)
83-
84-
85-
def process_crashfile(crashfile):
86-
"""Parse the contents of a crashfile and submit sentry messages."""
87-
crash_info = read_crashfile(str(crashfile))
88-
with sentry_sdk.push_scope() as scope:
89-
scope.level = 'fatal'
90-
91-
# Extract node name
92-
node_name = crash_info.pop('node').split('.')[-1]
93-
scope.set_tag('node_name', node_name)
94-
95-
# Massage the traceback, extract the gist
96-
traceback = crash_info.pop('traceback')
97-
# last line is probably most informative summary
98-
gist = traceback.splitlines()[-1]
99-
exception_text_start = 1
100-
for line in traceback.splitlines()[1:]:
101-
if not line[0].isspace():
102-
break
103-
exception_text_start += 1
104-
105-
exception_text = '\n'.join(traceback.splitlines()[exception_text_start:])
106-
107-
# Extract inputs, if present
108-
inputs = crash_info.pop('inputs', None)
109-
if inputs:
110-
scope.set_extra('inputs', dict(inputs))
111-
112-
# Extract any other possible metadata in the crash file
113-
for k, v in crash_info.items():
114-
strv = _chunks(str(v))
115-
if len(strv) == 1:
116-
scope.set_extra(k, strv[0])
117-
else:
118-
for i, chunk in enumerate(strv):
119-
scope.set_extra(f'{k}_{i:02d}', chunk)
120-
121-
fingerprint = ''
122-
issue_title = f'{node_name}: {gist}'
123-
for new_fingerprint, error_snippets in KNOWN_ERRORS.items():
124-
for error_snippet in error_snippets:
125-
if error_snippet in traceback:
126-
fingerprint = new_fingerprint
127-
issue_title = new_fingerprint
128-
break
129-
if fingerprint:
130-
break
131-
132-
message = issue_title + '\n\n'
133-
message += exception_text[-8192:]
134-
if fingerprint:
135-
sentry_sdk.add_breadcrumb(message=fingerprint, level='fatal')
136-
else:
137-
# remove file paths
138-
fingerprint = re.sub(r'(/[^/ ]*)+/?', '', message)
139-
# remove words containing numbers
140-
fingerprint = re.sub(r'([a-zA-Z]*[0-9]+[a-zA-Z]*)+', '', fingerprint)
141-
# adding the return code if it exists
142-
for line in message.splitlines():
143-
if line.startswith('Return code'):
144-
fingerprint += line
145-
break
146-
147-
scope.fingerprint = [fingerprint]
148-
sentry_sdk.capture_message(message, 'fatal')
149-
150-
151-
def before_send(event, hints):
152-
"""Filter log messages about crashed nodes."""
153-
if 'logentry' in event and 'message' in event['logentry']:
154-
msg = event['logentry']['message']
155-
if msg.startswith('could not run node:'):
156-
return None
157-
if msg.startswith('Saving crash info to '):
158-
return None
159-
if re.match('Node .+ failed to run on host .+', msg):
160-
return None
161-
162-
if 'breadcrumbs' in event and isinstance(event['breadcrumbs'], list):
163-
fingerprints_to_propagate = [
164-
'no-disk-space',
165-
'memory-error',
166-
'permission-denied',
167-
'keyboard-interrupt',
168-
]
169-
for bc in event['breadcrumbs']:
170-
msg = bc.get('message', 'empty-msg')
171-
if msg in fingerprints_to_propagate:
172-
event['fingerprint'] = [msg]
173-
break
174-
175-
return event
176-
177-
178-
def _chunks(string, length=CHUNK_SIZE):
179-
"""
180-
Split a string into smaller chunks.
181-
182-
>>> list(_chunks('some longer string.', length=3))
183-
['som', 'e l', 'ong', 'er ', 'str', 'ing', '.']
184-
185-
"""
186-
return [string[i : i + length] for i in range(0, len(string), length)]
187-
18831

18932
def setup_migas(init_ping: bool = True, exit_ping: bool = True) -> None:
19033
"""

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ container = [
7272
]
7373
telemetry = [
7474
"migas >= 0.4.0",
75-
"sentry-sdk >= 1.3",
7675
]
7776
test = [
7877
"coverage[toml] >= 5.2.1",

requirements.txt

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ certifi==2025.1.31
4040
# httpcore
4141
# httpx
4242
# requests
43-
# sentry-sdk
4443
cffi==1.17.1
4544
# via cryptography
4645
chardet==5.2.0
@@ -65,9 +64,7 @@ contourpy==1.3.1
6564
# bokeh
6665
# matplotlib
6766
cryptography==44.0.2
68-
# via
69-
# jwcrypto
70-
# secretstorage
67+
# via jwcrypto
7168
cycler==0.12.1
7269
# via matplotlib
7370
datalad==1.1.5
@@ -99,8 +96,6 @@ frozendict==2.4.6
9996
# via pybids
10097
fsspec==2025.2.0
10198
# via universal-pathlib
102-
greenlet==3.1.1
103-
# via sqlalchemy
10499
h11==0.14.0
105100
# via httpcore
106101
h5py==3.13.0
@@ -138,10 +133,6 @@ jaraco-context==6.0.1
138133
# keyrings-alt
139134
jaraco-functools==4.1.0
140135
# via keyring
141-
jeepney==0.9.0
142-
# via
143-
# keyring
144-
# secretstorage
145136
jinja2==3.1.6
146137
# via
147138
# bokeh
@@ -508,7 +499,6 @@ urllib3==2.3.0
508499
# via
509500
# botocore
510501
# requests
511-
# sentry-sdk
512502
wcwidth==0.2.13
513503
# via prompt-toolkit
514504
wrapt==1.17.2

0 commit comments

Comments
 (0)