Mini Shell

Direktori : /usr/share/lve/dbgovernor/scripts/
Upload File :
Current File : //usr/share/lve/dbgovernor/scripts/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"


Zerion Mini Shell 1.0