ログストリーミング
サンドボックス(隔離された一時的な実行環境)で長時間動作するプロセスを扱う場合、リアルタイムでログにアクセスし処理したいことがよくあります。
Daytona(サンドボックスを作成・管理するプラットフォーム)のSDKは次の両方をサポートします:
Fetching log snapshot
— 指定時点までのすべてのログを取得します。Log streaming
— プロセスの実行中に生成されるログをストリーミングします。
このガイドでは、非同期モードと同期モードの両方でログストリーミングを使用する方法を説明します。 リアルタイムストリーミングは、デバッグ、モニタリング、および可観測性ツールとの統合に特に有用です。
非同期
サンドボックス(隔離された一時的な実行環境)内のプロセスが大規模なシステムの一部で、長時間(あるいは無期限に)稼働する場合でも、 システムの他の処理を進めながら、ログをバックグラウンドで非同期に処理できます。
この方法は次の用途に最適です:
- 継続的な監視
- 長時間実行ジョブのデバッグ
- ライブログの転送や可視化
import asynciofrom 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 { Daytona, Sandbox } from '@daytonaio/sdk'
async function main() { const daytona = new Daytona() const sandbox = await daytona.create()
try { const sessionId = 'exec-session-async-logs' await sandbox.process.createSession(sessionId)
const command = await sandbox.process.executeSessionCommand(sessionId, { command: 'for i in {1..10}; do echo "Processing step $i..."; sleep 1; done', async: true, })
const logTask = sandbox.process.getSessionCommandLogs(sessionId, command.cmdId!, (chunk) => { console.log('Log chunk:', chunk) })
console.log('Continuing execution while logs are streaming...') sleep(1) console.log('Other operations completed!')
console.log('At the end wait for any asynchronous task to complete and clean up resources...') await logTask } catch (error) { console.error('Error:', error) } finally { console.log('Cleaning up sandbox...') await sandbox.delete() }}
main()
同期実行
コマンドの実行時間が予測できる場合、またはバックグラウンドで動かす必要がない場合は、 ログストリームを同期的に処理できます。たとえば、ログをファイルやその他のストレージに書き出せます。
import asyncioimport osfrom 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())
import { Daytona, Sandbox } from '@daytonaio/sdk'
async function main() { const daytona = new Daytona() const sandbox = await daytona.create()
try { const sessionId = 'exec-session-async-logs' await sandbox.process.createSession(sessionId)
const command = await sandbox.process.executeSessionCommand(sessionId, { command: 'counter=1; while (( counter <= 5 )); do echo "Count: $counter"; ((counter++)); sleep 2; done', async: true, })
const logFilePath = `./logs/logs-session-${sessionId}-command-${command.cmdId}.log` const logsDir = path.dirname(logFilePath) if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir, { recursive: true }) }
const stream = fs.createWriteStream(logFilePath) await sandbox.process.getSessionCommandLogs(sessionId, command.cmdId!, (chunk) => { const cleanChunk = chunk.replace(/\x00/g, '') stream.write(cleanChunk) }) stream.end() await logTask } catch (error) { console.error('Error:', error) } finally { console.log('Cleaning up sandbox...') await sandbox.delete() }}
main()