Skip to content

Commit fb48dc3

Browse files
committed
LogStorage: fix log limits (lines/length/size) with multi-line log msgs
1 parent 590df9f commit fb48dc3

1 file changed

Lines changed: 86 additions & 32 deletions

File tree

src/logging.rs

Lines changed: 86 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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\nsecond\nthird");
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\nsecond\nthird");
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

Comments
 (0)