wasmer_journal/concrete/
printing.rs

1use std::fmt;
2
3use super::*;
4use lz4_flex::block::uncompressed_size;
5use wasmer_wasix_types::wasi;
6
7/// Type of printing mode to use
8#[derive(Debug)]
9pub enum JournalPrintingMode {
10    Text,
11    Json,
12}
13impl Default for JournalPrintingMode {
14    fn default() -> Self {
15        Self::Text
16    }
17}
18
19/// The printing journal writes all the journal entries to the console
20/// as either text or json.
21#[derive(Debug, Default)]
22pub struct PrintingJournal {
23    mode: JournalPrintingMode,
24}
25
26impl PrintingJournal {
27    pub fn new(mode: JournalPrintingMode) -> Self {
28        Self { mode }
29    }
30}
31
32impl ReadableJournal for PrintingJournal {
33    fn read(&self) -> anyhow::Result<Option<LogReadResult<'_>>> {
34        Ok(None)
35    }
36
37    fn as_restarted(&self) -> anyhow::Result<Box<DynReadableJournal>> {
38        Ok(Box::<PrintingJournal>::default())
39    }
40}
41
42impl WritableJournal for PrintingJournal {
43    fn write<'a>(&'a self, entry: JournalEntry<'a>) -> anyhow::Result<LogWriteResult> {
44        match self.mode {
45            JournalPrintingMode::Text => println!("{entry}"),
46            JournalPrintingMode::Json => {
47                println!("{}", serde_json::to_string_pretty(&entry)?)
48            }
49        }
50        Ok(LogWriteResult {
51            record_start: 0,
52            record_end: entry.estimate_size() as u64,
53        })
54    }
55
56    fn flush(&self) -> anyhow::Result<()> {
57        Ok(())
58    }
59}
60
61impl Journal for PrintingJournal {
62    fn split(self) -> (Box<DynWritableJournal>, Box<DynReadableJournal>) {
63        (
64            Box::<PrintingJournal>::default(),
65            Box::<PrintingJournal>::default(),
66        )
67    }
68}
69
70impl fmt::Display for JournalEntry<'_> {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        match self {
73            JournalEntry::InitModuleV1 { wasm_hash } => {
74                write!(f, "init-module (hash={wasm_hash:x?})")
75            }
76            JournalEntry::ClearEtherealV1 => {
77                write!(f, "clear-ethereal")
78            }
79            JournalEntry::UpdateMemoryRegionV1 {
80                region,
81                compressed_data,
82            } => write!(
83                f,
84                "memory-update (start={}, end={}, data.len={}, compressed.len={})",
85                region.start,
86                region.end,
87                uncompressed_size(compressed_data.as_ref())
88                    .map(|a| a.0)
89                    .unwrap_or_else(|_| compressed_data.as_ref().len()),
90                compressed_data.len()
91            ),
92            JournalEntry::ProcessExitV1 { exit_code } => {
93                write!(f, "process-exit (code={exit_code:?})")
94            }
95            JournalEntry::SetThreadV1 {
96                id,
97                call_stack,
98                memory_stack,
99                store_data,
100                ..
101            } => write!(
102                f,
103                "thread-update (id={}, call-stack.len={}, mem-stack.len={}, store-size={})",
104                id,
105                call_stack.len(),
106                memory_stack.len(),
107                store_data.len(),
108            ),
109            JournalEntry::CloseThreadV1 { id, exit_code } => {
110                write!(f, "thread-close (id={id}, code={exit_code:?})")
111            }
112            JournalEntry::FileDescriptorSeekV1 { fd, offset, whence } => {
113                write!(f, "fd-seek (fd={fd}, offset={offset}, whence={whence:?})")
114            }
115            JournalEntry::FileDescriptorWriteV1 {
116                fd, offset, data, ..
117            } => write!(
118                f,
119                "fd-write (fd={fd}, offset={offset}, data.len={})",
120                data.len()
121            ),
122            JournalEntry::SetClockTimeV1 { clock_id, time } => {
123                write!(f, "set-clock-time (id={clock_id:?}, time={time})")
124            }
125            JournalEntry::CloseFileDescriptorV1 { fd } => write!(f, "fd-close (fd={fd})"),
126            JournalEntry::OpenFileDescriptorV1 {
127                fd, path, o_flags, ..
128            }
129            | JournalEntry::OpenFileDescriptorV2 {
130                fd, path, o_flags, ..
131            } => {
132                if o_flags.contains(wasi::Oflags::CREATE) {
133                    if o_flags.contains(wasi::Oflags::TRUNC) {
134                        write!(f, "fd-create-new (fd={fd}, path={path})")
135                    } else if o_flags.contains(wasi::Oflags::EXCL) {
136                        write!(f, "fd-create-excl (fd={fd}, path={path})")
137                    } else {
138                        write!(f, "fd-create (fd={fd}, path={path})")
139                    }
140                } else if o_flags.contains(wasi::Oflags::TRUNC) {
141                    write!(f, "fd-open-new (fd={fd}, path={path})")
142                } else {
143                    write!(f, "fd-open (fd={fd}, path={path})")
144                }
145            }
146            JournalEntry::RenumberFileDescriptorV1 { old_fd, new_fd } => {
147                write!(f, "fd-renumber (old={old_fd}, new={new_fd})")
148            }
149            JournalEntry::DuplicateFileDescriptorV1 {
150                original_fd,
151                copied_fd,
152            } => write!(
153                f,
154                "fd-duplicate (original={original_fd}, copied={copied_fd})"
155            ),
156            JournalEntry::DuplicateFileDescriptorV2 {
157                original_fd,
158                copied_fd,
159                cloexec,
160            } => write!(
161                f,
162                "fd-duplicate (original={original_fd}, copied={copied_fd}, cloexec={cloexec})"
163            ),
164            JournalEntry::CreateDirectoryV1 { fd, path } => {
165                write!(f, "path-create-dir (fd={fd}, path={path})")
166            }
167            JournalEntry::RemoveDirectoryV1 { fd, path } => {
168                write!(f, "path-remove-dir (fd={fd}, path={path})")
169            }
170            JournalEntry::PathSetTimesV1 {
171                path,
172                st_atim,
173                st_mtim,
174                ..
175            } => write!(
176                f,
177                "path-set-times (path={path}, atime={st_atim}, mtime={st_mtim}))"
178            ),
179            JournalEntry::FileDescriptorSetTimesV1 {
180                fd,
181                st_atim,
182                st_mtim,
183                ..
184            } => write!(
185                f,
186                "fd-set-times (fd={fd}, atime={st_atim}, mtime={st_mtim})"
187            ),
188            JournalEntry::FileDescriptorSetFdFlagsV1 { fd, flags } => {
189                write!(f, "fd-set-fd-flags (fd={fd}, flags={flags:?})")
190            }
191            JournalEntry::FileDescriptorSetFlagsV1 { fd, flags } => {
192                write!(f, "fd-set-flags (fd={fd}, flags={flags:?})")
193            }
194            JournalEntry::FileDescriptorSetRightsV1 {
195                fd,
196                fs_rights_base,
197                fs_rights_inheriting,
198            } => write!(
199                f,
200                "fd-set-rights (fd={fd}, base={fs_rights_base:?}, inherited={fs_rights_inheriting:?})"
201            ),
202            JournalEntry::FileDescriptorSetSizeV1 { fd, st_size } => {
203                write!(f, "fd-set-size (fd={fd}, size={st_size})")
204            }
205            JournalEntry::FileDescriptorAdviseV1 {
206                fd, offset, len, ..
207            } => write!(f, "fd-advise (fd={fd}, offset={offset}, len={len})"),
208            JournalEntry::FileDescriptorAllocateV1 { fd, offset, len } => {
209                write!(f, "fd-allocate (fd={fd}, offset={offset}, len={len})")
210            }
211            JournalEntry::CreateHardLinkV1 {
212                old_path, new_path, ..
213            } => write!(f, "path-link (from={old_path}, to={new_path})"),
214            JournalEntry::CreateSymbolicLinkV1 {
215                old_path, new_path, ..
216            } => write!(f, "path-symlink (from={old_path}, to={new_path})"),
217            JournalEntry::UnlinkFileV1 { path, .. } => write!(f, "path-unlink (path={path})"),
218            JournalEntry::PathRenameV1 {
219                old_path, new_path, ..
220            } => write!(f, "path-rename (old-path={old_path}, new-path={new_path})"),
221            JournalEntry::ChangeDirectoryV1 { path } => write!(f, "chdir (path={path})"),
222            JournalEntry::EpollCreateV1 { fd } => write!(f, "epoll-create (fd={fd})"),
223            JournalEntry::EpollCtlV1 { epfd, op, fd, .. } => {
224                write!(f, "epoll-ctl (epfd={epfd}, op={op:?}, fd={fd})")
225            }
226            JournalEntry::TtySetV1 { tty, line_feeds } => write!(
227                f,
228                "tty-set (echo={}, buffering={}, feeds={})",
229                tty.echo, tty.line_buffered, line_feeds
230            ),
231            JournalEntry::CreatePipeV1 { read_fd, write_fd } => {
232                write!(f, "fd-pipe (read_fd={read_fd}, write_fd={write_fd})")
233            }
234            JournalEntry::CreateEventV1 {
235                initial_val, fd, ..
236            } => write!(f, "fd-event (fd={fd}, initial={initial_val})"),
237            JournalEntry::PortAddAddrV1 { cidr } => {
238                write!(f, "port-addr-add (ip={}, prefix={})", cidr.ip, cidr.prefix)
239            }
240            JournalEntry::PortDelAddrV1 { addr } => write!(f, "port-addr-del (addr={addr})"),
241            JournalEntry::PortAddrClearV1 => write!(f, "port-addr-clear"),
242            JournalEntry::PortBridgeV1 { network, .. } => {
243                write!(f, "port-bridge (network={network})")
244            }
245            JournalEntry::PortUnbridgeV1 => write!(f, "port-unbridge"),
246            JournalEntry::PortDhcpAcquireV1 => write!(f, "port-dhcp-acquire"),
247            JournalEntry::PortGatewaySetV1 { ip } => write!(f, "port-gateway-set (ip={ip})"),
248            JournalEntry::PortRouteAddV1 {
249                cidr, via_router, ..
250            } => write!(
251                f,
252                "port-route-add (ip={}, prefix={}, via_router={})",
253                cidr.ip, cidr.prefix, via_router
254            ),
255            JournalEntry::PortRouteClearV1 => write!(f, "port-route-clear"),
256            JournalEntry::PortRouteDelV1 { ip } => write!(f, "port-route-del (ip={ip})"),
257            JournalEntry::SocketOpenV1 { af, ty, pt, fd } => {
258                write!(f, "sock-open (fd={fd}, af={af:?}, ty={ty:?}, pt={pt:?})")
259            }
260            JournalEntry::SocketPairV1 { fd1, fd2 } => {
261                write!(f, "sock-pair (fd1={fd1}, fd2={fd2})")
262            }
263            JournalEntry::SocketListenV1 { fd, backlog } => {
264                write!(f, "sock-listen (fd={fd}, backlog={backlog})")
265            }
266            JournalEntry::SocketBindV1 { fd, addr } => {
267                write!(f, "sock-bind (fd={fd}, addr={addr})")
268            }
269            JournalEntry::SocketConnectedV1 {
270                fd,
271                local_addr,
272                peer_addr,
273            } => {
274                write!(
275                    f,
276                    "sock-connect (fd={fd}, addr={local_addr}, peer={peer_addr})"
277                )
278            }
279            JournalEntry::SocketAcceptedV1 {
280                listen_fd,
281                fd,
282                local_addr,
283                peer_addr,
284                ..
285            } => write!(
286                f,
287                "sock-accept (listen-fd={listen_fd}, sock_fd={fd}, addr={local_addr}, peer={peer_addr})"
288            ),
289            JournalEntry::SocketJoinIpv4MulticastV1 {
290                fd,
291                multiaddr,
292                iface,
293            } => write!(
294                f,
295                "sock-join-mcast-ipv4 (fd={fd}, addr={multiaddr}, iface={iface})"
296            ),
297            JournalEntry::SocketJoinIpv6MulticastV1 {
298                fd,
299                multi_addr: multiaddr,
300                iface,
301            } => write!(
302                f,
303                "sock-join-mcast-ipv6 (fd={fd}, addr={multiaddr}, iface={iface})"
304            ),
305            JournalEntry::SocketLeaveIpv4MulticastV1 {
306                fd,
307                multi_addr: multiaddr,
308                iface,
309            } => write!(
310                f,
311                "sock-leave-mcast-ipv4 (fd={fd}, addr={multiaddr}, iface={iface})"
312            ),
313            JournalEntry::SocketLeaveIpv6MulticastV1 {
314                fd,
315                multi_addr: multiaddr,
316                iface,
317            } => write!(
318                f,
319                "sock-leave-mcast-ipv6 (fd={fd}, addr={multiaddr}, iface={iface})"
320            ),
321            JournalEntry::SocketSendFileV1 {
322                socket_fd,
323                file_fd,
324                offset,
325                count,
326            } => write!(
327                f,
328                "sock-send-file (sock-fd={socket_fd}, file-fd={file_fd}, offset={offset}, count={count})"
329            ),
330            JournalEntry::SocketSendToV1 { fd, data, addr, .. } => {
331                write!(
332                    f,
333                    "sock-send-to (fd={}, data.len={}, addr={})",
334                    fd,
335                    data.len(),
336                    addr
337                )
338            }
339            JournalEntry::SocketSendV1 { fd, data, .. } => {
340                write!(f, "sock-send (fd={}, data.len={})", fd, data.len())
341            }
342            JournalEntry::SocketSetOptFlagV1 { fd, opt, flag } => {
343                write!(f, "sock-set-opt (fd={fd}, opt={opt:?}, flag={flag})")
344            }
345            JournalEntry::SocketSetOptSizeV1 { fd, opt, size } => {
346                write!(f, "sock-set-opt (fd={fd}, opt={opt:?}, size={size})")
347            }
348            JournalEntry::SocketSetOptTimeV1 { fd, ty, time } => {
349                write!(f, "sock-set-opt (fd={fd}, opt={ty:?}, time={time:?})")
350            }
351            JournalEntry::SocketShutdownV1 { fd, how } => {
352                write!(f, "sock-shutdown (fd={fd}, how={how:?})")
353            }
354            JournalEntry::SnapshotV1 { when, trigger } => {
355                write!(f, "snapshot (when={when:?}, trigger={trigger:?})")
356            }
357        }
358    }
359}