Merge pull request #976 from ethcore/rpc-logs

Exposing application logs via RPC.
This commit is contained in:
Marek Kotewicz
2016-04-20 18:47:30 +02:00
6 changed files with 171 additions and 24 deletions

View File

@@ -19,6 +19,8 @@
use std::env;
use rlog::{LogLevelFilter};
use env_logger::LogBuilder;
use std::sync::{RwLock, RwLockReadGuard};
use arrayvec::ArrayVec;
lazy_static! {
static ref LOG_DUMMY: bool = {
@@ -40,3 +42,79 @@ lazy_static! {
pub fn init_log() {
let _ = *LOG_DUMMY;
}
const LOG_SIZE : usize = 128;
/// Logger implementation that keeps up to `LOG_SIZE` log elements.
pub struct RotatingLogger {
/// Defined logger levels
levels: String,
/// Logs array. Latest log is always at index 0
logs: RwLock<ArrayVec<[String; LOG_SIZE]>>,
}
impl RotatingLogger {
/// Creates new `RotatingLogger` with given levels.
/// It does not enforce levels - it's just read only.
pub fn new(levels: String) -> Self {
RotatingLogger {
levels: levels,
logs: RwLock::new(ArrayVec::<[_; LOG_SIZE]>::new()),
}
}
/// Append new log entry
pub fn append(&self, log: String) {
self.logs.write().unwrap().insert(0, log);
}
/// Return levels
pub fn levels(&self) -> &str {
&self.levels
}
/// Return logs
pub fn logs(&self) -> RwLockReadGuard<ArrayVec<[String; LOG_SIZE]>> {
self.logs.read().unwrap()
}
}
#[cfg(test)]
mod test {
use super::RotatingLogger;
fn logger() -> RotatingLogger {
RotatingLogger::new("test".to_owned())
}
#[test]
fn should_return_log_levels() {
// given
let logger = logger();
// when
let levels = logger.levels();
// then
assert_eq!(levels, "test");
}
#[test]
fn should_return_latest_logs() {
// given
let logger = logger();
// when
logger.append("a".to_owned());
logger.append("b".to_owned());
// then
let logs = logger.logs();
assert_eq!(logs[0], "b".to_owned());
assert_eq!(logs[1], "a".to_owned());
assert_eq!(logs.len(), 2);
}
}