|
18 | 18 | role = "crash"
|
19 | 19 | index = 1
|
20 | 20 |
|
21 |
| -# Get the current timestamp |
22 |
| -current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) |
23 |
| - |
24 |
| -# Print a message to stdout |
25 |
| -print(f'[{current_time}] {appname}: Application started', flush=True) |
| 21 | +COLOR_TABLE = [ |
| 22 | + ("\033[48;2;255;87;51m", "\033[38;2;255;255;255m"), # Vibrant Red bg, White text |
| 23 | + ("\033[48;2;46;204;113m", "\033[38;2;0;0;0m"), # Emerald Green bg, Black text |
| 24 | + ("\033[48;2;241;196;15m", "\033[38;2;0;0;0m"), # Bright Yellow bg, Black text |
| 25 | + ("\033[48;2;52;152;219m", "\033[38;2;255;255;255m"), # Sky Blue bg, White text |
| 26 | + ("\033[48;2;155;89;182m", "\033[38;2;255;255;255m"), # Amethyst bg, White text |
| 27 | + ("\033[48;2;26;188;156m", "\033[38;2;0;0;0m"), # Turquoise bg, Black text |
| 28 | + ("\033[48;2;231;76;60m", "\033[38;2;255;255;255m"), # Strong Red bg, White text |
| 29 | + ("\033[48;2;241;90;34m", "\033[38;2;255;255;255m"), # Orange bg, White text |
| 30 | + ("\033[48;2;39;174;96m", "\033[38;2;255;255;255m"), # Dark Green bg, White text |
| 31 | + ("\033[48;2;142;68;173m", "\033[38;2;255;255;255m"), # Dark Purple bg, White text |
| 32 | + ("\033[48;2;211;84;0m", "\033[38;2;255;255;255m"), # Pumpkin bg, White text |
| 33 | + ("\033[48;2;52;73;94m", "\033[38;2;255;255;255m"), # Midnight Blue bg, White text |
| 34 | +] |
| 35 | +RESET_COLOR = "\033[0m" |
| 36 | + |
| 37 | +# Logging function with colors |
| 38 | +def log_message(index, message): |
| 39 | + bg_color, text_color = COLOR_TABLE[index % len(COLOR_TABLE)] |
| 40 | + current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) |
| 41 | + print(f'[{current_time}] {appname}: {bg_color}{text_color}{message}{RESET_COLOR}', flush=True) |
26 | 42 |
|
27 | 43 | # Get index
|
28 | 44 | if len(sys.argv) >= 2:
|
29 | 45 | try:
|
30 | 46 | index = int(sys.argv[1])
|
31 | 47 | except ValueError:
|
32 | 48 | index = 1
|
33 |
| -print(f'[{current_time}] {appname}: Index set to {index}') |
| 49 | +log_message(index, f'Index set to {index}') |
34 | 50 |
|
35 | 51 | # Get role
|
36 | 52 | if len(sys.argv) >= 3:
|
37 | 53 | try:
|
38 | 54 | role = sys.argv[2]
|
39 | 55 | except ValueError:
|
40 | 56 | role = "crash"
|
41 |
| -print(f'[{current_time}] {appname}: Role set to {role}') |
| 57 | +log_message(index, f'Role set to {role}') |
| 58 | + |
| 59 | +# Get the PID |
| 60 | +pid = str(os.getpid()) |
| 61 | +log_message(index, f'Pid is {pid}') |
42 | 62 |
|
43 |
| -# Store the parameters in variables |
| 63 | +# Load configuration |
44 | 64 | config = configparser.ConfigParser()
|
45 |
| -config.optionxform=str |
| 65 | +config.optionxform = str |
46 | 66 | config.read('config.ini')
|
| 67 | +# Read UDP port |
47 | 68 | UDP_PORT = config.getint('processWatchdog', 'udp_port')
|
48 |
| -print(f'[{current_time}] {appname}: UDP_PORT set to {UDP_PORT}') |
49 |
| - |
50 |
| -#start_delay = config.getint('processWatchdog', str(index) + '_start_delay') |
51 |
| -#print(f'[{current_time}] {appname}: Start delay set to {start_delay}') |
52 |
| - |
53 |
| -heartbeat_delay = config.getint('processWatchdog', str(index) + '_heartbeat_delay') |
54 |
| -print(f'[{current_time}] {appname}: Heartbeat delay set to {heartbeat_delay}') |
55 |
| - |
56 |
| -heartbeat_interval = config.getint('processWatchdog', str(index) + '_heartbeat_interval') |
57 |
| -print(f'[{current_time}] {appname}: Heartbeat interval set to {heartbeat_interval}') |
58 |
| - |
59 |
| -name = config.get('processWatchdog', str(index) + '_name') |
60 |
| -print(f'[{current_time}] {appname}: Name set to {name}') |
| 69 | +log_message(index, f'UDP_PORT set to {UDP_PORT}') |
| 70 | +# Read name |
| 71 | +name = config.get('processWatchdog', f'{index}_name', fallback=f'process{index}').strip() |
| 72 | +if not name: |
| 73 | + name = f'Process{index}' |
| 74 | +log_message(index, f'Name set to {name}') |
| 75 | +# Read heartbeat delay |
| 76 | +heartbeat_delay = config.getint('processWatchdog', f'{index}_heartbeat_delay') |
| 77 | +log_message(index, f'{name} Heartbeat delay set to {heartbeat_delay}') |
| 78 | +# Read heartbeat_interval |
| 79 | +heartbeat_interval = config.getint('processWatchdog', f'{index}_heartbeat_interval') |
| 80 | +log_message(index, f'{name} Heartbeat interval set to {heartbeat_interval}') |
| 81 | + |
| 82 | +# Set the allowed running time dynamically |
| 83 | +max_runtime = max(abs(heartbeat_interval) * 5, 180) |
| 84 | +log_message(index, f'{name} Max runtime set to {max_runtime} seconds') |
| 85 | + |
| 86 | +# If heartbeat_interval is zero or negative, do not send periodic heartbeats |
| 87 | +if heartbeat_interval <= 0: |
| 88 | + log_message(index, f'{name} No periodic heartbeats will be sent') |
| 89 | + heartbeat_enabled = False |
| 90 | +else: |
| 91 | + heartbeat_enabled = True |
| 92 | + |
| 93 | +# Wait during given heartbeat delay if greater than zero |
| 94 | +if heartbeat_delay > 0: |
| 95 | + log_message(index, f'{name} Waiting {heartbeat_delay} seconds heartbeat_delay...') |
| 96 | + time.sleep(heartbeat_delay - 1) |
| 97 | +wait_time = max(heartbeat_delay, 0) |
61 | 98 |
|
62 | 99 | # Create a UDP socket
|
63 | 100 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
64 | 101 |
|
65 |
| -# Reuse the address |
66 |
| -#sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
67 |
| - |
68 |
| -# Bind the UDP socket |
69 |
| -#sock.bind(('localhost', UDP_PORT)) |
70 |
| - |
71 |
| -# Get the PID |
72 |
| -pid = str(os.getpid()) |
73 |
| - |
74 |
| -# Wait during given heartbeat delay |
75 |
| -heartbeat_delay = int(heartbeat_delay / 2 + 1) |
76 |
| -print(f'[{current_time}] {appname}: Waiting {heartbeat_delay} seconds heartbeat_delay...') |
77 |
| -time.sleep(heartbeat_delay) |
78 |
| -wait_time = heartbeat_delay |
79 |
| - |
80 |
| -if heartbeat_interval == 0: |
81 |
| - heartbeat_interval = 1000 |
82 |
| - |
83 |
| -# Set the running time of the program |
84 | 102 | start_time = time.time()
|
85 | 103 |
|
86 | 104 | while True:
|
87 |
| - # Create the data |
88 |
| - data = 'p' + pid |
| 105 | + if heartbeat_enabled: |
| 106 | + # Create the data |
| 107 | + data = 'p' + pid |
89 | 108 |
|
90 |
| - # Send the data |
91 |
| - sock.sendto(data.encode('utf-8'), ('localhost', UDP_PORT)) |
92 |
| - |
93 |
| - # Get the current timestamp |
94 |
| - current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) |
| 109 | + # Send the data |
| 110 | + sock.sendto(data.encode('utf-8'), ('localhost', UDP_PORT)) |
95 | 111 |
|
96 |
| - # Print a message to stdout |
97 |
| - print(f'[{current_time}] {appname}: {name} Heartbeat sent: {data} after {wait_time} seconds', flush=True) |
| 112 | + # Log heartbeat |
| 113 | + log_message(index, f'{name} Heartbeat sent: {data} after {wait_time} seconds') |
98 | 114 |
|
99 |
| - # Choose a random waiting time |
100 |
| - wait_time = random.randint(int(heartbeat_interval / 3), int(heartbeat_interval / 2)) |
| 115 | + # Choose a random waiting time |
| 116 | + wait_time = max(random.randint(int(heartbeat_interval / 3), int(heartbeat_interval / 2)), 0) |
101 | 117 |
|
102 |
| - # Wait for the random time |
103 |
| - time.sleep(wait_time) |
| 118 | + # Wait for the random time if greater than zero |
| 119 | + if wait_time > 0: |
| 120 | + time.sleep(wait_time) |
104 | 121 |
|
105 |
| - # Check the running time of the program |
| 122 | + # Check the running time of the process |
106 | 123 | elapsed_time = time.time() - start_time
|
107 |
| - if elapsed_time >= 180: |
108 |
| - # Print the final message to stdout |
| 124 | + if elapsed_time >= max_runtime: |
109 | 125 | if role == "noheartbeat":
|
110 |
| - print(f'[{current_time}] {appname}: {name} No more heartbeats', flush=True) |
111 |
| - time.sleep(9000) |
| 126 | + sleep_time = max(abs(heartbeat_interval) * 5, 100) |
| 127 | + interval = max(abs(heartbeat_interval + 1) / 10, 2) |
| 128 | + for _ in range(int(sleep_time / interval)): |
| 129 | + log_message(index, f'{name} No more heartbeats') |
| 130 | + time.sleep(interval) |
112 | 131 | elif role == "crash":
|
113 |
| - print(f'[{current_time}] {appname}: {name} Program stopped', flush=True) |
| 132 | + log_message(index, f'{name} process crashed') |
114 | 133 | sys.exit(0)
|
0 commit comments