1#![crate_type = "lib"]
2#![warn(unreachable_pub)]
3use std::{
4 io::{Write, self},
5 net::{TcpStream, Ipv4Addr},
6 time::{SystemTime, UNIX_EPOCH},
7 error::Error, fmt::{self, Display},
8};
9
10use chrono::{DateTime, Utc};
11use serde::{Serialize, Deserialize};
12use serde_json::json;
13
14pub struct Connection {
15 ip: &'static str, port: u16,
17}
18
19impl Connection {
20 fn new(ip: &'static str, port: u16) -> Self {
24 Connection { ip: ip, port: port }
25 }
26
27 fn default() -> Self {
28 Connection { ip: "127.0.0.1", port: 3306 }
29 }
30
31 fn connect(&self) -> io::Result<TcpStream> {
32 TcpStream::connect(format!("{}:{}", self.ip, self.port))
33 }
34
35}
36pub struct Logger {
37 id: u32,
38 connection: Option<Connection>,
39}
40
41impl Logger {
42 fn new(id: u32, connection: Connection) -> Self {
43 Logger {
44 id: id,
45 connection: Some(connection),
46 }
47 }
48
49 fn with_default_connection(id: u32) -> Self {
50 Logger {
51 id: id,
52 connection: Some(Connection::default()),
53 }
54 }
55
56 fn log(&self, message: &str, level: Level) -> Result<(), Box<dyn Error>> {
57 let log_message = LogMessage {
59 message: message.to_string(),
60 timestamp: Utc::now(),
61 level,
62 };
63
64 send_log_message(&log_message)
66 }
67}
68
69#[derive(Serialize, Deserialize)]
71pub struct LogMessage {
72 timestamp: DateTime<Utc>,
73 level: Level,
74 message: String,
75}
76
77#[derive(Serialize, Deserialize, Clone)]
79pub enum Level {
80 INFO,
81 WARNING,
82 ERROR,
83 DEBUG,
84 Custom(String),
85}
86
87impl Display for Level {
88
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 match self {
91 Level::INFO => write!(f, "INFO"),
92 Level::WARNING => write!(f, "WARNING"),
93 Level::ERROR => write!(f, "ERROR"),
94 Level::DEBUG => write!(f, "DEBUG"),
95 Level::Custom(str) => write!(f, "{}", str),
96 }
97 }
98
99}
100
101pub fn send_log_message(log_message: &LogMessage) -> Result<(), Box<dyn Error>> {
103 let mut stream = TcpStream::connect("graylog.example.com:12201")?;
105
106 let json_string = serde_json::to_string(log_message)?;
108
109 stream.write_all(json_string.as_bytes())?;
111 Ok(())
112}
113
114pub fn log(message: &str, level: Level) -> Result<(), Box<dyn Error>> {
116 let log_message = LogMessage {
118 message: message.to_string(),
119 timestamp: Utc::now(),
120 level,
121 };
122
123 send_log_message(&log_message)
125}
126
127#[test]
136fn test_levels() {
137
138 assert_eq!("INFO", Level::INFO.to_string());
139 assert_eq!("WARNING", Level::WARNING.to_string());
140 assert_eq!("ERROR", Level::ERROR.to_string());
141 assert_eq!("DEBUG", Level::DEBUG.to_string());
142
143}