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