1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45//! Log listener support library.
67#![deny(missing_docs)]
89use anyhow::{Context as _, Error};
10use fidl_fuchsia_logger::{
11 LogFilterOptions, LogListenerSafeRequest, LogListenerSafeRequestStream, LogMessage, LogProxy,
12};
13use futures::channel::mpsc;
14use futures::TryStreamExt;
1516/// This trait is used to pass log message back to client.
17pub trait LogProcessor {
18/// Called when log is received from logger.
19fn log(&mut self, message: LogMessage);
2021/// Called when logger service signals that it is done dumping logs.
22 /// This is only called if we request logger service to dump logs
23 /// rather than registering a listener.
24fn done(&mut self);
25}
2627async fn log_listener(
28mut processor: impl LogProcessor,
29mut stream: LogListenerSafeRequestStream,
30) -> Result<(), fidl::Error> {
31while let Some(request) = stream.try_next().await? {
32match request {
33 LogListenerSafeRequest::Log { log, responder } => {
34 processor.log(log);
35 responder.send().ok();
36 }
37 LogListenerSafeRequest::LogMany { log, responder } => {
38for msg in log {
39 processor.log(msg);
40 }
41 responder.send().ok();
42 }
43 LogListenerSafeRequest::Done { control_handle: _ } => {
44 processor.done();
45return Ok(());
46 }
47 }
48 }
49Ok(())
50}
5152/// Register listener or log dumper based on the parameters passed.
53pub async fn run_log_listener_with_proxy<'a>(
54 logger: &LogProxy,
55 processor: impl LogProcessor + 'a,
56 options: Option<&'a LogFilterOptions>,
57) -> Result<(), Error> {
58let (listener_ptr, listener_stream) = fidl::endpoints::create_request_stream();
59 logger.listen_safe(listener_ptr, options).context("failed to register listener")?;
60 log_listener(processor, listener_stream).await?;
61Ok(())
62}
6364impl LogProcessor for mpsc::UnboundedSender<LogMessage> {
65fn log(&mut self, message: LogMessage) {
66// this is called in spawned tasks which may outlive the test's interest
67self.unbounded_send(message).ok();
68 }
6970fn done(&mut self) {
71self.close_channel();
72 }
73}