1use anyhow::{anyhow, Result};
5use std::env;
6use std::fmt::Display;
7use syslog::{Facility, Formatter3164, Logger, LoggerBackend};
8
9pub trait Log {
10 fn debug<S: Display>(&mut self, message: S) -> Result<()>;
11 fn info<S: Display>(&mut self, message: S) -> Result<()>;
12 fn error<S: Display>(&mut self, message: S) -> Result<()>;
13}
14
15pub struct PrintLog;
16
17impl Log for PrintLog {
18 fn debug<S: Display>(&mut self, message: S) -> Result<()> {
19 println!("DEBUG: {}", message);
20 Ok(())
21 }
22
23 fn info<S: Display>(&mut self, message: S) -> Result<()> {
24 println!("INFO: {}", message);
25 Ok(())
26 }
27
28 fn error<S: Display>(&mut self, message: S) -> Result<()> {
29 println!("ERROR: {}", message);
30 Ok(())
31 }
32}
33
34pub struct SyslogLogger {
35 log: Logger<LoggerBackend, Formatter3164>,
36 prefix: String,
37 debug: bool,
38}
39
40impl SyslogLogger {
41 pub(crate) fn new(service_name: &str, debug: bool) -> Self {
42 match syslog::unix(Formatter3164 {
43 facility: Facility::LOG_AUTHPRIV,
44 hostname: None,
45 process: process_name().unwrap_or("unknown".into()),
46 pid: std::process::id(),
47 }) {
48 Ok(log) => SyslogLogger {
49 log,
50 prefix: format!("pam_ssh_agent({}:auth): ", service_name),
51 debug,
52 },
53 Err(e) => panic!("Failed to create syslog: {:?}", e),
54 }
55 }
56}
57
58impl Log for SyslogLogger {
59 fn debug<S: Display>(&mut self, message: S) -> Result<()> {
60 if !self.debug {
61 return Ok(());
62 }
63 self.log
64 .info(format!("{}{}", self.prefix, message))
65 .map_err(|e| anyhow!("failed to log: {:?}", e))
66 }
67
68 fn info<S: Display>(&mut self, message: S) -> Result<()> {
69 self.log
70 .info(format!("{}{}", self.prefix, message))
71 .map_err(|e| anyhow!("failed to log: {:?}", e))
72 }
73
74 fn error<S: Display>(&mut self, message: S) -> Result<()> {
75 self.log
76 .err(format!("{}{}", self.prefix, message))
77 .map_err(|e| anyhow!("failed to log: {:?}", e))
78 }
79}
80
81fn process_name() -> Result<String> {
82 Ok(env::current_exe()?
83 .file_name()
84 .ok_or(anyhow!("no filename"))?
85 .to_string_lossy()
86 .into())
87}