Skip to content

Commit 854e0ed

Browse files
committed
Refactor gelf messages convert into sentry
1 parent a2c68ac commit 854e0ed

File tree

4 files changed

+194
-90
lines changed

4 files changed

+194
-90
lines changed

src/gelf/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::error::Error;
22
use std::fmt::{Display, Formatter, Result};
33

4+
/// Gelf error struct, which used to e-prints when something wrong.
45
#[derive(Debug)]
56
pub struct GelfError {
67
message: String,

src/gelf/gelf_message_processor.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
use crate::gelf::gelf_reader::GelfReader;
1+
use crate::gelf::gelf_reader::GelfDataWrapper;
2+
use crate::sentry::sentry_processor::SentryEvent;
23
use actix::prelude::*;
3-
use serde_json::Value;
44

5-
pub struct GelfProcessorMessage(pub GelfReader);
5+
/// Message, which contains parsed gelf data
6+
pub struct GelfProcessorMessage(pub GelfDataWrapper);
67
impl Message for GelfProcessorMessage {
7-
type Result = Option<Value>;
8+
type Result = Option<SentryEvent>;
89
}
910

11+
/// Simplest Gelf Processor Actor
12+
/// Just prints gelf message to stdio
1013
pub struct GelfPrinterActor;
1114
impl GelfPrinterActor {
1215
#[allow(dead_code)]
@@ -20,7 +23,7 @@ impl Actor for GelfPrinterActor {
2023
}
2124

2225
impl Handler<GelfProcessorMessage> for GelfPrinterActor {
23-
type Result = Option<Value>;
26+
type Result = Option<SentryEvent>;
2427

2528
fn handle(
2629
&mut self,

src/gelf/gelf_reader.rs

Lines changed: 86 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,36 @@
11
use actix::prelude::*;
2-
use serde::de::Error;
2+
use serde::de::{Error, Unexpected};
33
use serde::{Deserialize, Serialize};
4-
use serde_json::{Map, Result as JsonResult, Value};
4+
use serde_json::{Error as JsonError, Map, Result as JsonResult, Value};
5+
use std::str::FromStr;
56

6-
pub struct GelfReader {
7+
/// Struct, which contains gelf data
8+
pub struct GelfDataWrapper {
79
data: GelfData,
810
}
911

10-
impl GelfReader {
11-
pub fn from_slice(buf: &[u8]) -> JsonResult<GelfReader> {
12+
impl GelfDataWrapper {
13+
/// Create gelf data wrapper from json slice
14+
pub fn from_slice(buf: &[u8]) -> JsonResult<GelfDataWrapper> {
1215
let data: Map<String, Value> = serde_json::from_slice(&buf)?;
1316

14-
let data = match to_gelf(data) {
15-
Some(data) => data,
16-
None => {
17-
return Err(serde_json::Error::missing_field(
18-
"one of the gelf data struct",
19-
))
20-
}
21-
};
17+
let data = to_gelf(data)?;
2218

23-
Ok(GelfReader { data })
19+
Ok(GelfDataWrapper { data })
2420
}
2521

22+
/// print gelf data to stdio
2623
pub fn print(&self) {
2724
println!("{}", self.to_string());
2825
}
2926

30-
pub fn as_gelf(&self) -> &GelfData {
31-
&self.data
27+
/// Returns a GelfData of this `String`'s contents.
28+
pub fn into_gelf(self) -> GelfData {
29+
self.data
3230
}
3331
}
3432

35-
impl ToString for GelfReader {
33+
impl ToString for GelfDataWrapper {
3634
fn to_string(&self) -> String {
3735
serde_json::to_string(&self.data).unwrap()
3836
}
@@ -41,7 +39,7 @@ impl ToString for GelfReader {
4139
pub struct GelfMessage(pub Vec<u8>);
4240

4341
impl Message for GelfMessage {
44-
type Result = JsonResult<GelfReader>;
42+
type Result = JsonResult<GelfDataWrapper>;
4543
}
4644

4745
pub struct GelfReaderActor;
@@ -57,50 +55,99 @@ impl Actor for GelfReaderActor {
5755
}
5856

5957
impl Handler<GelfMessage> for GelfReaderActor {
60-
type Result = JsonResult<GelfReader>;
58+
type Result = JsonResult<GelfDataWrapper>;
6159

6260
fn handle(&mut self, GelfMessage(msg): GelfMessage, _ctx: &mut Self::Context) -> Self::Result {
63-
GelfReader::from_slice(msg.as_slice())
61+
GelfDataWrapper::from_slice(msg.as_slice())
6462
}
6563
}
6664

6765
#[derive(Serialize, Deserialize)]
6866
pub struct GelfData {
6967
pub host: String,
70-
pub level: u8,
68+
pub level: GelfLevel,
7169
pub short_message: String,
7270
pub timestamp: f64,
7371
pub version: String,
7472
pub meta: Map<String, Value>,
7573
pub mechanism_data: Map<String, Value>,
7674
}
7775

78-
fn to_gelf(data: Map<String, Value>) -> Option<GelfData> {
76+
fn to_gelf(data: Map<String, Value>) -> JsonResult<GelfData> {
7977
let mut meta = Map::new();
8078
let mut mechanism_data = Map::new();
8179
let gelf_fields: [String; 5] = [
82-
"host".to_owned(),
83-
"level".to_owned(),
84-
"short_message".to_owned(),
85-
"timestamp".to_owned(),
86-
"version".to_owned(),
80+
"host".to_string(),
81+
"level".to_string(),
82+
"short_message".to_string(),
83+
"timestamp".to_string(),
84+
"version".to_string(),
8785
];
8886
data.iter().for_each(|(k, v)| {
89-
let str_k = k.as_str();
90-
if &str_k[..1] == "_" {
91-
meta.insert(str_k[1..].to_owned(), v.to_owned());
92-
} else if !gelf_fields.contains(k) {
93-
mechanism_data.insert(str_k.to_owned(), v.to_owned());
94-
}
87+
match k.split_at(1) {
88+
("_", field) => meta.insert(field.to_string(), v.to_owned()),
89+
(_, _) if !gelf_fields.contains(k) => mechanism_data.insert(k.to_owned(), v.to_owned()),
90+
_ => None,
91+
};
9592
});
9693

97-
Some(GelfData {
98-
host: data.get("host")?.to_string(),
99-
level: data.get("level")?.as_u64()? as u8,
100-
short_message: data.get("short_message")?.to_string(),
101-
timestamp: data.get("timestamp")?.as_f64()?,
102-
version: data.get("version")?.to_string(),
94+
Ok(GelfData {
95+
host: data
96+
.get("host")
97+
.ok_or_else(|| JsonError::missing_field("host"))?
98+
.to_string(),
99+
level: data
100+
.get("level")
101+
.ok_or_else(|| JsonError::missing_field("level"))?
102+
.to_string()
103+
.parse::<GelfLevel>()?,
104+
short_message: data
105+
.get("short_message")
106+
.ok_or_else(|| JsonError::missing_field("short_message"))?
107+
.to_string(),
108+
timestamp: data
109+
.get("timestamp")
110+
.ok_or_else(|| JsonError::missing_field("timestamp"))?
111+
.as_f64()
112+
.ok_or_else(|| JsonError::invalid_type(Unexpected::Other("timestamp"), &"u8"))?,
113+
version: data
114+
.get("version")
115+
.ok_or_else(|| JsonError::missing_field("version"))?
116+
.to_string(),
103117
meta,
104118
mechanism_data,
105119
})
106120
}
121+
122+
#[derive(Serialize, Deserialize, Clone)]
123+
pub enum GelfLevel {
124+
Emergency = 0,
125+
Alert = 1,
126+
Critical = 2,
127+
Error = 3,
128+
Warning = 4,
129+
Notice = 5,
130+
Informational = 6,
131+
Debug = 7,
132+
}
133+
134+
impl FromStr for GelfLevel {
135+
type Err = JsonError;
136+
137+
fn from_str(s: &str) -> Result<Self, Self::Err> {
138+
match s {
139+
"0" => Ok(GelfLevel::Emergency),
140+
"1" => Ok(GelfLevel::Alert),
141+
"2" => Ok(GelfLevel::Critical),
142+
"3" => Ok(GelfLevel::Error),
143+
"4" => Ok(GelfLevel::Warning),
144+
"5" => Ok(GelfLevel::Notice),
145+
"6" => Ok(GelfLevel::Informational),
146+
"7" => Ok(GelfLevel::Debug),
147+
_ => Err(JsonError::invalid_value(
148+
Unexpected::Other("level"),
149+
&"integers from 0 to 7",
150+
)),
151+
}
152+
}
153+
}

0 commit comments

Comments
 (0)