コンテンツにスキップ

ログストリーミング

サンドボックス(隔離された一時的な実行環境)で長時間動作するプロセスを扱う場合、リアルタイムでログにアクセスし処理したいことがよくあります。

Daytona(サンドボックスを作成・管理するプラットフォーム)のSDKは次の両方をサポートします:

  • Fetching log snapshot — 指定時点までのすべてのログを取得します。
  • Log streaming — プロセスの実行中に生成されるログをストリーミングします。

このガイドでは、非同期モードと同期モードの両方でログストリーミングを使用する方法を説明します。 リアルタイムストリーミングは、デバッグモニタリング、および可観測性ツールとの統合に特に有用です。

非同期

サンドボックス(隔離された一時的な実行環境)内のプロセスが大規模なシステムの一部で、長時間(あるいは無期限に)稼働する場合でも、 システムの他の処理を進めながら、ログをバックグラウンドで非同期に処理できます。

この方法は次の用途に最適です:

  • 継続的な監視
  • 長時間実行ジョブのデバッグ
  • ライブログの転送や可視化
import asyncio
from daytona import Daytona, SessionExecuteRequest
async def main():
daytona = Daytona()
sandbox = daytona.create()
try:
session_id = "exec-session-1"
sandbox.process.create_session(session_id)
command = sandbox.process.execute_session_command(
session_id,
SessionExecuteRequest(
command='for i in {1..10}; do echo "Processing step $i..."; sleep 1; done',
var_async=True,
),
)
logs_task = asyncio.create_task(
sandbox.process.get_session_command_logs_async(
session_id, command.cmd_id, lambda chunk: print(f"Log chunk: {chunk}")
)
)
print("Continuing execution while logs are streaming...")
await asyncio.sleep(1)
print("Other operations completed!")
print("At the end wait for any asynchronous task to complete and clean up resources...")
await logs_task
except Exception as e:
print(f"Error: {e}")
finally:
print("Cleaning up sandbox...")
sandbox.delete()
if __name__ == "__main__":
asyncio.run(main())

同期実行

コマンドの実行時間が予測できる場合、またはバックグラウンドで動かす必要がない場合は、 ログストリームを同期的に処理できます。たとえば、ログをファイルやその他のストレージに書き出せます。

import asyncio
import os
from daytona import Daytona, SessionExecuteRequest
async def main():
daytona = Daytona()
sandbox = daytona.create()
try:
session_id = "exec-session-1"
sandbox.process.create_session(session_id)
command = sandbox.process.execute_session_command(
session_id,
SessionExecuteRequest(
command='counter=1; while (( counter <= 5 )); do echo "Count: $counter"; ((counter++)); sleep 2; done',
var_async=True,
),
)
log_file_path = f"./logs/logs-session_{session_id}-command_{command.cmd_id}.log"
os.makedirs(os.path.dirname(log_file_path), exist_ok=True)
with open(log_file_path, "w") as log_file:
def handle_chunk(chunk: str):
# nullバイトを削除
clean_chunk = chunk.replace("\x00", "")
# ファイルに書き込む
log_file.write(clean_chunk)
log_file.flush()
await sandbox.process.get_session_command_logs_async(
session_id, command.cmd_id, handle_chunk
)
except Exception as e:
print(f"Error: {e}")
finally:
print("Cleaning up sandbox...")
sandbox.delete()
if __name__ == "__main__":
asyncio.run(main())