Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding system-scanner #71

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 206 additions & 0 deletions integration-examples/system-scanner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
# SystemScanner

This project is designed to check and report information about the operating system and various runtime environments installed on a machine, such as Java, Python, Node.js, and .NET Framework (on Windows).

## ⚠️ Warning: Work in Progress

**PLEASE NOTE: This project is currently in early development stages and is considered a rough work in progress.**

## Features

- Check operating system information
- Check Java runtime version
- Check Python runtime version
- Check Node.js runtime version
- Check OpenTelemetry Collector version and path
- Check .NET Framework versions (Windows only)

## Project Structure

```plaintext
system-scanner/
├── os_info.py
├── runtime_versions.py
├── dotnet_framework.py
└── main.py
```

### Module Descriptions

- **`os_info.py`**: Retrieves operating system information.
- **`runtime_versions.py`**: Handles version checking and retrieval for various runtimes like Java, Python, and Node.js.
- **`dotnet_framework.py`**: Specifically deals with retrieving .NET Framework versions on Windows systems.
- **`main.py`**: Entry point to orchestrate the retrieval and logging of system information.

## Requirements

- Python 3.9 or higher

## Installation

1. Clone the repository:
```bash
git clone https://github.com/splunk/observability-content-contrib.git

2. Navigate into the project directory:
```bash
cd observability-content-contrib/integration-examples/system-scanner
```

## Usage

To run the script and get information about your system's versions and runtimes, execute:
```bash
python3 main.py
```

### Output

The script generates a formatted report directly to the console, structured as follows:

```
==================================================
SYSTEM SCANNER REPORT
==================================================

OPERATING SYSTEM INFORMATION:
System: [OS Name]
Version: [OS Version]
Architecture: [OS Architecture]

--------------------------------------------------
RUNTIME VERSIONS:
Java: [Java Version]
Python: [Python Version]
Node.js: [Node.js Version]

--------------------------------------------------
OPENTELEMETRY COLLECTOR INFORMATION:
Version: [OTel Collector Version]
Path: [OTel Collector Path]

--------------------------------------------------
[.NET FRAMEWORK VERSIONS (if on Windows)]

==================================================
END OF SYSTEM SCANNER REPORT
==================================================
```


If running the script(s) isn't an option (for security reasons, etc), the same information can be obtained by referencing the below commands.


## Common Commands: Bash vs PowerShell

For users who need to run commands manually or understand the underlying operations, here are some common commands used in this project with their Bash and PowerShell equivalents:

| Operation | Bash (Unix-like systems) | PowerShell (Windows) |
|-----------|--------------------------|----------------------|
| Check Java version | `java -version` | `java -version` |
| Check Python version | `python --version` | `python --version` |
| Check Node.js version | `node --version` | `node --version` |
| Check OS version | `uname -a` | `[System.Environment]::OSVersion.Version` |
| List directory contents | `ls -l` | `Get-ChildItem` or `dir` |
| Create a directory | `mkdir -p new_folder` | `New-Item -ItemType Directory -Name new_folder` |
| Remove a file | `rm file.txt` | `Remove-Item file.txt` |
| Set an environment variable | `export VAR_NAME=value` | `$env:VAR_NAME = "value"` |
| Read an environment variable | `echo $VAR_NAME` | `$env:VAR_NAME` |
| Find a file | `find /path -name filename` | `Get-ChildItem -Path C:\ -Recurse -Filter filename` |
| Check if a file exists | `test -f filename && echo "Exists"` | `if (Test-Path filename) { "Exists" }` |
| Get current directory | `pwd` | `Get-Location` or `pwd` |
| Move/Rename a file | `mv old_name new_name` | `Move-Item -Path old_name -Destination new_name` |
| Copy a file | `cp source destination` | `Copy-Item -Path source -Destination destination` |
| Get OTel Collector version | `/bin/otelcol -v` | TBD |

Note: Some commands (like checking runtime versions) may be identical in both environments, while others differ significantly.

## .NET Framework Version Check (Windows Only)

To check the installed .NET Framework versions on a Windows system, you can use the following PowerShell command:

```powershell
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | Get-ItemProperty -Name version -EA 0 | Where { $_.PSChildName -Match '^(?!S)\p{L}'} | Select PSChildName, version
```

This command is already implemented in the `dotnet_framework.py` module for Windows systems.



## OTel Collector config location(s) (Default)

**Windows**
```powershell
C:\ProgramData\Splunk\OpenTelemetry Collector\agent_config.yaml
```

**Linux**
```bash
/etc/otel/collector/agent_config.yaml
```

The environment file with the required variables/values for the Splunk OpenTelemetry Collector service based on the specified parameters.

```bash
/etc/otel/collector/splunk-otel-collector.conf
```


## Tailing Collector Logs
**Linux**

Splunk Distro of OpenTelemetry:

```bash
sudo journalctl -u splunk-otel-collector -f -n 200
```

```bash
tail -f /var/log/[splunk-otel-collector]
```

Upstream OTel Collector (contrib):
```bash
sudo journalctl -u otelcol-contrib -f -n 200
```

```bash
tail -f /var/log/[otelcol-contrib]
```

## Getting Status/Restarting the OTel Collector

**Linux**

Splunk Distribution:
```bash
sudo systemctl [status/stop/start/restart] splunk-otel-collector
```

Upstream Contrib:
```bash
sudo systemctl [status/stop/start/restart] otelcol-contrib
```

**Windows**

Stop the Collector service:

```powershell
[Stop-Service/Start-Service] splunk-otel-collector
```

### Logging

While the main output is printed to the console, the script also generates a log file (`system_scanner.log`) in the same directory. This log file can be useful for debugging purposes.

## Error Handling

The script includes robust error handling mechanisms to catch potential exceptions during execution. Any errors or unexpected behaviors will be reflected in the output.

## Contributing

If you wish to contribute to this project, please fork the repository and submit a pull request.

**Note**: This project uses standard Python libraries to maintain portability and minimize dependencies.
84 changes: 84 additions & 0 deletions integration-examples/system-scanner/dotnet_framework.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
SystemScanner: .NET Framework Detection Module

This module is designed to detect and report installed versions
of the .NET Framework on Windows systems.

It uses the Windows Registry to gather this information and is
only functional on Windows operating systems.

Note: This module relies on the winreg library, which is only
available on Windows systems. On other operating systems,
the get_dotnet_versions function will return a message
indicating that the winreg module is not available.
"""

try:
import winreg as reg

def get_dotnet_versions():
try:
net_versions = []
path = r"SOFTWARE\Microsoft\NET Framework Setup\NDP"

def check_versions(key):
i = 0
while True:
try:
subkey_name = reg.EnumKey(key, i)
subkey_path = f"{path}\\{subkey_name}"
with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, subkey_path) as subkey:
try:
version, _ = reg.QueryValueEx(subkey, "Version")
net_versions.append((subkey_name, version))
except FileNotFoundError:
pass
i += 1
except OSError:
break

with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, path) as main_key:
check_versions(main_key)

return net_versions

except OSError as e:
return f"Error accessing registry: {e}"

except ImportError:

def get_dotnet_versions():
return "winreg module not available on this platform"


# Saving for a future iteration:

# def get_dotnet_versions():
# try:
# net_versions = []
# path = r"SOFTWARE\Microsoft\NET Framework Setup\NDP"

# def iterate_registry(key):
# stack = [(key, 0)]
# while stack:
# current_key, i = stack.pop()
# try:
# subkey_name = reg.EnumKey(current_key, i)
# subkey_path = f"{path}\\{subkey_name}"
# with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, subkey_path) as subkey:
# try:
# version, _ = reg.QueryValueEx(subkey, "Version")
# net_versions.append((subkey_name, version))
# except FileNotFoundError:
# pass
# stack.append((current_key, i + 1))
# except OSError:
# break

# with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, path) as main_key:
# iterate_registry(main_key)

# return net_versions

# except OSError as e:
# return f"Error accessing registry: {e}"
80 changes: 80 additions & 0 deletions integration-examples/system-scanner/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env python3

"""
SystemScanner
Version 0.2
Author: Brandon Blinderman
"""

from os_info import get_os_info
from runtime_versions import RuntimeFactory
from dotnet_framework import get_dotnet_versions
import logging


def print_separator():
print("-" * 50)


def main():
# Set up logging for debug purposes, but don't use it for main output
logging.basicConfig(
level=logging.DEBUG, filename="system_scanner.log", filemode="w"
)
logger = logging.getLogger(__name__)

print("=" * 50)
print("SYSTEM SCANNER REPORT")
print("=" * 50)
print()

# Operating System Information
os_name, os_version, os_architecture = get_os_info()
print("OPERATING SYSTEM INFORMATION:")
print(f" System: {os_name}")
print(f" Version: {os_version}")
print(f" Architecture: {os_architecture}")

print_separator()

# Runtime Versions
factory = RuntimeFactory()
print("RUNTIME VERSIONS:")

java_version = factory.get_version("java")
print(f" Java: {java_version}")

python_version = factory.get_version("python")
print(f" Python: {python_version}")

node_version = factory.get_version("node")
print(f" Node.js: {node_version}")

print_separator()

# OpenTelemetry Collector Information
print("OPENTELEMETRY COLLECTOR INFORMATION:")
otel_version, otel_path = factory.get_otel_collector_info()
print(f" Version: {otel_version}")
print(f" Path: {otel_path if otel_path else 'Not found'}")

print_separator()

# .NET Framework Versions (Windows only)
if os_name == "Windows":
print(".NET FRAMEWORK VERSIONS:")
dotnet_versions = get_dotnet_versions()
if isinstance(dotnet_versions, list):
for name, version in dotnet_versions:
print(f" {name}: {version}")
else:
print(f" Error: {dotnet_versions}")

print()
print("=" * 50)
print("END OF SYSTEM SCANNER REPORT")
print("=" * 50)


if __name__ == "__main__":
main()
Loading
Loading