view_messages.pyβ’10.2 kB
#!/usr/bin/env python3
"""
Enhanced Message Viewer for Resume Agent
Features: Real-time monitoring, filtering, statistics, formatted display
"""
import subprocess
import re
from datetime import datetime
import time
import os
import sys
from collections import Counter
# ANSI color codes
class Colors:
HEADER = '\033[95m'
BLUE = '\033[94m'
CYAN = '\033[96m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
class MessageViewer:
def __init__(self):
self.key_file = "/Users/vikramsiwach/nanda/personal-resume-agent/deploy/aws/nanda-resume-key.pem"
self.ec2_host = "ubuntu@52.73.59.119"
self.last_count = 0
def fetch_messages(self, count=50):
"""Fetch messages from EC2 agent logs"""
cmd = [
"ssh", "-i", self.key_file,
"-o", "StrictHostKeyChecking=no",
self.ec2_host,
f"sudo grep 'Received:' /var/log/resume-agent.log | tail -{count}"
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
return result.stdout.strip().split('\n') if result.stdout else []
def fetch_all_messages(self):
"""Fetch all messages for statistics"""
cmd = [
"ssh", "-i", self.key_file,
"-o", "StrictHostKeyChecking=no",
self.ec2_host,
"sudo grep -c 'Received:' /var/log/resume-agent.log"
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
return int(result.stdout.strip()) if result.stdout.strip().isdigit() else 0
def parse_message(self, log_line):
"""Parse log line to extract message details"""
# Extract timestamp, sender, and message
timestamp_match = re.search(r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})', log_line)
sender_match = re.search(r'sender_agent_id[\'"]:\s*[\'"]([^\'"]+)[\'"]', log_line)
message_match = re.search(r'Received: (.+)$', log_line)
timestamp = timestamp_match.group(1) if timestamp_match else datetime.now().strftime('%Y-%m-%d %H:%M:%S')
sender = sender_match.group(1) if sender_match else 'user'
message = message_match.group(1) if message_match else log_line
return {
'timestamp': timestamp,
'sender': sender,
'message': message
}
def display_messages(self, messages, show_details=True):
"""Display messages with formatting"""
if not messages:
print(f"{Colors.YELLOW}π No messages found{Colors.ENDC}\n")
return
print(f"\n{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f"{Colors.BOLD}π¬ Recent Messages ({len(messages)}){Colors.ENDC}")
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}\n")
for i, msg_data in enumerate(messages, 1):
sender_color = Colors.GREEN if msg_data['sender'] == 'user' else Colors.BLUE
if show_details:
print(f"{Colors.BOLD}[{i}]{Colors.ENDC} {Colors.CYAN}{msg_data['timestamp']}{Colors.ENDC}")
print(f" {sender_color}From:{Colors.ENDC} {msg_data['sender']}")
print(f" {Colors.YELLOW}Msg:{Colors.ENDC} {msg_data['message'][:65]}...")
if i < len(messages):
print()
else:
print(f"{i:2d}. [{msg_data['timestamp'][-8:]}] {sender_color}{msg_data['sender'][:15]:15s}{Colors.ENDC} | {msg_data['message'][:40]}...")
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}\n")
def display_statistics(self):
"""Display message statistics"""
try:
total = self.fetch_all_messages()
recent = self.fetch_messages(100)
parsed = [self.parse_message(line) for line in recent if line]
senders = Counter(msg['sender'] for msg in parsed)
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f"{Colors.BOLD}π Message Statistics{Colors.ENDC}")
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f" {Colors.BOLD}Total Messages Ever:{Colors.ENDC} {total}")
print(f" {Colors.BOLD}Recent Messages:{Colors.ENDC} {len(parsed)}")
print(f"\n {Colors.BOLD}Top Senders (last 100):{Colors.ENDC}")
for sender, count in senders.most_common(5):
sender_color = Colors.GREEN if sender == 'user' else Colors.BLUE
bar = 'β' * (count // 2)
print(f" {sender_color}{sender:20s}{Colors.ENDC} {bar} {count}")
print(f"\n {Colors.BOLD}Agent Status:{Colors.ENDC} {Colors.GREEN}β Active{Colors.ENDC}")
print(f" {Colors.BOLD}Endpoint:{Colors.ENDC} http://52.73.59.119:6050/a2a")
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}\n")
except Exception as e:
print(f"{Colors.RED}β Error fetching statistics: {e}{Colors.ENDC}\n")
def monitor_mode(self, interval=5):
"""Real-time monitoring mode"""
print(f"{Colors.GREEN}π Starting real-time monitor (refresh every {interval}s){Colors.ENDC}")
print(f"{Colors.YELLOW}Press Ctrl+C to exit{Colors.ENDC}\n")
try:
while True:
os.system('clear' if os.name != 'nt' else 'cls')
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f"{Colors.BOLD}{Colors.HEADER}π€ Resume Agent - Live Message Monitor{Colors.ENDC}")
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f"{Colors.GREEN}β{Colors.ENDC} Monitoring: {Colors.BOLD}http://52.73.59.119:6050/a2a{Colors.ENDC}")
print(f"{Colors.GREEN}β{Colors.ENDC} Refresh: Every {interval}s | Last update: {datetime.now().strftime('%H:%M:%S')}")
lines = self.fetch_messages(20)
messages = [self.parse_message(line) for line in lines if line]
current_count = len(messages)
if current_count > self.last_count:
new_msgs = current_count - self.last_count
print(f"{Colors.GREEN}β{Colors.ENDC} {Colors.BOLD}{new_msgs} new message(s)!{Colors.ENDC}")
self.last_count = current_count
self.display_messages(messages, show_details=False)
print(f"{Colors.YELLOW}β±οΈ Refreshing in {interval}s... (Ctrl+C to exit){Colors.ENDC}")
time.sleep(interval)
except KeyboardInterrupt:
print(f"\n\n{Colors.GREEN}π Exited monitor mode{Colors.ENDC}\n")
def filter_messages(self, sender_filter=None):
"""Display filtered messages"""
lines = self.fetch_messages(100)
messages = [self.parse_message(line) for line in lines if line]
if sender_filter:
messages = [msg for msg in messages if sender_filter.lower() in msg['sender'].lower()]
print(f"{Colors.YELLOW}π Filtered by sender: {sender_filter}{Colors.ENDC}")
self.display_messages(messages)
def show_help():
"""Display help information"""
print(f"\n{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f"{Colors.BOLD}π Available Options{Colors.ENDC}")
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f" {Colors.BOLD}python3 view_messages.py{Colors.ENDC}")
print(f" View recent messages (default)")
print()
print(f" {Colors.BOLD}python3 view_messages.py --monitor{Colors.ENDC}")
print(f" Start real-time monitoring mode")
print()
print(f" {Colors.BOLD}python3 view_messages.py --stats{Colors.ENDC}")
print(f" Show detailed statistics")
print()
print(f" {Colors.BOLD}python3 view_messages.py --filter <sender>{Colors.ENDC}")
print(f" Filter messages by sender (e.g., --filter tech-expert)")
print()
print(f" {Colors.BOLD}python3 view_messages.py --help{Colors.ENDC}")
print(f" Show this help message")
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}\n")
def main():
viewer = MessageViewer()
# Parse command line arguments
if len(sys.argv) > 1:
cmd = sys.argv[1].lower()
if cmd in ['--help', '-h']:
show_help()
return
elif cmd in ['--monitor', '-m']:
interval = int(sys.argv[2]) if len(sys.argv) > 2 else 5
viewer.monitor_mode(interval)
return
elif cmd in ['--stats', '-s']:
viewer.display_statistics()
return
elif cmd in ['--filter', '-f']:
if len(sys.argv) > 2:
viewer.filter_messages(sys.argv[2])
else:
print(f"{Colors.RED}β Please provide a sender to filter by{Colors.ENDC}")
return
# Default: show recent messages
try:
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f"{Colors.BOLD}{Colors.HEADER}π€ Resume Agent - Message Viewer{Colors.ENDC}")
print(f"{Colors.CYAN}{'β' * 70}{Colors.ENDC}")
print(f"{Colors.GREEN}β{Colors.ENDC} Connected to: {Colors.BOLD}http://52.73.59.119:6050/a2a{Colors.ENDC}")
print(f"{Colors.GREEN}β{Colors.ENDC} Type {Colors.BOLD}--help{Colors.ENDC} for more options")
lines = viewer.fetch_messages(20)
messages = [viewer.parse_message(line) for line in lines if line]
viewer.display_messages(messages)
print(f"{Colors.YELLOW}π‘ Quick Commands:{Colors.ENDC}")
print(f" β’ {Colors.BOLD}--monitor{Colors.ENDC} : Start real-time monitoring")
print(f" β’ {Colors.BOLD}--stats{Colors.ENDC} : View detailed statistics")
print(f" β’ {Colors.BOLD}--help{Colors.ENDC} : Show all options")
print()
except subprocess.TimeoutExpired:
print(f"{Colors.RED}β Timeout: Could not connect to agent{Colors.ENDC}\n")
except Exception as e:
print(f"{Colors.RED}β Error: {e}{Colors.ENDC}\n")
print(f"{Colors.YELLOW}Alternative: SSH directly and run:{Colors.ENDC}")
print(f" ssh ubuntu@52.73.59.119 \"sudo grep 'Received:' /var/log/resume-agent.log | tail -20\"")
if __name__ == "__main__":
main()