1 use leftwm_core::{Manager, XlibDisplayServer};
2 use slog::{o, Drain};
3 use std::panic;
4 
main()5 fn main() {
6     //let _log_guard = setup_logfile();
7     let _log_guard = setup_logging();
8     log::info!("leftwm-worker booted!");
9 
10     let completed = panic::catch_unwind(|| {
11         let rt = tokio::runtime::Runtime::new().expect("ERROR: couldn't init Tokio runtime");
12         let _rt_guard = rt.enter();
13 
14         let config = leftwm::load();
15 
16         let manager = Manager::<leftwm::Config, XlibDisplayServer>::new(config);
17         manager.register_child_hook();
18 
19         rt.block_on(manager.event_loop());
20     });
21 
22     match completed {
23         Ok(_) => log::info!("Completed"),
24         Err(err) => log::error!("Completed with error: {:?}", err),
25     }
26 }
27 
28 // Very basic logging used when developing.
29 // outputs to /tmp/leftwm/leftwm-XXXXXXXXXXXX.log
30 #[allow(dead_code)]
setup_logfile() -> slog_scope::GlobalLoggerGuard31 fn setup_logfile() -> slog_scope::GlobalLoggerGuard {
32     use chrono::Local;
33     use std::fs;
34     use std::fs::OpenOptions;
35     let date = Local::now();
36     let path = "/tmp/leftwm";
37     let _droppable = fs::create_dir_all(path);
38     let log_path = format!("{}/leftwm-{}.log", path, date.format("%Y%m%d%H%M"));
39     let file = OpenOptions::new()
40         .create(true)
41         .write(true)
42         .truncate(true)
43         .open(log_path)
44         .expect("ERROR: couldn't open log file");
45     let decorator = slog_term::PlainDecorator::new(file);
46     let drain = slog_term::FullFormat::new(decorator).build().fuse();
47     let drain = slog_async::Async::new(drain).build().fuse();
48     let envlogger = slog_envlogger::LogBuilder::new(drain)
49         .parse(&std::env::var("RUST_LOG").unwrap_or_else(|_| "trace".into()))
50         .build()
51         .ignore_res();
52     let logger = slog::Logger::root(slog_async::Async::default(envlogger).ignore_res(), o!());
53     slog_stdlog::init().unwrap_or_else(|err| {
54         eprintln!("failed to setup logging: {}", err);
55     });
56     slog_scope::set_global_logger(logger)
57 }
58 
59 /// Log to both stdout and journald.
60 #[allow(dead_code)]
setup_logging() -> slog_scope::GlobalLoggerGuard61 fn setup_logging() -> slog_scope::GlobalLoggerGuard {
62     #[cfg(feature = "slog-journald")]
63     let journald = slog_journald::JournaldDrain.ignore_res();
64 
65     #[cfg(feature = "slog-term")]
66     let stdout = slog_term::CompactFormat::new(slog_term::TermDecorator::new().stdout().build())
67         .build()
68         .ignore_res();
69 
70     #[cfg(all(feature = "slog-journald", feature = "slog-term"))]
71     let drain = slog::Duplicate(journald, stdout).ignore_res();
72     #[cfg(all(feature = "slog-journald", not(feature = "slog-term")))]
73     let drain = journald;
74     #[cfg(all(not(feature = "slog-journald"), feature = "slog-term"))]
75     let drain = stdout;
76 
77     // Set level filters from RUST_LOG. Defaults to `info`.
78     let envlogger = slog_envlogger::LogBuilder::new(drain)
79         .parse(&std::env::var("RUST_LOG").unwrap_or_else(|_| "info".into()))
80         .build()
81         .ignore_res();
82 
83     let logger = slog::Logger::root(slog_async::Async::default(envlogger).ignore_res(), o!());
84 
85     slog_stdlog::init().unwrap_or_else(|err| {
86         eprintln!("failed to setup logging: {}", err);
87     });
88 
89     slog_scope::set_global_logger(logger)
90 }
91