sf-veritas 0.10.3__cp314-cp314-manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sf-veritas might be problematic. Click here for more details.
- sf_veritas/__init__.py +20 -0
- sf_veritas/_sffastlog.c +889 -0
- sf_veritas/_sffastlog.cpython-314-x86_64-linux-gnu.so +0 -0
- sf_veritas/_sffastnet.c +924 -0
- sf_veritas/_sffastnet.cpython-314-x86_64-linux-gnu.so +0 -0
- sf_veritas/_sffastnetworkrequest.c +730 -0
- sf_veritas/_sffastnetworkrequest.cpython-314-x86_64-linux-gnu.so +0 -0
- sf_veritas/_sffuncspan.c +2155 -0
- sf_veritas/_sffuncspan.cpython-314-x86_64-linux-gnu.so +0 -0
- sf_veritas/_sffuncspan_config.c +617 -0
- sf_veritas/_sffuncspan_config.cpython-314-x86_64-linux-gnu.so +0 -0
- sf_veritas/_sfheadercheck.c +341 -0
- sf_veritas/_sfheadercheck.cpython-314-x86_64-linux-gnu.so +0 -0
- sf_veritas/_sfnetworkhop.c +1451 -0
- sf_veritas/_sfnetworkhop.cpython-314-x86_64-linux-gnu.so +0 -0
- sf_veritas/_sfservice.c +1175 -0
- sf_veritas/_sfservice.cpython-314-x86_64-linux-gnu.so +0 -0
- sf_veritas/_sfteepreload.c +5167 -0
- sf_veritas/app_config.py +49 -0
- sf_veritas/cli.py +336 -0
- sf_veritas/constants.py +10 -0
- sf_veritas/custom_excepthook.py +304 -0
- sf_veritas/custom_log_handler.py +129 -0
- sf_veritas/custom_output_wrapper.py +144 -0
- sf_veritas/custom_print.py +146 -0
- sf_veritas/django_app.py +5 -0
- sf_veritas/env_vars.py +186 -0
- sf_veritas/exception_handling_middleware.py +18 -0
- sf_veritas/exception_metaclass.py +69 -0
- sf_veritas/fast_frame_info.py +116 -0
- sf_veritas/fast_network_hop.py +293 -0
- sf_veritas/frame_tools.py +112 -0
- sf_veritas/funcspan_config_loader.py +556 -0
- sf_veritas/function_span_profiler.py +1174 -0
- sf_veritas/import_hook.py +62 -0
- sf_veritas/infra_details/__init__.py +3 -0
- sf_veritas/infra_details/get_infra_details.py +24 -0
- sf_veritas/infra_details/kubernetes/__init__.py +3 -0
- sf_veritas/infra_details/kubernetes/get_cluster_name.py +147 -0
- sf_veritas/infra_details/kubernetes/get_details.py +7 -0
- sf_veritas/infra_details/running_on/__init__.py +17 -0
- sf_veritas/infra_details/running_on/kubernetes.py +11 -0
- sf_veritas/interceptors.py +497 -0
- sf_veritas/libsfnettee.so +0 -0
- sf_veritas/local_env_detect.py +118 -0
- sf_veritas/package_metadata.py +6 -0
- sf_veritas/patches/__init__.py +0 -0
- sf_veritas/patches/concurrent_futures.py +19 -0
- sf_veritas/patches/constants.py +1 -0
- sf_veritas/patches/exceptions.py +82 -0
- sf_veritas/patches/multiprocessing.py +32 -0
- sf_veritas/patches/network_libraries/__init__.py +76 -0
- sf_veritas/patches/network_libraries/aiohttp.py +281 -0
- sf_veritas/patches/network_libraries/curl_cffi.py +363 -0
- sf_veritas/patches/network_libraries/http_client.py +419 -0
- sf_veritas/patches/network_libraries/httpcore.py +515 -0
- sf_veritas/patches/network_libraries/httplib2.py +204 -0
- sf_veritas/patches/network_libraries/httpx.py +515 -0
- sf_veritas/patches/network_libraries/niquests.py +211 -0
- sf_veritas/patches/network_libraries/pycurl.py +385 -0
- sf_veritas/patches/network_libraries/requests.py +633 -0
- sf_veritas/patches/network_libraries/tornado.py +341 -0
- sf_veritas/patches/network_libraries/treq.py +270 -0
- sf_veritas/patches/network_libraries/urllib_request.py +468 -0
- sf_veritas/patches/network_libraries/utils.py +398 -0
- sf_veritas/patches/os.py +17 -0
- sf_veritas/patches/threading.py +218 -0
- sf_veritas/patches/web_frameworks/__init__.py +54 -0
- sf_veritas/patches/web_frameworks/aiohttp.py +793 -0
- sf_veritas/patches/web_frameworks/async_websocket_consumer.py +317 -0
- sf_veritas/patches/web_frameworks/blacksheep.py +527 -0
- sf_veritas/patches/web_frameworks/bottle.py +502 -0
- sf_veritas/patches/web_frameworks/cherrypy.py +678 -0
- sf_veritas/patches/web_frameworks/cors_utils.py +122 -0
- sf_veritas/patches/web_frameworks/django.py +944 -0
- sf_veritas/patches/web_frameworks/eve.py +395 -0
- sf_veritas/patches/web_frameworks/falcon.py +926 -0
- sf_veritas/patches/web_frameworks/fastapi.py +724 -0
- sf_veritas/patches/web_frameworks/flask.py +520 -0
- sf_veritas/patches/web_frameworks/klein.py +501 -0
- sf_veritas/patches/web_frameworks/litestar.py +551 -0
- sf_veritas/patches/web_frameworks/pyramid.py +428 -0
- sf_veritas/patches/web_frameworks/quart.py +824 -0
- sf_veritas/patches/web_frameworks/robyn.py +697 -0
- sf_veritas/patches/web_frameworks/sanic.py +857 -0
- sf_veritas/patches/web_frameworks/starlette.py +723 -0
- sf_veritas/patches/web_frameworks/strawberry.py +813 -0
- sf_veritas/patches/web_frameworks/tornado.py +481 -0
- sf_veritas/patches/web_frameworks/utils.py +91 -0
- sf_veritas/print_override.py +13 -0
- sf_veritas/regular_data_transmitter.py +409 -0
- sf_veritas/request_interceptor.py +401 -0
- sf_veritas/request_utils.py +550 -0
- sf_veritas/server_status.py +1 -0
- sf_veritas/shutdown_flag.py +11 -0
- sf_veritas/subprocess_startup.py +3 -0
- sf_veritas/test_cli.py +145 -0
- sf_veritas/thread_local.py +970 -0
- sf_veritas/timeutil.py +114 -0
- sf_veritas/transmit_exception_to_sailfish.py +28 -0
- sf_veritas/transmitter.py +132 -0
- sf_veritas/types.py +47 -0
- sf_veritas/unified_interceptor.py +1580 -0
- sf_veritas/utils.py +39 -0
- sf_veritas-0.10.3.dist-info/METADATA +97 -0
- sf_veritas-0.10.3.dist-info/RECORD +132 -0
- sf_veritas-0.10.3.dist-info/WHEEL +5 -0
- sf_veritas-0.10.3.dist-info/entry_points.txt +2 -0
- sf_veritas-0.10.3.dist-info/top_level.txt +1 -0
- sf_veritas.libs/libbrotlicommon-6ce2a53c.so.1.0.6 +0 -0
- sf_veritas.libs/libbrotlidec-811d1be3.so.1.0.6 +0 -0
- sf_veritas.libs/libcom_err-730ca923.so.2.1 +0 -0
- sf_veritas.libs/libcrypt-52aca757.so.1.1.0 +0 -0
- sf_veritas.libs/libcrypto-bdaed0ea.so.1.1.1k +0 -0
- sf_veritas.libs/libcurl-eaa3cf66.so.4.5.0 +0 -0
- sf_veritas.libs/libgssapi_krb5-323bbd21.so.2.2 +0 -0
- sf_veritas.libs/libidn2-2f4a5893.so.0.3.6 +0 -0
- sf_veritas.libs/libk5crypto-9a74ff38.so.3.1 +0 -0
- sf_veritas.libs/libkeyutils-2777d33d.so.1.6 +0 -0
- sf_veritas.libs/libkrb5-a55300e8.so.3.3 +0 -0
- sf_veritas.libs/libkrb5support-e6594cfc.so.0.1 +0 -0
- sf_veritas.libs/liblber-2-d20824ef.4.so.2.10.9 +0 -0
- sf_veritas.libs/libldap-2-cea2a960.4.so.2.10.9 +0 -0
- sf_veritas.libs/libnghttp2-39367a22.so.14.17.0 +0 -0
- sf_veritas.libs/libpcre2-8-516f4c9d.so.0.7.1 +0 -0
- sf_veritas.libs/libpsl-99becdd3.so.5.3.1 +0 -0
- sf_veritas.libs/libsasl2-7de4d792.so.3.0.0 +0 -0
- sf_veritas.libs/libselinux-d0805dcb.so.1 +0 -0
- sf_veritas.libs/libssh-c11d285b.so.4.8.7 +0 -0
- sf_veritas.libs/libssl-60250281.so.1.1.1k +0 -0
- sf_veritas.libs/libunistring-05abdd40.so.2.1.0 +0 -0
- sf_veritas.libs/libuuid-95b83d40.so.1.3.0 +0 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from typing import Any, Dict, List, Optional
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
from . import app_config
|
|
7
|
+
from .env_vars import SF_DEBUG
|
|
8
|
+
from .package_metadata import PACKAGE_LIBRARY_TYPE, __version__
|
|
9
|
+
from .request_utils import non_blocking_post, non_blocking_post_with_response
|
|
10
|
+
from .thread_local import suppress_network_recording
|
|
11
|
+
from .timeutil import TimeSync
|
|
12
|
+
|
|
13
|
+
# Try to import C extension for fast path
|
|
14
|
+
try:
|
|
15
|
+
from . import _sfservice
|
|
16
|
+
_SFSERVICE_AVAILABLE = True
|
|
17
|
+
except Exception:
|
|
18
|
+
_sfservice = None
|
|
19
|
+
_SFSERVICE_AVAILABLE = False
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BaseTransmitter:
|
|
23
|
+
def __init__(self, api_key: str = None):
|
|
24
|
+
self.api_key = api_key or app_config._sailfish_api_key
|
|
25
|
+
self.endpoint = app_config._sailfish_graphql_endpoint
|
|
26
|
+
self.query_type = "mutation"
|
|
27
|
+
self.service_identifier = app_config._service_identifier
|
|
28
|
+
self.git_sha = app_config._git_sha
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def query_name(self) -> str:
|
|
32
|
+
return (
|
|
33
|
+
self.operation_name[0].lower() + self.operation_name[1:]
|
|
34
|
+
if self.operation_name
|
|
35
|
+
else ""
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# TODO - Strip out everything EXCEPT for `reentrancyGuardPreactive`
|
|
39
|
+
def get_default_variables(self):
|
|
40
|
+
timestamp_ms = TimeSync.get_instance().get_utc_time_in_ms()
|
|
41
|
+
return {
|
|
42
|
+
"apiKey": self.api_key,
|
|
43
|
+
"serviceUuid": app_config._service_uuid,
|
|
44
|
+
"timestampMs": str(timestamp_ms),
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
def get_variables(
|
|
48
|
+
self,
|
|
49
|
+
additional_variables: Optional[Dict[str, Any]] = None,
|
|
50
|
+
) -> Dict[str, Any]:
|
|
51
|
+
additional_variables = (
|
|
52
|
+
additional_variables if additional_variables is not None else {}
|
|
53
|
+
)
|
|
54
|
+
return {
|
|
55
|
+
**additional_variables,
|
|
56
|
+
**self.get_default_variables(),
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ServiceIdentifier(BaseTransmitter):
|
|
61
|
+
def __init__(self, api_key: str = app_config._sailfish_api_key):
|
|
62
|
+
super().__init__(api_key)
|
|
63
|
+
self.operation_name = "IdentifyServiceDetails"
|
|
64
|
+
|
|
65
|
+
def do_send(self, args) -> None:
|
|
66
|
+
# Service identification is now handled by _sfservice C extension in setup_interceptors()
|
|
67
|
+
# This method is kept as no-op for backward compatibility
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
def send(self):
|
|
71
|
+
"""
|
|
72
|
+
Sends the service identification details as a GraphQL mutation.
|
|
73
|
+
This method overrides the `send` method from `DataTransmitter`.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
query = f"""
|
|
77
|
+
{self.query_type} {self.operation_name}(
|
|
78
|
+
$apiKey: String!,
|
|
79
|
+
$timestampMs: String!,
|
|
80
|
+
$serviceUuid: String!,
|
|
81
|
+
$serviceIdentifier: String,
|
|
82
|
+
$serviceVersion: String,
|
|
83
|
+
$serviceAdditionalMetadata: JSON,
|
|
84
|
+
$library: String!,
|
|
85
|
+
$version: String!,
|
|
86
|
+
$infrastructureType: String,
|
|
87
|
+
$infrastructureDetails: JSON,
|
|
88
|
+
$setupInterceptorsFilePath: String,
|
|
89
|
+
$setupInterceptorsLineNumber: Int
|
|
90
|
+
) {{
|
|
91
|
+
{self.query_name}(
|
|
92
|
+
apiKey: $apiKey,
|
|
93
|
+
timestampMs: $timestampMs,
|
|
94
|
+
serviceUuid: $serviceUuid,
|
|
95
|
+
serviceIdentifier: $serviceIdentifier,
|
|
96
|
+
serviceVersion: $serviceVersion,
|
|
97
|
+
serviceAdditionalMetadata: $serviceAdditionalMetadata,
|
|
98
|
+
library: $library,
|
|
99
|
+
version: $version,
|
|
100
|
+
infrastructureType: $infrastructureType,
|
|
101
|
+
infrastructureDetails: $infrastructureDetails
|
|
102
|
+
setupInterceptorsFilePath: $setupInterceptorsFilePath,
|
|
103
|
+
setupInterceptorsLineNumber: $setupInterceptorsLineNumber
|
|
104
|
+
)
|
|
105
|
+
}}
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
if SF_DEBUG:
|
|
110
|
+
print(f"Sending query: {query}", log=False)
|
|
111
|
+
|
|
112
|
+
# Non-blocking POST request to send the GraphQL query
|
|
113
|
+
variables = self.get_variables(
|
|
114
|
+
{
|
|
115
|
+
"serviceIdentifier": app_config._service_identifier,
|
|
116
|
+
"gitSha": app_config._git_sha,
|
|
117
|
+
"serviceVersion": app_config._service_version,
|
|
118
|
+
"serviceAdditionalMetadata": app_config._service_additional_metadata,
|
|
119
|
+
"library": PACKAGE_LIBRARY_TYPE,
|
|
120
|
+
"version": __version__,
|
|
121
|
+
"infrastructureType": app_config._infra_details.system.value, # or whatever string you're passing
|
|
122
|
+
"infrastructureDetails": app_config._infra_details.details,
|
|
123
|
+
"setupInterceptorsFilePath": app_config._setup_interceptors_call_filename,
|
|
124
|
+
"setupInterceptorsLineNumber": app_config._setup_interceptors_call_lineno,
|
|
125
|
+
},
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
future = non_blocking_post_with_response(
|
|
129
|
+
self.endpoint, self.operation_name, query, variables
|
|
130
|
+
)
|
|
131
|
+
if future is None:
|
|
132
|
+
return
|
|
133
|
+
response = future.result()
|
|
134
|
+
if SF_DEBUG and response is None:
|
|
135
|
+
print(
|
|
136
|
+
f"IdentifyServiceDetails NOT sent successfully for service: UUID={app_config._service_uuid}",
|
|
137
|
+
log=False,
|
|
138
|
+
)
|
|
139
|
+
return
|
|
140
|
+
service_identification_received = response.get("data", {}).get(
|
|
141
|
+
self.query_name, False
|
|
142
|
+
)
|
|
143
|
+
app_config._service_identification_received = (
|
|
144
|
+
service_identification_received
|
|
145
|
+
)
|
|
146
|
+
if SF_DEBUG:
|
|
147
|
+
print(
|
|
148
|
+
f"IdentifyServiceDetails sent successfully for service: UUID={app_config._service_uuid}; service_identification_received={str(service_identification_received)}",
|
|
149
|
+
log=False,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
except Exception as e:
|
|
153
|
+
# Log any exceptions that occur during sending
|
|
154
|
+
if SF_DEBUG:
|
|
155
|
+
print(f"Error occurred while sending service identification: {e}")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class DataTransmitter(BaseTransmitter):
|
|
159
|
+
def __init__(self, api_key: str = None):
|
|
160
|
+
self.api_key = api_key or app_config._sailfish_api_key
|
|
161
|
+
self.endpoint = app_config._sailfish_graphql_endpoint
|
|
162
|
+
self.operation_name: Optional[str] = ""
|
|
163
|
+
self.query_type = "mutation"
|
|
164
|
+
self.service_identifier = ServiceIdentifier()
|
|
165
|
+
|
|
166
|
+
def check_if_contents_should_be_ignored(
|
|
167
|
+
self, contents
|
|
168
|
+
): # pylint: disable=unused-argument
|
|
169
|
+
return False
|
|
170
|
+
|
|
171
|
+
def _send_app_identifier(self) -> None:
|
|
172
|
+
return
|
|
173
|
+
if SF_DEBUG:
|
|
174
|
+
print(
|
|
175
|
+
"_send_app_identifier...SENDING DATA...args=",
|
|
176
|
+
set(),
|
|
177
|
+
log=False,
|
|
178
|
+
)
|
|
179
|
+
self.service_identifier.do_send(set())
|
|
180
|
+
|
|
181
|
+
def do_send(self, args) -> None:
|
|
182
|
+
self._send_app_identifier()
|
|
183
|
+
try:
|
|
184
|
+
self.send(*args)
|
|
185
|
+
except RuntimeError:
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
def send(self, contents, session_id: str):
|
|
189
|
+
if self.check_if_contents_should_be_ignored(contents):
|
|
190
|
+
return
|
|
191
|
+
query = f"""
|
|
192
|
+
{self.query_type} {self.operation_name}($apiKey: String!, $serviceUuid: String!, $contents: String!, $library: String!, $timestampMs: String!, $version: String!) {{
|
|
193
|
+
{self.query_name}(apiKey: $apiKey, serviceUuid: $serviceUuid, contents: $contents, library: $library, timestampMs: $timestampMs, version: $version)
|
|
194
|
+
}}
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
non_blocking_post(
|
|
198
|
+
self.endpoint,
|
|
199
|
+
self.operation_name,
|
|
200
|
+
query,
|
|
201
|
+
self.get_variables({"contents": contents}),
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class DomainsToNotPassHeaderToTransmitter(DataTransmitter):
|
|
206
|
+
def __init__(self, api_key: str = app_config._sailfish_api_key):
|
|
207
|
+
super().__init__(api_key)
|
|
208
|
+
self.operation_name = "DomainsToNotPassHeaderTo"
|
|
209
|
+
|
|
210
|
+
def send(
|
|
211
|
+
self,
|
|
212
|
+
domains: List[str],
|
|
213
|
+
):
|
|
214
|
+
# Fast path: Use C extension if available
|
|
215
|
+
if _SFSERVICE_AVAILABLE and _sfservice:
|
|
216
|
+
try:
|
|
217
|
+
_sfservice.domains(domains=domains)
|
|
218
|
+
return
|
|
219
|
+
except Exception:
|
|
220
|
+
# Fall through to Python implementation
|
|
221
|
+
pass
|
|
222
|
+
|
|
223
|
+
# Fallback: Use Python implementation
|
|
224
|
+
query = f"""
|
|
225
|
+
{self.query_type} {self.operation_name}($apiKey: String!, $serviceUuid: String!, $timestampMs: String!, $domains: [String!]!) {{
|
|
226
|
+
{self.query_name}(apiKey: $apiKey, serviceUuid: $serviceUuid, timestampMs: $timestampMs, domains: $domains)
|
|
227
|
+
}}
|
|
228
|
+
"""
|
|
229
|
+
variables = self.get_variables(
|
|
230
|
+
{
|
|
231
|
+
"domains": domains,
|
|
232
|
+
},
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
non_blocking_post(self.endpoint, self.operation_name, query, variables)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class UpdateServiceIdentifierMetadata(DataTransmitter):
|
|
239
|
+
def __init__(self, api_key: str = app_config._sailfish_api_key):
|
|
240
|
+
super().__init__(api_key)
|
|
241
|
+
self.operation_name = "UpdateServiceDetails"
|
|
242
|
+
|
|
243
|
+
def send(
|
|
244
|
+
self,
|
|
245
|
+
service_identifier: Optional[str] = None,
|
|
246
|
+
service_version: Optional[str] = None,
|
|
247
|
+
service_additional_metadata: Optional[Dict[str, Any]] = None,
|
|
248
|
+
git_sha: Optional[str] = None,
|
|
249
|
+
):
|
|
250
|
+
"""
|
|
251
|
+
Sends updateServiceDetails mutation to update service metadata.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
service_identifier: Service identifier string
|
|
255
|
+
service_version: Service version string
|
|
256
|
+
service_additional_metadata: Dictionary of additional metadata
|
|
257
|
+
git_sha: Git SHA hash
|
|
258
|
+
"""
|
|
259
|
+
# NOTE: C extension for update_service is not compatible with GraphQL schema
|
|
260
|
+
# The C implementation expects domains[] but schema expects service metadata
|
|
261
|
+
# Therefore, we always use Python implementation here
|
|
262
|
+
|
|
263
|
+
query = f"""
|
|
264
|
+
{self.query_type} {self.operation_name}(
|
|
265
|
+
$apiKey: String!,
|
|
266
|
+
$serviceUuid: String!,
|
|
267
|
+
$timestampMs: String!,
|
|
268
|
+
$serviceIdentifier: String,
|
|
269
|
+
$serviceVersion: String,
|
|
270
|
+
$serviceAdditionalMetadata: JSON,
|
|
271
|
+
$gitSha: String
|
|
272
|
+
) {{
|
|
273
|
+
{self.query_name}(
|
|
274
|
+
apiKey: $apiKey,
|
|
275
|
+
serviceUuid: $serviceUuid,
|
|
276
|
+
timestampMs: $timestampMs,
|
|
277
|
+
serviceIdentifier: $serviceIdentifier,
|
|
278
|
+
serviceVersion: $serviceVersion,
|
|
279
|
+
serviceAdditionalMetadata: $serviceAdditionalMetadata,
|
|
280
|
+
gitSha: $gitSha
|
|
281
|
+
)
|
|
282
|
+
}}
|
|
283
|
+
"""
|
|
284
|
+
variables = self.get_variables(
|
|
285
|
+
{
|
|
286
|
+
"serviceIdentifier": service_identifier,
|
|
287
|
+
"serviceVersion": service_version,
|
|
288
|
+
"serviceAdditionalMetadata": service_additional_metadata,
|
|
289
|
+
"gitSha": git_sha,
|
|
290
|
+
},
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
non_blocking_post(self.endpoint, self.operation_name, query, variables)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class NetworkHopsTransmitter(DataTransmitter):
|
|
297
|
+
"""
|
|
298
|
+
A transmitter class responsible for sending network hop data as a GraphQL mutation.
|
|
299
|
+
|
|
300
|
+
This class extends `DataTransmitter` and sends `collectNetworkHops` mutation requests
|
|
301
|
+
to log network hop details for a given session.
|
|
302
|
+
|
|
303
|
+
Attributes:
|
|
304
|
+
operation_name (str): The GraphQL mutation name ("collectNetworkHops").
|
|
305
|
+
|
|
306
|
+
Methods:
|
|
307
|
+
send(session_id: str, line: str, column: str, name: str, entrypoint: str):
|
|
308
|
+
Sends a non-blocking GraphQL mutation request to log network hops.
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
def __init__(self, api_key: str = app_config._sailfish_api_key):
|
|
312
|
+
super().__init__(api_key)
|
|
313
|
+
self.operation_name = "collectNetworkHops"
|
|
314
|
+
|
|
315
|
+
def send(
|
|
316
|
+
self,
|
|
317
|
+
session_id: str,
|
|
318
|
+
line: str,
|
|
319
|
+
column: str,
|
|
320
|
+
name: str,
|
|
321
|
+
entrypoint: str,
|
|
322
|
+
):
|
|
323
|
+
query = f"""
|
|
324
|
+
{self.query_type} {self.operation_name}(
|
|
325
|
+
$apiKey: String!,
|
|
326
|
+
$sessionId: String!,
|
|
327
|
+
$timestampMs: String!,
|
|
328
|
+
$line: String!,
|
|
329
|
+
$column: String!,
|
|
330
|
+
$name: String!,
|
|
331
|
+
$entrypoint: String!,
|
|
332
|
+
$serviceUuid: String
|
|
333
|
+
) {{
|
|
334
|
+
{self.query_name}(
|
|
335
|
+
apiKey: $apiKey,
|
|
336
|
+
sessionId: $sessionId,
|
|
337
|
+
timestampMs: $timestampMs,
|
|
338
|
+
line: $line,
|
|
339
|
+
column: $column,
|
|
340
|
+
name: $name,
|
|
341
|
+
entrypoint: $entrypoint,
|
|
342
|
+
serviceUuid: $serviceUuid
|
|
343
|
+
)
|
|
344
|
+
}}
|
|
345
|
+
"""
|
|
346
|
+
|
|
347
|
+
variables = self.get_variables(
|
|
348
|
+
{
|
|
349
|
+
"sessionId": session_id,
|
|
350
|
+
"line": line,
|
|
351
|
+
"column": column,
|
|
352
|
+
"name": name,
|
|
353
|
+
"entrypoint": entrypoint,
|
|
354
|
+
"serviceUuid": app_config._service_uuid,
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
if SF_DEBUG:
|
|
358
|
+
print("[[NetworkHopsTransmitter.send]] variables=", variables, log=False)
|
|
359
|
+
non_blocking_post(self.endpoint, self.operation_name, query, variables)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
class NetworkRequestTransmitter(DataTransmitter):
|
|
363
|
+
def __init__(self, api_key: str = None):
|
|
364
|
+
super().__init__(api_key)
|
|
365
|
+
self.operation_name = "collectNetworkRequest"
|
|
366
|
+
|
|
367
|
+
def send(
|
|
368
|
+
self,
|
|
369
|
+
request_id: str,
|
|
370
|
+
page_visit_id: Optional[str],
|
|
371
|
+
recording_session_id: str,
|
|
372
|
+
service_uuid: str,
|
|
373
|
+
timestamp_start: int,
|
|
374
|
+
timestamp_end: int,
|
|
375
|
+
response_code: int,
|
|
376
|
+
success: bool,
|
|
377
|
+
error: Optional[str],
|
|
378
|
+
url: str,
|
|
379
|
+
method: str,
|
|
380
|
+
):
|
|
381
|
+
# build the mutation to match the new input type:
|
|
382
|
+
query = f"""
|
|
383
|
+
{self.query_type} {self.operation_name}($data: NetworkRequestInput!) {{
|
|
384
|
+
{self.query_name}(data: $data)
|
|
385
|
+
}}
|
|
386
|
+
"""
|
|
387
|
+
|
|
388
|
+
# Only include fields expected by the NetworkRequestInput type
|
|
389
|
+
variables = {
|
|
390
|
+
"data": {
|
|
391
|
+
"apiKey": self.api_key,
|
|
392
|
+
"requestId": request_id,
|
|
393
|
+
"pageVisitId": page_visit_id,
|
|
394
|
+
"recordingSessionId": recording_session_id,
|
|
395
|
+
"serviceUuid": app_config._service_uuid,
|
|
396
|
+
"timestampStart": timestamp_start,
|
|
397
|
+
"timestampEnd": timestamp_end,
|
|
398
|
+
"responseCode": response_code,
|
|
399
|
+
"success": success,
|
|
400
|
+
"error": error,
|
|
401
|
+
"url": url,
|
|
402
|
+
"method": method,
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if SF_DEBUG:
|
|
407
|
+
print(f"[NetworkRequestTransmitter] variables={variables}", log=False)
|
|
408
|
+
|
|
409
|
+
non_blocking_post(self.endpoint, self.operation_name, query, variables)
|