spin icon indicating copy to clipboard operation
spin copied to clipboard

stdio in spin

Open Mossaka opened this issue 2 years ago • 10 comments

How does application wire it's own stdin/out/err path to spin such that spin pass them to WasiCtxBuilder?

I found the relevent implementation here: https://github.com/fermyon/spin/blob/a9181f7b7ed290ee0b724ccb266f7d8d00f28431/crates/http/src/spin.rs#L217-L235

Mossaka avatar May 04 '22 06:05 Mossaka

We don't currently expose stdio streams, we just save them to logs. PR #431 aims to extend this behavior to optionally forward guest stdio to host stdio. Could you expand on what you'd like to do? If you have another use case it might change the design of #431.

lann avatar May 04 '22 13:05 lann

ref #380

radu-matei avatar May 04 '22 14:05 radu-matei

Could you expand on what you'd like to do?

I am using the Http Trigger in an application, which has inherited stdio (they are path to stdio files). I want to wire them to spin's stdio, or more specifically, WasiCtx's stdio

Mossaka avatar May 04 '22 17:05 Mossaka

As @lann points out, #380 and #431 address redirecting component stdio to Spin's standard output/error. So if the goal is to capture logs, #380 is the place we are trying to figure out the user stories for that.

(see https://github.com/fermyon/spin/pull/431/files#diff-e009a66ed5d35b924eb37f0c5fc5c5abd0abf68521a94d316a4dba88c97410a9R1)

radu-matei avatar May 04 '22 17:05 radu-matei

I was mistaken - we do expose stdio, but only as buffers (Vec<u8>), so you can pass in a complete buffer to stdin and get the stdout/stderr buffers. What we don't support is a streaming interface to either of these.

For your use-case, can you clarify if you want stdio for logging or some other purpose? The Wagi HTTP executor, for example, uses stdin to provide the request to the guest, and parses stdout into the response: https://github.com/fermyon/spin/blob/0f51ad0b86b798ae18cb4f211f0c3fcfbbe9a156/crates/http/src/wagi.rs#L54 https://github.com/fermyon/spin/blob/0f51ad0b86b798ae18cb4f211f0c3fcfbbe9a156/crates/http/src/wagi.rs#L116

lann avatar May 04 '22 17:05 lann

@lann ~ We are looking to capture IO to memory. Actually, it seems like #431 implements pretty much all we need. We'd make use of capture_io_to_memory, and the updated prepare_component. The only thing we'd like and that is currently not provided is the ability to pass our own Box<dyn WasiFile>s to capture_io_to_memory.

danbugs avatar May 05 '22 21:05 danbugs

@danbugs If you want to pass your own Box<dyn WasiFile>, and are at the level where you could call capture_io_to_memory yourself, you could construct a ModuleIoRedirects directly. capture_io_to_memory just encapsulates a pattern for producing WasiFles backed by memory buffers with optional streaming. You can also lean on redirect_to_mem_buffer which does the "standard" behaviour for the output streams.

Would that provide the flexibility you need? This area and the current PR draft are very much up for refinement, and it would be great to have your feedback on the right structure.

itowlson avatar May 05 '22 21:05 itowlson

@itowlson ~ If I understand this correctly, redirect_to_mem_buffer just gives us a pipe (i.e., WasiFile) to build ModuleIoRedirects with, which we pass to prepare_component that hooks up the spin engine to use that for IO, right?

If that's the case, I don't think we need redirect_to_mem_buffer — we have our WasiFiles already. We just need to create a ModuleIoRedirects instance with our own WasiFiles and pass to prepare_component...

danbugs avatar May 05 '22 22:05 danbugs

That's exactly right. If you have your WasiFiles already, you can call ModuleIoRedirects::new directly, and pass that to prepare_component. (At least, you'll be able to if that PR is accepted.)

WAGI does this in a very simple form because it needs different behaviour for stdin, and a slightly different interaction with the buffer for stdout. It's really valuable to know that this is more broadly useful as a public customisation point though!

itowlson avatar May 05 '22 22:05 itowlson

https://github.com/fermyon/spin/pull/431#issuecomment-1119240466

How would we feel about prepending the component name in the followed logs? For example, following the logs of the Spin docs from this repo, it is unclear in which component a log line originated.

Not found: /favicon.ico

Cannot read file: cannot open /image/nonexistent.png

Caused by:
    No such file or directory (os error 44)

For example, Docker Compose's output (source):

#docker-compose -f docker-compose-all.yml logs -t|head
Attaching to oauth_web_1, oauth_core_1, oauth_core-ok_1, oauth_core-fb_1, oauth_oauth_1, oauth_fill-sqls-web_1, oauth_fill-sqls-oauth_1, oauth_web-redis_1, oauth_core-redis_1, oauth_core-mysql_1, oauth_oauth-mysql_1, oauth_web-mysql_1
core_1 | 2016-10-07T06:22:10.603699134Z [nodemon] 1.10.2
web_1 | 2016-10-07T06:23:26.013419543Z [06:23:26] Using gulpfile /usr/src/app/gulpfile.js

radu-matei avatar May 06 '22 04:05 radu-matei

This is addressed by #763

lann avatar Sep 19 '22 22:09 lann