mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 16:57:58 +00:00
client: remove stale file (#7239)
This commit is contained in:
@@ -1,272 +0,0 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2020 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use ansi_term::Colour;
|
||||
use flexi_logger::{
|
||||
DeferredNow, Duplicate, LogSpecBuilder,
|
||||
LogSpecification, LogTarget, Logger, Criterion, Naming, Cleanup, Age,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
use crate::error::{Error, Result};
|
||||
|
||||
type IoResult = std::result::Result<(), std::io::Error>;
|
||||
|
||||
/// Default size used for rotation. Basically unlimited.
|
||||
const DEFAULT_ROTATION_SIZE: u64 = u64::MAX;
|
||||
|
||||
/// Options for log rotation.
|
||||
#[derive(Debug, StructOpt, Default, Clone)]
|
||||
pub struct LogRotationOpt {
|
||||
/// Specify the path of the directory which will contain the log files.
|
||||
/// Defaults to never rotating logs.
|
||||
#[structopt(long, parse(from_os_str))]
|
||||
log_directory: Option<PathBuf>,
|
||||
|
||||
/// Rotate the log file when the local clock has started a new day/hour/minute/second
|
||||
/// since the current file has been created.
|
||||
#[structopt(long,
|
||||
conflicts_with("log-size"),
|
||||
possible_values(&["day", "hour", "minute", "second"]),
|
||||
parse(from_str = age_from_str))
|
||||
]
|
||||
log_age: Option<Age>,
|
||||
|
||||
/// Rotate the log file when it exceeds this size (in bytes).
|
||||
#[structopt(long, conflicts_with("log-age"))]
|
||||
log_size: Option<u64>,
|
||||
}
|
||||
|
||||
/// Utility for parsing an Age from a &str.
|
||||
fn age_from_str(s: &str) -> Age {
|
||||
match s {
|
||||
"day" => Age::Day,
|
||||
"hour" => Age::Hour,
|
||||
"minute" => Age::Minute,
|
||||
"second" => Age::Second,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Format used when writing to a tty. Colors the output.
|
||||
fn colored_fmt(
|
||||
w: &mut dyn std::io::Write,
|
||||
_now: &mut DeferredNow,
|
||||
record: &log::Record,
|
||||
) -> IoResult {
|
||||
let now = time::now();
|
||||
let timestamp =
|
||||
time::strftime("%Y-%m-%d %H:%M:%S", &now).expect("Error formatting log timestamp");
|
||||
|
||||
let output = if log::max_level() <= log::LevelFilter::Info {
|
||||
format!(
|
||||
"{} {}",
|
||||
Colour::Black.bold().paint(timestamp),
|
||||
record.args(),
|
||||
)
|
||||
} else {
|
||||
let name = ::std::thread::current()
|
||||
.name()
|
||||
.map_or_else(Default::default, |x| {
|
||||
format!("{}", Colour::Blue.bold().paint(x))
|
||||
});
|
||||
let millis = (now.tm_nsec as f32 / 1000000.0).floor() as usize;
|
||||
let timestamp = format!("{}.{:03}", timestamp, millis);
|
||||
format!(
|
||||
"{} {} {} {} {}",
|
||||
Colour::Black.bold().paint(timestamp),
|
||||
name,
|
||||
record.level(),
|
||||
record.target(),
|
||||
record.args()
|
||||
)
|
||||
};
|
||||
|
||||
write!(w, "{}", output)
|
||||
}
|
||||
|
||||
/// Format used when logging to files. Does not add any colors.
|
||||
fn file_fmt(
|
||||
w: &mut dyn std::io::Write,
|
||||
_now: &mut DeferredNow,
|
||||
record: &log::Record,
|
||||
) -> IoResult {
|
||||
let now = time::now();
|
||||
let timestamp =
|
||||
time::strftime("%Y-%m-%d %H:%M:%S", &now).expect("Error formatting log timestamp");
|
||||
|
||||
let output = if log::max_level() <= log::LevelFilter::Info {
|
||||
format!("{} {}", timestamp, record.args(),)
|
||||
} else {
|
||||
let name = std::thread::current()
|
||||
.name()
|
||||
.map_or_else(Default::default, |x| format!("{}", x));
|
||||
let millis = (now.tm_nsec as f32 / 1000000.0).floor() as usize;
|
||||
let timestamp = format!("{}.{:03}", timestamp, millis);
|
||||
format!(
|
||||
"{} {} {} {} {}",
|
||||
timestamp,
|
||||
name,
|
||||
record.level(),
|
||||
record.target(),
|
||||
record.args()
|
||||
)
|
||||
};
|
||||
|
||||
// Required because substrate sometimes sends strings that are colored.
|
||||
// Doing this ensures no colors are ever printed to files.
|
||||
let output = kill_color(&output);
|
||||
|
||||
write!(w, "{}", output)
|
||||
}
|
||||
|
||||
/// Initialize the logger
|
||||
pub fn init_logger(
|
||||
pattern: &str,
|
||||
log_rotation_opt: Option<LogRotationOpt>,
|
||||
) -> Result<()> {
|
||||
let mut builder = LogSpecBuilder::new();
|
||||
// Disable info logging by default for some modules:
|
||||
builder.module("ws", log::LevelFilter::Off);
|
||||
builder.module("yamux", log::LevelFilter::Off);
|
||||
builder.module("hyper", log::LevelFilter::Warn);
|
||||
builder.module("cranelift_wasm", log::LevelFilter::Warn);
|
||||
// Always log the special target `sc_tracing`, overrides global level
|
||||
builder.module("sc_tracing", log::LevelFilter::Info);
|
||||
// Enable info for others.
|
||||
builder.default(log::LevelFilter::Info);
|
||||
|
||||
// Add filters defined by RUST_LOG.
|
||||
builder.insert_modules_from(LogSpecification::env()?);
|
||||
|
||||
// Add filters passed in as argument.
|
||||
builder.insert_modules_from(LogSpecification::parse(pattern)?);
|
||||
|
||||
// Build the LogSpec.
|
||||
let spec = builder.build();
|
||||
|
||||
// Use timestamps to differentiate logs.
|
||||
let naming = Naming::Timestamps;
|
||||
// Never cleanup old logs; let the end-user take care of that.
|
||||
let cleanup = Cleanup::Never;
|
||||
|
||||
let log_rotation_opt = log_rotation_opt.unwrap_or_default();
|
||||
let age = log_rotation_opt.log_age;
|
||||
let size = log_rotation_opt.log_size;
|
||||
|
||||
// Build a Criterion from the options.
|
||||
let criterion = match (age, size) {
|
||||
(Some(a), None) => Criterion::Age(a),
|
||||
(None, Some(s)) => Criterion::Size(s),
|
||||
// Default to rotating with a size of `DEFAULT_ROTATION_SIZE`.
|
||||
(None, None) => Criterion::Size(DEFAULT_ROTATION_SIZE),
|
||||
_ => return Err(Error::Input("Only one of Age or Size should be defined".into()))
|
||||
};
|
||||
|
||||
let isatty_stderr = atty::is(atty::Stream::Stderr);
|
||||
let isatty_stdout = atty::is(atty::Stream::Stdout);
|
||||
let logger = Logger::with(spec)
|
||||
.format(file_fmt)
|
||||
.format_for_stderr(colored_fmt)
|
||||
.format_for_stdout(colored_fmt)
|
||||
.rotate(criterion, naming, cleanup); // Won't get used if log_directory has not been specified.
|
||||
|
||||
|
||||
let logger = match (log_rotation_opt.log_directory.as_ref(), isatty_stderr) {
|
||||
// Only log to stderr using colored format; nothing to file, nothing to stdout.
|
||||
(None, true) => {
|
||||
logger.log_target(LogTarget::StdErr)
|
||||
}
|
||||
// Log to stderr using file format, log to stdout using colored format.
|
||||
(None, false) => {
|
||||
let logger = logger
|
||||
.log_target(LogTarget::DevNull)
|
||||
.format_for_stderr(file_fmt)
|
||||
.duplicate_to_stderr(Duplicate::All);
|
||||
|
||||
// Write to stdout only if it's a tty.
|
||||
if isatty_stdout {
|
||||
logger.duplicate_to_stdout(Duplicate::Info)
|
||||
} else {
|
||||
logger
|
||||
}
|
||||
}
|
||||
// Log to stderr with colored format, log to file with file format. Nothing to stdout.
|
||||
(Some(file), true) => {
|
||||
logger
|
||||
.log_target(LogTarget::File)
|
||||
.duplicate_to_stderr(Duplicate::All)
|
||||
.directory(file)
|
||||
}
|
||||
// Log to stderr with file format, log to file with file format, log to stdout with colored format.
|
||||
(Some(file), false) => {
|
||||
let logger = logger
|
||||
.log_target(LogTarget::File)
|
||||
.format_for_stderr(file_fmt)
|
||||
.duplicate_to_stderr(Duplicate::All)
|
||||
.directory(file);
|
||||
|
||||
// Write to stdout only if it's a tty.
|
||||
if isatty_stdout {
|
||||
logger.duplicate_to_stdout(Duplicate::Info)
|
||||
} else {
|
||||
logger
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
logger.start().map(|_| ()).map_err(|e| e.into())
|
||||
}
|
||||
|
||||
fn kill_color(s: &str) -> String {
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new("\x1b\\[[^m]+m").expect("Error initializing color regex");
|
||||
}
|
||||
RE.replace_all(s, "").to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn logger_default() {
|
||||
let pattern = "";
|
||||
let log_rotation_opt = LogRotationOpt {
|
||||
log_directory: None,
|
||||
log_age: None,
|
||||
log_size: None,
|
||||
};
|
||||
|
||||
assert!(init_logger(pattern, Some(log_rotation_opt)).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn logger_conflicting_opt() {
|
||||
let pattern = "";
|
||||
let log_rotation_opt = LogRotationOpt {
|
||||
log_directory: None,
|
||||
log_age: Some(Age::Day),
|
||||
log_size: Some(1337),
|
||||
};
|
||||
|
||||
assert!(init_logger(pattern, Some(log_rotation_opt)).is_err());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user