GrayLogger/
lib.rs

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, //todo: accept ipv4, ipv6, or web domain
16    port: u16,
17}
18
19impl Connection {
20    //todo
21    //default port of 3306
22    //ip parameter should be able to take ipv4, ipv6, and web domains
23    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        // Create a new log message with the current timestamp.
58        let log_message = LogMessage {
59            message: message.to_string(),
60            timestamp: Utc::now(),
61            level,
62        };
63
64        // Send the log message to the graylog server.
65        send_log_message(&log_message)
66    }
67}
68
69// Struct representing a log message.
70#[derive(Serialize, Deserialize)]
71pub struct LogMessage {
72    timestamp: DateTime<Utc>,
73    level: Level,
74    message: String,
75}
76
77// Enum laying out possible message types
78#[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
101// Function to send a log message to the graylog server.
102pub fn send_log_message(log_message: &LogMessage) -> Result<(), Box<dyn Error>> {
103    // Establish a connection to the graylog server.
104    let mut stream = TcpStream::connect("graylog.example.com:12201")?;
105
106    // Serialize the log message as JSON.
107    let json_string = serde_json::to_string(log_message)?;
108
109    // Write the serialized JSON to the stream.
110    stream.write_all(json_string.as_bytes())?;
111    Ok(())
112}
113
114// Function to create and send a log message with the specified message and level.
115pub fn log(message: &str, level: Level) -> Result<(), Box<dyn Error>> {
116    // Create a new log message with the current timestamp.
117    let log_message = LogMessage {
118        message: message.to_string(),
119        timestamp: Utc::now(),
120        level,
121    };
122
123    // Send the log message to the graylog server.
124    send_log_message(&log_message)
125}
126
127// // Example usage of the logger.
128// fn main() -> Result<(), Box<dyn Error>> {
129    
130//     log("Hello, world!", Level::INFO)?;
131    
132//     Ok(())
133// }
134
135#[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}