PATH:
usr
/
share
/
lve
/
dbgovernor
/
scripts
/
Editing: sentry_sdk_wrapper.py
#!/opt/cloudlinux/venv/bin/python3 # coding:utf-8 # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2024 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT # import os import sys import platform import sentry_sdk from sentry_sdk.integrations.logging import LoggingIntegration import logging from clcommon.utils import get_rhn_systemid_value from clcommon import get_lve_version from clcommon.lib.cledition import get_cl_edition_readable from clcommon.lib.network import get_ip_addr, get_hostname from clsentry.utils import get_pkg_version from dbgovernor_version import GOVERNOR_CUR_VER sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../") # utilities.py lives one level higher from utilities import exec_command SENTRY_DSN_FILE = "/usr/share/lve/dbgovernor/sentry-dsn" """ Wrapper around sentry_sdk. Provides CL-specific tags to Sentry events. Accommodates events to our Sentry server-side version. """ def init(): """ Initialize. """ with open(SENTRY_DSN_FILE) as f: dsn = f.read().strip() os_name = get_rhn_systemid_value('operating_system') os_version = get_rhn_systemid_value('os_release') os2 = [s for s in exec_command("cldetect --detect-os", as_string=True, no_debug_log=True).split(" ") if s] # do this before sentry_sdk.init(): not only because these are constants, but also to avoid 'subprocess' calls being put into breadcrumbs: if len(os2) == 2: os_name, os_version = os2 sentry_sdk.init( dsn = dsn, #debug = True, # uncomment to look deeper under the hood of 'sentry_sdk' before_send = before_send, # to strip away undesirable event attributes release = GOVERNOR_CUR_VER, # version of db_governor/libgovernor.so integrations = [LoggingIntegration(event_level=logging.WARNING)], # this kind of integration is set manually only to set non-default 'event_level' send_client_reports = False # our Sentry server doesn't like 'client_report' events and responds with HTTP '400 Bad Request' ) with sentry_sdk.configure_scope() as scope: # set permanent tags scope.set_user({ "id": VIS(get_rhn_systemid_value('system_id'))}) scope.set_context("device", { "architecture": VIS(get_rhn_systemid_value("architecture") or platform.machine()) }) scope.set_context("os", { "name": VIS(os_name), "version": VIS(os_version), "build": VIS(platform.version()), "Kernel-version": VIS(platform.release()), "CloudLinux-edition": VIS(get_cl_edition_readable()) }) scope.set_tag("lve.version", VIS(get_lve_version()[0])) scope.set_tag("lvemanager", VIS(get_pkg_version("lvemanager"))) scope.set_tag("lve-stats", VIS(get_pkg_version("lve-stats"))) scope.set_tag("lve-utils", VIS(get_pkg_version("lve-utils"))) scope.set_tag("ip_address", VIS(get_ip_addr(get_hostname()))) def is_healthy(): return sentry_sdk.Hub.current.client.transport.is_healthy() strip_event_pythonicity = False def before_send(event, hint): event.pop("transaction_info", None) # our Sentry server doesn't understand it and throws a pink msg box "There was 1 error encountered while processing this event: transaction_info: Discarded unknown attribute". Possibly it will go away after Sentry server upgrade. global strip_event_pythonicity if strip_event_pythonicity: # remove irrelevant attributes - misleading and obstructing for events forwarded from C code if "extra" in event: event["extra"].pop("sys.argv", None) if "contexts" in event: event["contexts"].pop("runtime", None) for attr in ("modules", "sdk", "breadcrumbs"): event.pop(attr, None) return event def VIS(x): """ Visualize - replace anything "pythonically Falsy" with an explicit "n/a". There are Sentry tags that we consider mandatory for a regular machine. Although, sometimes the corresponding values can be None, and set_tag(..., None) wouldn't make them visible on the Sentry page. We wrap them in this call to force visibility. """ return x if x else "n/a"
SAVE
CANCEL