@@ -174,43 +174,45 @@ impl SealedLog for LogStorage {
174174 if inner. truncated {
175175 return ;
176176 }
177- if let Some ( max_lines) = self . max_lines
178- && inner. records . len ( ) >= max_lines
179- {
180- inner. records . push ( StoredRecord {
181- level : Level :: Warn ,
182- message : "too many lines in the log, truncating it" . into ( ) ,
183- } ) ;
184- inner. truncated = true ;
185- return ;
186- }
187- let mut message = record. args ( ) . to_string ( ) ;
188-
189- if let Some ( max_line_length) = self . max_line_length
190- && message. len ( ) > max_line_length
191- {
192- let mut length = max_line_length - 3 ;
193- while !message. is_char_boundary ( length) {
194- length -= 1 ;
177+
178+ for mut message in record. args ( ) . to_string ( ) . lines ( ) . map ( ToOwned :: to_owned) {
179+ if let Some ( max_lines) = self . max_lines
180+ && inner. records . len ( ) >= max_lines
181+ {
182+ inner. records . push ( StoredRecord {
183+ level : Level :: Warn ,
184+ message : "too many lines in the log, truncating it" . into ( ) ,
185+ } ) ;
186+ inner. truncated = true ;
187+ return ;
195188 }
196- message = format ! ( "{}..." , & message[ ..length] ) ;
197- }
198189
199- if let Some ( max_size) = self . max_size
200- && inner. size + message. len ( ) >= max_size
201- {
190+ if let Some ( max_line_length) = self . max_line_length
191+ && message. len ( ) > max_line_length
192+ {
193+ let mut length = max_line_length - 3 ;
194+ while !message. is_char_boundary ( length) {
195+ length -= 1 ;
196+ }
197+ message = format ! ( "{}..." , & message[ ..length] ) ;
198+ }
199+
200+ if let Some ( max_size) = self . max_size
201+ && inner. size + message. len ( ) >= max_size
202+ {
203+ inner. records . push ( StoredRecord {
204+ level : Level :: Warn ,
205+ message : "too much data in the log, truncating it" . into ( ) ,
206+ } ) ;
207+ inner. truncated = true ;
208+ return ;
209+ }
210+ inner. size += message. len ( ) ;
202211 inner. records . push ( StoredRecord {
203- level : Level :: Warn ,
204- message : "too much data in the log, truncating it" . into ( ) ,
212+ level : record . level ( ) ,
213+ message,
205214 } ) ;
206- inner. truncated = true ;
207- return ;
208215 }
209- inner. size += message. len ( ) ;
210- inner. records . push ( StoredRecord {
211- level : record. level ( ) ,
212- message,
213- } ) ;
214216 }
215217
216218 fn flush ( & self ) { }
@@ -376,6 +378,58 @@ mod tests {
376378 ) ;
377379 }
378380
381+ #[ test]
382+ fn test_multiline_messages_are_split_into_records ( ) {
383+ logging:: init ( ) ;
384+
385+ let storage = LogStorage :: new ( LevelFilter :: Info ) ;
386+ logging:: capture ( & storage, || {
387+ info ! ( "first\n second\n third" ) ;
388+ } ) ;
389+
390+ assert_eq ! (
391+ storage. inner. lock( ) . unwrap( ) . records,
392+ vec![
393+ StoredRecord {
394+ level: Level :: Info ,
395+ message: "first" . to_string( ) ,
396+ } ,
397+ StoredRecord {
398+ level: Level :: Info ,
399+ message: "second" . to_string( ) ,
400+ } ,
401+ StoredRecord {
402+ level: Level :: Info ,
403+ message: "third" . to_string( ) ,
404+ } ,
405+ ]
406+ ) ;
407+ }
408+
409+ #[ test]
410+ fn test_multiline_messages_respect_max_lines ( ) {
411+ logging:: init ( ) ;
412+
413+ let mut storage = LogStorage :: new ( LevelFilter :: Info ) ;
414+ storage. set_max_lines ( 2 ) ;
415+ logging:: capture ( & storage, || {
416+ info ! ( "first\n second\n third" ) ;
417+ } ) ;
418+
419+ let inner = storage. inner . lock ( ) . unwrap ( ) ;
420+ assert_eq ! ( inner. records. len( ) , 3 ) ;
421+ assert_eq ! ( inner. records[ 0 ] . message, "first" ) ;
422+ assert_eq ! ( inner. records[ 1 ] . message, "second" ) ;
423+ assert ! (
424+ inner
425+ . records
426+ . last( )
427+ . unwrap( )
428+ . message
429+ . contains( "too many lines" )
430+ ) ;
431+ }
432+
379433 #[ test]
380434 fn test_too_long_line ( ) {
381435 logging:: init ( ) ;
0 commit comments