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