blob: d7ba5718da9907d0405651d45ae2dbfc1dcf511a [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! The Archivist collects and stores diagnostic data from components.
#![warn(missing_docs)]
use {
anyhow::{Context, Error},
archivist_lib::{archivist, configs, diagnostics, logs},
argh::FromArgs,
fidl_fuchsia_sys2::EventSourceMarker,
fidl_fuchsia_sys_internal::{ComponentEventProviderMarker, LogConnectorMarker},
fuchsia_async as fasync,
fuchsia_component::client::connect_to_service,
fuchsia_component::server::MissingStartupHandle,
fuchsia_syslog, fuchsia_zircon as zx,
log::{info, warn},
std::path::PathBuf,
};
/// Monitor, collect, and store diagnostics from components.
#[derive(Debug, Default, FromArgs)]
pub struct Args {
/// disables proxying kernel logger
#[argh(switch)]
disable_klog: bool,
/// disables log connector so that indivisual instances of
/// observer don't compete for log connector listener.
#[argh(switch)]
disable_log_connector: bool,
/// serve fuchsia.diagnostics.test.Controller
#[argh(switch)]
install_controller: bool,
/// path to a JSON configuration file
#[argh(option)]
config_path: PathBuf,
}
fn main() -> Result<(), Error> {
let opt: Args = argh::from_env();
let (log_client, log_server) = zx::Socket::create(zx::SocketOpts::DATAGRAM)?;
let log_name = if opt.disable_klog { "observer" } else { "archivist" };
fuchsia_syslog::init_with_socket_and_name(log_client, log_name)?;
info!("Logging started.");
let mut executor = fasync::Executor::new()?;
let legacy_event_provider = connect_to_service::<ComponentEventProviderMarker>()
.context("failed to connect to event provider")?;
let event_source =
connect_to_service::<EventSourceMarker>().context("failed to connect to event source")?;
diagnostics::init();
let archivist_configuration: configs::Config = match configs::parse_config(&opt.config_path) {
Ok(config) => config,
Err(parsing_error) => panic!("Parsing configuration failed: {}", parsing_error),
};
let num_threads = archivist_configuration.num_threads;
let mut archivist = archivist::Archivist::new(archivist_configuration)?;
archivist
.install_logger_services()
.add_event_source("v1", Box::new(legacy_event_provider))
.add_event_source("v2", Box::new(event_source));
archivist.log_manager().spawn_internal_sink(log_server, log_name)?;
if !opt.disable_log_connector {
archivist.set_log_connector(connect_to_service::<LogConnectorMarker>()?);
}
if opt.install_controller {
archivist.install_controller_service();
}
if !opt.disable_klog {
let log_manager = archivist.log_manager().clone();
let debug_log = logs::KernelDebugLog::new().context("Failed to read kernel logs")?;
executor
.run(async move { log_manager.spawn_debuglog_drainer(debug_log).await }, num_threads)?;
}
let startup_handle =
fuchsia_runtime::take_startup_handle(fuchsia_runtime::HandleType::DirectoryRequest.into())
.ok_or(MissingStartupHandle)?;
executor.run(archivist.run(zx::Channel::from(startup_handle)), num_threads)?;
Ok(())
}