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

Improve cross-platform implementation #68

Merged
merged 2 commits into from
May 2, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# secrets
config.yaml
config.*.yaml

# dev files
.idea
Expand Down
59 changes: 38 additions & 21 deletions src/chia_log/log_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import logging
import subprocess
from abc import ABC, abstractmethod
from pathlib import Path
from pathlib import Path, PurePosixPath, PureWindowsPath, PurePath
from threading import Thread
from typing import List, Optional

Expand Down Expand Up @@ -83,20 +83,19 @@ def _consume_loop(self):
class NetworkLogConsumer(LogConsumer):
"""Consume logs over the network"""

def __init__(self, remote_log_path: Path, remote_user, remote_host):
def __init__(self, remote_log_path: PurePath, remote_user, remote_host, remote_platform=OS.LINUX):
pieterhelsen marked this conversation as resolved.
Show resolved Hide resolved
logging.info("Enabled network log consumer.")
super().__init__()

self._remote_user = remote_user
self._remote_host = remote_host
self._remote_log_path = remote_log_path
self._remote_platform = remote_platform

self._ssh_client = paramiko.client.SSHClient()
self._ssh_client.load_system_host_keys()
self._ssh_client.connect(hostname=self._remote_host, username=self._remote_user)

self._remote_platform = self._get_remote_platform()

# Start thread
self._is_running = True
self._thread = Thread(target=self._consume_loop)
Expand All @@ -107,32 +106,42 @@ def stop(self):
self._is_running = False

def _consume_loop(self):
logging.info(f"Consuming remote log file {self._remote_log_path} from {self._remote_host} ({self._remote_platform})")
logging.info(
f"Consuming remote log file {self._remote_log_path} from {self._remote_host} ({self._remote_platform})"
)

if self._remote_platform == OS.WINDOWS:
stdin, stdout, stderr = self._ssh_client.exec_command(f"powershell.exe Get-Content {self._remote_log_path} -Wait -Tail 1")
stdin, stdout, stderr = self._ssh_client.exec_command(
f"powershell.exe Get-Content {self._remote_log_path} -Wait -Tail 1"
)
else:
stdin, stdout, stderr = self._ssh_client.exec_command(f"tail -F {self._remote_log_path}")

while self._is_running:
log_line = stdout.readline()
self._notify_subscribers(log_line)

def _get_remote_platform(self):
stdin, stdout, stderr = self._ssh_client.exec_command(f"uname -a")
fout: str = stdout.readline().lower()
ferr: str = stderr.readline().lower()

if 'linux' in fout:
return OS.LINUX
elif 'darwin' in fout:
return OS.MACOS
elif 'not recognized' in ferr:
return OS.WINDOWS
else:
logging.error(f"Found unsupported platform on remote host, assuming Linux and hope for the best.")

return OS.LINUX
def get_host_info(host: str, user: str, path: str):
pieterhelsen marked this conversation as resolved.
Show resolved Hide resolved

client = paramiko.client.SSHClient()
client.load_system_host_keys()
client.connect(hostname=host, username=user)

stdin, stdout, stderr = client.exec_command("uname -a")
fout: str = stdout.readline().lower()
ferr: str = stderr.readline().lower()

if "linux" in fout:
return OS.LINUX, PurePosixPath(path)
elif "darwin" in fout:
return OS.MACOS, PurePosixPath(path)
elif "not recognized" in ferr:
return OS.WINDOWS, PureWindowsPath(path)
else:
logging.error("Found unsupported platform on remote host, assuming Linux and hope for the best.")

return OS.LINUX
pieterhelsen marked this conversation as resolved.
Show resolved Hide resolved


def create_log_consumer_from_config(config: dict) -> Optional[LogConsumer]:
Expand All @@ -159,10 +168,18 @@ def create_log_consumer_from_config(config: dict) -> Optional[LogConsumer]:
required_keys=["remote_file_path", "remote_host", "remote_user"], config=enabled_consumer_config
):
return None

platform, path = get_host_info(
enabled_consumer_config["remote_host"],
enabled_consumer_config["remote_user"],
enabled_consumer_config["remote_file_path"],
)

return NetworkLogConsumer(
remote_log_path=Path(enabled_consumer_config["remote_file_path"]),
remote_log_path=path,
remote_host=enabled_consumer_config["remote_host"],
remote_user=enabled_consumer_config["remote_user"],
remote_platform=platform,
)

logging.error("Unhandled consumer type")
Expand Down
7 changes: 3 additions & 4 deletions src/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

class OS(Enum):

LINUX = 'LINUX'
MACOS = 'MACOS'
WINDOWS = 'WINDOWS'

LINUX = "LINUX"
MACOS = "MACOS"
WINDOWS = "WINDOWS"
pieterhelsen marked this conversation as resolved.
Show resolved Hide resolved