Compare commits

..
21 Commits
Author SHA1 Message Date
retoor 0cc2a7022c Update.
Build and test Zhurnal / Test (push) Has been cancelled
2025-05-05 20:35:21 +02:00
retoor c23e289e0c Update. 2025-05-05 20:29:54 +02:00
bot fa4d3a80ae Update export statistics 2024-12-10 19:46:24 +00:00
retoor eb4b0b8575 New build.
Build and test Zhurnal / Test (push) Successful in 2m3s
2024-12-10 01:38:31 +01:00
retoor 983969ed9e Update name.
Build and test Zhurnal / Test (push) Waiting to run
2024-12-10 01:35:43 +01:00
bot 86d4f8f1d3 Update export statistics 2024-12-01 07:52:21 +00:00
retoor 0aa8955b4a Formatted.
Build and test Zhurnal / Test (push) Successful in 1m0s
2024-12-01 08:50:26 +01:00
retoor a2354c2ba7 Release new version.
Build and test Zhurnal / Test (push) Successful in 1m4s
2024-12-01 06:18:53 +01:00
retoor ea825f0190 Replace replace with ignore. 2024-12-01 06:18:19 +01:00
retoor a44108901e New release with beter decoding.
Build and test Zhurnal / Test (push) Successful in 1m11s
2024-12-01 06:14:33 +01:00
bot 14782c06c4 Update export statistics 2024-11-27 21:28:23 +00:00
retoor fdcdca8e87 Version bump
Build and test Zhurnal / Test (push) Successful in 55s
2024-11-27 22:25:24 +01:00
bot 66556bf890 Update export statistics 2024-11-27 21:24:01 +00:00
retoor 0511c74f0b Added screen logging
Build and test Zhurnal / Test (push) Successful in 52s
2024-11-27 22:23:03 +01:00
bot 92db21739a Update export statistics 2024-11-27 16:06:54 +00:00
retoor bc9408fc73 Fixed typo.
Build and test Zhurnal / Test (push) Successful in 1m4s
2024-11-27 17:05:42 +01:00
bot ebfcfb9f67 Update export statistics 2024-11-27 14:58:02 +00:00
retoor 239341c032 Typo.
Build and test Zhurnal / Test (push) Successful in 1m8s
2024-11-27 15:56:34 +01:00
retoor b2a88d9a78 Updated readme
Build and test Zhurnal / Test (push) Successful in 1m3s
2024-11-27 15:38:07 +01:00
retoor 7be813c0aa Added build server
Build and test Zhurnal / Test (push) Waiting to run
2024-11-27 15:30:45 +01:00
retoor 8ad5b590de Initial commit 2024-11-27 15:28:30 +01:00
5 changed files with 20 additions and 26 deletions
Binary file not shown.
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -1,6 +1,6 @@
Metadata-Version: 2.4 Metadata-Version: 2.4
Name: zhurnal Name: zhurnal
Version: 0.2.0 Version: 0.1.0
Summary: Process monitoring and management web application Summary: Process monitoring and management web application
Author: retoor Author: retoor
Author-email: retoor@molodetz.nl Author-email: retoor@molodetz.nl
@@ -8,7 +8,7 @@ Requires-Python: >=3.8
Description-Content-Type: text/markdown Description-Content-Type: text/markdown
Requires-Dist: aiohttp Requires-Dist: aiohttp
Requires-Dist: setuptools Requires-Dist: setuptools
Requires-Dist: app @ git+https://retoor.molodetz.nl/retoor/app.git Requires-Dist: app@ git+https://retoor.molodetz.nl/retoor/app.git
# Zhurnal: Real-Time Process Monitoring Web Interface 🚀 # Zhurnal: Real-Time Process Monitoring Web Interface 🚀
+1 -1
View File
@@ -1,3 +1,3 @@
aiohttp aiohttp
setuptools setuptools
app @ git+https://retoor.molodetz.nl/retoor/app.git app@ git+https://retoor.molodetz.nl/retoor/app.git
+17 -23
View File
@@ -209,15 +209,15 @@ class Zhurnal(BaseApplication):
self.process_tasks = {} self.process_tasks = {}
self.shutdown_event = asyncio.Event() self.shutdown_event = asyncio.Event()
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# Register signal handlers for graceful shutdown # Register signal handlers for graceful shutdown
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
for sig in (signal.SIGINT, signal.SIGTERM): for sig in (signal.SIGINT, signal.SIGTERM):
loop.add_signal_handler(sig, self.handle_exit) loop.add_signal_handler(sig, self.handle_exit)
self.on_startup.append(self.start_processes) self.on_startup.append(self.start_processes)
self.on_cleanup.append(self.cleanup_processes) self.on_cleanup.append(self.cleanup_processes)
self.clients = [] self.clients = []
self.router.add_get("/ws", self.websocket_handler) self.router.add_get("/ws", self.websocket_handler)
self.router.add_get("/", self.index_handler) self.router.add_get("/", self.index_handler)
@@ -231,12 +231,12 @@ class Zhurnal(BaseApplication):
async def cleanup_processes(self, app): async def cleanup_processes(self, app):
"""Cleanup all running subprocesses.""" """Cleanup all running subprocesses."""
log.info("Cleaning up processes...") log.info("Cleaning up processes...")
# Terminate all running processes # Terminate all running processes
for command, process_info in list(self.processes.items()): for command, process_info in list(self.processes.items()):
try: try:
# Get the subprocess # Get the subprocess
process = process_info.get("process") process = process_info.get('process')
if process and process.returncode is None: if process and process.returncode is None:
log.info(f"Terminating process: {command}") log.info(f"Terminating process: {command}")
try: try:
@@ -250,7 +250,7 @@ class Zhurnal(BaseApplication):
process.kill() process.kill()
except Exception as e: except Exception as e:
log.error(f"Error cleaning up process {command}: {e}") log.error(f"Error cleaning up process {command}: {e}")
# Cancel any running tasks # Cancel any running tasks
for task in list(self.process_tasks.values()): for task in list(self.process_tasks.values()):
if not task.done(): if not task.done():
@@ -297,10 +297,13 @@ class Zhurnal(BaseApplication):
stdout=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
) )
# Store process information # Store process information
self.processes[command] = {"process": process, "name": process_name} self.processes[command] = {
'process': process,
'name': process_name
}
log.info(f"Running process {process_name}: {command}") log.info(f"Running process {process_name}: {command}")
async def read_output(app, name, process, f, is_stderr=False): async def read_output(app, name, process, f, is_stderr=False):
@@ -310,17 +313,15 @@ class Zhurnal(BaseApplication):
# Check if shutdown is requested # Check if shutdown is requested
if self.shutdown_event.is_set(): if self.shutdown_event.is_set():
break break
time_current = time.time() time_current = time.time()
time_elapsed = round( time_elapsed = round(
time_previous and time_current - time_previous or 0, 4 time_previous and time_current - time_previous or 0, 4
) )
decoded_line = line.decode("utf-8", "ignore").strip() decoded_line = line.decode("utf-8", "ignore").strip()
print(decoded_line) print(decoded_line)
decoded_line = "".join( decoded_line = "".join(c for c in decoded_line if c.isprintable())
c for c in decoded_line if c.isprintable()
)
# Broadcast to all WebSocket clients # Broadcast to all WebSocket clients
for client in app.clients: for client in app.clients:
await client.send_str( await client.send_str(
@@ -345,13 +346,7 @@ class Zhurnal(BaseApplication):
# Read stdout and stderr concurrently # Read stdout and stderr concurrently
await asyncio.gather( await asyncio.gather(
read_output(self, f"{process_name}:stdout", process, process.stdout), read_output(self, f"{process_name}:stdout", process, process.stdout),
read_output( read_output(self, f"{process_name}:stderr", process, process.stderr, is_stderr=True)
self,
f"{process_name}:stderr",
process,
process.stderr,
is_stderr=True,
),
) )
# Wait for process to complete # Wait for process to complete
@@ -366,7 +361,7 @@ class Zhurnal(BaseApplication):
log.error( log.error(
f"Process {process_name}:{command} exited with non-zero status {process.returncode}." f"Process {process_name}:{command} exited with non-zero status {process.returncode}."
) )
except Exception as e: except Exception as e:
log.error(f"Error running process {process_name}: {e}") log.error(f"Error running process {process_name}: {e}")
finally: finally:
@@ -427,6 +422,5 @@ def cli():
app.run(host=args.host, port=args.port) app.run(host=args.host, port=args.port)
if __name__ == "__main__": if __name__ == "__main__":
cli() cli()