11use actix:: prelude:: * ;
2- use serde:: de:: Error ;
2+ use serde:: de:: { Error , Unexpected } ;
33use 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 {
4139pub struct GelfMessage ( pub Vec < u8 > ) ;
4240
4341impl Message for GelfMessage {
44- type Result = JsonResult < GelfReader > ;
42+ type Result = JsonResult < GelfDataWrapper > ;
4543}
4644
4745pub struct GelfReaderActor ;
@@ -57,50 +55,99 @@ impl Actor for GelfReaderActor {
5755}
5856
5957impl 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 ) ]
6866pub 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