prevent silent errors in daemon mode (#10007)
* prevent silent errors in daemon mode * change author in Cargo.toml, add preamble to pipe.rs * set the uid and gid on daemon process, fix permission errors when writing to pid file * call setup_logger before daemonize to prevent crashing when attempting to create logfile * map_err for calls to splice and ioctl, fix spaces in Cargo.toml * split out daemonize to own repo * removed util/daemonize * renamed dep to parity-daemonize * fix(parity-clib): enable `logger` * bump parity-daemonize * remove obsolete comment Co-Authored-By: seunlanlege <seunlanlege@gmail.com> * fix(grumbles): docs and log in ParityParams * Add FIXME comment regarding @tomaka grumbles * Unify logger with the C-API in ParityParams (less type-safety with more from_raw() conversions) * Add better documentation in the `parity.h` * Apply suggestions from code review Co-Authored-By: seunlanlege <seunlanlege@gmail.com> * docs(parity lib): add link to logging issue * fix(parity-clib): JNI enable `logger` * fix(parity-clib): update `Java example` * Update example to the API changes * Remove needless printouts which can be controlled via logger instead
This commit is contained in:
committed by
Afri Schoedon
parent
12c42bce9b
commit
0f9b2218da
@@ -28,9 +28,9 @@ public class Parity {
|
||||
*
|
||||
* @param options The CLI options to start Parity with
|
||||
*/
|
||||
public Parity(String[] options) {
|
||||
public Parity(String[] options, String loggerMode, String loggerFile) {
|
||||
long config = configFromCli(options);
|
||||
inner = build(config);
|
||||
inner = build(config, loggerMode, loggerFile);
|
||||
}
|
||||
|
||||
/** Performs an asynchronous RPC query by spawning a background thread that is executed until
|
||||
@@ -76,7 +76,7 @@ public class Parity {
|
||||
}
|
||||
|
||||
private static native long configFromCli(String[] cliOptions);
|
||||
private static native long build(long config);
|
||||
private static native long build(long config, String loggerMode, String loggerFile);
|
||||
private static native void destroy(long inner);
|
||||
private static native void rpcQueryNative(long inner, String rpc, long timeoutMillis, Object callback);
|
||||
private static native long subscribeWebSocketNative(long inner, String rpc, Object callback);
|
||||
|
||||
@@ -53,10 +53,8 @@ const std::vector<std::string> ws_subscriptions {
|
||||
void callback(void* user_data, const char* response, size_t _len) {
|
||||
Callback* cb = static_cast<Callback*>(user_data);
|
||||
if (cb->type == CALLBACK_RPC) {
|
||||
printf("rpc response: %s\r\n", response);
|
||||
cb->counter -= 1;
|
||||
} else if (cb->type == CALLBACK_WS) {
|
||||
printf("websocket response: %s\r\n", response);
|
||||
std::regex is_subscription ("\\{\"jsonrpc\":\"2.0\",\"result\":\"0[xX][a-fA-F0-9]{16}\",\"id\":1\\}");
|
||||
if (std::regex_match(response, is_subscription) == true) {
|
||||
cb->counter -= 1;
|
||||
@@ -153,7 +151,8 @@ void* parity_run(std::vector<const char*> args) {
|
||||
ParityParams cfg = {
|
||||
.configuration = nullptr,
|
||||
.on_client_restart_cb = callback,
|
||||
.on_client_restart_cb_custom = nullptr
|
||||
.on_client_restart_cb_custom = nullptr,
|
||||
.logger = nullptr
|
||||
};
|
||||
|
||||
std::vector<size_t> str_lens;
|
||||
@@ -173,6 +172,10 @@ void* parity_run(std::vector<const char*> args) {
|
||||
}
|
||||
}
|
||||
|
||||
// enable logging but only the `rpc module` and don't write it to a file
|
||||
char log_mode [] = "rpc=trace";
|
||||
parity_set_logger(log_mode, strlen(log_mode), nullptr, 0, &cfg.logger);
|
||||
|
||||
void *parity = nullptr;
|
||||
if (parity_start(&cfg, &parity) != 0) {
|
||||
return nullptr;
|
||||
|
||||
@@ -35,7 +35,9 @@ class Main {
|
||||
};
|
||||
|
||||
public static void runParity(String[] config) {
|
||||
Parity parity = new Parity(config);
|
||||
String loggerMode = "rpc=trace";
|
||||
String loggerFile = "foo.log";
|
||||
Parity parity = new Parity(config, loggerMode, loggerFile);
|
||||
|
||||
Callback rpcCallback = new Callback(1);
|
||||
Callback webSocketCallback = new Callback(2);
|
||||
@@ -94,12 +96,6 @@ class Callback {
|
||||
}
|
||||
|
||||
public void callback(Object response) {
|
||||
response = (String) response;
|
||||
if (callbackType == 1) {
|
||||
System.out.println("rpc: " + response);
|
||||
} else if (callbackType == 2) {
|
||||
System.out.println("ws: " + response);
|
||||
}
|
||||
counter.getAndIncrement();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ struct ParityParams {
|
||||
|
||||
/// Custom parameter passed to the `on_client_restart_cb` callback as first parameter.
|
||||
void *on_client_restart_cb_custom;
|
||||
|
||||
/// Logger object which must be created by the `parity_config_logger` function
|
||||
void *logger;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -63,6 +66,33 @@ extern "C" {
|
||||
///
|
||||
int parity_config_from_cli(char const* const* args, size_t const* arg_lens, size_t len, void** out);
|
||||
|
||||
/// Builds a new logger object which should be a member of the `ParityParams struct`
|
||||
///
|
||||
/// - log_mode : String representing the log mode according to `Rust LOG` or nullptr to disable logging.
|
||||
/// See module documentation for `ethcore-logger` for more info.
|
||||
/// - log_mode_len : Length of the log_mode or zero to disable logging
|
||||
/// - log_file : String respresenting the file name to write to log to or nullptr to disable logging to a file
|
||||
/// - log_mode_len : Length of the log_file or zero to disable logging to a file
|
||||
/// - logger : Pointer to point to the created `Logger` object
|
||||
|
||||
/// **Important**: This function must only be called exactly once otherwise it will panic. If you want to disable a
|
||||
/// logging mode or logging to a file make sure that you pass the `length` as zero
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// void* cfg;
|
||||
/// const char *args[] = {"--light", "--can-restart"};
|
||||
/// size_t str_lens[] = {7, 13};
|
||||
/// if (parity_config_from_cli(args, str_lens, 2, &cfg) != 0) {
|
||||
/// return 1;
|
||||
/// }
|
||||
/// char[] logger_mode = "rpc=trace";
|
||||
/// parity_set_logger(logger_mode, strlen(logger_mode), nullptr, 0, &cfg.logger);
|
||||
/// ```
|
||||
///
|
||||
int parity_set_logger(const char* log_mode, size_t log_mode_len, const char* log_file, size_t log_file_len, void** logger);
|
||||
|
||||
/// Destroys a configuration object created earlier.
|
||||
///
|
||||
/// **Important**: You probably don't need to call this function. Calling `parity_start` destroys
|
||||
|
||||
@@ -20,7 +20,7 @@ use std::time::Duration;
|
||||
use std::thread;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
use {parity_config_from_cli, parity_destroy, parity_start, parity_unsubscribe_ws, ParityParams, error};
|
||||
use {parity_config_from_cli, parity_destroy, parity_set_logger, parity_start, parity_unsubscribe_ws, ParityParams, error};
|
||||
|
||||
use futures::{Future, Stream};
|
||||
use futures::sync::mpsc;
|
||||
@@ -96,12 +96,24 @@ pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_configFromCli(env:
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_build(env: JNIEnv, _: JClass, config: va_list) -> jlong {
|
||||
let params = ParityParams {
|
||||
pub unsafe extern "system" fn Java_io_parity_ethereum_Parity_build(
|
||||
env: JNIEnv,
|
||||
_: JClass,
|
||||
config: va_list,
|
||||
logger_mode: JString,
|
||||
logger_file: JString
|
||||
) -> jlong {
|
||||
let mut params = ParityParams {
|
||||
configuration: config,
|
||||
.. mem::zeroed()
|
||||
};
|
||||
|
||||
let logger_mode: String = env.get_string(logger_mode).expect("valid JString; qed").into();
|
||||
let logger_file: String = env.get_string(logger_file).expect("valid JString; qed").into();
|
||||
|
||||
parity_set_logger(logger_mode.as_ptr(), logger_mode.as_bytes().len(), logger_file.as_ptr(),
|
||||
logger_file.as_bytes().len(), &mut params.logger);
|
||||
|
||||
let mut out = ptr::null_mut();
|
||||
match parity_start(¶ms, &mut out) {
|
||||
0 => out as jlong,
|
||||
|
||||
@@ -54,6 +54,7 @@ pub struct ParityParams {
|
||||
pub configuration: *mut c_void,
|
||||
pub on_client_restart_cb: Callback,
|
||||
pub on_client_restart_cb_custom: *mut c_void,
|
||||
pub logger: *mut c_void
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -112,6 +113,7 @@ pub unsafe extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_
|
||||
*output = ptr::null_mut();
|
||||
let cfg: &ParityParams = &*cfg;
|
||||
|
||||
let logger = Arc::from_raw(cfg.logger as *mut parity_ethereum::RotatingLogger);
|
||||
let config = Box::from_raw(cfg.configuration as *mut parity_ethereum::Configuration);
|
||||
|
||||
let on_client_restart_cb = {
|
||||
@@ -122,7 +124,7 @@ pub unsafe extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_
|
||||
move |new_chain: String| { cb.call(new_chain.as_bytes()); }
|
||||
};
|
||||
|
||||
let action = match parity_ethereum::start(*config, on_client_restart_cb, || {}) {
|
||||
let action = match parity_ethereum::start(*config, logger, on_client_restart_cb, || {}) {
|
||||
Ok(action) => action,
|
||||
Err(_) => return 1,
|
||||
};
|
||||
@@ -262,6 +264,25 @@ pub unsafe extern fn parity_set_panic_hook(callback: Callback, param: *mut c_voi
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn parity_set_logger(
|
||||
logger_mode: *const u8,
|
||||
logger_mode_len: usize,
|
||||
log_file: *const u8,
|
||||
log_file_len: usize,
|
||||
logger: *mut *mut c_void) {
|
||||
|
||||
let mut logger_cfg = parity_ethereum::LoggerConfig::default();
|
||||
logger_cfg.mode = String::from_utf8(slice::from_raw_parts(logger_mode, logger_mode_len).to_owned()).ok();
|
||||
|
||||
// Make sure an empty string is not constructed as file name (to prevent panic)
|
||||
if log_file_len != 0 && !log_file.is_null() {
|
||||
logger_cfg.file = String::from_utf8(slice::from_raw_parts(log_file, log_file_len).to_owned()).ok();
|
||||
}
|
||||
|
||||
*logger = Arc::into_raw(parity_ethereum::setup_log(&logger_cfg).expect("Logger initialized only once; qed")) as *mut _;
|
||||
}
|
||||
|
||||
// Internal structure for handling callbacks that get passed a string.
|
||||
struct CallbackStr {
|
||||
user_data: *mut c_void,
|
||||
|
||||
Reference in New Issue
Block a user