Mini Shell
#!/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