Viewing file: sentry.py (5.01 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
"""Helper for integrate sentry in stand-alone scripts""" import json import os import subprocess
from contextlib import suppress from pathlib import Path from typing import List, Optional, Literal
import distro import sentry_sdk
from defence360agent.application import tags from defence360agent.contracts import sentry
IMUNIFY360 = "imunify360" IMUNIFYAV = "imunify-antivirus" IMUNIFY360_PKG = "imunify360-firewall" LICENSE = "/var/imunify360/license.json" LICENSE_FREE = "/var/imunify360/license-free.json" FREE_ID = "IMUNIFYAV" UNKNOWN_ID = "UNKNOWN" SENTRY_DSN_PATH = Path("/opt/imunify360/venv/share/imunify360/sentry") SENTRY_DSN_DEFAULT = "https://6de77a2763bd40c58fc9e3a89285aaa8@im360.sentry.cloudlinux.com/3?timeout=20" # noqa: E501
def get_sentry_dsn() -> str: """Return dsn from the file or the default one.""" try: return SENTRY_DSN_PATH.read_text(encoding="ascii").strip() except (OSError, UnicodeDecodeError): return SENTRY_DSN_DEFAULT
def get_server_id() -> str: with suppress(Exception): for filename in [LICENSE, LICENSE_FREE]: with suppress(FileNotFoundError), open(filename) as file: return json.load(file)["id"] return UNKNOWN_ID
def collect_output(cmd: List[str]) -> str: try: cp = subprocess.run( cmd, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, ) except OSError: return "" if cp.returncode != 0: return "" return os.fsdecode(cp.stdout)
def get_rpm_version(pkg: str) -> str: cmd = ["rpm", "-q", "--queryformat=%{VERSION}-%{RELEASE}", pkg] return collect_output(cmd)
def get_dpkg_version(pkg: str) -> str: cmd = ["dpkg-query", "--showformat=${Version}", "--show", pkg] return collect_output(cmd)
def get_current_os(): platform_os = distro.linux_distribution()[0] return platform_os.lower()
def get_package_name(): platform_os = get_current_os() service_name = IMUNIFY360_PKG if platform_os != "ubuntu" and get_rpm_version(IMUNIFYAV): service_name = IMUNIFYAV else: service_name = IMUNIFY360 return service_name
def get_service_version(service_name) -> str: platform_os = get_current_os() if platform_os != "ubuntu": version = get_rpm_version(service_name) else: version = get_dpkg_version(service_name) return version
def configure_sentry(): # using LoggingIntegration (contained in default Integrations) # logging event with *error* level will be reported to Sentry automatically sentry_sdk.init(dsn=get_sentry_dsn()) with sentry_sdk.configure_scope() as scope: package = get_package_name() scope.user = {"id": get_server_id()} scope.set_tag("name", package) scope.set_tag("version", get_service_version(package)) tags.cached_fill() for tag, value in sentry.tags().items(): scope.set_tag(tag, value)
def flush_sentry(): client = sentry_sdk.Hub.current.client if client is not None: client.flush(timeout=2.0)
def log_message( message: str, format_args: Optional[dict] = None, level: Literal[ "fatal", "critical", "error", "warning", "info", "debug" ] = "warning", fingerprint: Optional[str] = None, component: Optional[str] = None, **kwargs ): """ Helper function to log messages to Sentry with optional fingerprinting.
This is useful when you need to log messages to Sentry without relying on error handling.
Args: message: The message to log format_args: Dictionary of arguments to format the message with (optional) level: Log level (default: "warning") fingerprint: String for Sentry fingerprinting (optional) component: Component name to tag the message with (optional) **kwargs: Additional keyword arguments passed to sentry_sdk.capture_message() Common options include: - extra: dict of extra data to include - tags: dict of additional tags - contexts: dict of additional contexts """ if format_args is None: format_args = {}
# Only format the message if format_args is not empty if format_args: try: formatted_message = message.format(**format_args) except KeyError: # If formatting fails due to missing keys, use the original message formatted_message = message else: formatted_message = message
# Remove 'level' from kwargs if present to avoid conflicts kwargs.pop("level", None)
if fingerprint or component: with sentry_sdk.push_scope() as scope: if fingerprint: scope.fingerprint = [fingerprint] if component: scope.set_tag("component", component) sentry_sdk.capture_message( formatted_message, level=level, **kwargs ) else: sentry_sdk.capture_message(formatted_message, level=level, **kwargs)
|